@ovotech/laminar-pg
TypeScript icon, indicating that this package has built-in type declarations

0.12.6 • Public • Published

Laminar Postgres Service

Handle lifecyle of the pg connection pool.

Usage

examples/simple.ts

import { get, init, HttpService, jsonOk, router, HttpListener } from '@ovotech/laminar';
import { PgService, pgMiddleware } from '@ovotech/laminar-pg';
import { Pool } from 'pg';

const pool = new PgService(
  new Pool({ connectionString: 'postgres://example-admin:example-pass@localhost:5432/example', max: 5 }),
);
const withDb = pgMiddleware({ db: pool });

const listener: HttpListener = withDb(
  router(
    get('/test', async ({ db }) => {
      const { rows } = await db.query(`SELECT 'example' as "col"`);
      return jsonOk(rows);
    }),
  ),
);

const http = new HttpService({ listener });

// Wait for the pool to be connected, before starting the service
init({ initOrder: [pool, http], logger: console });

Loading enum types

PG doesn't parse enum arrays properly, since their oids are dynamic https://github.com/brianc/node-pg-types/issues/56

laminar-pg can mitigate that by loading all the enum oids at runtime and setting the appropriate parsers, before the pool is set to accept requests.

examples/enum-arrays.ts

import { get, init, HttpService, jsonOk, router, HttpListener } from '@ovotech/laminar';
import { PgService, pgMiddleware } from '@ovotech/laminar-pg';
import { Pool } from 'pg';

const pool = new PgService(
  new Pool({ connectionString: 'postgres://example-admin:example-pass@localhost:5432/example', max: 5 }),
  { initEnumTypeParsers: true },
);
const withDb = pgMiddleware({ db: pool });

const listener: HttpListener = withDb(
  router(
    get('/test', async ({ db }) => {
      const { rows } = await db.query(`SELECT ARRAY['Pending', 'Active']::enum_state[] as "col"`);
      return jsonOk(rows);
    }),
  ),
);

const http = new HttpService({ listener });

// Wait for the pool to be connected, before starting the service
init({ initOrder: [pool, http], logger: console });

Transactions

You can use transactions to make sure related queries are linked together and don't affect the database state unless everything passes. The transaction promise is wrapped in "BEGIN" and "COMMIT" as we as call "ROLLBACK" if the promise is rejected.

examples/transactions.ts:(transactions)

const insertedIds = await db.transaction(async (t) => {
  const result1 = await t.query<{ id: number }>('INSERT INTO animals (name) VALUES ($1) RETURNING id', [
    'transaction-test1',
  ]);

  const result2 = await t.query<{ id: number }>('INSERT INTO animals (name) VALUES ($1) RETURNING id', [
    'transaction-test2',
  ]);

  return [result1.rows[0].id, result2.rows[0].id];
});

const { rows } = await db.query<{ id: number; name: string }>(
  'SELECT name, id FROM animals WHERE id = ANY($1) ORDER BY name ASC',
  [insertedIds],
);

Isolation level

Transactions allow for setting isolation options for them.

examples/transactions-isolation-level.ts:(transactions)

const insertedIds = await db.transaction({ isolationLevel: 'serializable' }, async (t) => {
  const result1 = await t.query<{ id: number }>('INSERT INTO animals (name) VALUES ($1) RETURNING id', [
    'transaction-test1',
  ]);

  return [result1.rows[0].id];
});

Running the tests

You can run the tests with:

yarn test

Coding style (linting, etc) tests

Style is maintained with prettier and eslint

yarn lint

Deployment

Deployment is preferment by yarn automatically on merge / push to main, but you'll need to bump the package version numbers yourself. Only updated packages with newer versions will be pushed to the npm registry.

Contributing

Have a bug? File an issue with a simple example that reproduces this so we can take a look & confirm.

Want to make a change? Submit a PR, explain why it's useful, and make sure you've updated the docs (this file) and the tests (see test folder).

License

This project is licensed under Apache 2 - see the LICENSE file for details

Readme

Keywords

none

Package Sidebar

Install

npm i @ovotech/laminar-pg

Weekly Downloads

438

Version

0.12.6

License

Apache-2.0

Unpacked Size

51.1 kB

Total Files

30

Last publish

Collaborators

  • ovox
  • oep-accounts-bot
  • ovo.backstage.admins
  • bookings-team
  • orion-bot
  • bizval-bot
  • oeptariffs
  • props
  • metering-reads-health-bot
  • ovotech-identity
  • paceteamkaluza
  • trading-and-dispatch
  • retail-payg-tech
  • accrecovo
  • ovo.trading.tech
  • qe-team
  • ovotech-smart-thermostat
  • rise-team
  • engagement-insights
  • myovo-self-serve-service-account
  • mars-rover
  • ape-team
  • kaluza-devex
  • ohs-aurora
  • kaluza-rnr
  • ipa-bot
  • kawbot
  • data.discovery.ovo
  • ovotech-sg
  • ovotech-qs
  • ovoenergyapps
  • homemoves
  • ovo-oot-bot
  • cp-ui-tooling
  • ovo-bit-tech
  • sir_hiss