Skip to content

Types: Add "pg" property to FastifyInstance #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,33 @@ fastify.listen(3000, err => {

As you can see there is no need to close the client, since is done internally. Promises and async await are supported as well.

### Name option
If you need to have multiple databases set up, then you can name each one of them by passing `name: 'foo'`. It will then be accessible as `fastify.pg.foo` instead of `fastify.pg`.
You can't use both named and an unnamed postgres conenction at once.

```js
const fastify = require('fastify')()

fastify.register(require('fastify-postgres'), {
connectionString: 'postgres://postgres@localhost/postgres',
name: 'foo'
})

fastify.get('/user/:id', (req, reply) => {
fastify.pg.foo.query(
'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
function onResult (err, result) {
reply.send(err || result)
}
)
})

fastify.listen(3000, err => {
if (err) throw err
console.log(`server listening on ${fastify.server.address().port}`)
})
```

### Native option
If you want to gain the maximum performances you can install [pg-native](https://github.com/brianc/node-pg-native), and pass `native: true` to the plugin options.
*Note: it requires PostgreSQL client libraries & tools installed, see [instructions](https://github.com/brianc/node-pg-native#install).*
Expand Down Expand Up @@ -211,10 +238,24 @@ Install the compiler and typings for pg module:
npm install --save-dev typescript @types/pg
```

You can find examples in the [examples/typescript](./examples/typescript) directory.
Add the `pg` property to `FastifyInstance`. Like this if you use an unnamed instance:

```typescript
import type { PostgresDb } from 'fastify-postgres';

declare module 'fastify' {
export interface FastifyInstance {
pg: PostgresDb;
}
}
```

More examples in the [examples/typescript](./examples/typescript) directory.

## Development and Testing

### Docker approach

First, start postgres with:

```
Expand All @@ -234,6 +275,18 @@ CREATE TABLE
$ npm test
```

### Custom Postgres approach

1. Set up a database of your choice oin a postgres server of your choice
2. Create the required table using
```sql
CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);
```
3. Specify a connection string to it in a `DATABASE_TEST_URL` environment variable when you run the tests
```bash
DATABASE_TEST_URL="postgres://username:password@localhost/something_thats_a_test_database" npm test
```

## Acknowledgements

This project is kindly sponsored by:
Expand Down
6 changes: 3 additions & 3 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ function fastifyPostgres (fastify, options, next) {
if (name) {
if (!fastify.pg) {
fastify.decorate('pg', {})
}

if (fastify.pg[name]) {
} else if (fastify.pg.pool instanceof pg.Pool) {
return next(new Error('fastify-postgres already has an unnamed instance registered'))
} else if (fastify.pg[name]) {
return next(new Error(`fastify-postgres '${name}' instance name has already been registered`))
}

Expand Down
11 changes: 11 additions & 0 deletions test/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use strict'

const BAD_DB_NAME = 'db_that_does_not_exist'
const connectionString = process.env.DATABASE_TEST_URL || 'postgres://postgres:postgres@localhost/postgres'
const connectionStringBadDbName = connectionString.replace(/\/[^/]+$/, '/' + BAD_DB_NAME)

module.exports = Object.freeze({
BAD_DB_NAME,
connectionString,
connectionStringBadDbName
})
48 changes: 35 additions & 13 deletions test/initialization.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const t = require('tap')
const test = t.test
const Fastify = require('fastify')
const fastifyPostgres = require('../index')
const { connectionString } = require('./helpers')

test('Should be able to use native module', (t) => {
t.plan(2)
Expand All @@ -12,7 +13,7 @@ test('Should be able to use native module', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
native: true
})

Expand All @@ -38,7 +39,7 @@ test('Should be able to use an alternative pg module', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
pg: altPg
})

Expand All @@ -64,20 +65,20 @@ test('Should not throw if registered within different scopes (with and without n

fastify.register(function scopeOne (instance, opts, next) {
instance.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

next()
})

fastify.register(function scopeTwo (instance, opts, next) {
instance.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'one'
})

instance.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'two'
})

Expand All @@ -96,16 +97,37 @@ test('Should throw when trying to register multiple instances without giving a n
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

fastify.ready((err) => {
t.ok(err)
t.is(err.message, 'fastify-postgres has already been registered')
t.is((err || {}).message, 'fastify-postgres has already been registered')
})
})

test('Should throw when trying to register a named instance after an unnamed', (t) => {
t.plan(2)

const fastify = Fastify()
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString
})

fastify.register(fastifyPostgres, {
connectionString,
name: 'two'
})

fastify.ready((err) => {
t.ok(err)
t.is((err || {}).message, 'fastify-postgres already has an unnamed instance registered')
})
})

Expand All @@ -118,17 +140,17 @@ test('Should throw when trying to register duplicate connection names', (t) => {

fastify
.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name
})
fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name
})

fastify.ready((err) => {
t.ok(err)
t.is(err.message, `fastify-postgres '${name}' instance name has already been registered`)
t.is((err || {}).message, `fastify-postgres '${name}' instance name has already been registered`)
})
})

Expand All @@ -139,7 +161,7 @@ test('fastify.pg namespace should exist', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

fastify.ready((err) => {
Expand All @@ -159,7 +181,7 @@ test('fastify.pg.test namespace should exist', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'test'
})

Expand Down
37 changes: 18 additions & 19 deletions test/query.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ const t = require('tap')
const test = t.test
const Fastify = require('fastify')
const fastifyPostgres = require('../index')
const {
BAD_DB_NAME,
connectionString,
connectionStringBadDbName
} = require('./helpers')

test('When fastify.pg root namespace is used:', (t) => {
t.test('Should be able to connect and perform a query with a callback', (t) => {
Expand All @@ -13,7 +18,7 @@ test('When fastify.pg root namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

fastify.ready((err) => {
Expand All @@ -40,7 +45,7 @@ test('When fastify.pg root namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

fastify.ready((err) => {
Expand All @@ -60,7 +65,7 @@ test('When fastify.pg root namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres'
connectionString
})

fastify.ready((err) => {
Expand All @@ -85,10 +90,8 @@ test('When fastify.pg root namespace is used:', (t) => {
const fastify = Fastify()
t.teardown(() => fastify.close())

const DB_NAME = 'database_that_do_not_exist'

fastify.register(fastifyPostgres, {
connectionString: `postgres://postgres:postgres@localhost/${DB_NAME}`
connectionString: connectionStringBadDbName
})

