Skip to content

Instantly share code, notes, and snippets.

@Vinorcola
Last active November 2, 2015 21:01
Show Gist options
  • Save Vinorcola/714bf21884dde48203f9 to your computer and use it in GitHub Desktop.
Save Vinorcola/714bf21884dde48203f9 to your computer and use it in GitHub Desktop.
Node - pg with native promises (pattern)

Use Promises with PostgreSQL in Node

This pattern is a pattern I use for all my Node projects that need PostgreSQL. I work a lot with Promises, and ended-up designing this db.js file.

Put this file wherever you want in your app directory. Edit the connectionInfo string and voilà!

Call the execute method passing a callback function. Your callback function will be called with a function as first parameter which will allow you to execute SQL queries retourning Promises. Execute as much queries as you want, but don't forget to return a Promise that must be resolved once all your queries are done. After that, the database connection will be properly closed automatically.

var pg = require('pg')
var connectionInfo = 'postgres://username:password@localhost/database'
var self = {
/**
* Open a connection and execute the callback passing the connection as the first argument.
*
* @note Your callback must return a Promise.
*/
execute: function(callback)
{
return new Promise(function(resolve, reject)
{
pg.connect(connectionInfo, function(error, connection, closeConnection)
{
if (error)
{
error.message = 'Database connection failed: ' + error.message
reject(error)
}
else
{
callback(function()
{
var param = []
for (var i = 0; i < arguments.length; ++i)
{
param.push(arguments[i])
}
return new Promise(function(resolve, reject)
{
param.push(function(error, result)
{
if (error)
{
reject(error)
}
else
{
resolve(result)
}
})
connection.query.apply(connection, param)
})
}, connection)
.then(function(result)
{
closeConnection()
resolve(result)
})
.catch(function(error)
{
closeConnection()
reject(error)
})
}
})
})
}
}
module.exports = self
var db = require('./db')
db.execute(function(query /*, connection*/)// You can get the connection as 2nd argument for more
// complex queries (e.g. with cursor)
{
// Insert something.
return query(
'INSERT INTO myTable(column1, column2) VALUES($1, $2)',
[ 'value1', 'value2' ]
)
.then(function(result)
{
// ...
return Promise.resolve()
})
// Select something.
.then(function()
{
return query(
'SELECT * FROM myTable'
)
.then(function(result)
{
// ...
return Promise.resolve()
})
})
})
// Database connection auto-close here before executing what's in the next then:
.then(function()
{
// Do something else here without the database...
})
.catch(function(error)
{
console.error(error)
})
@Vinorcola
Copy link
Author

Great. I should give it a try in a new project. You say you use a single connection within the application? In my code, I'm rather using a connection per request. Is that OK to keep a single connection for the whole server?

@vitaly-t
Copy link

vitaly-t commented Nov 2, 2015

pg-promise uses the connection pool implemented by node-postgres, which in turn redirects it into generic-pool. with pg-promise you do need to worry about keeping the connection at all.

P.S. It is awkward writing here, because posts here do not provide any notification, no way of knowing when somebody has replied.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment