https://github.com/conjurelabs/pg-dir
query postgres using directories of templatized sql flat files
https://github.com/conjurelabs/pg-dir
flat-file node postgres templatized
Last synced: 3 months ago
JSON representation
query postgres using directories of templatized sql flat files
- Host: GitHub
- URL: https://github.com/conjurelabs/pg-dir
- Owner: ConjureLabs
- License: mit
- Created: 2020-01-20T22:15:35.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2023-10-03T14:03:19.000Z (over 1 year ago)
- Last Synced: 2025-03-05T00:34:18.082Z (3 months ago)
- Topics: flat-file, node, postgres, templatized
- Language: JavaScript
- Size: 72.3 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: LICENSE
Awesome Lists containing this project
README
# pg-dir
this module exports a class that uses [pg-dot-template](https://github.com/ConjureLabs/pg-dot-template/) to fill in templatized sql files, and provides some nicities to query and use data.
## install
```sh
# peer dependency
npm install pg# this module
npm install @conjurelabs/pg-dir
```## use
see [the node postgres docs](https://node-postgres.com/) 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](https://node-postgres.com/api/pool) which will be used for all pool connections
```js
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_
```sql
select *
from accounts
where id = $PG{id}
limit 1;
```_./sql/accounts/create-account.sql_
```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_
```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__
```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 '' 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
```js
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
```js
const accounts = await accountsSql.getAllAccounts.hash('email')({
limit: 10
})
// returns { [email]: }
```### .fullResponse()
if you need to access the full postgres response object, you can use `.fullResponse`
```js
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](https://github.com/ConjureLabs/pg-dot-template#postgres-expression-handlers) to see more.
### transactions
`pg-dir` adds utility methods for dealing with `begin`, `commit` and `rollback` (transaction blocks)
```js
const transaction = await accountsSql.transactiontry {
// 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
```js
await transaction.savepoint('some_point')// do something else
await transaction.rollback('some_point')
```### console logging
logging is built in - this library uses the [debug](https://www.npmjs.com/package/debug) module
```sh
DEBUG="pg-dir:query" node ./
```this will log all queries _before_ they are executed, and these logs will be sanitized on non-development environments
```sh
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