Skip to content

Commit 276ad5c

Browse files
committed
Fix native constructor and pool exports
Update documentation Verbiage
1 parent d4d5626 commit 276ad5c

File tree

7 files changed

+118
-49
lines changed

7 files changed

+118
-49
lines changed

README.md

Lines changed: 74 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,77 @@
33
[![Build Status](https://secure.travis-ci.org/brianc/node-postgres.svg?branch=master)](http://travis-ci.org/brianc/node-postgres)
44
[![Dependency Status](https://david-dm.org/brianc/node-postgres.svg)](https://david-dm.org/brianc/node-postgres)
55

6-
PostgreSQL client for node.js. Pure JavaScript and optional native libpq bindings.
6+
Non-blocking PostgreSQL client for node.js. Pure JavaScript and optional native libpq bindings.
77

88
## Install
99

1010
```sh
1111
$ npm install pg
1212
```
1313

14+
## Intro & Examples
1415

15-
## Examples
16+
### Simple example
17+
18+
```js
19+
var pg = require('pg');
20+
21+
// instantiate a new client
22+
// the client will read connection information from
23+
// the same environment varaibles used by postgres cli tools
24+
var client = new pg.Client();
25+
26+
// connect to our PostgreSQL server instance
27+
client.connect(function (err) {
28+
if (err) throw err;
29+
30+
// execute a query on our database
31+
client.query('SELECT $1::text as name', ['brianc'], function (err, result) {
32+
if (err) throw err;
33+
34+
// just print the result to the console
35+
console.log(result.rows[0]); // outputs: { name: 'brianc' }
36+
37+
// disconnect the client
38+
client.end(function (err) {
39+
if (err) throw err;
40+
});
41+
});
42+
});
43+
44+
```
1645

1746
### Client pooling
1847

19-
Generally you will access the PostgreSQL server through a pool of clients. A client takes a non-trivial amount of time to establish a new connection. A client also consumes a non-trivial amount of resources on the PostgreSQL server - not something you want to do on every http request. Good news: node-postgres ships with built in client pooling.
48+
If you're working on something like a web application which makes frequent queries you'll want to access the PostgreSQL server through a pool of clients. Why? There is ~20-30 millisecond delay (YMMV) when connecting a new client to the PostgreSQL server because of the startup handshake. Also, PostgreSQL can only support a limited number of clients...it depends on the amount of ram on your database server, but generally more than 100 clients at a time is a bad thing. :tm: Finally
49+
PostgreSQL can only execute 1 query at a time per connected client.
50+
51+
With that in mind we can imagine a situtation where you have a web server which connects and disconnects a new client for every web request or every query (don't do this!). If you get only 1 request at a time everything will seem to work fine, though it will be a touch slower due to the connection overhead. Once you get >500 simultaneous requests your web server will attempt to open 500 connections to the PostgreSQL backend and :boom: you'll run out of memory on the PostgreSQL server, it will become
52+
unresponsive, your app will seem to hang, and everything will break. Boooo!
53+
54+
__Good news__: node-postgres ships with built in client pooling.
2055

2156
```javascript
22-
var Pool = require('pg').Pool;
57+
var pg = require('pg');
2358

59+
// create a config to configure both pooling behavior
60+
// and client options
61+
// note: all config is optional and the environment variables
62+
// will be read if the config is not present
2463
var config = {
2564
user: 'foo', //env var: PGUSER
2665
database: 'my_db', //env var: PGDATABASE
2766
password: 'secret', //env var: PGPASSWORD
28-
port: 5432 //env var: PGPORT
67+
port: 5432, //env var: PGPORT
68+
max: 10, // max number of clients in the pool
69+
idleTimeoutMillis: 30000, // how long a client is allowed to remain idle before being closed
2970
};
3071

31-
var pool = new Pool(config);
72+
var pool = new pg.Pool(config);
3273

3374
//this initializes a connection pool
34-
//it will keep idle connections open for a (configurable) 30 seconds
35-
//and set a limit of 10 (also configurable)
75+
//it will keep idle connections open for a 30 seconds
76+
//and set a limit of maximum 10 idle clients
3677
pool.connect(function(err, client, done) {
3778
if(err) {
3879
return console.error('error fetching client from pool', err);
@@ -50,35 +91,13 @@ pool.connect(function(err, client, done) {
5091
});
5192
```
5293

53-
node-postgres uses [pg-pool](https://github.com/brianc/node-pg-pool.git) to manage pooling and only provides a very thin layer on top. It's highly recommend you read the documentation for [pg-pool](https://github.com/brianc/node-pg-pool.git)
94+
node-postgres uses [pg-pool](https://github.com/brianc/node-pg-pool.git) to manage pooling and includes it and exports it for convienience. If you want, you can `require('pg-pool')` and use it directly - its the same as the constructor exported at `pg.Pool`.
5495

55-
[Check this out for the get up and running quickly example](https://github.com/brianc/node-postgres/wiki/Example)
96+
It's __highly recommend__ you read the documentation for [pg-pool](https://github.com/brianc/node-pg-pool.git).
5697

57-
### Client instance
5898

59-
Sometimes you may not want to use a pool of connections. You can easily connect a single client to a postgres instance, run some queries, and disconnect.
60-
61-
```javascript
62-
var pg = require('pg');
99+
[Here is an up & running quickly example](https://github.com/brianc/node-postgres/wiki/Example)
63100

64-
var conString = "postgres://username:password@localhost/database";
65-
66-
var client = new pg.Client(conString);
67-
client.connect(function(err) {
68-
if(err) {
69-
return console.error('could not connect to postgres', err);
70-
}
71-
client.query('SELECT NOW() AS "theTime"', function(err, result) {
72-
if(err) {
73-
return console.error('error running query', err);
74-
}
75-
console.log(result.rows[0].theTime);
76-
//output: Tue Jan 15 2013 19:12:47 GMT-600 (CST)
77-
client.end();
78-
});
79-
});
80-
81-
```
82101

83102
## [More Documentation](https://github.com/brianc/node-postgres/wiki)
84103

@@ -91,26 +110,41 @@ $ npm install pg pg-native
91110
```
92111

93112

94-
node-postgres contains a pure JavaScript protocol implementation which is quite fast, but you can optionally use native bindings for a 20-30% increase in parsing speed. Both versions are adequate for production workloads.
113+
node-postgres contains a pure JavaScript protocol implementation which is quite fast, but you can optionally use [native](https://github.com/brianc/node-pg-native) [bindings](https://github.com/brianc/node-libpq) for a 20-30% increase in parsing speed (YMMV). Both versions are adequate for production workloads. I personally use the pure JavaScript implementation because I like knowing whats going on all the way down to the binary on the socket, and it allows for some fancier [use](https://github.com/brianc/node-pg-cursor) [cases](https://github.com/brianc/node-pg-query-stream) which are difficult to do with libpq. :smile:
114+
115+
To use the native bindings, first install [pg-native](https://github.com/brianc/node-pg-native.git). Once pg-native is installed, simply replace `var pg = require('pg')` with `var pg = require('pg').native`. Make sure any exported constructors from `pg` are from the native instance. Example:
95116

96-
To use the native bindings, first install [pg-native](https://github.com/brianc/node-pg-native.git). Once pg-native is installed, simply replace `require('pg')` with `require('pg').native`.
117+
```js
118+
var pg = require('pg').native
119+
var Pool = require('pg').Pool // bad! this is not bound to the native client
120+
var Client = require('pg').Client // bad! this is the pure JavaScript client
121+
122+
var pg = require('pg').native
123+
var Pool = pg.Pool // good! a pool bound to the native client
124+
var Client = pg.Client // good! this client uses libpq bindings
125+
```
97126

98127
node-postgres abstracts over the pg-native module to provide exactly the same interface as the pure JavaScript version. Care has been taken to keep the number of api differences between the two modules to a minimum; however, it is recommend you use either the pure JavaScript or native bindings in both development and production and don't mix & match them in the same process - it can get confusing!
99128

100129
## Features
101130

102131
* pure JavaScript client and native libpq bindings share _the same api_
103-
* optional connection pooling
132+
* connection pooling
104133
* extensible js<->postgresql data-type coercion
105134
* supported PostgreSQL features
106135
* parameterized queries
107136
* named statements with query plan caching
108137
* async notifications with `LISTEN/NOTIFY`
109138
* bulk import & export with `COPY TO/COPY FROM`
110139

140+
## Extras
141+
142+
node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture.
143+
Entire list can be found on [wiki](https://github.com/brianc/node-postgres/wiki/Extras)
144+
111145
## Contributing
112146

113-
__We love contributions!__
147+
__:heart: contributions!__
114148

115149
If you need help getting the tests running locally or have any questions about the code when working on a patch please feel free to email me or gchat me.
116150

@@ -132,17 +166,14 @@ If at all possible when you open an issue please provide
132166

133167
Usually I'll pop the code into the repo as a test. Hopefully the test fails. Then I make the test pass. Then everyone's happy!
134168

135-
If you need help or run into _any_ issues getting node-postgres to work on your system please report a bug or contact me directly. I am usually available via google-talk at my github account public email address.
169+
If you need help or run into _any_ issues getting node-postgres to work on your system please report a bug or contact me directly. I am usually available via google-talk at my github account public email address. Remember this is a labor of love, and though I try to get back to everything sometimes life takes priority, and I might take a while. It helps if you use nice code formatting in your issue, search for existing answers before posting, and come back and close out the issue if you figure out a solution. The easier you can make it for me, the quicker I'll try and respond to you!
170+
171+
If you need deeper support, have application specific questions, would like to sponsor development, or want consulting around node & postgres please send me an email, I'm always happy to discuss!
136172

137173
I usually tweet about any important status updates or changes to node-postgres on twitter.
138174
Follow me [@briancarlson](https://twitter.com/briancarlson) to keep up to date.
139175

140176

141-
## Extras
142-
143-
node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture.
144-
Entire list can be found on [wiki](https://github.com/brianc/node-postgres/wiki/Extras)
145-
146177
## License
147178

148179
Copyright (c) 2010-2016 Brian Carlson (brian.m.carlson@gmail.com)

lib/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ var Client = require('./client');
44
var defaults = require('./defaults');
55
var Connection = require('./connection');
66
var ConnectionParameters = require('./connection-parameters');
7-
var Pool = require('pg-pool');
7+
var poolFactory = require('./pool-factory');
88

99
var PG = function(clientConstructor) {
1010
EventEmitter.call(this);
1111
this.defaults = defaults;
1212
this.Client = clientConstructor;
1313
this.Query = this.Client.Query;
14-
this.Pool = Pool;
14+
this.Pool = poolFactory(this.Client);
1515
this._pools = [];
1616
this.Connection = Connection;
1717
this.types = require('pg-types');
@@ -58,7 +58,7 @@ PG.prototype.connect = function(config, callback) {
5858
config.idleTimeoutMillis = config.idleTimeoutMillis || config.poolIdleTimeout || defaults.poolIdleTimeout;
5959
config.log = config.log || config.poolLog || defaults.poolLog;
6060

61-
this._pools[poolName] = this._pools[poolName] || new Pool(config, this.Client);
61+
this._pools[poolName] = this._pools[poolName] || new this.Pool(config);
6262
var pool = this._pools[poolName];
6363
pool.connect(callback);
6464
if(!pool.listeners('error').length) {
@@ -69,7 +69,7 @@ PG.prototype.connect = function(config, callback) {
6969
}
7070
};
7171

72-
// cancel the query runned by the given client
72+
// cancel the query running on the given client
7373
PG.prototype.cancel = function(config, client, query) {
7474
if(client.native) {
7575
return client.cancel(query);

lib/pool-factory.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
var Client = require('./client');
2+
var util = require('util');
3+
var Pool = require('pg-pool');
4+
5+
module.exports = function(Client) {
6+
7+
var BoundPool = function(options) {
8+
var config = { Client: Client };
9+
for (var key in options) {
10+
config[key] = options[key];
11+
}
12+
Pool.call(this, config);
13+
};
14+
15+
util.inherits(BoundPool, Pool);
16+
17+
return BoundPool;
18+
};

test/integration/client/api-tests.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ test('api', function() {
2121
pg.connect(helper.config, assert.calls(function(err, client, done) {
2222
assert.equal(err, null, "Failed to connect: " + helper.sys.inspect(err));
2323

24+
if (helper.args.native) {
25+
assert(client.native)
26+
} else {
27+
assert(!client.native)
28+
}
29+
2430
client.query('CREATE TEMP TABLE band(name varchar(100))');
2531

2632
['the flaming lips', 'wolf parade', 'radiohead', 'bright eyes', 'the beach boys', 'dead black hearts'].forEach(function(bandName) {

test/integration/client/heroku-ssl-tests.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ test('connection with config ssl = true', function() {
2525
pg.end();
2626
}))
2727
}));
28-
});
28+
});

test/integration/connection-pool/error-tests.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
var helper = require(__dirname + "/../test-helper");
22
var pg = require(__dirname + "/../../../lib");
3-
pg = pg;
43

54
//first make pool hold 2 clients
65
pg.defaults.poolSize = 2;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var helper = require(__dirname + "/../test-helper")
2+
var pg = helper.pg
3+
var native = helper.args.native
4+
5+
var pool = new pg.Pool()
6+
7+
pool.connect(assert.calls(function(err, client, done) {
8+
if (native) {
9+
assert(client.native)
10+
} else {
11+
assert(!client.native)
12+
}
13+
done()
14+
pool.end()
15+
}))

0 commit comments

Comments
 (0)