Skip to content

Commit 9168956

Browse files
committed
Merge remote branch 'upstream/master'
Conflicts: lib/query.js lib/types.js test/unit/client/query-tests.js test/unit/client/typed-query-results-tests.js
2 parents 36243af + 45f2168 commit 9168956

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1019
-649
lines changed

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
/.emacs-project
1+
node_modules/
22
*.swp
33
*.log
44
.lock-wscript
55
build/
6-
/todo.org

README.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
#node-postgres
22

3-
Non-blocking PostgreSQL client for node.js. Pure JavaScript and native libpq bindings.
3+
Non-blocking PostgreSQL client for node.js. Pure JavaScript and native libpq bindings. Active development, well tested, and production use.
44

55
## Installation
66

77
npm install pg
8+
9+
### notice
10+
node-postgres compiles native bindings when you install. The native bindings do not _currently_ compile with node v0.5.x. I'm working on support for v0.5.x. In the mean time if you get a compilation failure during installation you have still successfully installed the module; however, you cannot use the native bindings -- only the pure javascript bindings.
811

912
## Examples
1013

11-
All examples will work with the pure javascript bindings (currently default) or the libpq native (c/c++) bindings (currently in beta)
12-
13-
To use native libpq bindings replace `require('pg')` with `require('pg').native`.
14-
15-
The two share the same interface so __no other code changes should be required__. If you find yourself having to change code other than the require statement when switching from `pg` to `pg.native`, please report an issue.
16-
17-
node-postgres supports both an 'event emitter' style API and a 'callback' style. The callback style is more concise and generally preferred, but the evented API can come in handy. They can be mixed and matched. The only events which do __not__ fire when callbacks are supplied are the `error` events, as they are to be handled by the callback function.
18-
1914
### Simple, using built-in client pool
2015

2116
var pg = require('pg');
@@ -73,9 +68,19 @@ node-postgres supports both an 'event emitter' style API and a 'callback' style.
7368
client.end();
7469
});
7570

71+
### Example notes
72+
73+
node-postgres supports both an 'event emitter' style API and a 'callback' style. The callback style is more concise and generally preferred, but the evented API can come in handy. They can be mixed and matched. The only events which do __not__ fire when callbacks are supplied are the `error` events, as they are to be handled by the callback function.
74+
75+
All examples will work with the pure javascript bindings (currently default) or the libpq native (c/c++) bindings (currently in beta)
76+
77+
To use native libpq bindings replace `require('pg')` with `require('pg').native`.
78+
79+
The two share the same interface so __no other code changes should be required__. If you find yourself having to change code other than the require statement when switching from `pg` to `pg.native`, please report an issue.
80+
7681
### Info
7782

78-
* a pure javascript client and native libpq bindings with _the same api_
83+
* pure javascript client and native libpq bindings share _the same api_
7984
* _heavily_ tested
8085
* the same suite of 200+ integration tests passed by both javascript & libpq bindings
8186
* benchmark & long-running memory leak tests performed before releases
@@ -84,7 +89,7 @@ node-postgres supports both an 'event emitter' style API and a 'callback' style.
8489
* Linux, OS X
8590
* node 2.x & 4.x
8691
* row-by-row result streaming
87-
* optional, built-in connection pooling
92+
* built-in (optional) connection pooling
8893
* responsive project maintainer
8994
* supported PostgreSQL features
9095
* parameterized queries
@@ -94,9 +99,7 @@ node-postgres supports both an 'event emitter' style API and a 'callback' style.
9499
* query queue
95100
* active development
96101
* fast
97-
* No dependencies (other than PostgreSQL)
98-
* No monkey patching
99-
* Tried to mirror the node-mysql api as much as possible for future multi-database-supported ORM implementation ease
102+
* close mirror of the node-mysql api for future multi-database-supported ORM implementation ease
100103

101104
### Contributors
102105

