All Projects â†’ terkelg â†’ Sqliterally

terkelg / Sqliterally

Licence: mit
Lightweight SQL query builder

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Sqliterally

Loukoum
A simple SQL Query Builder
Stars: ✭ 305 (+32.03%)
Mutual labels:  sql, query, query-builder, postgresql, postgres
Sqlx
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.
Stars: ✭ 5,039 (+2081.39%)
Mutual labels:  sql, mysql, postgresql, postgres
Jet
Type safe SQL builder with code generation and automatic query result data mapping
Stars: ✭ 373 (+61.47%)
Mutual labels:  sql, mysql, postgresql, postgres
Querybuilder
SQL query builder, written in c#, helps you build complex queries easily, supports SqlServer, MySql, PostgreSql, Oracle, Sqlite and Firebird
Stars: ✭ 2,111 (+813.85%)
Mutual labels:  sql, query-builder, mysql, postgresql
Walkable
A Clojure(script) SQL library for building APIs: Datomic® (GraphQL-ish) pull syntax, data driven configuration, dynamic filtering with relations in mind
Stars: ✭ 384 (+66.23%)
Mutual labels:  sql, query, mysql, postgresql
Sql
MySQL & PostgreSQL pipe
Stars: ✭ 81 (-64.94%)
Mutual labels:  sql, mysql, postgresql, postgres
Vscode Sqltools
Database management for VSCode
Stars: ✭ 741 (+220.78%)
Mutual labels:  sql, mysql, postgresql, postgres
Sql Lint
An SQL linter
Stars: ✭ 243 (+5.19%)
Mutual labels:  sql, mysql, postgresql, postgres
Squid
🦑 Provides SQL tagged template strings and schema definition functions.
Stars: ✭ 57 (-75.32%)
Mutual labels:  sql, query-builder, postgresql, postgres
Goqu
SQL builder and query library for golang
Stars: ✭ 984 (+325.97%)
Mutual labels:  sql, mysql, postgresql, postgres
Sqorn
A Javascript library for building SQL queries
Stars: ✭ 1,871 (+709.96%)
Mutual labels:  sql, query-builder, postgresql, postgres
Octosql
OctoSQL is a query tool that allows you to join, analyse and transform data from multiple databases and file formats using SQL.
Stars: ✭ 2,579 (+1016.45%)
Mutual labels:  sql, query, mysql, postgresql
Fluentpdo
A PHP SQL query builder using PDO
Stars: ✭ 783 (+238.96%)
Mutual labels:  sql, query, mysql, postgresql
Electrocrud
Database CRUD Application Built on Electron | MySQL, Postgres, SQLite
Stars: ✭ 1,267 (+448.48%)
Mutual labels:  sql, mysql, postgresql, postgres
Go Structured Query
Type safe SQL query builder and struct mapper for Go
Stars: ✭ 101 (-56.28%)
Mutual labels:  sql, query-builder, mysql, postgres
Yuniql
Free and open source schema versioning and database migration made natively with .NET Core.
Stars: ✭ 156 (-32.47%)
Mutual labels:  sql, mysql, postgresql
Neo4j Etl
Data import from relational databases to Neo4j.
Stars: ✭ 165 (-28.57%)
Mutual labels:  sql, mysql, postgresql
Rom Sql
SQL support for rom-rb
Stars: ✭ 169 (-26.84%)
Mutual labels:  sql, mysql, postgresql
Atdatabases
TypeScript clients for databases that prevent SQL Injection
Stars: ✭ 154 (-33.33%)
Mutual labels:  sql, mysql, postgres
Sqlcheck
Automatically identify anti-patterns in SQL queries
Stars: ✭ 2,062 (+792.64%)
Mutual labels:  sql, mysql, postgresql
sqliterally

Composable and safe parameterized queries using tagged template literals


SQLiterally makes it easy to compose safe parameterized SQL queries using template literals. Clauses are automatically arranged which means you can re-use, subquery and append new clauses as you like – order doesn't matter. All queries are well formatted and ready to be passed directly to node-pg and mysql.

Use SQLiterally as a lightweight alternative to extensive query builders like Knex.js or when big ORMs are over-kill.

