npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pg-sql-helpers

v0.3.7

Published

A set helpers for writing dynamic SQL queries with `pg-sql` in Javascript.

Downloads

109

Readme

pg-sql-helpers

A set helpers for writing dynamic SQL queries with pg-sql in Javascript.

It's sort of like a lodash or polished for writing SQL.


Features

  • Uses a simple, SQL-like syntax for building queries.
  • Enables dynamic WHERE, ORDER BY, INSERT, UPDATE, … clauses.
  • Built on top of pg-sql for writing simple SQL strings in Javascript.
  • Compatible with pg out of the box.

Example

Out of the box, pg-sql lets you write SQL just like you're used to:

import { sql } from 'pg-sql'

const name = 'john'

await pg.query(sql`
  SELECT id, name, age
  FROM users
  WHERE name = ${name}
`)

With pg-sql-helpers you can use the same SQL-like syntax when writing queries with dynamic clauses, like:

import { sql } from 'pg-sql'
import { INSERT, ORDER_BY, WHERE } from 'pg-sql-helpers'

await pg.query(sql`
  SELECT id, name, age
  FROM users
  ${WHERE({ name: 'john', age: { gt: 42 } })}
`)

await pg.query(sql`
  ${INSERT('users', { name: 'jane', age: 42 })}
  RETURNING *
`)

await pg.query(sql`
  SELECT id, name, age
  FROM users
  ${ORDER_BY(['name', '-age'])}
`)

So that when building APIs that allow dynamic user input (eg. inserts, updates, filters, sorting, pagination, etc.) you can write powerful queries without concatenating strings or doing other confusing things.


Why?

Choosing not to use an ORM is a very common and reasonable choice. But one of the biggest downsides is that you lose some of the expressiveness when dynamic SQL statements are concerned. For example when you need to...

  • ...insert or update from a handful of different attributes.
  • ...filter by custom parameters.
  • ...limit, order and paginate with custom parameters.

Building SQL strings by hand for these dynamic inputs is tedious.

There are libraries that try to solve this, but most of them re-invent the entire SQL syntax with Javascript methods—some even require defining your schema in advance. You're basically back to re-inventing an ORM but without any of the benefits.

pg-sql-helpers lets you continue to write simple, composable SQL strings with the help of pg-sql, while giving you a handful of helper functions to make building queries from dynamic, user-provided values much, much easier.


API

All of the helpers are exported in lowercase and uppercase, so you can match your existing SQL preferences.

AND

AND([table: String], params: Object)

sql`
  SELECT *
  FROM users
  WHERE name = 'John'
  ${AND({ age: { gt: 42 } })}
`

The same as the WHERE helper, but the keyword will be AND instead. Useful when you've already got a hardcoded WHERE you need to augment. The table string is optional, but can be passed to qualify the columns to match.

INSERT

INSERT(table: String, values: Object|Array<Object>)

sql`
  ${INSERT('users', { name: 'john', age: 42 })}
  WHERE id = '1'
  RETURNING *
`

Create a SQL "INSERT" clause from a set of values. Useful when writing dynamic updates based on attributes that may or may not be passed. In the case of an array of values, the keys from the first object in the array will be used.

KEYS

KEYS(values: Object|Array<Object>)

sql`
  SELECT ${KEYS({ name: true, age: true })}
  FROM users
`

Extract and join the keys of values into a SQL string. Useful for building dynamic clauses like SELECT, INSERT, UPDATE, etc. In the case of an array of values, the keys from the first object in the array will be used.

LIMIT

LIMIT(number: Number)

sql`
  SELECT id, name, age
  FROM users
  ${LIMIT(20)}
`

Create a SQL "LIMIT" clause from a dynamic number. In the number is Infinity, LIMIT ALL will be output instead.

OFFSET

OFFSET(number: Number)

sql`
  SELECT id, name, age
  FROM users
  LIMIT 10 ${OFFSET(20)}
`

Create a SQL "OFFSET" clause from a dynamic number.

OR

OR([table: String], params: Object)

sql`
  SELECT *
  FROM users
  WHERE name = 'John'
  ${OR({ age: { gt: 42 } })}
`

The same as the WHERE helper, but the keyword will be OR instead. Useful when you've already got a hardcoded WHERE you need to augment. The table string is optional, but can be passed to qualify the columns to match.

ORDER_BY

ORDER_BY([table: String], params: Array)

sql`
  SELECT *
  FROM users
  ${ORDER_BY(['name', '-age'])}
`

Create a SQL "ORDER BY" clause from an array of params. The params are column name identifiers. They default to ASC NULLS LAST, but can be prefixed with '-' to denote DESC NULLS LAST.

SELECT

SELECT([table: String], values: Object|Array<Object>|Array<String>)

sql`
  ${SELECT(['id', 'name'])}
  FROM users
  WHERE id = '1'
`

UPDATE

UPDATE(table: String, values: Object|Array<Object>)

sql`
  ${UPDATE('users', { name: 'john', age: 42 })}
  WHERE id = '1'
  RETURNING *
`

Create a SQL "UPDATE" clause from a set of values. Useful when writing dynamic updates based on attributes that may or may not be passed. In the case of an array of values, the keys from the first object in the array will be used.

UPSERT

UPSERT(table: String, constraint: String|Array<String>, values: Object|Array<Object>)

sql`
  ${UPSERT('users', 'id', { id: 3, name: 'john', age: 42 })}
  RETURNING *
`

Create a SQL "INSERT ON CONFLICT UPDATE" clause from a set of values. Useful when writing dynamic inserts where a row might already exist with outdated properties that you want to update. In the case of an array of values, the keys from the first object in the array will be used.

VALUES

VALUES(values: Object|Array<Object>)

sql`
  UPDATE users
  SET (name, age) = (${VALUES({ name: 'john', age: 42 })})
`

Extract and join the values of values into a SQL string. Useful for building dynamic clauses like INSERT, UPDATE, etc.

WHERE

WHERE([table: String], params: Object)

sql`
  SELECT * 
  FROM users
  ${WHERE({ age: { gte: 42 } })}
`

Create a SQL "WHERE" clause from a set of params, with optional table name string. Useful when writing dynamic filters based on parameters that may or may not be passed. The table string is optional, but can be passed to qualify the columns to match.

The parameters are nested objects with modifiers:

| Operator | SQL | | ------------ | ------- | | eq | = | | ne | != | | gt | > | | gte | >= | | lt | < | | lte | <= |

If a parameter value is not an object, it will be defaulted to eq and compared using =.


License

This package is MIT-licensed.