@@ -2,7 +2,7 @@ var sys = require('sys');
22var net = require ( 'net' ) ;
33var crypto = require ( 'crypto' ) ;
44var EventEmitter = require ( 'events' ) . EventEmitter ;
5-
5+ var Query = require ( __dirname + '/query' ) ;
66var utils = require ( __dirname + '/utils' ) ;
77
88var Connection = require ( __dirname + '/connection' ) ;
@@ -15,10 +15,11 @@ var Client = function(config) {
1515 this . port = config . port || 5432 ;
1616 this . host = config . host ;
1717 this . queryQueue = [ ] ;
18-
1918 this . connection = config . connection || new Connection ( { stream : config . stream || new net . Stream ( ) } ) ;
2019 this . queryQueue = [ ] ;
2120 this . password = config . password || '' ;
21+
22+ //internal references only declared here for clarity
2223 this . lastBuffer = false ;
2324 this . lastOffset = 0 ;
2425 this . buffer = null ;
@@ -95,181 +96,4 @@ Client.md5 = function(string) {
9596 return crypto . createHash ( 'md5' ) . update ( string ) . digest ( 'hex' ) ;
9697} ;
9798
98- var Query = function ( config ) {
99- this . text = config . text ;
100- this . values = config . values ;
101- this . rows = config . rows ;
102- this . types = config . types ;
103- this . name = config . name ;
104- //for code clarity purposes we'll declare this here though it's not
105- //set or used until a rowDescription message comes in
106- this . rowDescription = null ;
107- EventEmitter . call ( this ) ;
108- } ;
109-
110- sys . inherits ( Query , EventEmitter ) ;
111- var p = Query . prototype ;
112-
113- p . requiresPreparation = function ( ) {
114- return ( this . values || 0 ) . length > 0 || this . name || this . rows ;
115- } ;
116-
117- p . submit = function ( connection ) {
118- var self = this ;
119- if ( this . requiresPreparation ( ) ) {
120- this . prepare ( connection ) ;
121- } else {
122- connection . query ( this . text ) ;
123- }
124- var handleRowDescription = function ( msg ) {
125- self . onRowDescription ( msg ) ;
126- } ;
127- var handleDatarow = function ( msg ) {
128- self . onDataRow ( msg ) ;
129- } ;
130- connection . on ( 'rowDescription' , handleRowDescription ) ;
131- connection . on ( 'dataRow' , handleDatarow ) ;
132- connection . once ( 'readyForQuery' , function ( ) {
133- //remove all listeners
134- connection . removeListener ( 'rowDescription' , handleRowDescription ) ;
135- connection . removeListener ( 'dataRow' , handleDatarow ) ;
136- self . emit ( 'end' ) ;
137- } ) ;
138- } ;
139-
140- p . hasBeenParsed = function ( connection ) {
141- return this . name && connection . parsedStatements [ this . name ] ;
142- } ;
143-
144- p . prepare = function ( connection ) {
145- var self = this ;
146- var onParseComplete = function ( ) {
147- if ( self . values ) {
148- self . values = self . values . map ( function ( val ) {
149- return ( val instanceof Date ) ? JSON . stringify ( val ) : val ;
150- } ) ;
151- }
152- //http://developer.postgresql.org/pgdocs/postgres/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY
153- connection . bind ( {
154- portal : self . name ,
155- statement : self . name ,
156- values : self . values
157- } ) ;
158- connection . describe ( {
159- type : 'P' ,
160- name : self . name || ""
161- } ) ;
162- connection . execute ( {
163- portal : self . name ,
164- rows : self . rows
165- } ) ;
166- connection . flush ( ) ;
167- } ;
168-
169-
170- if ( this . hasBeenParsed ( connection ) ) {
171- onParseComplete ( ) ;
172- } else {
173- connection . parsedStatements [ this . name ] = true ;
174- connection . parse ( {
175- text : self . text ,
176- name : self . name ,
177- types : self . types
178- } ) ;
179- onParseComplete ( ) ;
180- }
181-
182-
183- //TODO support EmptyQueryResponse, ErrorResponse, and PortalSuspended
184- var onCommandComplete = function ( ) {
185- connection . sync ( ) ;
186- } ;
187- connection . once ( 'commandComplete' , onCommandComplete ) ;
188-
189- } ;
190-
191- var noParse = function ( val ) {
192- return val ;
193- } ;
194-
195- p . onRowDescription = function ( msg ) {
196- this . converters = msg . fields . map ( function ( field ) {
197- return Client . dataTypeParser [ field . dataTypeID ] || noParse ;
198- } ) ;
199- } ;
200-
201- //handles the raw 'dataRow' event from the connection does type coercion
202- p . onDataRow = function ( msg ) {
203- for ( var i = 0 ; i < msg . fields . length ; i ++ ) {
204- if ( msg . fields [ i ] !== null ) {
205- msg . fields [ i ] = this . converters [ i ] ( msg . fields [ i ] ) ;
206- }
207- }
208- this . emit ( 'row' , msg ) ;
209- } ;
210-
211- var dateParser = function ( isoDate ) {
212- //TODO find some regexp help
213- //this method works but it's ooglay
214- var split = isoDate . split ( ' ' ) ;
215- var dateMatcher = / ( \d { 4 } ) - ( \d { 2 } ) - ( \d { 2 } ) / ;
216-
217- var date = split [ 0 ] ;
218- var time = split [ 1 ] ;
219- var match = dateMatcher . exec ( date ) ;
220- var splitDate = date . split ( '-' ) ;
221- var year = match [ 1 ] ;
222- var month = parseInt ( match [ 2 ] ) - 1 ;
223- var day = match [ 3 ] ;
224-
225- var splitTime = time . split ( ':' ) ;
226- var hour = parseInt ( splitTime [ 0 ] ) ;
227- var min = splitTime [ 1 ] ;
228- var end = splitTime [ 2 ] ;
229- var seconds = / ( \d { 2 } ) / . exec ( end ) ;
230- seconds = ( seconds ? seconds [ 1 ] : 0 ) ;
231- var mili = / \. ( \d { 1 , } ) / . exec ( end ) ;
232- mili = mili ? mili [ 1 ] . slice ( 0 , 3 ) : 0 ;
233- var tZone = / ( [ Z | + \- ] ) ( \d { 2 } ) ? ( \d { 2 } ) ? / . exec ( end ) ;
234- //minutes to adjust for timezone
235- var tzAdjust = 0 ;
236- if ( tZone ) {
237- var type = tZone [ 1 ] ;
238- switch ( type ) {
239- case 'Z' : break ;
240- case '-' :
241- tzAdjust = - ( ( ( parseInt ( tZone [ 2 ] ) * 60 ) + ( parseInt ( tZone [ 3 ] || 0 ) ) ) ) ;
242- break ;
243- case '+' :
244- tzAdjust = ( ( ( parseInt ( tZone [ 2 ] ) * 60 ) + ( parseInt ( tZone [ 3 ] || 0 ) ) ) ) ;
245- break ;
246- default :
247- throw new Error ( "Unidentifed tZone part " + type ) ;
248- }
249- }
250-
251- var utcOffset = Date . UTC ( year , month , day , hour , min , seconds , mili ) ;
252-
253- var date = new Date ( utcOffset - ( tzAdjust * 60 * 1000 ) ) ;
254- return date ;
255- } ;
256-
257- Client . dataTypeParser = {
258- 20 : parseInt ,
259- 21 : parseInt ,
260- 23 : parseInt ,
261- 26 : parseInt ,
262- 1700 : parseFloat ,
263- 700 : parseFloat ,
264- 701 : parseFloat ,
265- 16 : function ( dbVal ) { //boolean
266- return dbVal === 't' ;
267- } ,
268- // 1083: timeParser,
269- // 1266: timeParser,
270- 1114 : dateParser ,
271- 1184 : dateParser
272- } ;
273-
274- //end parsing methods
27599module . exports = Client ;
0 commit comments