Skip to content

Commit fa35c13

Browse files
committed
Merge remote branch 'upstream/master'
Conflicts: lib/query.js
2 parents 01e0fb1 + ab76f64 commit fa35c13

File tree

2 files changed

+106
-91
lines changed

2 files changed

+106
-91
lines changed

lib/connection.js

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,12 @@ p.startup = function(config) {
7575

7676
p.password = function(password) {
7777
//0x70 = 'p'
78-
this.send(0x70, this.writer.addCString(password).flush());
78+
this._send(0x70, this.writer.addCString(password));
7979
};
8080

81-
p.send = function(code, bodyBuffer) {
82-
var length = bodyBuffer.length + 4;
83-
var buffer = Buffer(length + 1);
84-
var offset = 0;
85-
buffer[offset++] = code;
86-
buffer[offset++] = length >>> 24 & 0xFF;
87-
buffer[offset++] = length >>> 16 & 0xFF;
88-
buffer[offset++] = length >>> 8 & 0xFF;
89-
buffer[offset++] = length >>> 0 & 0xFF;
90-
bodyBuffer.copy(buffer, offset, 0);
91-
return this.stream.write(buffer);
92-
};
81+
p._send = function(code, writer) {
82+
return this.stream.write(writer.flush(code));
83+
}
9384

9485
var termBuffer = new Buffer([0x58, 0, 0, 0, 4]);
9586
p.end = function() {
@@ -98,7 +89,7 @@ p.end = function() {
9889

9990
p.query = function(text) {
10091
//0x51 = Q
101-
this.send(0x51, this.writer.addCString(text).flush());
92+
this.stream.write(this.writer.addCString(text).flush(0x51));
10293
};
10394

10495
p.parse = function(query) {
@@ -121,7 +112,7 @@ p.parse = function(query) {
121112
}
122113

123114
//0x50 = 'P'
124-
this.send(0x50, buffer.flush());
115+
this._send(0x50, buffer);
125116

126117
return this;
127118
};
@@ -151,7 +142,8 @@ p.bind = function(config) {
151142
buffer.addInt16(1); // format codes to use binary
152143
buffer.addInt16(1);
153144
//0x42 = 'B'
154-
this.send(0x42, buffer.flush());
145+
146+
this._send(0x42, buffer);
155147
};
156148

157149
p.execute = function(config) {
@@ -160,30 +152,31 @@ p.execute = function(config) {
160152
config.rows = config.rows || '';
161153
var buffer = this.writer
162154
.addCString(config.portal)
163-
.addInt32(config.rows)
164-
.flush();
165-
155+
.addInt32(config.rows);
156+
166157
//0x45 = 'E'
167-
this.send(0x45, buffer);
158+
this._send(0x45, buffer);
168159
};
169160

161+
var emptyBuffer = Buffer(0);
162+
170163
p.flush = function() {
171164
//0x48 = 'H'
172-
this.send(0x48,Buffer(0));
165+
this._send(0x48,this.writer.add(emptyBuffer));
173166
}
174167

175168
p.sync = function() {
176169
//0x53 = 'S'
177-
this.send(0x53, Buffer(0));
170+
this._send(0x53, this.writer.add(emptyBuffer));
178171
};
179172

180173
p.end = function() {
181174
//0x58 = 'X'
182-
this.send(0x58, Buffer(0));
175+
this._send(0x58, this.writer.add(emptyBuffer));
183176
};
184177

185178
p.describe = function(msg) {
186-
this.send(0x44, this.writer.addCString(msg.type + (msg.name || '')).flush());
179+
this._send(0x44, this.writer.addCString(msg.type + (msg.name || '')));
187180
};
188181

189182
//parsing methods

lib/query.js

Lines changed: 89 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var EventEmitter = require('events').EventEmitter;
22
var sys = require('sys');var sys = require('sys');
3+
var Result = require(__dirname + "/result");
34

45
var Query = function(config) {
56
this.text = config.text;
@@ -26,76 +27,119 @@ var noParse = function(val) {
2627
return val;
2728
};
2829

30+
//creates datarow metatdata from the supplied
31+
//data row information
32+
var buildDataRowMetadata = function(msg, converters, names) {
33+
var len = msg.fields.length;
34+
for(var i = 0; i < len; i++) {
35+
var field = msg.fields[i];
36+
var dataTypeId = field.dataTypeID;
37+
names[i] = field.name;
38+
switch(dataTypeId) {
39+
case 20:
40+
converters[i] = parseBinaryInt64;
41+
break;
42+
case 21:
43+
converters[i] = parseBinaryInt16;
44+
break;
45+
case 23:
46+
converters[i] = parseBinaryInt32;
47+
break;
48+
case 26:
49+
converters[i] = parseBinaryInt64;
50+
break;
51+
case 1700:
52+
case 700:
53+
converters[i] = parseBinaryFloat32;
54+
case 701:
55+
converters[i] = parseBinaryFloat64;
56+
break;
57+
case 16:
58+
converters[i] = function(val) {
59+
return val == 1;
60+
};
61+
break;
62+
case 1114:
63+
case 1184:
64+
converters[i] = parseDate;
65+
break;
66+
case 1007:
67+
case 1008:
68+
converters[i] = arrayParser,
69+
break;
70+
default:
71+
converters[i] = dataTypeParsers[dataTypeId] || noParse;
72+
break;
73+
}
74+
};
75+
}
76+
2977
p.submit = function(connection) {
3078
var self = this;
3179
if(this.requiresPreparation()) {
3280
this.prepare(connection);
3381
} else {
3482
connection.query(this.text);
3583
}
84+
3685
var converters = [];
3786
var names = [];
38-
var rows = [];
3987
var handleRowDescription = function(msg) {
40-
for(var i = 0; i < msg.fields.length; i++) {
41-
converters[i] = dataTypeParsers[msg.fields[i].dataTypeID] || noParse;
42-
names[i] = msg.fields[i].name;
43-
};
88+
buildDataRowMetadata(msg, converters, names);
4489
};
90+
91+
var result = new Result();
92+
4593
var handleDatarow = function(msg) {
46-
var result = {};
94+
var row = {};
4795
for(var i = 0; i < msg.fields.length; i++) {
4896
var rawValue = msg.fields[i];
49-
result[names[i]] = rawValue === null ? null : converters[i](rawValue);
97+
row[names[i]] = rawValue === null ? null : converters[i](rawValue);
5098
}
51-
self.emit('row', result);
99+
self.emit('row', row);
52100

53-
//if no reciever, buffer rows
101+
//if there is a callback collect rows
54102
if(self.callback) {
55-
rows.push(result);
103+
result.addRow(row);
56104
}
57105
};
58106

59-
var onCommandComplete = function() {
60-
self.callback(null, {rows: rows});
61-
rows = [];
62-
}
63-
64-
if(self.callback) {
65-
connection.on('commandComplete', onCommandComplete)
66-
}
107+
var onCommandComplete = function(msg) {
108+
result.addCommandComplete(msg);
109+
};
67110

68111
var onError = function(err) {
69112
//remove all listeners
70-
connection.removeListener('rowDescription', handleDatarow);
71-
connection.removeListener('dataRow', handleDatarow);
72-
connection.removeListener('error', onError);
73-
connection.removeListener('readyForQuery', onReadyForQuery);
113+
removeListeners();
74114
if(self.callback) {
75115
self.callback(err);
76-
connection.removeListener('commandComplete', onCommandComplete);
77116
} else {
78117
self.emit('error', err);
79118
}
80119
self.emit('end');
81120
};
82121

83122
var onReadyForQuery = function() {
123+
removeListeners();
124+
if(self.callback) {
125+
self.callback(null, result);
126+
}
127+
self.emit('end', result);
128+
};
129+
130+
var removeListeners = function() {
84131
//remove all listeners
85132
connection.removeListener('rowDescription', handleRowDescription);
86133
connection.removeListener('dataRow', handleDatarow);
87134
connection.removeListener('readyForQuery', onReadyForQuery);
135+
connection.removeListener('commandComplete', onCommandComplete);
88136
connection.removeListener('error', onError);
89-
if(self.callback) {
90-
connection.removeListener('commandComplete', onCommandComplete);
91-
}
92-
self.emit('end');
93137
};
94138

95139
connection.on('rowDescription', handleRowDescription);
96140
connection.on('dataRow', handleDatarow);
97141
connection.on('readyForQuery', onReadyForQuery);
98-
142+
connection.on('commandComplete', onCommandComplete);
99143
connection.on('error', onError);
100144
};
101145

@@ -107,12 +151,12 @@ p.prepare = function(connection) {
107151
var self = this;
108152

109153
if(!this.hasBeenParsed(connection)) {
110-
connection.parsedStatements[this.name] = true;
111154
connection.parse({
112155
text: self.text,
113156
name: self.name,
114157
types: self.types
115158
});
159+
connection.parsedStatements[this.name] = true;
116160
}
117161

118162
//TODO is there some btter way to prepare values for the database?
@@ -144,7 +188,6 @@ p.prepare = function(connection) {
144188

145189
getRows();
146190

147-
//TODO support EmptyQueryResponse, ErrorResponse, and PortalSuspended
148191
var onCommandComplete = function() {
149192
connection.removeListener('error', onCommandComplete);
150193
connection.removeListener('commandComplete', onCommandComplete);
@@ -159,32 +202,28 @@ p.prepare = function(connection) {
159202
};
160203

161204
var dateParser = function(isoDate) {
162-
//TODO find some regexp help
163-
//this method works but it's ooglay
164-
//if you wanna contribute...... ;)
165-
var split = isoDate.split(' ');
166-
var dateMatcher = /(\d{4})-(\d{2})-(\d{2})/;
167-
168-
var date = split[0];
169-
var time = split[1];
170-
var match = dateMatcher.exec(date);
171-
var splitDate = date.split('-');
205+
//TODO this could do w/ a refactor
206+
207+
var dateMatcher = /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(\.\d{1,})?/;
208+
209+
var match = dateMatcher.exec(isoDate);
172210
var year = match[1];
173211
var month = parseInt(match[2],10)-1;
174212
var day = match[3];
213+
var hour = parseInt(match[4],10);
214+
var min = parseInt(match[5],10);
215+
var seconds = parseInt(match[6], 10);
216+
217+
var miliString = match[7];
218+
var mili = 0;
219+
if(miliString) {
220+
mili = 1000 * parseFloat(miliString);
221+
}
175222

176-
var splitTime = time.split(':');
177-
var hour = parseInt(splitTime[0],10);
178-
var min = parseInt(splitTime[1],10);
179-
var end = splitTime[2];
180-
var seconds = /(\d{2})/.exec(end);
181-
seconds = (seconds ? seconds[1] : 0);
182-
seconds = parseInt(seconds,10);
183-
var mili = /\.(\d{1,})/.exec(end+"000");
184-
mili = mili ? mili[1].slice(0,3) : 0;
185-
var tZone = /([Z|+\-])(\d{2})?(\d{2})?/.exec(end);
223+
var tZone = /([Z|+\-])(\d{2})?(\d{2})?/.exec(isoDate.split(' ')[1]);
186224
//minutes to adjust for timezone
187225
var tzAdjust = 0;
226+
188227
if(tZone) {
189228
var type = tZone[1];
190229
switch(type) {
@@ -408,23 +447,6 @@ var arrayParser = function(value) {
408447
Query.dateParser = dateParser;
409448

410449
var dataTypeParsers = {
411-
16: function(dbVal) { //boolean
412-
console.log(JSON.stringify(dbVal));
413-
return value[0] == 1;
414-
},
415-
416-
20: parseBinaryInt64,
417-
21: parseBinaryInt16,
418-
23: parseBinaryInt32,
419-
26: parseBinaryInt64,
420-
700: parseBinaryFloat32,
421-
701: parseBinaryFloat64,
422-
1007: arrayParser,
423-
1009: arrayParser,
424-
1114: parseDate,
425-
//1184: parseBinaryInt64
426-
// 1700: parseFloat,
427450
};
428451

429-
430452
module.exports = Query;

0 commit comments

Comments
 (0)