@@ -109,15 +112,23 @@ Many thanks to the following:
109112
* [JulianBirch](https://github.com/JulianBirch)
110113
* [ef4](https://github.com/ef4)
111114
* [napa3um](https://github.com/napa3um)
115+
* [drdaeman](https://github.com/drdaeman)
116+
* [booo](https://github.com/booo)
117+
* [neonstalwart](https://github.com/neonstalwart)
118+
* [homme](https://github.com/homme)
119+
* [bdunavant](https://github.com/bdunavant)
120+
* [tokumine](https://github.com/tokumine)
112121

113122
## Documentation
114123

115-
Still a work in progress, I am trying to flesh out the wiki...
124+
Documentation is a work in progress primarily taking place on the github WIKI
116125

117126
### [Documentation](https://github.com/brianc/node-postgres/wiki)
118127

119128
### __PLEASE__ check out the WIKI
120129

130+
If you have a question, post it to the FAQ section of the WIKI so everyone can read the answer
131+
121132
## Production Use
122133
* [bayt.com](http://bayt.com)
123134

lib/client-pool.js

Lines changed: 0 additions & 93 deletions
This file was deleted.

lib/client.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
var sys = require('sys');
21
var crypto = require('crypto');
32
var EventEmitter = require('events').EventEmitter;
3+
var util = require('util');
44

55
var Query = require(__dirname + '/query');
66
var utils = require(__dirname + '/utils');
@@ -17,19 +17,18 @@ var Client = function(config) {
1717
this.database = config.database || defaults.database;
1818
this.port = config.port || defaults.port;
1919
this.host = config.host || defaults.host;
20-
this.queryQueue = [];
2120
this.connection = config.connection || new Connection({stream: config.stream});
2221
this.queryQueue = [];
2322
this.password = config.password || defaults.password;
2423
this.encoding = 'utf8';
2524
var self = this;
2625
};
2726

28-
sys.inherits(Client, EventEmitter);
27+
util.inherits(Client, EventEmitter);
2928

3029
var p = Client.prototype;
3130

32-
p.connect = function() {
31+
p.connect = function(callback) {
3332
var self = this;
3433
var con = this.connection;
3534
if(this.host && this.host.indexOf('/') === 0) {
@@ -85,11 +84,17 @@ p.connect = function() {
8584
}
8685
});
8786

88-
self.emit('connect');
87+
if (!callback) {
88+
self.emit('connect');
89+
} else {
90+
callback(null,self);
91+
//remove callback for proper error handling after the connect event
92+
callback = null;
93+
}
8994

9095
con.on('notification', function(msg) {
9196
self.emit('notification', msg);
92-
})
97+
});
9398

9499
});
95100

@@ -104,7 +109,11 @@ p.connect = function() {
104109

105110
con.on('error', function(error) {
106111
if(!self.activeQuery) {
107-
self.emit('error', error);
112+
if(!callback) {
113+
self.emit('error', error);
114+
} else {
115+
callback(error);
116+
}
108117
} else {
109118
//need to sync after error during a prepared statement
110119
if(self.activeQuery.isPreparedStatement) {
@@ -117,7 +126,7 @@ p.connect = function() {
117126

118127
con.on('notice', function(msg) {
119128
self.emit('notice', msg);
120-
})
129+
});
121130

122131
};
123132

@@ -130,7 +139,7 @@ p._pulseQueryQueue = function() {
130139
this.activeQuery.submit(this.connection);
131140
} else if(this.hasExecuted) {
132141
this.activeQuery = null;
133-
this.emit('drain')
142+
this._drainPaused > 0 ? this._drainPaused++ : this.emit('drain')
134143
}
135144
}
136145
};
@@ -155,6 +164,19 @@ p.query = function(config, values, callback) {
155164
return query;
156165
};
157166

167+
//prevents client from otherwise emitting 'drain' event until 'resumeDrain' is called
168+
p.pauseDrain = function() {
169+
this._drainPaused = 1;
170+
};
171+
172+
//resume raising 'drain' event
173+
p.resumeDrain = function() {
174+
if(this._drainPaused > 1) {
175+
this.emit('drain');
176+
}
177+
this._drainPaused = 0;
178+
};
179+
158180
p.end = function() {
159181
this.connection.end();
160182
};

lib/connection.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
var sys = require('sys');
21
var net = require('net');
32
var crypto = require('crypto');
43
var EventEmitter = require('events').EventEmitter;
4+
var util = require('util');
55

66
var utils = require(__dirname + '/utils');
77
var Writer = require(__dirname + '/writer');
@@ -19,7 +19,7 @@ var Connection = function(config) {
1919
this.writer = new Writer();
2020
};
2121

22-
sys.inherits(Connection, EventEmitter);
22+
util.inherits(Connection, EventEmitter);
2323

2424
var p = Connection.prototype;
2525

@@ -86,11 +86,6 @@ p._send = function(code, more) {
8686
}
8787
}
8888

89-
var termBuffer = new Buffer([0x58, 0, 0, 0, 4]);
90-
p.end = function() {
91-
var wrote = this.stream.write(termBuffer);
92-
};
93-
9489
p.query = function(text) {
9590
//0x51 = Q
9691
this.stream.write(this.writer.addCString(text).flush(0x51));
@@ -138,7 +133,7 @@ p.bind = function(config, more) {
138133
.addInt16(len); //number of parameters
139134
for(var i = 0; i < len; i++) {
140135
var val = values[i];
141-
if(val === null) {
136+
if(val === null || typeof val === "undefined") {
142137
buffer.addInt32(-1);
143138
} else {
144139
val = val.toString();
@@ -326,7 +321,7 @@ p.parseR = function(msg) {
326321
return msg;
327322
}
328323
}
329-
throw new Error("Unknown authenticatinOk message type" + sys.inspect(msg));
324+
throw new Error("Unknown authenticatinOk message type" + util.inspect(msg));
330325
};
331326

332327
p.parseS = function(msg) {
@@ -387,16 +382,30 @@ p.parseD = function(msg) {
387382
};
388383

389384
//parses error
390-
p.parseE = function(msg) {
385+
p.parseE = function(input) {
391386
var fields = {};
387+
var msg, item;
392388
var fieldType = this.readString(1);
393389
while(fieldType != '\0') {
394390
fields[fieldType] = this.parseCString();
395391
fieldType = this.readString(1);
396392
}
393+
if (input.name === 'error') {
394+
// the msg is an Error instance
395+
msg = new Error(fields.M);
396+
for (item in input) {
397+
// copy input properties to the error
398+
if (input.hasOwnProperty(item)) {
399+
msg[item] = input[item];
400+
}
401+
}
402+
} else {
403+
// the msg is an object literal
404+
msg = input;
405+
msg.message = fields.M;
406+
}
397407
msg.severity = fields.S;
398408
msg.code = fields.C;
399-
msg.message = fields.M;
400409
msg.detail = fields.D;
401410
msg.hint = fields.H;
402411
msg.position = fields.P;

lib/defaults.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,7 @@ module.exports = {
1212
rows: 0,
1313
//number of connections to use in connection pool
1414
//0 will disable connection pooling
15-
poolSize: 10
15+
poolSize: 10,
16+
//duration of node-pool timeout
17+
poolIdleTimeout: 30000
1618
}

0 commit comments

Comments
 (0)