make type coercion a part of the api
This commit is contained in:
parent
8a6725688f
commit
08eddd26e2
@ -4,6 +4,7 @@ var EventEmitter = require('events').EventEmitter;
|
|||||||
|
|
||||||
var binding = require(__dirname + '/../build/default/binding');
|
var binding = require(__dirname + '/../build/default/binding');
|
||||||
var utils = require(__dirname + "/utils");
|
var utils = require(__dirname + "/utils");
|
||||||
|
var types = require(__dirname + "/types");
|
||||||
var Connection = binding.Connection;
|
var Connection = binding.Connection;
|
||||||
var p = Connection.prototype;
|
var p = Connection.prototype;
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ var ctor = function(config) {
|
|||||||
})
|
})
|
||||||
connection.on('_error', function(err) {
|
connection.on('_error', function(err) {
|
||||||
if(connection._activeQuery) {
|
if(connection._activeQuery) {
|
||||||
connection._activeQuery.emit('error', err);
|
connection._activeQuery.handleError(err);
|
||||||
} else {
|
} else {
|
||||||
connection.emit('error', err);
|
connection.emit('error', err);
|
||||||
}
|
}
|
||||||
@ -110,6 +111,9 @@ var connect = function(config, callback) {
|
|||||||
client.on('connect', function() {
|
client.on('connect', function() {
|
||||||
callback(null, client);
|
callback(null, client);
|
||||||
})
|
})
|
||||||
|
client.on('error', function(err) {
|
||||||
|
callback(err, null);
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
//event emitter proxy
|
//event emitter proxy
|
||||||
@ -141,13 +145,8 @@ var mapRowData = function(row) {
|
|||||||
var result = {};
|
var result = {};
|
||||||
for(var i = 0, len = row.length; i < len; i++) {
|
for(var i = 0, len = row.length; i < len; i++) {
|
||||||
var item = row[i];
|
var item = row[i];
|
||||||
switch(item.type) {
|
var parser = types.getStringTypeParser(item.type);
|
||||||
case 23:
|
result[item.name] = parser(item.value);
|
||||||
result[item.name] = parseInt(item.value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result[item.name] = item.value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -160,6 +159,15 @@ p.handleRow = function(rowData) {
|
|||||||
this.emit('row', row);
|
this.emit('row', row);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
p.handleError = function(error) {
|
||||||
|
if(this.callback) {
|
||||||
|
this.callback(error);
|
||||||
|
this.callback = null;
|
||||||
|
} else {
|
||||||
|
this.emit('error', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p.handleReadyForQuery = function() {
|
p.handleReadyForQuery = function() {
|
||||||
if(this.callback) {
|
if(this.callback) {
|
||||||
this.callback(null, { rows: this.rows });
|
this.callback(null, { rows: this.rows });
|
||||||
@ -178,5 +186,8 @@ p._translateValues = function() {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Client: ctor,
|
Client: ctor,
|
||||||
connect: connect
|
connect: connect,
|
||||||
|
end: function() {
|
||||||
|
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
107
lib/query.js
107
lib/query.js
@ -1,6 +1,7 @@
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var sys = require('sys');var sys = require('sys');
|
var sys = require('sys');var sys = require('sys');
|
||||||
var Result = require(__dirname + "/result");
|
var Result = require(__dirname + "/result");
|
||||||
|
var types = require(__dirname + "/types");
|
||||||
|
|
||||||
var Query = function(config) {
|
var Query = function(config) {
|
||||||
this.text = config.text;
|
this.text = config.text;
|
||||||
@ -40,33 +41,8 @@ p.handleRowDescription = function(msg) {
|
|||||||
var len = msg.fields.length;
|
var len = msg.fields.length;
|
||||||
for(var i = 0; i < len; i++) {
|
for(var i = 0; i < len; i++) {
|
||||||
var field = msg.fields[i];
|
var field = msg.fields[i];
|
||||||
var dataTypeId = field.dataTypeID;
|
|
||||||
this._fieldNames[i] = field.name;
|
this._fieldNames[i] = field.name;
|
||||||
switch(dataTypeId) {
|
this._fieldConverters[i] = types.getStringTypeParser(field.dataTypeID);
|
||||||
case 20:
|
|
||||||
case 21:
|
|
||||||
case 23:
|
|
||||||
case 26:
|
|
||||||
this._fieldConverters[i] = parseInt;
|
|
||||||
break;
|
|
||||||
case 1700:
|
|
||||||
case 700:
|
|
||||||
case 701:
|
|
||||||
this._fieldConverters[i] = parseFloat;
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
this._fieldConverters[i] = function(val) {
|
|
||||||
return val === 't';
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case 1114:
|
|
||||||
case 1184:
|
|
||||||
this._fieldConverters[i] = dateParser;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this._fieldConverters[i] = dataTypeParsers[dataTypeId] || noParse;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,83 +147,4 @@ p.prepare = function(connection) {
|
|||||||
this.getRows(connection);
|
this.getRows(connection);
|
||||||
};
|
};
|
||||||
|
|
||||||
var dateParser = function(isoDate) {
|
|
||||||
//TODO this could do w/ a refactor
|
|
||||||
|
|
||||||
var dateMatcher = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(\.\d{1,})?/;
|
|
||||||
|
|
||||||
var match = dateMatcher.exec(isoDate);
|
|
||||||
var year = match[1];
|
|
||||||
var month = parseInt(match[2],10)-1;
|
|
||||||
var day = match[3];
|
|
||||||
var hour = parseInt(match[4],10);
|
|
||||||
var min = parseInt(match[5],10);
|
|
||||||
var seconds = parseInt(match[6], 10);
|
|
||||||
|
|
||||||
var miliString = match[7];
|
|
||||||
var mili = 0;
|
|
||||||
if(miliString) {
|
|
||||||
mili = 1000 * parseFloat(miliString);
|
|
||||||
}
|
|
||||||
|
|
||||||
var tZone = /([Z|+\-])(\d{2})?(\d{2})?/.exec(isoDate.split(' ')[1]);
|
|
||||||
//minutes to adjust for timezone
|
|
||||||
var tzAdjust = 0;
|
|
||||||
|
|
||||||
if(tZone) {
|
|
||||||
var type = tZone[1];
|
|
||||||
switch(type) {
|
|
||||||
case 'Z': break;
|
|
||||||
case '-':
|
|
||||||
tzAdjust = -(((parseInt(tZone[2],10)*60)+(parseInt(tZone[3]||0,10))));
|
|
||||||
break;
|
|
||||||
case '+':
|
|
||||||
tzAdjust = (((parseInt(tZone[2],10)*60)+(parseInt(tZone[3]||0,10))));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("Unidentifed tZone part " + type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var utcOffset = Date.UTC(year, month, day, hour, min, seconds, mili);
|
|
||||||
|
|
||||||
var date = new Date(utcOffset - (tzAdjust * 60* 1000));
|
|
||||||
return date;
|
|
||||||
};
|
|
||||||
|
|
||||||
// To help we test dateParser
|
|
||||||
Query.dateParser = dateParser;
|
|
||||||
|
|
||||||
var dataTypeParsers = {
|
|
||||||
};
|
|
||||||
|
|
||||||
//TODO document this public method
|
|
||||||
Query.registerParser = function(typeOid, parseFunction) {
|
|
||||||
dataTypeParsers[typeOid] = parseFunction;
|
|
||||||
};
|
|
||||||
|
|
||||||
//parses integer arrays
|
|
||||||
Query.registerParser(1007, function(val) {
|
|
||||||
return JSON.parse(val.replace("{","[").replace("}","]"));
|
|
||||||
});
|
|
||||||
|
|
||||||
//parses string arrays
|
|
||||||
//this only works in happy cases
|
|
||||||
//does not yet support strings with , or { or }
|
|
||||||
Query.registerParser(1009, function(val) {
|
|
||||||
if (!val) return null;
|
|
||||||
if (val[0] !== '{' || val[val.length-1] !== '}')
|
|
||||||
throw "Not postgresql array! (" + arrStr + ")";
|
|
||||||
|
|
||||||
var x = val.substring(1, val.length - 1);
|
|
||||||
x = x.match(/(NULL|[^,]+|"((?:.|\n|\r)*?)(?!\\)"|\{((?:.|\n|\r)*?(?!\\)\}) (,|$))/mg);
|
|
||||||
if (x === null) throw "Not postgre array";
|
|
||||||
return x.map(function (el) {
|
|
||||||
if (el === 'NULL') return null;
|
|
||||||
if (el[0] === '{') return arguments.callee(el);
|
|
||||||
if (el[0] === '\"') return el.substring(1, el.length - 1).replace('\\\"', '\"');
|
|
||||||
return el;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = Query;
|
module.exports = Query;
|
||||||
|
@ -101,6 +101,6 @@ registerStringTypeParser(1007, parseIntegerArray);
|
|||||||
registerStringTypeParser(1009, parseStringArray);
|
registerStringTypeParser(1009, parseStringArray);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
registerTypeParser: registerTypeParser,
|
registerStringTypeParser: registerStringTypeParser,
|
||||||
getTypeParser: getTypeParser
|
getStringTypeParser: getStringTypeParser
|
||||||
}
|
}
|
||||||
|
@ -253,6 +253,10 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HandleNotice(void *arg, const PGresult *res)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
//called to process io_events from libev
|
//called to process io_events from libev
|
||||||
void HandleIOEvent(int revents)
|
void HandleIOEvent(int revents)
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
var helper = require(__dirname + '/test-helper');
|
var helper = require(__dirname + '/test-helper');
|
||||||
var q = require('query')
|
var q = {};
|
||||||
|
q.dateParser = require(__dirname + "/../../../lib/types").getStringTypeParser(1114);
|
||||||
|
|
||||||
test("testing dateParser", function() {
|
test("testing dateParser", function() {
|
||||||
assert.equal(q.dateParser("2010-12-11 09:09:04").toUTCString(),new Date("2010-12-11 09:09:04 GMT").toUTCString());
|
assert.equal(q.dateParser("2010-12-11 09:09:04").toUTCString(),new Date("2010-12-11 09:09:04 GMT").toUTCString());
|
||||||
|
Loading…
Reference in New Issue
Block a user