npm package: @rdcl/pg
Description: A wrapper around [node-postgres](https://node-postgres.com) which introduces some more convenient API's.
Author: Ruud van der Weide
Latest version: 2.0.1

# @rdcl/pg

A wrapper around [node-postgres] which introduces some more convenient API's.

[[_TOC_]]

## Usage

```javascript
// One class is exported: PG. Its arguments correspond with the arguments of Client from node-postgres.
const { PG } = require('@rdcl/pg')
const pg = new PG({
  ssl: { rejectUnauthorized: false },
})

// Helper methods are exposed to easily perform queries and return their results.
// All methods are bound to the instance so you can safely extract them.
const { select, selectOne, execute, withDB } = pg

// All results are promises.
const list = () => select`
  select id, name
  from people
`

// In the `select` and `selectOne` methods, you may specify a row mapper.
// The query is converted to a prepared statement, interpolated values are passed along safely.
const insert = (name, age) => selectOne(row => row.id)`
  insert into people (id, name, age)
  values (uuid(), ${ name }, ${ age })
  returning id
`

// The withDb method allows you to do more complicated things.
// All helper methods are available on the `db` object.
// Again, all results are promises.
const updateAge = (id, age) => withDb(async db => {
  const result = await db.selectOne`
    select *
    from people
    where id = ${ id }
  `

  if (result) {
    await db.execute`
      update people
      set
        name = ${ result.name },
        age = ${ age }
    `
  }
})

// You may also specify error mappers to translate errors to domain specific errors.
const createTransaction = (account, amount) => selectOne(row => row.id, {
  errorMapper: {
    23503: () => new NoSuchAccount(`Account ${ account } does not exist`),
  },
})`
  insert into transactions (id, account, amount)
  values (uuid(), ${ account }, ${ amount })
  returning id
`

// Alternatively, you may also use postfix notation.
const { q } = pg
const get = () => q`
  select id, name
  from shapes
`.select()
```

## Reference

### `new PG(...)`

Takes the same arguments as `Client` from [node-postgres].
Returns an object which has a couple of convenience methods.

### `PG::select`

Performs the provided query and returns the selected rows.
Optionally takes a row mapper and an error mapper.

#### Examples

```javascript
select`select 1`
select()`select 1`
select(row => row.id)`select 1 as id`
select(row => row, {
  123456: err => new Error('your error'),
})`select 1`
```

### `PG::selectOne`

Same as `PG::select`, but only returns the first row (or undefined).

### `PG::execute`

Pretty much the same as `PG::select`, but does not return anything (so does not accept a row mapper either).

### `PG::withDb`

A wrapper method which takes a callback.
This callback is called with a `Connection` object, which contains helper methods.
This method will take care of setting up a database connection, and cleaning it up afterwards (even if there were errors).

### `PG::q`

Returns a `QuerySpecification` object, which has `select`, `selectOne` and `execute` methods which function identically to the functions described above.

#### Examples

```javascript
withDb(async db => {
  // do your database stuff here
})
```

### `Connection::client`

The [node-postgres] client.

### `Connection::query`

Low level wrapper for queries, which return the original `QueryResult`.

#### Examples

```javascript
withDb(async db => {
  const result1 = await db.query`...`
  const result2 = await db.query()`...`
  const result3 = await db.query({
    errorMapper: {
      // ...
    },
  })
})
```

### `Connection::select`, `Connection::selectOne`, `Connection::execute`

Identical to the top level methods, except that these do not open a new connection (where the top level methods do).


[node-postgres]: https://node-postgres.com