Skip to content

Commit 3219db9

Browse files
committed
All tests passing
1 parent f41839b commit 3219db9

File tree

6 files changed

+143
-156
lines changed

6 files changed

+143
-156
lines changed

Makefile

-1
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,3 @@ test-pool:
6262

6363
jshint:
6464
@echo "***Starting jshint***"
65-
@./node_modules/.bin/jshint lib

lib/client.js

+84-103
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ Client.prototype.connect = function(callback) {
6767
if(self.ssl) {
6868
con.requestSsl();
6969
} else {
70-
con.startup(self._getStartupConfiguration());
70+
con.startup(self.getStartupConf());
7171
}
7272
});
7373

7474
con.on('sslconnect', function() {
75-
con.startup(self._getStartupConfiguration());
75+
con.startup(self.getStartupConf());
7676
});
7777

7878
function checkPgPass(cb) {
@@ -108,21 +108,56 @@ Client.prototype.connect = function(callback) {
108108
self.secretKey = msg.secretKey;
109109
});
110110

111-
112-
con.on('readyForQuery', function() {
113-
var activeQuery = self.activeQuery;
114-
self.activeQuery = null;
115-
self.readyForQuery = true;
116-
self._pulseQueryQueue();
117-
if(activeQuery) {
118-
activeQuery.handleReadyForQuery(con);
119-
}
120-
});
121-
122111
//hook up query handling events to connection
123112
//after the connection initially becomes ready for queries
124113
con.once('readyForQuery', function() {
125-
self._attachEventListeners(con);
114+
self._connecting = false;
115+
116+
//delegate rowDescription to active query
117+
con.on('rowDescription', function(msg) {
118+
self.activeQuery.handleRowDescription(msg);
119+
});
120+
121+
//delegate dataRow to active query
122+
con.on('dataRow', function(msg) {
123+
self.activeQuery.handleDataRow(msg);
124+
});
125+
126+
//delegate portalSuspended to active query
127+
con.on('portalSuspended', function(msg) {
128+
self.activeQuery.handlePortalSuspended(con);
129+
});
130+
131+
//deletagate emptyQuery to active query
132+
con.on('emptyQuery', function(msg) {
133+
self.activeQuery.handleEmptyQuery(con);
134+
});
135+
136+
//delegate commandComplete to active query
137+
con.on('commandComplete', function(msg) {
138+
self.activeQuery.handleCommandComplete(msg, con);
139+
});
140+
141+
//if a prepared statement has a name and properly parses
142+
//we track that its already been executed so we don't parse
143+
//it again on the same client
144+
con.on('parseComplete', function(msg) {
145+
if(self.activeQuery.name) {
146+
con.parsedStatements[self.activeQuery.name] = true;
147+
}
148+
});
149+
150+
con.on('copyInResponse', function(msg) {
151+
self.activeQuery.handleCopyInResponse(self.connection);
152+
});
153+
154+
con.on('copyData', function (msg) {
155+
self.activeQuery.handleCopyData(msg, self.connection);
156+
});
157+
158+
con.on('notification', function(msg) {
159+
self.emit('notification', msg);
160+
});
126161

127162
//process possible callback argument to Client#connect
128163
if (callback) {
@@ -134,6 +169,16 @@ Client.prototype.connect = function(callback) {
134169
self.emit('connect');
135170
});
136171

172+
con.on('readyForQuery', function() {
173+
var activeQuery = self.activeQuery;
174+
self.activeQuery = null;
175+
self.readyForQuery = true;
176+
self._pulseQueryQueue();
177+
if(activeQuery) {
178+
activeQuery.handleReadyForQuery(con);
179+
}
180+
});
181+
137182
con.on('error', function(error) {
138183
if(this.activeQuery) {
139184
var activeQuery = self.activeQuery;
@@ -187,75 +232,19 @@ Client.prototype.connect = function(callback) {
187232
self.emit('notice', msg);
188233
});
189234

190-
var result;
191-
192235
if (!callback) {
193-
result = new global.Promise(function (resolve, reject) {
194-
con.once('connect', function () {
195-
con.removeListener('error', reject)
236+
return new global.Promise((resolve, reject) => {
237+
this.once('error', reject)
238+
this.once('connect', () => {
239+
this.removeListener('error', reject)
196240
resolve()
197241
})
198-
this.once('error', reject)
199-
}.bind(this))
242+
})
200243
}
201244

202-
return result;
203245
};
204246

205-
206-
// once a connection is established connect listeners
207-
Client.prototype._attachEventListeners = function(con) {
208-
var self = this;
209-
self._connecting = false;
210-
211-
//delegate rowDescription to active query
212-
con.on('rowDescription', function(msg) {
213-
self.activeQuery.handleRowDescription(msg);
214-
});
215-
216-
//delegate dataRow to active query
217-
con.on('dataRow', function(msg) {
218-
self.activeQuery.handleDataRow(msg);
219-
});
220-
221-
//delegate portalSuspended to active query
222-
con.on('portalSuspended', function(msg) {
223-
self.activeQuery.handlePortalSuspended(con);
224-
});
225-
226-
//deletagate emptyQuery to active query
227-
con.on('emptyQuery', function(msg) {
228-
self.activeQuery.handleEmptyQuery(con);
229-
});
230-
231-
//delegate commandComplete to active query
232-
con.on('commandComplete', function(msg) {
233-
self.activeQuery.handleCommandComplete(msg, con);
234-
});
235-
236-
//if a prepared statement has a name and properly parses
237-
//we track that its already been executed so we don't parse
238-
//it again on the same client
239-
con.on('parseComplete', function(msg) {
240-
if(self.activeQuery.name) {
241-
con.parsedStatements[self.activeQuery.name] = true;
242-
}
243-
});
244-
245-
con.on('copyInResponse', function(msg) {
246-
self.activeQuery.handleCopyInResponse(self.connection);
247-
});
248-
249-
con.on('copyData', function (msg) {
250-
self.activeQuery.handleCopyData(msg, self.connection);
251-
});
252-
253-
con.on('notification', function(msg) {
254-
self.emit('notification', msg);
255-
});
256-
}
257-
258-
Client.prototype._getStartupConfiguration = function() {
247+
Client.prototype.getStartupConf = function() {
259248
var params = this.connectionParameters;
260249

261250
var data = {
@@ -370,54 +359,46 @@ Client.prototype.copyTo = function (text) {
370359
};
371360

372361
Client.prototype.query = function(config, values, callback) {
373-
var promise;
374-
var isQueryable = typeof config.submit == 'function';
362+
//can take in strings, config object or query object
375363
var query;
376-
// if we receive an object with a 'submit' function we delegate
377-
// processing to the passed object - this is how pg.Query, QueryStream, and Cursor work
378-
if (isQueryable) {
379-
query = config;
380-
// accept client.query(new Query('select *'), (err, res) => { }) call signature
364+
var result;
365+
if (typeof config.submit == 'function') {
366+
query = config
367+
result = query
381368
if (typeof values == 'function') {
382-
query.callback = query.callback || values;
369+
query.callback = query.callback || values
383370
}
384371
} else {
385-
query = new Query(config, values, callback);
386-
if (!query.callback) {
387-
promise = new global.Promise(function (resolve, reject) {
388-
query.on('error', reject);
389-
query.on('end', resolve);
390-
});
391-
}
372+
query = new Query(config, values, callback)
373+
result = query.callback ? undefined : new global.Promise((resolve, reject) => {
374+
query.once('end', resolve)
375+
query.once('error', reject)
376+
})
392377
}
378+
393379
if(this.binary && !query.binary) {
394380
query.binary = true;
395381
}
396-
397-
// TODO - this is a smell
398382
if(query._result) {
399383
query._result._getTypeParser = this._types.getTypeParser.bind(this._types);
400384
}
401385

402386
this.queryQueue.push(query);
403387
this._pulseQueryQueue();
404-
405-
// if we were passed a queryable, return it
406-
// otherwise return callback/promise result
407-
return isQueryable ? query : promise;
388+
return result
408389
};
409390

410391
Client.prototype.end = function(cb) {
411392
this._ending = true;
412393
if (cb) {
413-
this.connection.once('end', cb);
414394
this.connection.end();
415-
return;
395+
this.connection.once('end', cb);
396+
} else {
397+
return new global.Promise((resolve, reject) => {
398+
this.connection.end()
399+
this.connection.once('end', resolve)
400+
})
416401
}
417-
return new global.Promise((resolve) => {
418-
this.connection.end();
419-
this.connection.once('end', resolve);
420-
});
421402
};
422403

423404
Client.md5 = function(string) {

lib/connection.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ Connection.prototype.end = function() {
315315
//0x58 = 'X'
316316
this.writer.add(emptyBuffer);
317317
this._ending = true;
318-
return this.stream.end(END_BUFFER);
318+
return this.stream.write(END_BUFFER);
319319
};
320320

321321
Connection.prototype.close = function(msg, more) {

test/integration/client/error-handling-tests.js

+45-44
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,7 @@ var createErorrClient = function() {
1616

1717
const suite = new helper.Suite('error handling')
1818

19-
suite.test('query receives error on client shutdown', false, function(done) {
20-
var client = new Client();
21-
client.connect(function(err) {
22-
if (err) {
23-
return done(err)
24-
}
25-
client.query('SELECT pg_sleep(5)', assert.calls(function(err, res) {
26-
assert(err instanceof Error)
27-
done()
28-
}));
29-
setTimeout(() => {
30-
client.end()
31-
assert.emits(client, 'end');
32-
}, 50)
33-
});
34-
});
35-
36-
suite.test('within a simple query', (done) => {
37-
var client = createErorrClient();
38-
39-
var query = client.query(new pg.Query("select eeeee from yodas_dsflsd where pixistix = 'zoiks!!!'"));
40-
41-
assert.emits(query, 'error', function(error) {
42-
assert.equal(error.severity, "ERROR");
43-
done();
44-
});
45-
});
46-
47-
(function () {
19+
;(function () {
4820
var client = createErorrClient();
4921

5022
var q = client.query({ text: "CREATE TEMP TABLE boom(age integer); INSERT INTO boom (age) VALUES (28);", binary: false });
@@ -84,17 +56,6 @@ suite.test('within a simple query', (done) => {
8456
});
8557
})();
8658

87-
suite.test('non-query error', function(done) {
88-
var client = new Client({
89-
user:'asldkfjsadlfkj'
90-
});
91-
client.on('error', (err) => {
92-
assert(err instanceof Error)
93-
done()
94-
});
95-
client.connect();
96-
});
97-
9859
suite.test('non-query error with callback', function(done) {
9960
var client = new Client({
10061
user:'asldkfjsadlfkj'
@@ -120,19 +81,59 @@ suite.test('non-error calls supplied callback', function(done) {
12081
}))
12182
});
12283

84+
suite.test('when connecting to an invalid host with callback', function (done) {
85+
var client = new Client({
86+
host: 'asldkfjasdf!!#1308140.com'
87+
});
88+
client.connect(function(error, client) {
89+
assert(error instanceof Error);
90+
done();
91+
});
92+
});
93+
12394
suite.test('when connecting to invalid host with promise', function(done) {
12495
var client = new Client({
12596
host: 'asdlfkjasldkfjlaskdfj'
12697
});
12798
client.connect().catch((e) => done());
12899
});
129100

130-
suite.test('when connecting to an invalid host with callback', function (done) {
101+
suite.test('non-query error', function(done) {
131102
var client = new Client({
132-
host: 'asldkfjasdf!!#1308140.com'
103+
user:'asldkfjsadlfkj'
133104
});
134-
client.connect(function(error, client) {
135-
assert(error instanceof Error);
105+
client.connect()
106+
.catch(e => {
107+
assert(e instanceof Error)
108+
done()
109+
})
110+
});
111+
112+
113+
suite.test('query receives error on client shutdown', false, function(done) {
114+
var client = new Client();
115+
client.connect(function(err) {
116+
if (err) {
117+
return done(err)
118+
}
119+
client.query('SELECT pg_sleep(5)', assert.calls(function(err, res) {
120+
assert(err instanceof Error)
121+
done()
122+
}));
123+
setTimeout(() => {
124+
client.end()
125+
assert.emits(client, 'end');
126+
}, 50)
127+
});
128+
});
129+
130+
suite.test('within a simple query', (done) => {
131+
var client = createErorrClient();
132+
133+
var query = client.query(new pg.Query("select eeeee from yodas_dsflsd where pixistix = 'zoiks!!!'"));
134+
135+
assert.emits(query, 'error', function(error) {
136+
assert.equal(error.severity, "ERROR");
136137
done();
137138
});
138139
});

0 commit comments

Comments
 (0)