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 utils = require(__dirname + "/utils");
|
||||
var types = require(__dirname + "/types");
|
||||
var Connection = binding.Connection;
|
||||
var p = Connection.prototype;
|
||||
|
||||
@ -91,7 +92,7 @@ var ctor = function(config) {
|
||||
})
|
||||
connection.on('_error', function(err) {
|
||||
if(connection._activeQuery) {
|
||||
connection._activeQuery.emit('error', err);
|
||||
connection._activeQuery.handleError(err);
|
||||
} else {
|
||||
connection.emit('error', err);
|
||||
}
|
||||
@ -110,6 +111,9 @@ var connect = function(config, callback) {
|
||||
client.on('connect', function() {
|
||||
callback(null, client);
|
||||
})
|
||||
client.on('error', function(err) {
|
||||
callback(err, null);
|
||||
})
|
||||
};
|
||||
|
||||
//event emitter proxy
|
||||
@ -141,13 +145,8 @@ var mapRowData = function(row) {
|
||||
var result = {};
|
||||
for(var i = 0, len = row.length; i < len; i++) {
|
||||
var item = row[i];
|
||||
switch(item.type) {
|
||||
case 23:
|
||||
result[item.name] = parseInt(item.value);
|
||||
break;
|
||||
default:
|
||||
result[item.name] = item.value;
|
||||
}
|
||||
var parser = types.getStringTypeParser(item.type);
|
||||
result[item.name] = parser(item.value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -160,6 +159,15 @@ p.handleRow = function(rowData) {
|
||||
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() {
|
||||
if(this.callback) {
|
||||
this.callback(null, { rows: this.rows });
|
||||
@ -178,5 +186,8 @@ p._translateValues = function() {
|
||||
|
||||
module.exports = {
|
||||
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 sys = require('sys');var sys = require('sys');
|
||||
var Result = require(__dirname + "/result");
|
||||
var types = require(__dirname + "/types");
|
||||
|
||||
var Query = function(config) {
|
||||
this.text = config.text;
|
||||
@ -40,33 +41,8 @@ p.handleRowDescription = function(msg) {
|
||||
var len = msg.fields.length;
|
||||
for(var i = 0; i < len; i++) {
|
||||
var field = msg.fields[i];
|
||||
var dataTypeId = field.dataTypeID;
|
||||
this._fieldNames[i] = field.name;
|
||||
switch(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;
|
||||
}
|
||||
this._fieldConverters[i] = types.getStringTypeParser(field.dataTypeID);
|
||||
};
|
||||
};
|
||||
|
||||
@ -171,83 +147,4 @@ p.prepare = function(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;
|
||||
|
@ -101,6 +101,6 @@ registerStringTypeParser(1007, parseIntegerArray);
|
||||
registerStringTypeParser(1009, parseStringArray);
|
||||
|
||||
module.exports = {
|
||||
registerTypeParser: registerTypeParser,
|
||||
getTypeParser: getTypeParser
|
||||
registerStringTypeParser: registerStringTypeParser,
|
||||
getStringTypeParser: getStringTypeParser
|
||||
}
|
||||
|
@ -253,6 +253,10 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleNotice(void *arg, const PGresult *res)
|
||||
{
|
||||
}
|
||||
|
||||
//called to process io_events from libev
|
||||
void HandleIOEvent(int revents)
|
||||
{
|
||||
|
@ -1,5 +1,6 @@
|
||||
var helper = require(__dirname + '/test-helper');
|
||||
var q = require('query')
|
||||
var q = {};
|
||||
q.dateParser = require(__dirname + "/../../../lib/types").getStringTypeParser(1114);
|
||||
|
||||
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());
|
||||
|
Loading…
Reference in New Issue
Block a user