All Projects → martijndeh → lego

martijndeh / lego

Licence: MIT license
A lightweight SQL (string) builder using ES6 template strings. Lego embraces SQL instead of adding yet another abstraction layer.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to lego

pgsink
Logically replicate data out of Postgres into sinks (files, Google BigQuery, etc)
Stars: ✭ 53 (-1.85%)
Mutual labels:  postgres
pg-dba-egitim
Eğitim Konuları
Stars: ✭ 23 (-57.41%)
Mutual labels:  postgres
Venflow
A brand new, fast and lightweight ORM, build for PostgreSQL.
Stars: ✭ 162 (+200%)
Mutual labels:  postgres
gae-postgres
Connect to Cloud SQL for PostgreSQL from Google App Engine
Stars: ✭ 23 (-57.41%)
Mutual labels:  postgres
sqlx-adapter
Asynchronous casbin adapter for mysql, postgres, sqlite based on sqlx-rs
Stars: ✭ 27 (-50%)
Mutual labels:  postgres
pycroft
The new AG DSN management system
Stars: ✭ 16 (-70.37%)
Mutual labels:  postgres
migrant lib
Embeddable migration management
Stars: ✭ 22 (-59.26%)
Mutual labels:  postgres
pgsql-ast-parser
Yet another simple Postgres SQL parser
Stars: ✭ 152 (+181.48%)
Mutual labels:  postgres
pg-ipc
IPC over PostgreSQL LISTEN/NOTIFY/UNLISTEN exposed as an EventEmitter
Stars: ✭ 27 (-50%)
Mutual labels:  postgres
google-bigtable-postgres-fdw
Google Bigtable Postgres FDW in Rust
Stars: ✭ 37 (-31.48%)
Mutual labels:  postgres
flan
A tasty tool that lets you save, load and share postgres snapshots with ease
Stars: ✭ 177 (+227.78%)
Mutual labels:  postgres
django-postgres-copy
Quickly import and export delimited data with Django support for PostgreSQL's COPY command
Stars: ✭ 151 (+179.63%)
Mutual labels:  postgres
ParseCareKit
Securely synchronize any CareKit 2.1+ based app to a Parse Server Cloud. Compatible with parse-hipaa.
Stars: ✭ 28 (-48.15%)
Mutual labels:  postgres
rocket-rest-api-with-jwt
A Rusty Rocket fuelled with Diesel and secured by JWT
Stars: ✭ 62 (+14.81%)
Mutual labels:  postgres
elephantry
PostgreSQL OMM for rust
Stars: ✭ 28 (-48.15%)
Mutual labels:  postgres
Odin-Securities
A master database of securities data for use with the Odin algorithmic trading platform.
Stars: ✭ 17 (-68.52%)
Mutual labels:  postgres
integresql
IntegreSQL manages isolated PostgreSQL databases for your integration tests.
Stars: ✭ 475 (+779.63%)
Mutual labels:  postgres
postgres-deno
A PostgreSQL extension for Deno: run Typescript in PostgreSQL functions and triggers.
Stars: ✭ 87 (+61.11%)
Mutual labels:  postgres
clock-in-out
A clock-in/out system using nestJS, PostgreSQL, TypeORM, Angular, Arduino, RxJS
Stars: ✭ 61 (+12.96%)
Mutual labels:  postgres
zenith
Neon: Serverless Postgres. We separated storage and compute to offer autoscaling, branching, and bottomless storage.
Stars: ✭ 4,239 (+7750%)
Mutual labels:  postgres

Lego.js

Build Status Coverage Status

A lightweight SQL (string) builder using ES6 template strings. Lego embraces SQL instead of adding yet another abstraction layer.

Lego.sql `SELECT * FROM users WHERE name = ${name}`;

Lego does not do simple string concatenation. Instead, Lego creates parameterized queries. For example, the following query is created from the previous call:

SELECT * FROM users WHERE name = $1

Quick start

Lego uses ES6 template strings. From the template string, a parameterized query is created and passed to the driver. The driver creates a pool of connections with the url from process.env.DATABASE_URL.

Lego.sql `INSERT INTO projects (name) VALUES (${name}) RETURNING *`
	.then((projects) => {
		return Lego.sql `INSERT INTO project_settings (project_id) VALUES (${projects[0].id})`;
	})
	.then(() => {
		// Ready! :-)
	})

You can also nest arrays of Lego instances:

Lego.sql `INSERT INTO projects (name) VALUES ${projects.map((project) => {
	return Lego.sql `(${project.name})`;
})}`;

Which creates and executes the query INSERT INTO projects (name) VALUES ($1), ($2).

Lego#append

In some cases, you want to append a statement:

const lego = Lego.sql `SELECT * FROM tests`;

if (shouldOrderBy) {
	lego.append `ORDER BY value`;
}

