1
1
var EventEmitter = require ( 'events' ) . EventEmitter ;
2
2
var sys = require ( 'sys' ) ; var sys = require ( 'sys' ) ;
3
+ var Result = require ( __dirname + "/result" ) ;
3
4
4
5
var Query = function ( config ) {
5
6
this . text = config . text ;
@@ -26,76 +27,119 @@ var noParse = function(val) {
26
27
return val ;
27
28
} ;
28
29
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
+
29
77
p . submit = function ( connection ) {
30
78
var self = this ;
31
79
if ( this . requiresPreparation ( ) ) {
32
80
this . prepare ( connection ) ;
33
81
} else {
34
82
connection . query ( this . text ) ;
35
83
}
84
+
36
85
var converters = [ ] ;
37
86
var names = [ ] ;
38
- var rows = [ ] ;
39
87
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 ) ;
44
89
} ;
90
+
91
+ var result = new Result ( ) ;
92
+
45
93
var handleDatarow = function ( msg ) {
46
- var result = { } ;
94
+ var row = { } ;
47
95
for ( var i = 0 ; i < msg . fields . length ; i ++ ) {
48
96
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 ) ;
50
98
}
51
- self . emit ( 'row' , result ) ;
99
+ self . emit ( 'row' , row ) ;
52
100
53
- //if no reciever, buffer rows
101
+ //if there is a callback collect rows
54
102
if ( self . callback ) {
55
- rows . push ( result ) ;
103
+ result . addRow ( row ) ;
56
104
}
57
105
} ;
58
106
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
+ } ;
67
110
68
111
var onError = function ( err ) {
69
112
//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 ( ) ;
74
114
if ( self . callback ) {
75
115
self . callback ( err ) ;
76
- connection . removeListener ( 'commandComplete' , onCommandComplete ) ;
77
116
} else {
78
117
self . emit ( 'error' , err ) ;
79
118
}
80
119
self . emit ( 'end' ) ;
81
120
} ;
82
121
83
122
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 ( ) {
84
131
//remove all listeners
85
132
connection . removeListener ( 'rowDescription' , handleRowDescription ) ;
86
133
connection . removeListener ( 'dataRow' , handleDatarow ) ;
87
134
connection . removeListener ( 'readyForQuery' , onReadyForQuery ) ;
135
+ connection . removeListener ( 'commandComplete' , onCommandComplete ) ;
88
136
connection . removeListener ( 'error' , onError ) ;
89
- if ( self . callback ) {
90
- connection . removeListener ( 'commandComplete' , onCommandComplete ) ;
91
- }
92
- self . emit ( 'end' ) ;
93
137
} ;
94
138
95
139
connection . on ( 'rowDescription' , handleRowDescription ) ;
96
140
connection . on ( 'dataRow' , handleDatarow ) ;
97
141
connection . on ( 'readyForQuery' , onReadyForQuery ) ;
98
-
142
+ connection . on ( 'commandComplete' , onCommandComplete ) ;
99
143
connection . on ( 'error' , onError ) ;
100
144
} ;
101
145
@@ -107,12 +151,12 @@ p.prepare = function(connection) {
107
151
var self = this ;
108
152
109
153
if ( ! this . hasBeenParsed ( connection ) ) {
110
- connection . parsedStatements [ this . name ] = true ;
111
154
connection . parse ( {
112
155
text : self . text ,
113
156
name : self . name ,
114
157
types : self . types
115
158
} ) ;
159
+ connection . parsedStatements [ this . name ] = true ;
116
160
}
117
161
118
162
//TODO is there some btter way to prepare values for the database?
@@ -144,7 +188,6 @@ p.prepare = function(connection) {
144
188
145
189
getRows ( ) ;
146
190
147
- //TODO support EmptyQueryResponse, ErrorResponse, and PortalSuspended
148
191
var onCommandComplete = function ( ) {
149
192
connection . removeListener ( 'error' , onCommandComplete ) ;
150
193
connection . removeListener ( 'commandComplete' , onCommandComplete ) ;
@@ -159,32 +202,28 @@ p.prepare = function(connection) {
159
202
} ;
160
203
161
204
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 ) ;
172
210
var year = match [ 1 ] ;
173
211
var month = parseInt ( match [ 2 ] , 10 ) - 1 ;
174
212
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
+ }
175
222
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 ] ) ;
186
224
//minutes to adjust for timezone
187
225
var tzAdjust = 0 ;
226
+
188
227
if ( tZone ) {
189
228
var type = tZone [ 1 ] ;
190
229
switch ( type ) {
@@ -408,23 +447,6 @@ var arrayParser = function(value) {
408
447
Query . dateParser = dateParser ;
409
448
410
449
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,
427
450
} ;
428
451
429
-
430
452
module . exports = Query ;
0 commit comments