Skip to content

Commit cb9d11c

Browse files
committed
build
1 parent 36dbe2f commit cb9d11c

File tree

11 files changed

+122
-33
lines changed

11 files changed

+122
-33
lines changed

cf/src/connection.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
295295
if (incomings) {
296296
incomings.push(x)
297297
remaining -= x.length
298-
if (remaining >= 0)
298+
if (remaining > 0)
299299
return
300300
}
301301

@@ -383,10 +383,13 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
383383
function errored(err) {
384384
stream && (stream.destroy(err), stream = null)
385385
query && queryError(query, err)
386-
initial && (queryError(initial, err), initial = null)
386+
initial && (initial.reserve ? initial.reject(err) : queryError(initial, err), initial = null)
387387
}
388388

389389
function queryError(query, err) {
390+
if (!err || typeof err !== 'object')
391+
err = new Error(err)
392+
390393
'query' in err || 'parameters' in err || Object.defineProperties(err, {
391394
stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
392395
query: { value: query.string, enumerable: options.debug },

cf/src/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,10 @@ function Postgres(a, b) {
205205
const queue = Queue()
206206
const c = open.length
207207
? open.shift()
208-
: await new Promise(r => {
209-
queries.push({ reserve: r })
210-
closed.length && connect(closed.shift())
208+
: await new Promise((resolve, reject) => {
209+
const query = { reserve: resolve, reject }
210+
queries.push(query)
211+
closed.length && connect(closed.shift(), query)
211212
})
212213

213214
move(c, reserved)
@@ -481,7 +482,7 @@ function parseOptions(a, b) {
481482
{}
482483
),
483484
connection : {
484-
application_name: 'postgres.js',
485+
application_name: env.PGAPPNAME || 'postgres.js',
485486
...o.connection,
486487
...Object.entries(query).reduce((acc, [k, v]) => (k in defaults || (acc[k] = v), acc), {})
487488
},

cjs/src/connection.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
293293
if (incomings) {
294294
incomings.push(x)
295295
remaining -= x.length
296-
if (remaining >= 0)
296+
if (remaining > 0)
297297
return
298298
}
299299

@@ -381,10 +381,13 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
381381
function errored(err) {
382382
stream && (stream.destroy(err), stream = null)
383383
query && queryError(query, err)
384-
initial && (queryError(initial, err), initial = null)
384+
initial && (initial.reserve ? initial.reject(err) : queryError(initial, err), initial = null)
385385
}
386386

387387
function queryError(query, err) {
388+
if (!err || typeof err !== 'object')
389+
err = new Error(err)
390+
388391
'query' in err || 'parameters' in err || Object.defineProperties(err, {
389392
stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
390393
query: { value: query.string, enumerable: options.debug },

cjs/src/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,10 @@ function Postgres(a, b) {
204204
const queue = Queue()
205205
const c = open.length
206206
? open.shift()
207-
: await new Promise(r => {
208-
queries.push({ reserve: r })
209-
closed.length && connect(closed.shift())
207+
: await new Promise((resolve, reject) => {
208+
const query = { reserve: resolve, reject }
209+
queries.push(query)
210+
closed.length && connect(closed.shift(), query)
210211
})
211212

212213
move(c, reserved)
@@ -480,7 +481,7 @@ function parseOptions(a, b) {
480481
{}
481482
),
482483
connection : {
483-
application_name: 'postgres.js',
484+
application_name: env.PGAPPNAME || 'postgres.js',
484485
...o.connection,
485486
...Object.entries(query).reduce((acc, [k, v]) => (k in defaults || (acc[k] = v), acc), {})
486487
},

cjs/tests/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,30 @@ t('Reconnect using SSL', { timeout: 2 }, async() => {
429429
return [1, (await sql`select 1 as x`)[0].x]
430430
})
431431

432+
t('Proper handling of non object Errors', async() => {
433+
const sql = postgres({ socket: () => { throw 'wat' } }) // eslint-disable
434+
435+
return [
436+
'wat', await sql`select 1 as x`.catch(e => e.message)
437+
]
438+
})
439+
440+
t('Proper handling of null Errors', async() => {
441+
const sql = postgres({ socket: () => { throw null } }) // eslint-disable
442+
443+
return [
444+
'null', await sql`select 1 as x`.catch(e => e.message)
445+
]
446+
})
447+
448+
t('Ensure reserve throws proper error', async() => {
449+
const sql = postgres({ socket: () => { throw 'wat' }, idle_timeout }) // eslint-disable
450+
451+
return [
452+
'wat', await sql.reserve().catch(e => e)
453+
]
454+
})
455+
432456
t('Login without password', async() => {
433457
return [true, (await postgres({ ...options, ...login })`select true as x`)[0].x]
434458
})

deno/README.md

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,27 @@ select * from users
338338
select * from users where user_id = $1
339339
```
340340

341+
### Dynamic ordering
342+
343+
```js
344+
const id = 1
345+
const order = {
346+
username: 'asc'
347+
created_at: 'desc'
348+
}
349+
await sql`
350+
select
351+
*
352+
from ticket
353+
where account = ${ id }
354+
order by ${
355+
Object.entries(order).flatMap(([column, order], i) =>
356+
[i ? sql`,` : sql``, sql`${ sql(column) } ${ order === 'desc' ? sql`desc` : sql`asc` }`]
357+
)
358+
}
359+
`
360+
```
361+
341362
### SQL functions
342363
Using keywords or calling functions dynamically is also possible by using ``` sql`` ``` fragments.
343364
```js
@@ -564,6 +585,8 @@ If you know what you're doing, you can use `unsafe` to pass any string you'd lik
564585
sql.unsafe('select ' + danger + ' from users where id = ' + dragons)
565586
```
566587

588+
By default, `sql.unsafe` assumes the `query` string is sufficiently dynamic that prepared statements do not make sense, and so defaults them to off. If you'd like to re-enable prepared statements, you can pass `{ prepare: true }`.
589+
567590
You can also nest `sql.unsafe` within a safe `sql` expression. This is useful if only part of your fraction has unsafe elements.
568591

569592
```js
@@ -1121,20 +1144,25 @@ It is also possible to connect to the database without a connection string or an
11211144
const sql = postgres()
11221145
```
11231146

1124-
| Option | Environment Variables |
1125-
| ----------------- | ------------------------ |
1126-
| `host` | `PGHOST` |
1127-
| `port` | `PGPORT` |
1128-
| `database` | `PGDATABASE` |
1129-
| `username` | `PGUSERNAME` or `PGUSER` |
1130-
| `password` | `PGPASSWORD` |
1131-
| `idle_timeout` | `PGIDLE_TIMEOUT` |
1132-
| `connect_timeout` | `PGCONNECT_TIMEOUT` |
1147+
| Option | Environment Variables |
1148+
| ------------------ | ------------------------ |
1149+
| `host` | `PGHOST` |
1150+
| `port` | `PGPORT` |
1151+
| `database` | `PGDATABASE` |
1152+
| `username` | `PGUSERNAME` or `PGUSER` |
1153+
| `password` | `PGPASSWORD` |
1154+
| `application_name` | `PGAPPNAME` |
1155+
| `idle_timeout` | `PGIDLE_TIMEOUT` |
1156+
| `connect_timeout` | `PGCONNECT_TIMEOUT` |
11331157

11341158
### Prepared statements
11351159

11361160
Prepared statements will automatically be created for any queries where it can be inferred that the query is static. This can be disabled by using the `prepare: false` option. For instance — this is useful when [using PGBouncer in `transaction mode`](https://github.com/porsager/postgres/issues/93#issuecomment-656290493).
11371161

1162+
**update**: [since 1.21.0](https://www.pgbouncer.org/2023/10/pgbouncer-1-21-0)
1163+
PGBouncer supports protocol-level named prepared statements when [configured
1164+
properly](https://www.pgbouncer.org/config.html#max_prepared_statements)
1165+
11381166
## Custom Types
11391167

11401168
You can add ergonomic support for custom types, or simply use `sql.typed(value, type)` inline, where type is the PostgreSQL `oid` for the type and the correctly serialized string. _(`oid` values for types can be found in the `pg_catalog.pg_type` table.)_
@@ -1294,8 +1322,8 @@ This error is thrown if the user has called [`sql.end()`](#teardown--cleanup) an
12941322
12951323
This error is thrown for any queries that were pending when the timeout to [`sql.end({ timeout: X })`](#teardown--cleanup) was reached.
12961324

1297-
##### CONNECTION_CONNECT_TIMEOUT
1298-
> write CONNECTION_CONNECT_TIMEOUT host:port
1325+
##### CONNECT_TIMEOUT
1326+
> write CONNECT_TIMEOUT host:port
12991327
13001328
This error is thrown if the startup phase of the connection (tcp, protocol negotiation, and auth) took more than the default 30 seconds or what was specified using `connect_timeout` or `PGCONNECT_TIMEOUT`.
13011329

deno/src/connection.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
296296
if (incomings) {
297297
incomings.push(x)
298298
remaining -= x.length
299-
if (remaining >= 0)
299+
if (remaining > 0)
300300
return
301301
}
302302

@@ -384,10 +384,13 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
384384
function errored(err) {
385385
stream && (stream.destroy(err), stream = null)
386386
query && queryError(query, err)
387-
initial && (queryError(initial, err), initial = null)
387+
initial && (initial.reserve ? initial.reject(err) : queryError(initial, err), initial = null)
388388
}
389389

390390
function queryError(query, err) {
391+
if (!err || typeof err !== 'object')
392+
err = new Error(err)
393+
391394
'query' in err || 'parameters' in err || Object.defineProperties(err, {
392395
stack: { value: err.stack + query.origin.replace(/.*\n/, '\n'), enumerable: options.debug },
393396
query: { value: query.string, enumerable: options.debug },

deno/src/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,10 @@ function Postgres(a, b) {
205205
const queue = Queue()
206206
const c = open.length
207207
? open.shift()
208-
: await new Promise(r => {
209-
queries.push({ reserve: r })
210-
closed.length && connect(closed.shift())
208+
: await new Promise((resolve, reject) => {
209+
const query = { reserve: resolve, reject }
210+
queries.push(query)
211+
closed.length && connect(closed.shift(), query)
211212
})
212213

213214
move(c, reserved)
@@ -481,7 +482,7 @@ function parseOptions(a, b) {
481482
{}
482483
),
483484
connection : {
484-
application_name: 'postgres.js',
485+
application_name: env.PGAPPNAME || 'postgres.js',
485486
...o.connection,
486487
...Object.entries(query).reduce((acc, [k, v]) => (k in defaults || (acc[k] = v), acc), {})
487488
},

deno/tests/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,30 @@ t('Reconnect using SSL', { timeout: 2 }, async() => {
431431
return [1, (await sql`select 1 as x`)[0].x]
432432
})
433433

434+
t('Proper handling of non object Errors', async() => {
435+
const sql = postgres({ socket: () => { throw 'wat' } }) // eslint-disable
436+
437+
return [
438+
'wat', await sql`select 1 as x`.catch(e => e.message)
439+
]
440+
})
441+
442+
t('Proper handling of null Errors', async() => {
443+
const sql = postgres({ socket: () => { throw null } }) // eslint-disable
444+
445+
return [
446+
'null', await sql`select 1 as x`.catch(e => e.message)
447+
]
448+
})
449+
450+
t('Ensure reserve throws proper error', async() => {
451+
const sql = postgres({ socket: () => { throw 'wat' }, idle_timeout }) // eslint-disable
452+
453+
return [
454+
'wat', await sql.reserve().catch(e => e)
455+
]
456+
})
457+
434458
t('Login without password', async() => {
435459
return [true, (await postgres({ ...options, ...login })`select true as x`)[0].x]
436460
})

deno/types/index.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,8 @@ declare namespace postgres {
458458
| 'NOT_TAGGED_CALL'
459459
| 'UNDEFINED_VALUE'
460460
| 'MAX_PARAMETERS_EXCEEDED'
461-
| 'SASL_SIGNATURE_MISMATCH';
461+
| 'SASL_SIGNATURE_MISMATCH'
462+
| 'UNSAFE_TRANSACTION';
462463
message: string;
463464
}
464465

tests/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,23 +430,23 @@ t('Reconnect using SSL', { timeout: 2 }, async() => {
430430
})
431431

432432
t('Proper handling of non object Errors', async() => {
433-
const sql = postgres({ socket: () => { throw 'wat' } })
433+
const sql = postgres({ socket: () => { throw 'wat' } }) // eslint-disable
434434

435435
return [
436436
'wat', await sql`select 1 as x`.catch(e => e.message)
437437
]
438438
})
439439

440440
t('Proper handling of null Errors', async() => {
441-
const sql = postgres({ socket: () => { throw null } })
441+
const sql = postgres({ socket: () => { throw null } }) // eslint-disable
442442

443443
return [
444444
'null', await sql`select 1 as x`.catch(e => e.message)
445445
]
446446
})
447447

448448
t('Ensure reserve throws proper error', async() => {
449-
const sql = postgres({ socket: () => { throw 'wat' }, idle_timeout })
449+
const sql = postgres({ socket: () => { throw 'wat' }, idle_timeout }) // eslint-disable
450450

451451
return [
452452
'wat', await sql.reserve().catch(e => e)

0 commit comments

Comments
 (0)