fastify.ready((err) => {
Expand All @@ -97,7 +100,7 @@ test('When fastify.pg root namespace is used:', (t) => {
fastify.pg.query('SELECT NOW()', (err, result) => {
t.is(result, undefined)
t.ok(err)
t.is(err.message, `database "${DB_NAME}" does not exist`)
t.is(err.message, `database "${BAD_DB_NAME}" does not exist`)
})
})
}
Expand All @@ -109,10 +112,8 @@ test('When fastify.pg root namespace is used:', (t) => {
const fastify = Fastify()
t.teardown(() => fastify.close())

const DB_NAME = 'database_that_do_not_exist'

fastify.register(fastifyPostgres, {
connectionString: `postgres://postgres:postgres@localhost/${DB_NAME}`
connectionString: connectionStringBadDbName
})

fastify.ready((err) => {
Expand All @@ -125,7 +126,7 @@ test('When fastify.pg root namespace is used:', (t) => {
})
.catch((err) => {
t.ok(err)
t.is(err.message, `database "${DB_NAME}" does not exist`)
t.is(err.message, `database "${BAD_DB_NAME}" does not exist`)
})
})
})
Expand All @@ -141,7 +142,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'test'
})

Expand All @@ -167,7 +168,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'test'
})

Expand All @@ -187,7 +188,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'test'
})

Expand All @@ -212,7 +213,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
t.teardown(() => fastify.close())

fastify.register(fastifyPostgres, {
connectionString: 'postgres://postgres:postgres@localhost/postgres',
connectionString,
name: 'test',
native: true
})
Expand All @@ -237,10 +238,8 @@ test('When fastify.pg.test namespace is used:', (t) => {
const fastify = Fastify()
t.teardown(() => fastify.close())

const DB_NAME = 'database_that_do_not_exist'

fastify.register(fastifyPostgres, {
connectionString: `postgres://postgres:postgres@localhost/${DB_NAME}`,
connectionString: connectionStringBadDbName,
name: 'test'
})

Expand All @@ -254,7 +253,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
})
.catch((err) => {
t.ok(err)
t.is(err.message, `database "${DB_NAME}" does not exist`)
t.is(err.message, `database "${BAD_DB_NAME}" does not exist`)
})
})
})
Expand Down
Loading