Skip to content

Commit

Permalink
Give access to field names and types independently of rows (brianc#209)
Browse files Browse the repository at this point in the history
Adds a 'rowDescription' event in query object.
Add test for accessing field info via both event and result object
  • Loading branch information
Sandro Santilli committed May 30, 2013
1 parent 30d97e3 commit 77f480c
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 1 deletion.
7 changes: 7 additions & 0 deletions lib/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,19 @@ Query.prototype.handleRowDescription = function(msg) {
this._fieldNames = [];
this._fieldConverters = [];
var len = msg.fields.length;
var fields = [];
for(var i = 0; i < len; i++) {
var field = msg.fields[i];
var format = field.format;
this._fieldNames[i] = field.name;
this._fieldConverters[i] = Types.getTypeParser(field.dataTypeID, format);
fields[i] = {
name: field.name,
type: Types.getTypeName(field.dataTypeID)
};
}
this._result.fields = fields;
this.emit('rowDescription', fields);
};

Query.prototype.handleDataRow = function(msg) {
Expand Down
111 changes: 110 additions & 1 deletion lib/types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,114 @@ var noParse = function(val) {
return String(val);
};

// returns a type name for a type oid
var getTypeName = function(oid) {
// extracted with:
// select '''' || oid || ''': ' || '''' || typname || ''',' from pg_type where oid < 2048 order by oid;
var typeNames = {
'16': 'bool',
'17': 'bytea',
'18': 'char',
'19': 'name',
'20': 'int8',
'21': 'int2',
'22': 'int2vector',
'23': 'int4',
'24': 'regproc',
'25': 'text',
'26': 'oid',
'27': 'tid',
'28': 'xid',
'29': 'cid',
'30': 'oidvector',
'71': 'pg_type',
'75': 'pg_attribute',
'81': 'pg_proc',
'83': 'pg_class',
'142': 'xml',
'143': '_xml',
'194': 'pg_node_tree',
'210': 'smgr',
'600': 'point',
'601': 'lseg',
'602': 'path',
'603': 'box',
'604': 'polygon',
'628': 'line',
'629': '_line',
'650': 'cidr',
'651': '_cidr',
'700': 'float4',
'701': 'float8',
'702': 'abstime',
'703': 'reltime',
'704': 'tinterval',
'705': 'unknown',
'718': 'circle',
'719': '_circle',
'790': 'money',
'791': '_money',
'829': 'macaddr',
'869': 'inet',
'1000': '_bool',
'1001': '_bytea',
'1002': '_char',
'1003': '_name',
'1005': '_int2',
'1006': '_int2vector',
'1007': '_int4',
'1008': '_regproc',
'1009': '_text',
'1010': '_tid',
'1011': '_xid',
'1012': '_cid',
'1013': '_oidvector',
'1014': '_bpchar',
'1015': '_varchar',
'1016': '_int8',
'1017': '_point',
'1018': '_lseg',
'1019': '_path',
'1020': '_box',
'1021': '_float4',
'1022': '_float8',
'1023': '_abstime',
'1024': '_reltime',
'1025': '_tinterval',
'1027': '_polygon',
'1028': '_oid',
'1033': 'aclitem',
'1034': '_aclitem',
'1040': '_macaddr',
'1041': '_inet',
'1042': 'bpchar',
'1043': 'varchar',
'1082': 'date',
'1083': 'time',
'1114': 'timestamp',
'1115': '_timestamp',
'1182': '_date',
'1183': '_time',
'1184': 'timestamptz',
'1185': '_timestamptz',
'1186': 'interval',
'1187': '_interval',
'1231': '_numeric',
'1248': 'pg_database',
'1263': '_cstring',
'1266': 'timetz',
'1270': '_timetz',
'1560': 'bit',
'1561': '_bit',
'1562': 'varbit',
'1563': '_varbit',
'1700': 'numeric',
'1790': 'refcursor'
};
if ( typeNames[oid] ) return typeNames[oid];
return oid;
};

//returns a function used to convert a specific type (specified by
//oid) into a result javascript type
var getTypeParser = function(oid, format) {
Expand Down Expand Up @@ -41,5 +149,6 @@ binaryParsers.init(function(oid, converter) {

module.exports = {
getTypeParser: getTypeParser,
setTypeParser: setTypeParser
setTypeParser: setTypeParser,
getTypeName: getTypeName
};
33 changes: 33 additions & 0 deletions test/integration/client/api-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,36 @@ test('null and undefined are both inserted as NULL', function() {
}))
}))
})

test('provides field names and types to the callback', function() {
pg.connect(helper.config, assert.calls(function(err, client, done) {
assert.isNull(err);
var config = {
text: 'select $1::text as val limit 0'
};
client.query(config, ['hi'], assert.calls(function(err, result) {
assert.isNull(err);
assert.equal(result.fields.length, 1);
assert.equal(result.fields[0].name, 'val');
assert.equal(result.fields[0].type, 'text');
done();
}))
}))
})

test('provides field names and types to the rowDescription event', function() {
pg.connect(helper.config, assert.calls(function(err, client, done) {
assert.isNull(err);
var config = {
text: 'select $1::text as val limit 1'
};
var query = client.query(config, ['hi']);
assert.emits(query, 'rowDescription', function(fields) {
assert.equal(fields.length, 1);
assert.equal(fields[0].name, 'val');
assert.equal(fields[0].type, 'text');
done();
})
}))
})

0 comments on commit 77f480c

Please sign in to comment.