Lego#raw

You cannot pass raw values to your queries, unless you use Lego#raw. Be very careful not to use this with user input.

const column = 'name';
Lego.sql `UPDATE users SET ${Lego.raw(column)} = ${value}`;

Return value

Lego.sql returns a Promise-like object and the query is executed when .then(..) is invoked. The Promise is resolved with the query's result.

In DELETE, UPDATE and INSERT queries, when not using a RETURNING clause, the number of affected rows is resolved. Otherwise, the row data is resolved.

Rows to objects

Lego makes it easy to parse rows and transform them to objects. Consider the following rows:

const rows = [{
	id: 1,
	test_id: 1,
	test_name: 'Test 1'
}, {
	id: 1,
	test_id: 2,
	test_name: 'Test 2'
}];

These rows are flat but do contain 1 root object and 2 child objects. Something like the below:

const objects = [{
	id: 1,
	tests: [{
		id: 1,
		name: 'Test 1'
	}, {
		id: 2,
		name: 'Test 2'
	}]
}]

You can transform the rows by simply passing the rows to Lego's parse system and providing a definition object:

Lego.parse(rows, [{
	id: 'id',
	tests: [{
		id: 'test_id',
		name: 'test_name'
	}]
}]);

The definition object describes how to map columns and rows to objects. Every property refers to a column name. You can also call .parse(..) on a Lego object directly.

const project = await Lego.sql `SELECT
	projects.id,
	projects.created_at,
	project_members.id member_id,
	project_members.name member_name,
	project_members.email member_email
	project_members.joined_at member_joined_at
FROM projects
INNER JOIN project_members ON projects.id = project_members.project_id
WHERE
	projects.id = ${projectID}`
	.parse(rows, {
		id: 'id',
		createdAt: 'created_at',
		members: [{
			id: 'member_id',
			name: 'member_name',
			email: 'member_email',
			joinedAt: 'member_joined_at'
		}]
	});

Please have a look at the parse test cases to learn more about the different ways to transform rows to objects.

Lego#first

Or if you just want the first result from a query (or null if there were no results):

Lego.sql `SELECT * FROM accounts LIMIT 1`
	.first()
	.then((account) => {
		// account is the first row from the query, or null if no rows were found.
	});

Transactions

Transactions are also supported. You can either chain the calls manually by returning a promise in the transaction's callback:

Lego.transaction((transaction) => {
	return transaction.sql `UPDATE money SET value = value + 100`
		.then(() => {
			return transaction.sql `UPDATE money SET value = value - 100`;
		});
});

Or use the transaction's queue which invokes the queries in series:

Lego.transaction((transaction) => {
	transaction.sql `UPDATE money SET value = value + 100`;
	transaction.sql `UPDATE money SET value = value - 100`;
});

Alternatively, you can construct regular Lego instances and assign them to the transaction:

Lego.transaction((transaction) => {
	return Lego
		.sql `UPDATE money SET value = value + 100`
		.transacting(transaction)
		.then(() => {
			return Lego
				.sql `UPDATE money SET value = value - 100`
				.transacting(transaction);
		});
});

Lego#transaction returns a promise with the result of the transaction's callback.

Migrations

To create a migration you can simply invoke lego migrate:make. This creates an empty migration with an up and a down function in which you can write your queries to alter your database.

To execute migrations, simply invoke lego migrate:latest. Migrations are executed in a transaction. The transaction is passed as argument in the migrate functions.

export function up(transaction) {
	transaction.sql `CREATE TABLE tests (name TEXT UNIQUE, value INTEGER)`;
	transaction.sql `INSERT INTO tests VALUES ('Martijn', 123)`;
}

export function down(transaction) {
	transaction.sql `DROP TABLE tests`;
}

Lego creates a migrations table to keep track of all the migrations. This migrations table is created in it's own schema called lego, so don't worry about any collisions.

To execute your migrations when you call npm run release you should add a run script to your package.json:

"release": "node -r babel-register ./node_modules/.bin/lego migrate:latest",

CLI

The command line interface supports the following commands:

lego version                         Prints the version of Lego.
lego migrate:make                    Creates a new migration file.
lego migrate:latest                  Migrates to the latest migration.
lego migrate:rollback                Rolls back the previous migration.
lego migrate:<version>               Migrates or rolls back to the target migration <version>.

Environment variables

Variable Description
DATABASE_URL The connection string to the database.
LEGO_DISABLE_SSL By default, Lego requires an SSL connection to the database. To disable this, you can set the LEGO_DISABLE_SSL environment variable to false.
LEGO_MAX_POOL_SIZE Sets the maximum pool size. If you don't set the max pool size, the driver sets a default value.
LEGO_MIN_POOL_SIZE Sets the minimum pool size. If you don't set the min pool size, the driver sets a default value.
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].