Skip to content

Commit

Permalink
Merge pull request #1 from fastify/init
Browse files Browse the repository at this point in the history
Init
  • Loading branch information
delvedor authored Oct 11, 2017
2 parents eecdf42 + e5f06bd commit 51191e7
Show file tree
Hide file tree
Showing 6 changed files with 305 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,8 @@ typings/
# dotenv environment variables file
.env

# mac files
.DS_Store

# vim swap files
*.swp
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: node_js

node_js:
- "8"
- "6"
- "4"

services:
- postgresql

notifications:
email:
on_success: never
on_failure: always
106 changes: 105 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,106 @@
# fastify-postgres
Fastify PostgreSQL connection plugin

[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) [![Build Status](https://travis-ci.org/fastify/fastify-postgres.svg?branch=master)](https://travis-ci.org/fastify/fastify-postgres)

Fastify PostgreSQL connection plugin, with this you can share the same PostgreSQL connection pool in every part of your server.
Under the hood the [node-postgres](https://github.com/brianc/node-postgres) is used, the options that you pass to `register` will be passed to the PostgreSQL pool builder.

## Install
```
npm i fastify-postgres --save
```
## Usage
Add it to you project with `register` and you are done!
This plugin will add the `pg` namespace in your Fastify instance, with the following properties:
```
connect: the function to get a connection from the pool
pool: the pool instance
Client: a clinet constructor for a single query
query: an utility to perform a query without a transaction
```

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

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

fastify.get('/user/:id', (req, reply) => {
fastify.pg.connect(onConnect)

function onConnect (err, client, release) {
if (err) return reply.send(err)

client.query(
'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
function onResult (err, result) {
release()
reply.send(err || result)
}
)
}
})

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

Async await is supported as well!
```js
const fastify = require('fastify')

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

fastify.get('/user/:id', async (req, reply) => {
const client = await fastify.pg.connect()
const { result } = await client.query(
'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
)
client.release()
return result
})

fastify.listen(3000, err => {
if (err) throw err
console.log(`server listening on ${fastify.server.address().port}`)
})
```
Use of `pg.query`
```js
const fastify = require('fastify')

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

fastify.get('/user/:id', (req, reply) => {
fastify.pg.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}`)
})
```
As you can see there is no need to close the client, since is done internally. Promises and async await are supported as well.

## Acknowledgements

This project is kindly sponsored by:
- [nearForm](http://nearform.com)
- [LetzDoIt](http://www.letzdoitapp.com/)

## License

Licensed under [MIT](./LICENSE).
50 changes: 50 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use strict'

const fp = require('fastify-plugin')
const promisify = require('util.promisify')
const pg = require('pg')

function fastifyPostgres (fastify, options, next) {
const pool = new pg.Pool(options)

fastify.decorate('pg', {
connect: pool.connect.bind(pool),
pool: pool,
Client: pg.Client,
query: promisify(query)
})

function query (text, value, callback) {
if (typeof value === 'function') {
callback = value
value = null
}

pool.connect(onConnect)

function onConnect (err, client, release) {
if (err) return callback(err)

if (value) {
client.query(text, value, onResult)
} else {
client.query(text, onResult)
}

function onResult (err, result) {
release()
callback(err, result)
}
}
}

fastify.addHook('onClose', onClose)

next()
}

function onClose (fastify, done) {
fastify.pg.pool.end(done)
}

module.exports = fp(fastifyPostgres, '>=0.13.1')
38 changes: 38 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "fastify-postgres",
"version": "0.1.0",
"description": "Fastify PostgreSQL connection plugin",
"main": "index.js",
"scripts": {
"test": "standard && tap test.js",
"postgres": "docker run --rm -p 5432:5432 postgres:9.6-alpine"
},
"repository": {
"type": "git",
"url": "git+https://github.com/fastify/fastify-postgres.git"
},
"keywords": [
"fastify",
"postgres",
"postgresql",
"database",
"connection",
"sql"
],
"author": "Tomas Della Vedova - @delvedor (http://delved.org)",
"license": "MIT",
"bugs": {
"url": "https://github.com/fastify/fastify-postgres/issues"
},
"homepage": "https://github.com/fastify/fastify-postgres#readme",
"dependencies": {
"fastify-plugin": "^0.1.1",
"pg": "^7.3.0",
"util.promisify": "^1.0.0"
},
"devDependencies": {
"fastify": "^0.29.2",
"standard": "^10.0.3",
"tap": "^10.7.2"
}
}
93 changes: 93 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict'

const t = require('tap')
const test = t.test
const Fastify = require('fastify')
const fastifyPostgres = require('./index')

test('fastify.pg namespace should exist', t => {
t.plan(5)

const fastify = Fastify()

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

fastify.ready(err => {
t.error(err)
t.ok(fastify.pg)
t.ok(fastify.pg.connect)
t.ok(fastify.pg.pool)
t.ok(fastify.pg.Client)
fastify.close()
})
})

test('should be able to connect and perform a query', t => {
t.plan(4)

const fastify = Fastify()

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

fastify.ready(err => {
t.error(err)
fastify.pg.connect(onConnect)
})

function onConnect (err, client, done) {
t.error(err)
client.query('SELECT NOW()', (err, result) => {
done()
t.error(err)
t.ok(result.rows)
fastify.close()
})
}
})

test('use query util', t => {
t.plan(3)

const fastify = Fastify()

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

fastify.ready(err => {
t.error(err)
fastify.pg.query('SELECT NOW()', (err, result) => {
t.error(err)
t.ok(result.rows)
fastify.close()
})
})
})

test('use query util with promises', t => {
t.plan(2)

const fastify = Fastify()

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

fastify.ready(err => {
t.error(err)
fastify.pg
.query('SELECT NOW()')
.then(result => {
t.ok(result.rows)
fastify.close()
})
.catch(err => {
t.fail(err)
fastify.close()
})
})
})

0 comments on commit 51191e7

Please sign in to comment.