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

@conjurelabs/pg-dir

v2.3.0

Published

query postgres using directories of templatized sql flat files

Downloads

63

Readme

pg-dir

this module exports a class that uses pg-dot-template to fill in templatized sql files, and provides some nicities to query and use data.

install

# peer dependency
npm install pg

# this module
npm install @conjurelabs/pg-dir

use

see the node postgres docs on setting up your database connection.

once pg is connected, then store you .sql files in a directory and initialize PgDir to start querying.

pg pool config

you can set the config which will be used for all pool connections

const { usingPoolConfig } = require('@conjurelabs/pg-dir')

usingPoolConfig({
  idleTimeoutMillis: 10000
})

this should be set before any use of sql

directory setup

./sql/accounts/get-account.sql

select *
from accounts
where id = $PG{id}
limit 1;

./sql/accounts/create-account.sql

insert into accounts (first_name, last_name, type, email, added)
values (!PG{firstName}, !PG{lastName}, $PG{type}, !PG{email}, now())
returning *;

./sql/accounts/index.js

const PgDir = require('@conjurelabs/pg-dir')

module.exports = new PgDir(__dirname)

normal queries

an instance of PgDir will expose camel-cased filenames, allowing you to query each easily

index.js

const accountsSql = require('./sql/accounts')

async function main() {
  const accounts = await accountsSql.getAccount({
    id: 123
  })

  console.log(accounts[0])
  // row keys are camel-cased
  /*
    {
      id: 123,
      firstName: 'Timo',
      lastName: 'Mars',
      type: 'admin',
      email: '[email protected]',
      added: '2020-01-20T23:04:00.250Z'
    }
   */
  
  // `firstName`, `lastName` and `email`
  // will log '<REDACTED>' to console
  // but will pass actual values to postgres
  // (due to using `!PG{...}`)
  //
  // `type` will show 'user' in console
  // and will pass 'user' to postgres
  // (due to using `$PG{...}`)
  await accountsSql.createAccount({
    firstName: 'timoteo',
    lastName: 'marshall',
    type: 'user',
    email: '[email protected]'
  })
}
await main()

.one()

often you will only want a single row

const account = await accountsSql.getAccount.one({
  id: 123
})

.hash(key)

a common pattern is to pull rows and have them stored in a lookup hash, by specific key

const accounts = await accountsSql.getAllAccounts.hash('email')({
  limit: 10
})
// returns { [email]: <row> }

.fullResponse()

if you need to access the full postgres response object, you can use .fullResponse

const accountsResponse = await accountsSql.getAccount.fullResponse({
  id: 123
})
const account = accountsResponse.rows[0]

custom template handlers

$PG{name} can be used to replace values, and !PG{name} can be used to replace while redacting values from console logs.

these will only work in a postgres where clause

see the pg-dot-template docs' section on expression handlers to see more.

transactions

pg-dir adds utility methods for dealing with begin, commit and rollback (transaction blocks)

const transaction = await accountsSql.transaction

try {
  // triggers `begin` query
  await transaction.begin()

  const newAccountRow = await transaction.createAccount.one({
    firstName: 'timoteo',
    lastName: 'marshall',
    type: 'user',
    email: '[email protected]'
  })

  await transaction.createAccountLogin({
    accountId: newAccountRow.id
  })

  // triggers `commit` query
  // then attempts connection.release()
  await transaction.commit()
} catch(err) {
  // triggers `rollback` query
  // then connection.release()
  await transaction.rollback()

  console.error(err)
}

you can also create savepoints, and rollback to these savepoints

note that if you rollback to a savepoint the sql pool connection will not be released

await transaction.savepoint('some_point')

// do something else

await transaction.rollback('some_point')

console logging

logging is built in - this library uses the debug module

DEBUG="pg-dir:query" node ./

this will log all queries before they are executed, and these logs will be sanitized on non-development environments

DEBUG="pg-dir:executed" node ./

this will log queries as they are executed, with no sanitization

the exact query being passed to pg, along with an array of arguments for placeholder values, will be logged