@@ -42,7 +42,6 @@ class Client extends EventEmitter {
42
42
this . _connected = false
43
43
this . _connectionError = false
44
44
this . _queryable = true
45
-
46
45
this . connection =
47
46
c . connection ||
48
47
new Connection ( {
@@ -52,10 +51,14 @@ class Client extends EventEmitter {
52
51
keepAliveInitialDelayMillis : c . keepAliveInitialDelayMillis || 0 ,
53
52
encoding : this . connectionParameters . client_encoding || 'utf8' ,
54
53
} )
54
+ this . hasExecuted = false ;
55
55
this . queryQueue = [ ]
56
56
this . binary = c . binary || defaults . binary
57
+ this . usePipeline = false ;
58
+ this . preparedQueries = [ ] ;
57
59
this . processID = null
58
60
this . secretKey = null
61
+ this . hasQueriesPrepared = false ;
59
62
this . ssl = this . connectionParameters . ssl || false
60
63
// As with Password, make SSL->Key (the private key) non-enumerable.
61
64
// It won't show up in stack traces
@@ -311,7 +314,9 @@ class Client extends EventEmitter {
311
314
if ( activeQuery ) {
312
315
activeQuery . handleReadyForQuery ( this . connection )
313
316
}
314
- this . _pulseQueryQueue ( )
317
+ if ( this . usePipeline == false ) {
318
+ this . _pulseQueryQueue ( )
319
+ }
315
320
}
316
321
317
322
// if we receieve an error event or error message
@@ -478,11 +483,10 @@ class Client extends EventEmitter {
478
483
479
484
_pulseQueryQueue ( ) {
480
485
if ( this . readyForQuery === true ) {
481
- this . activeQuery = this . queryQueue . shift ( )
486
+ this . activeQuery = this . queryQueue . shift ( ) ;
482
487
if ( this . activeQuery ) {
483
488
this . readyForQuery = false
484
489
this . hasExecuted = true
485
-
486
490
const queryError = this . activeQuery . submit ( this . connection )
487
491
if ( queryError ) {
488
492
process . nextTick ( ( ) => {
@@ -498,6 +502,120 @@ class Client extends EventEmitter {
498
502
}
499
503
}
500
504
505
+ async queryPipeline ( queries ) {
506
+ console . log ( "Entered pipeline" ) ;
507
+ this . usePipeline = true ;
508
+ let queriesComputed = [ ] ;
509
+ let resultList = [ ] ;
510
+ for ( let elem of queries ) {
511
+ let queryToInsert , result ;
512
+ [ queryToInsert , result ] = this . queryForPipeline ( elem . config , elem . values ) ;
513
+ queriesComputed . push ( queryToInsert ) ;
514
+ resultList . push ( result ) ;
515
+ }
516
+ for ( let i = 0 ; i < queriesComputed . length ; i ++ ) {
517
+ console . log ( `Processing query ${ i } ` ) ;
518
+ let current = queriesComputed [ i ] ;
519
+ this . activeQuery = current ;
520
+ let next ;
521
+ if ( i + 1 < queriesComputed . length ) {
522
+ next = queriesComputed [ i + 1 ] ;
523
+ }
524
+ if ( ! current . isPreparedSomehow ( ) ) {
525
+ await current . queryPrepareNew ( this . connection ) ;
526
+ } else {
527
+ console . log ( "Already prepared" ) ;
528
+ }
529
+ let pList = [ ] ;
530
+ pList . push ( current . submitNew ( this . connection ) ) ;
531
+ if ( next ) {
532
+ pList . push ( next . queryPrepareNew ( this . connection ) ) ;
533
+ }
534
+ await Promise . all ( pList ) ;
535
+ console . log ( `Done processing query ${ i } ` ) ;
536
+ }
537
+ this . activeQuery = null ;
538
+ this . emit ( 'drain' ) ;
539
+ this . usePipeline = false ;
540
+ return resultList ;
541
+ }
542
+
543
+ queryForPipeline ( config , values , callback ) {
544
+ // can take in strings, config object or query object
545
+ var query
546
+ var result
547
+ var readTimeout
548
+ var readTimeoutTimer
549
+ var queryCallback
550
+
551
+ if ( config === null || config === undefined ) {
552
+ throw new TypeError ( 'Client was passed a null or undefined query' )
553
+ } else if ( typeof config . submit === 'function' ) {
554
+ readTimeout = config . query_timeout || this . connectionParameters . query_timeout
555
+ result = query = config
556
+ if ( typeof values === 'function' ) {
557
+ query . callback = query . callback || values
558
+ }
559
+ } else {
560
+ readTimeout = this . connectionParameters . query_timeout
561
+ query = new Query ( config , values , callback )
562
+ if ( ! query . callback ) {
563
+ result = new this . _Promise ( ( resolve , reject ) => {
564
+ query . callback = ( err , res ) => ( err ? reject ( err ) : resolve ( res ) )
565
+ } ) . catch ( err => {
566
+ // replace the stack trace that leads to `TCP.onStreamRead` with one that leads back to the
567
+ // application that created the query
568
+ Error . captureStackTrace ( err ) ;
569
+ throw err ;
570
+ } )
571
+ }
572
+ }
573
+
574
+ if ( readTimeout ) {
575
+ queryCallback = query . callback
576
+
577
+ readTimeoutTimer = setTimeout ( ( ) => {
578
+ var error = new Error ( 'Query read timeout' )
579
+ process . nextTick ( ( ) => {
580
+ query . handleError ( error , this . connection )
581
+ } )
582
+ queryCallback ( error )
583
+ // we already returned an error,
584
+ // just do nothing if query completes
585
+ query . callback = ( ) => { }
586
+ } , readTimeout )
587
+
588
+ query . callback = ( err , res ) => {
589
+ clearTimeout ( readTimeoutTimer )
590
+ queryCallback ( err , res )
591
+ }
592
+ }
593
+
594
+ if ( this . binary && ! query . binary ) {
595
+ query . binary = true
596
+ }
597
+
598
+ if ( query . _result && ! query . _result . _types ) {
599
+ query . _result . _types = this . _types
600
+ }
601
+
602
+ if ( ! this . _queryable ) {
603
+ process . nextTick ( ( ) => {
604
+ query . handleError ( new Error ( 'Client has encountered a connection error and is not queryable' ) , this . connection )
605
+ } )
606
+ return result
607
+ }
608
+
609
+ if ( this . _ending ) {
610
+ process . nextTick ( ( ) => {
611
+ query . handleError ( new Error ( 'Client was closed and is not queryable' ) , this . connection )
612
+ } )
613
+ return result
614
+ }
615
+
616
+ return [ query , result ]
617
+ }
618
+
501
619
query ( config , values , callback ) {
502
620
// can take in strings, config object or query object
503
621
var query
@@ -543,15 +661,16 @@ class Client extends EventEmitter {
543
661
544
662
// we already returned an error,
545
663
// just do nothing if query completes
546
- query . callback = ( ) => { }
664
+ query . callback = ( ) => { }
547
665
548
666
// Remove from queue
549
667
var index = this . queryQueue . indexOf ( query )
550
668
if ( index > - 1 ) {
551
669
this . queryQueue . splice ( index , 1 )
552
670
}
553
-
554
- this . _pulseQueryQueue ( )
671
+ if ( this . usePipeline == false ) {
672
+ this . _pulseQueryQueue ( )
673
+ }
555
674
} , readTimeout )
556
675
557
676
query . callback = ( err , res ) => {
@@ -582,8 +701,10 @@ class Client extends EventEmitter {
582
701
return result
583
702
}
584
703
585
- this . queryQueue . push ( query )
586
- this . _pulseQueryQueue ( )
704
+ this . queryQueue . push ( query ) ;
705
+ if ( this . usePipeline == false ) {
706
+ this . _pulseQueryQueue ( ) ;
707
+ }
587
708
return result
588
709
}
589
710
0 commit comments