• Stars
    star
    217
  • Rank 182,446 (Top 4 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A composable SQL query builder using template literals โœจ

Cuery - Composable SQL Querying CircleCI status

A composable SQL query builder based inspired by styled-components ๐Ÿ’… โœจ

๐Ÿ’ƒ Replace weird $1 or ? in your queries with simple functions!

โญ PostgreSQL and MySQL support!

๐Ÿ”’ Type safety (and autocompletion) with TypeScript

Why

In 2016, I wrote a blog post about composing SQL queries and published this library as a reference. The years passed, and there are much cooler ways of doing it, so this is the new way - using template literals.

Installation

For PostgreSQL users:

yarn add cuery pg
# or
npm install --save cuery pg

For MySQL users:

yarn add cuery mysql
# or
npm install --save cuery mysql

API

Import the modules for the database you use:

  • cuery/pg for PostgreSQL
  • cuery/mysql for MySQL

Both modules export the same two basic functions:

sql<Input, Output> template literal

The sql<Input, Output> template literal is meant for constructing an SQL query. It accepts functions, that will be acted as "getters" from the object you supply to the execute function, and compose other SQL queries too.

The two generics are meant for type safety, so you would declare your input and output types co-located with your query, just like a function: (input: Input) => Output.

It returns an SQL query, that later can be executed with the options needed, such as a pool (or a connection in MySQL)

const returnsNumber = sql<
  {}, // Takes no parameters as input
  { age: number }
>` // Returns a number as output
  SELECT 27 AS age
`;

const takesNumberAndReturnsIt = sql<
  { age: number }, // Takes a number as input
  { age: number }
>` // Returns a number as output
  SELECT ${p => p.age} AS age
`;

(await takesNumberAndReturnsIt.execute({ age: 27 }, { pool: new Pg.Pool() }))[0]
  .age === 27;

createSqlWithDefaults(defaults)

This function returns an sql<Input, Output> template literal function, that defaults to a specific execute options. Normally, it would be stored in a specific file in your project, that contains the information about the database connection, so you won't need to pass it all around your application.

const sql = createSqlWithDefaults({ pool: new Pg.Pool() });
const query = sql<{}, { age: number }>`SELECT 27 AS age`;
(await query.execute({}))[0].age === 27;

raw

This function is a helper function to say that the primitive passed into this function should be stringified and be added "as is" to the query. This is unsafe by nature, but when used correctly can have good implications like generating table names.

sql<{}, {}>`SELECT 27 AS ${raw("age")}`;

Usage

PostgreSQL

import { sql } from "cuery/pg";

const usersQuery = sql`SELECT name, age FROM users`;
const usersWithNameQuery = sql<{ name: string }, { name: string; age: number }>`
  SELECT name, age FROM (${usersQuery})
  WHERE name = ${params => params.name}
`;

// pool = new Pg.Pool()

const rows = await usersWithNameQuery.execute({ name: "John" }, { pool });
rows[0].age; // Type safe!

MySQL

import { sql } from "cuery/mysql";

const usersQuery = sql`SELECT name, age FROM users`;
const usersWithNameQuery = sql<{ name: string }, { name: string; age: number }>`
  SELECT name, age FROM (${usersQuery})
  WHERE name = ${params => params.name}
`;

// connection = create a new mysql connection

const rows = await usersWithNameQuery.execute({ name: "John" }, { connection });
rows[0].age; // Type safe!

Transformations

You can declare helper methods that do magic on your queries, like limit:

function limit<Input, Output>(query: Query<Input, Output>) {
  return sql<Input & { limit: Number; offset: Number }, Output>`
    SELECT *
    FROM (${query}) LIMITED__QUERY__${raw(Math.floor(Math.random() * 99999))}
    LIMIT ${p => p.limit}
    OFFSET ${p => p.offset}
  `;
}

// then you can just compose your queries!

const users = sql<
  {},
  { name: string; age: number }
>`SELECT name, age FROM users`;
const usersWithLimit = limit(users);
execute(usersWithLimit, { limit: 10, offset: 10 }); // start with offset of 10, then take 10 records.

Running tests

docker run --rm -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres:10
docker run --rm -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=password mysql:5.7
npm test

More Repositories

1

fnm

๐Ÿš€ Fast and simple Node.js version manager, built in Rust
Rust
15,628
star
2

cmd-ts

๐Ÿ’ป A type-driven command line argument parser
TypeScript
206
star
3

gpkg

๐ŸŒŽ A global Node binary manager written in Rust
Rust
63
star
4

react-gooey-nav

The React Gooey Navigation Menuโ„ข
TypeScript
55
star
5

remastered

A full-stack approach to React development
TypeScript
50
star
6

svgify

service to threshold-svg your images
JavaScript
28
star
7

pointguard

An MVP-worthy background job server for PostgreSQL, written in Rust
Rust
27
star
8

next-static-paths

Statically prevent 404s in your Next.js applications using TypeScript
TypeScript
23
star
9

factoree

๐Ÿ’ฅ๐Ÿ”’ Fail early, fail fast: type-safe and runtime-safe partial factories for TypeScript
TypeScript
23
star
10

fnm.rs

An experimental Rust implementation of fnm
Rust
20
star
11

sapapa

A soothing CouchDB client for Reason and OCaml
OCaml
17
star
12

bs-faker

Faker.js bindings for BuckleScript in Reason
Reason
17
star
13

migratype

๐Ÿ”’โ–ถ๐Ÿ”’ Safe runtime type migrations for TypeScript
TypeScript
13
star
14

benchy-action

a hassle-free GitHub Action to benchmark your code continuously.
TypeScript
12
star
15

reason-pr-labels

Look for PR labels in GitHub pull requests
OCaml
12
star
16

dotfiles

my dotfiles
Shell
11
star
17

httyped

โ›“๏ธ Type-safe HTTP client/server communications with awesome autocompletion
TypeScript
11
star
18

route-ts

TypeScript
9
star
19

simpleplan

Simple dependency injector for your precious node apps.
JavaScript
8
star
20

draft-js-create-inline-style-plugin

Handle Draft.js' inline styles as if they were controlled by strategies ๐Ÿ’ฅ
JavaScript
7
star
21

libre-converter

Converting LibreOffice documents to other formats. like PDF and stuff. yeah.
CoffeeScript
7
star
22

infer-types

Returns the exported inferred types from TypeScript.
TypeScript
6
star
23

need-this

One Store To Rule Them All
JavaScript
6
star
24

soundtype-commander

A type-safe wrapper around commander.js with excellent type inference.
TypeScript
6
star
25

lets-chat-reverseproxy

reverse proxy sso header add-on for Let's Chat
JavaScript
5
star
26

obsidian-prettier

TypeScript
4
star
27

matcher-ts

TypeScript
4
star
28

soundtype-eventemitter

A typesafe event emitter for TypeScript
TypeScript
4
star
29

draft-js-lister-plugin

automatic unordered and ordered lists in draftjs based on draft-js-plugins
JavaScript
4
star
30

tgrm

TypeScript
4
star
31

react-contexter

Use Context with Higher Order Components for better testing and reuse.
JavaScript
4
star
32

fnm-playground

I want to add Changesets so I'll do it in a different repo to test
Rust
3
star
33

circleci_redirection

Use Circle CI's artifact system to host binaries and documentation
Crystal
3
star
34

home-automation-cluster

My home automation cluster
TypeScript
3
star
35

functional-programming-smalltalks

small talks about fp in js for Keywee
3
star
36

magic-string-playground

TypeScript
2
star
37

reql-pointfree

Functional RethinkDB functions for point free programming
JavaScript
2
star
38

ical_http_server

another project to play with rust
Rust
2
star
39

neder

really simple and jewish javascript promises
JavaScript
2
star
40

homebrew-tap

A custom homebrew tap
2
star
41

telegram-to-facebook-bot

Post links tagged with `#fullstack` in your Telegram froup to your Facebook group
JavaScript
2
star
42

fb-group-poster

Posts to a facebook group using your credentials using Selenium WebDriver
JavaScript
2
star
43

serverless-graphql-demo

JavaScript
2
star
44

js-playgrounds

Experimental editor agnostic in-line evaluation: like Swift playgrounds, only for JS!
JavaScript
2
star
45

nextjs-example-fetching-gzipped

JavaScript
1
star
46

decompress-wasm-example

JavaScript
1
star
47

streaming-tester

TypeScript
1
star
48

windows-vc-dev-modules-repro

JavaScript
1
star
49

new-dotfiles

Shell
1
star
50

prs_look_for_labels

Look for PR labels in GitHub pull requests
Crystal
1
star
51

jt

small and easy jira ticket helper for bash
Shell
1
star
52

kiwi_json.cr

Save and load typed objects from Kiwi stores
Crystal
1
star
53

delegator.cr

Decorates an object and delegates missing methods to it
Crystal
1
star
54

cargo-mdbook

Distribute https://github.com/rust-lang/mdBook as a npm dependency
TypeScript
1
star
55

redis_mutex.cr

Distributed mutex in Ruby using Redis for Crystal
Crystal
1
star
56

ramda-immutable

Immutable.js helpers for Ramda
JavaScript
1
star
57

test-css-modules

JavaScript
1
star
58

docker-node-gyp

A node docker image with the headers already installed in
1
star
59

m1-node-versions

1
star
60

chrome-fulfill-request-issue

JavaScript
1
star
61

beg-to-differ

Simple string diff patching for node.js
JavaScript
1
star
62

merged_branches.rs

๐Ÿšฎ Delete merged branches from GitHub. Squashed too.
Rust
1
star