Skip to content

Commit d3b47a9

Browse files
committed
Merge pull request #679 from whitelynx/master
Added per-client type parser overrides.
2 parents e2ea482 + 4bfdc04 commit d3b47a9

File tree

5 files changed

+91
-2
lines changed

5 files changed

+91
-2
lines changed

lib/client.js

+12
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var crypto = require('crypto');
22
var EventEmitter = require('events').EventEmitter;
33
var util = require('util');
44
var pgPass = require('pgpass');
5+
var TypeOverrides = require('./type-overrides');
56

67
var ConnectionParameters = require(__dirname + '/connection-parameters');
78
var Query = require(__dirname + '/query');
@@ -20,6 +21,8 @@ var Client = function(config) {
2021

2122
var c = config || {};
2223

24+
this._types = new TypeOverrides(c.types);
25+
2326
this.connection = c.connection || new Connection({
2427
stream: c.stream,
2528
ssl: this.connectionParameters.ssl
@@ -227,6 +230,14 @@ Client.prototype.cancel = function(client, query) {
227230
}
228231
};
229232

233+
Client.prototype.setTypeParser = function(oid, format, parseFn) {
234+
return this._types.setTypeParser(oid, format, parseFn);
235+
};
236+
237+
Client.prototype.getTypeParser = function(oid, format) {
238+
return this._types.getTypeParser(oid, format);
239+
};
240+
230241
// Ported from PostgreSQL 9.2.4 source code in src/interfaces/libpq/fe-exec.c
231242
Client.prototype.escapeIdentifier = function(str) {
232243

@@ -302,6 +313,7 @@ Client.prototype.query = function(config, values, callback) {
302313
if(this.binary && !query.binary) {
303314
query.binary = true;
304315
}
316+
query._result._getTypeParser = this._types.getTypeParser.bind(this._types);
305317

306318
this.queryQueue.push(query);
307319
this._pulseQueryQueue();

lib/native/index.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var Native = require('pg-native');
2+
var TypeOverrides = require('../type-overrides');
23
var semver = require('semver');
34
var pkg = require('../../package.json');
45
var assert = require('assert');
@@ -15,8 +16,10 @@ var Client = module.exports = function(config) {
1516
EventEmitter.call(this);
1617
config = config || {};
1718

19+
this._types = new TypeOverrides(config.types);
20+
1821
this.native = new Native({
19-
types: config.types || require('pg-types')
22+
types: this._types
2023
});
2124

2225
this._queryQueue = [];
@@ -180,3 +183,11 @@ Client.prototype.cancel = function(query) {
180183
this._queryQueue.splice(this._queryQueue.indexOf(query), 1);
181184
}
182185
};
186+
187+
Client.prototype.setTypeParser = function(oid, format, parseFn) {
188+
return this._types.setTypeParser(oid, format, parseFn);
189+
};
190+
191+
Client.prototype.getTypeParser = function(oid, format) {
192+
return this._types.getTypeParser(oid, format);
193+
};

lib/result.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Result.prototype.addFields = function(fieldDescriptions) {
8888
for(var i = 0; i < fieldDescriptions.length; i++) {
8989
var desc = fieldDescriptions[i];
9090
this.fields.push(desc);
91-
var parser = types.getTypeParser(desc.dataTypeID, desc.format || 'text');
91+
var parser = this._getTypeParser(desc.dataTypeID, desc.format || 'text');
9292
this._parsers.push(parser);
9393
//this is some craziness to compile the row result parsing
9494
//results in ~60% speedup on large query result sets
@@ -99,4 +99,6 @@ Result.prototype.addFields = function(fieldDescriptions) {
9999
}
100100
};
101101

102+
Result.prototype._getTypeParser = types.getTypeParser;
103+
102104
module.exports = Result;

lib/type-overrides.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
var types = require('pg-types');
2+
3+
function TypeOverrides(userTypes) {
4+
this._types = userTypes || types;
5+
this.text = {};
6+
this.binary = {};
7+
}
8+
9+
TypeOverrides.prototype.getOverrides = function(format) {
10+
switch(format) {
11+
case 'text': return this.text;
12+
case 'binary': return this.binary;
13+
default: return {};
14+
}
15+
};
16+
17+
TypeOverrides.prototype.setTypeParser = function(oid, format, parseFn) {
18+
if(typeof format == 'function') {
19+
parseFn = format;
20+
format = 'text';
21+
}
22+
this.getOverrides(format)[oid] = parseFn;
23+
};
24+
25+
TypeOverrides.prototype.getTypeParser = function(oid, format) {
26+
format = format || 'text';
27+
return this.getOverrides(format)[oid] || this._types.getTypeParser(oid, format);
28+
};
29+
30+
module.exports = TypeOverrides;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
var helper = require(__dirname + '/test-helper');
2+
3+
function testTypeParser(client, expectedResult, done) {
4+
var boolValue = true;
5+
client.query('CREATE TEMP TABLE parserOverrideTest(id bool)');
6+
client.query('INSERT INTO parserOverrideTest(id) VALUES ($1)', [boolValue]);
7+
client.query('SELECT * FROM parserOverrideTest', assert.success(function(result) {
8+
assert.equal(result.rows[0].id, expectedResult);
9+
helper.pg.end();
10+
done();
11+
}));
12+
}
13+
14+
helper.pg.connect(helper.config, assert.success(function(client1, done1) {
15+
helper.pg.connect(helper.config, assert.success(function(client2, done2) {
16+
var boolTypeOID = 16;
17+
client1.setTypeParser(boolTypeOID, function(){
18+
return 'first client';
19+
});
20+
client2.setTypeParser(boolTypeOID, function(){
21+
return 'second client';
22+
});
23+
24+
client1.setTypeParser(boolTypeOID, 'binary', function(){
25+
return 'first client binary';
26+
});
27+
client2.setTypeParser(boolTypeOID, 'binary', function(){
28+
return 'second client binary';
29+
});
30+
31+
testTypeParser(client1, 'first client', done1);
32+
testTypeParser(client2, 'second client', done2);
33+
}));
34+
}));

0 commit comments

Comments
 (0)