OBS: SQLiterally provides a lot of freedom by design and it's not meant to reduce the SQL learning curve. It won't prevent you from writing incorrect queries.

Features

  • Build queries programmatically
  • Works directly with node-pg and mysql
  • Supports nested sub-queries
  • Queries are parametrized to protect against SQL injections
  • Write SQL as you like with no restrictions using string literals
  • Produces well-formatted queries with line breaks
  • Lightweight with no dependencies!

This module exposes two module definitions:

  • ES Module: dist/sqliterally.mjs
  • CommonJS: dist/sqliterally.js

Installation

npm install sqliterally --save

Usage

The module exposes two functions:

  • sql: Use this to construct any query. Useful for complex SQL scripts or when you know the full query and all you need is a parameterized query object.
  • query: Use this to programmatically compose parameterized queries. Useful for constructing queries as you go.
import {sql, query} from 'sqliterally';

let movie = 'Memento', year = 2001;

sql`SELECT director FROM movies WHERE title = ${movie}`;
// => {
//  text: 'SELECT director FROM movies WHERE title = $1'
//  sql => 'SELECT director FROM movies WHERE title = ?'
//  values => ['Memento']
// }

let q = query
   .select`director`
   .select`year`
   .from`movies`
   .where`title = ${movie}`
   .limit`5`;

if (year) q = q.where`year >= ${year}`;
if (writers) q = q.select`writers`;

q.build();
// => {
//  text: `SELECT director, year FROM movies WHERE title = $1 AND year >= $2 LIMIT 5'
//  sql => 'SELECT director, year FROM movies WHERE title = ? AND year >= ? LIMIT 5'
//  values => ['Memento', 2001]
// }

API

sql`string`

Returns: Object

The string can contain nested SQLiterally query and sql objects. Indexes and values are taken care of automatically.

You can pass this directly to node-pg and mysql.

let name = 'Harry Potter';
let max = 10, min = 0;

sub = sql`age > ${min} AND age < ${max}`;
sql`SELECT * FROM x WHERE name = ${name} OR (${sub}) LIMIT 2`;
// => {
//  text: 'SELECT * FROM x WHERE name = $1 OR (age > $2 OR age < $3) LIMIT 2',
//  sql: 'SELECT * FROM x WHERE name = ? OR (age > ? OR age < ?) LIMIT 2',
//  values: ['Harry Potter', 0, 10]
// }

let script = sql`
CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.modified = now();
    RETURN NEW;
END;
$$ language 'plpgsql';
`
// => { text: 'CREATE OR REPL...', sql: 'CREATE OR REPL...' values: [] }

text

Type: String

Getter that returns the parameterized string for Postgres.

sql

Type: String

Getter that returns the parameterized string for MySQL.

values

Type: Array

Getter that returns the corresponding values in order.

query

Build a query by adding clauses. The order in which clauses are added doesn't matter. The final output is sorted and returned in the correct order no matter what order you call the methods in.

You can nest as many query and sql as you like. You don't have to build sub-queries before nesting them.

query is immutable and all method calls return a new instance. This means you can build up a base query and re-use it. For example, with conditional where clauses or joins.

OBS: If you call a method multiple times, the values are concatenated in the same order you called them.

let age = 13, limit = 10, page = 1, paginate = false;

let sub = query
    .select`id`
    .from`customers`
    .where`salary > 45000`;

let main = query
    .select`*`
    .from`customers`
    .where`age > '${age}'`
    .where`id IN (${sub})`;

main = paginate ? main.limit`${limit} OFFSET ${limit * page}` : main;

main.build();

build(delimiter?)

Constructs the final query and returns a sql query object ready for node-pg and mysql.

You can still append to the returned sql object or use it as a sub-query. You don't have to call .build() when nesting queries – there's no reason to call build before you need the parameterized string and values.

delimiter

Type: String
Default: \n

Change the delimiter used to combine clauses. The default is a line break.

select`string`

Returns: query

All .select calls get reduced and joined with , on .build().

query.select`*`.build()
// => SELECT *
query.select`cat`.select`zebra`.build()
// => SELECT cat, zebra
query.select`cat, dog`.select`zebra`.build()
// => SELECT cat, dog, zebra
query.select`something`.select`5 * 3 AS result`.build()
// => SELECT something, 5 * 3 AS result

