1- import os from 'os'
2- import fs from 'fs'
1+ import { process } from '../polyfills.js'
2+ import { os } from '../polyfills.js'
3+ import { fs } from '../polyfills.js'
34
45import {
56 mergeUserTypes ,
@@ -74,8 +75,8 @@ function Postgres(a, b) {
7475 END : CLOSE ,
7576 PostgresError,
7677 options,
78+ reserve,
7779 listen,
78- notify,
7980 begin,
8081 close,
8182 end
@@ -95,6 +96,7 @@ function Postgres(a, b) {
9596 types : typed ,
9697 typed,
9798 unsafe,
99+ notify,
98100 array,
99101 json,
100102 file
@@ -199,11 +201,42 @@ function Postgres(a, b) {
199201 return await sql `select pg_notify(${ channel } , ${ '' + payload } )`
200202 }
201203
204+ async function reserve ( ) {
205+ const q = Queue ( )
206+ const c = open . length
207+ ? open . shift ( )
208+ : await new Promise ( r => {
209+ queries . push ( { reserve : r } )
210+ closed . length && connect ( closed . shift ( ) )
211+ } )
212+
213+ move ( c , reserved )
214+ c . reserved = ( ) => q . length
215+ ? c . execute ( q . shift ( ) )
216+ : move ( c , reserved )
217+ c . reserved . release = true
218+
219+ const sql = Sql ( handler )
220+ sql . release = ( ) => {
221+ c . reserved = null
222+ onopen ( c )
223+ }
224+
225+ return sql
226+
227+ function handler ( q ) {
228+ c . queue === full
229+ ? q . push ( q )
230+ : c . execute ( q ) || move ( c , full )
231+ }
232+ }
233+
202234 async function begin ( options , fn ) {
203235 ! fn && ( fn = options , options = '' )
204236 const queries = Queue ( )
205237 let savepoints = 0
206238 , connection
239+ , prepare = null
207240
208241 try {
209242 await sql . unsafe ( 'begin ' + options . replace ( / [ ^ a - z ] / ig, '' ) , [ ] , { onexecute } ) . execute ( )
@@ -215,6 +248,7 @@ function Postgres(a, b) {
215248 async function scope ( c , fn , name ) {
216249 const sql = Sql ( handler )
217250 sql . savepoint = savepoint
251+ sql . prepare = x => prepare = x . replace ( / [ ^ a - z 0 - 9 $ - _ . ] / gi)
218252 let uncaughtError
219253 , result
220254
@@ -235,7 +269,12 @@ function Postgres(a, b) {
235269 throw e instanceof PostgresError && e . code === '25P02' && uncaughtError || e
236270 }
237271
238- ! name && await sql `commit`
272+ if ( ! name ) {
273+ prepare
274+ ? await sql `prepare transaction '${ sql . unsafe ( prepare ) } '`
275+ : await sql `commit`
276+ }
277+
239278 return result
240279
241280 function savepoint ( name , fn ) {
@@ -270,6 +309,7 @@ function Postgres(a, b) {
270309 queue === open
271310 ? c . idleTimer . start ( )
272311 : c . idleTimer . cancel ( )
312+ return c
273313 }
274314
275315 function json ( x ) {
@@ -348,6 +388,7 @@ function Postgres(a, b) {
348388 function connect ( c , query ) {
349389 move ( c , connecting )
350390 c . connect ( query )
391+ return c
351392 }
352393
353394 function onend ( c ) {
@@ -361,8 +402,13 @@ function Postgres(a, b) {
361402 let max = Math . ceil ( queries . length / ( connecting . length + 1 ) )
362403 , ready = true
363404
364- while ( ready && queries . length && max -- > 0 )
365- ready = c . execute ( queries . shift ( ) )
405+ while ( ready && queries . length && max -- > 0 ) {
406+ const query = queries . shift ( )
407+ if ( query . reserve )
408+ return query . reserve ( c )
409+
410+ ready = c . execute ( query )
411+ }
366412
367413 ready
368414 ? move ( c , busy )
@@ -393,6 +439,7 @@ function parseOptions(a, b) {
393439 query . sslmode && ( query . ssl = query . sslmode , delete query . sslmode )
394440 'timeout' in o && ( console . log ( 'The timeout option is deprecated, use idle_timeout instead' ) , o . idle_timeout = o . timeout ) // eslint-disable-line
395441
442+ const ints = [ 'idle_timeout' , 'connect_timeout' , 'max_lifetime' , 'max_pipeline' , 'backoff' , 'keep_alive' ]
396443 const defaults = {
397444 max : 10 ,
398445 ssl : false ,
@@ -416,12 +463,16 @@ function parseOptions(a, b) {
416463 database : o . database || o . db || ( url . pathname || '' ) . slice ( 1 ) || env . PGDATABASE || user ,
417464 user : user ,
418465 pass : o . pass || o . password || url . password || env . PGPASSWORD || '' ,
419- ...Object . entries ( defaults ) . reduce ( ( acc , [ k , d ] ) =>
420- ( acc [ k ] = k in o ? o [ k ] : k in query
421- ? ( query [ k ] === 'disable' || query [ k ] === 'false' ? false : query [ k ] )
422- : env [ 'PG' + k . toUpperCase ( ) ] || d ,
423- acc
424- ) ,
466+ ...Object . entries ( defaults ) . reduce (
467+ ( acc , [ k , d ] ) => {
468+ const value = k in o ? o [ k ] : k in query
469+ ? ( query [ k ] === 'disable' || query [ k ] === 'false' ? false : query [ k ] )
470+ : env [ 'PG' + k . toUpperCase ( ) ] || d
471+ acc [ k ] = typeof value === 'string' && ints . includes ( k )
472+ ? + value
473+ : value
474+ return acc
475+ } ,
425476 { }
426477 ) ,
427478 connection : {
0 commit comments