update`string`

Returns: query

Calling .update more than once result in the clause being overwritten.

query.update`film`.build()
// => UPDATE film
query.update`film`.update`books`.build()
// => UPDATE books

set`string`

Returns: query

All .set calls get reduced and joined with , on .build().

query.set`a = b`.build()
// => SET a = b
query.set`a = b`.set`z = y`.build()
// => SET a = b, z = y

from`string`

Returns: query

Calling .from more than once result in the clause being overwritten.

query.from`film`.build()
// => FROM film
query.from`film AS f`.build()
// => FROM film AS f
query.from`film`.from`books`.build()
// => FROM books

join`string`

Returns: query

query.join`c ON d`.build()
// => JOIN c ON d
query.join`a ON b.id`.join`c ON d`.build()
// => JOIN a ON b.id\nJOIN c ON d

leftJoin`string`

query.leftJoin`c ON d`.build()
// => LEFT JOIN c ON d
query.leftJoin`a ON b.id`.leftJoin`c ON d`.build()
// => LEFT JOIN a ON b.id\nLEFT JOIN c ON d

where`string`

Returns: query

All .where calls get reduced and joined with AND on .build().

query.where`a < b`.build()
// => WHERE a < b
query.where`a < b`.where`z = y`.build()
// => WHERE a < b AND z = y
query.where`a = z OR a = y`.build()
// => WHERE a = z OR a = y

orWhere`string`

Returns: query

All .orWhere calls get reduced and joined with OR on .build().

query.orWhere`a < b`.build()
// => WHERE a < b
query.orWhere`a < b`.orWhere`z = y`.build()
// => WHERE a < b OR z = y

having`string`

Returns: query

All .having calls get reduced and joined with AND on .build().

query.having`MAX (list_price) > 4000`
// => HAVING MAX (list_price) > 4000
query.having`MAX (list_price) > 4000`.having`MIN (list_price) < 500`
// => HAVING MAX (list_price) > 4000 AND MIN (list_price) < 500'

orHaving`string`

Returns: query

All .orHaving calls get reduced and joined with OR on .build().

query.orHaving`MAX (list_price) > 4000`
// => HAVING MAX (list_price) > 4000
query.orHaving`MAX (list_price) > 4000`.orHaving`MIN (list_price) < 500`
// => HAVING MAX (list_price) > 4000 OR MIN (list_price) < 500'

groupBy`string`

Returns: query

All .groupBy calls get reduced and joined with , on .build().

query.groupBy`a, b`.groupBy`c`.groupBy`d`.build()
// => GROUP BY a, b, c, d

orderBy`string`

Returns: query

All .orderBy calls get reduced and joined with , on .build().

query.orderBy`a, b`.orderBy`COUNT(c) DESC`.orderBy`d`.build()
// => ORDER BY a, b, COUNT(c) DESC, d

limit`string`

Returns: query

Calling .limit more than once result on the clause being overwritten.

query.limit`5`.build()
// => LIMIT 5
query.limit`5 OFFSET 2`.build()
// => LIMIT 5 OFFSET 2
query.limit`5`.limit`10`.build()
// => LIMIT 10

returning`string`

Returns: query

All .returning calls get reduced and joined with , on .build().

query.returning`a, b`.returning`c`.returning`d`.build()
// => RETURNING a, b, c, d

lockInShareMode

Returns: query

Getter method. Multiple invocations get ignored.

query.lockInShareMode.build()
// => LOCK IN SHARE MODE
query.select`*`.from`x`.lockInShareMode.build()
// => SELECT * FROM x LOCK IN SHARE MODE

forUpdate

Returns: query

Getter method. Multiple invocations get ignored.

query.forUpdate.build()
// => FOR UPDATE
query.select`*`.from`x`.forUpdate.build()
// => SELECT * FROM x FOR UPDATE
query.select`*`.from`x`.lockInShareMode.forUpdate.build()
// => SELECT * FROM x LOCK IN SHARE MODE FOR UPDATE

Credit

This module is inspired by sql-concat but with a different implementation, support for Postgres, single queries and with a reduced API.

The sql function and merge algorithm are based on prepare-sql.

License

MIT © Terkel Gjervig

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].