postgrejs 3.8.0 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -1
- package/README.md +50 -0
- package/connection/connection.d.ts +14 -2
- package/connection/connection.js +63 -11
- package/connection/intl-connection.d.ts +164 -6
- package/connection/intl-connection.js +558 -37
- package/connection/pool.d.ts +30 -6
- package/connection/pool.js +22 -3
- package/connection/prepared-statement.js +22 -2
- package/data-type-map.d.ts +16 -0
- package/data-type-map.js +56 -12
- package/data-types/circle-type.js +5 -2
- package/data-types/classes/geometric.d.ts +49 -7
- package/data-types/classes/geometric.js +59 -11
- package/data-types/classes/interval.d.ts +40 -16
- package/data-types/classes/interval.js +68 -40
- package/data-types/classes/numeric.d.ts +6 -0
- package/data-types/classes/numeric.js +8 -0
- package/data-types/classes/range.d.ts +6 -1
- package/data-types/classes/range.js +6 -1
- package/data-types/date-type.js +2 -2
- package/data-types/interval-type.js +1 -1
- package/data-types/money-type.d.ts +38 -0
- package/data-types/money-type.js +212 -0
- package/data-types/numeric-type.d.ts +2 -0
- package/data-types/numeric-type.js +22 -11
- package/data-types/temporal-types.d.ts +19 -0
- package/data-types/temporal-types.js +520 -0
- package/data-types/timestamp-type.js +2 -2
- package/data-types/timestamptz-type.js +2 -2
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/interfaces/data-mapping-options.d.ts +126 -4
- package/interfaces/database-connection-params.d.ts +32 -5
- package/interfaces/query-options.d.ts +32 -0
- package/interfaces/script-execute-options.d.ts +32 -0
- package/interfaces/transaction-options.d.ts +27 -0
- package/interfaces/transaction-options.js +1 -0
- package/package.json +1 -1
- package/protocol/database-error.d.ts +15 -0
- package/protocol/database-error.js +19 -0
- package/protocol/frontend.js +1 -1
- package/protocol/pg-socket.js +7 -10
- package/util/array-leaf.d.ts +10 -0
- package/util/array-leaf.js +22 -0
- package/util/connection-config.js +11 -1
- package/util/date-style.d.ts +47 -0
- package/util/date-style.js +123 -0
- package/util/decimal-as-string.d.ts +11 -0
- package/util/decimal-as-string.js +30 -0
- package/util/fetch-as-string.d.ts +33 -0
- package/util/fetch-as-string.js +122 -0
- package/util/get-parsers.js +18 -1
- package/util/parse-datetime.d.ts +4 -3
- package/util/parse-datetime.js +34 -9
- package/util/resolve-column-formats.d.ts +5 -11
- package/util/resolve-column-formats.js +28 -24
- package/util/row-decoder.d.ts +24 -4
- package/util/row-decoder.js +25 -10
- package/util/sql-tag.js +2 -1
- package/util/stringify-for-sql.js +6 -5
- package/util/temporal.d.ts +47 -0
- package/util/temporal.js +61 -0
- package/util/transaction-command.d.ts +7 -0
- package/util/transaction-command.js +32 -0
- package/util/unspecified-param.d.ts +18 -8
- package/util/unspecified-param.js +22 -14
package/util/temporal.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reaching the `Temporal` the application provides, without depending on
|
|
3
|
+
* one.
|
|
4
|
+
*
|
|
5
|
+
* No runtime ships Temporal yet - Node 24.15 and Bun 1.3.10 both answer
|
|
6
|
+
* `undefined`, with or without `--harmony` - so today every caller that
|
|
7
|
+
* turns `temporalTypes` on has installed a polyfill. That is why this is
|
|
8
|
+
* read off `globalThis` when it is needed rather than imported: this
|
|
9
|
+
* package takes no dependency, a polyfill loaded after this module is
|
|
10
|
+
* still seen, and the day a runtime ships Temporal nothing here changes.
|
|
11
|
+
*/
|
|
12
|
+
let _systemTimeZone;
|
|
13
|
+
const _knownZones = new Set();
|
|
14
|
+
/**
|
|
15
|
+
* The runtime's `Temporal`, or an error saying how to get one.
|
|
16
|
+
*
|
|
17
|
+
* Called when a type map is built - which for a connection is while it
|
|
18
|
+
* is being constructed - so a missing Temporal is reported before any
|
|
19
|
+
* I/O rather than in the middle of decoding a row.
|
|
20
|
+
*/
|
|
21
|
+
export function getTemporal() {
|
|
22
|
+
const t = globalThis.Temporal;
|
|
23
|
+
if (!t || !t.ZonedDateTime)
|
|
24
|
+
throw new Error('Temporal is not available in this runtime. postgrejs reads ' +
|
|
25
|
+
'globalThis.Temporal and takes no dependency of its own: install ' +
|
|
26
|
+
'`temporal-polyfill` and import it before connecting, or leave ' +
|
|
27
|
+
'`temporalTypes` off.');
|
|
28
|
+
return t;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The zone a `timestamptz` is printed in when the caller named none.
|
|
32
|
+
*
|
|
33
|
+
* Only the printing: a timestamptz is an absolute instant and arrives as
|
|
34
|
+
* one, so the zone decides what wall clock the ZonedDateTime shows and
|
|
35
|
+
* nothing about which moment it is.
|
|
36
|
+
*/
|
|
37
|
+
export function systemTimeZone() {
|
|
38
|
+
if (_systemTimeZone === undefined)
|
|
39
|
+
_systemTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
40
|
+
return _systemTimeZone;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Checks a zone name before it is handed to Temporal, so the complaint
|
|
44
|
+
* names the setting it came from instead of surfacing from inside a
|
|
45
|
+
* decode. `Intl` accepts exactly what Temporal does and is here whether
|
|
46
|
+
* Temporal is or not.
|
|
47
|
+
*/
|
|
48
|
+
export function requireTimeZone(zone, where) {
|
|
49
|
+
if (_knownZones.has(zone))
|
|
50
|
+
return zone;
|
|
51
|
+
try {
|
|
52
|
+
new Intl.DateTimeFormat('en-US', { timeZone: zone });
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
throw new Error(`"${zone}" (${where}) is not a time zone this runtime knows, so a ` +
|
|
56
|
+
'timestamptz cannot be given one. Pass `timeZone` in the mapping ' +
|
|
57
|
+
'options to name one yourself.');
|
|
58
|
+
}
|
|
59
|
+
_knownZones.add(zone);
|
|
60
|
+
return zone;
|
|
61
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Whether `sql` opens or closes a transaction. */
|
|
2
|
+
export declare function isTransactionCommand(sql: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Whether `sql` must not run inside a savepoint - it is a transaction
|
|
5
|
+
* command, or it configures the transaction.
|
|
6
|
+
*/
|
|
7
|
+
export declare function refusesSavepoint(sql: string): boolean;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statements that open or close a transaction, and so manage their own
|
|
3
|
+
* boundaries: an implicit BEGIN or COMMIT around one would be wrong, and
|
|
4
|
+
* wrapping one in a savepoint - COMMIT, say - is nonsense.
|
|
5
|
+
*/
|
|
6
|
+
const TRANSACTION_COMMAND_PATTERN = /^(\bBEGIN\b|\bCOMMIT\b|\bSTART\b|\bROLLBACK|SAVEPOINT|RELEASE\b)/i;
|
|
7
|
+
/**
|
|
8
|
+
* `SET TRANSACTION`, which configures the transaction it runs in rather
|
|
9
|
+
* than opening or closing one.
|
|
10
|
+
*
|
|
11
|
+
* It needs an answer of its own because the two are not the same
|
|
12
|
+
* question. PostgreSQL refuses two of its forms inside a subtransaction
|
|
13
|
+
* - `SET TRANSACTION ISOLATION LEVEL` and `SET TRANSACTION [NOT]
|
|
14
|
+
* DEFERRABLE`, both 25001 - so the savepoint `rollbackOnError` puts
|
|
15
|
+
* around every statement in a transaction made them impossible to run
|
|
16
|
+
* at all. But the implicit BEGIN that `autoCommit: false` adds is
|
|
17
|
+
* exactly what they need, so answering "transaction command" for them
|
|
18
|
+
* and suppressing both would trade one failure for another.
|
|
19
|
+
*/
|
|
20
|
+
const CONFIGURES_TRANSACTION_PATTERN = /^\bSET\s+TRANSACTION\b/i;
|
|
21
|
+
/** Whether `sql` opens or closes a transaction. */
|
|
22
|
+
export function isTransactionCommand(sql) {
|
|
23
|
+
return TRANSACTION_COMMAND_PATTERN.test(sql);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Whether `sql` must not run inside a savepoint - it is a transaction
|
|
27
|
+
* command, or it configures the transaction.
|
|
28
|
+
*/
|
|
29
|
+
export function refusesSavepoint(sql) {
|
|
30
|
+
return (TRANSACTION_COMMAND_PATTERN.test(sql) ||
|
|
31
|
+
CONFIGURES_TRANSACTION_PATTERN.test(sql));
|
|
32
|
+
}
|
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The first value inside `v` that is not itself an array - what an array
|
|
3
|
-
* parameter's element type would be read from. A scalar answers itself.
|
|
4
|
-
*/
|
|
5
|
-
export declare function arrayLeaf(v: any): any;
|
|
6
1
|
/**
|
|
7
2
|
* Whether a parameter goes out with no declared type (OID 0), as text,
|
|
8
3
|
* for the server to resolve from wherever it lands.
|
|
@@ -25,8 +20,23 @@ export declare function arrayLeaf(v: any): any;
|
|
|
25
20
|
* as it does under `pg`. A cast (`$1::text`) or a named type
|
|
26
21
|
* (`new BindParam(DataTypeOIDs.varchar, v)`) says which type is meant.
|
|
27
22
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
23
|
+
* - An array of numbers is the same question, and the answer matters
|
|
24
|
+
* more: `[1, 2]` is `int2[]`, `int4[]`, `int8[]`, `numeric[]`,
|
|
25
|
+
* `float4[]` or `float8[]` depending on where it lands, and unlike
|
|
26
|
+
* their scalars those types have no operators or implicit casts
|
|
27
|
+
* between them. A declared `int4[]` is therefore not merely a guess
|
|
28
|
+
* but a wrong answer wherever the column is one of the other five:
|
|
29
|
+
* `array[1,2]::int8[] = $1` is `42883 operator does not exist:
|
|
30
|
+
* bigint[] = integer[]`, and `numeric[] = double precision[]` the
|
|
31
|
+
* same. The scalars are left declared because they do have those
|
|
32
|
+
* operators - `1::int8 = $1` and `1.5::numeric = $1` both resolve.
|
|
33
|
+
*
|
|
34
|
+
* A scalar number, a boolean, a Buffer, and an array of anything but
|
|
35
|
+
* numbers keep their declared types: an array of booleans, of Buffers
|
|
36
|
+
* or of one of this client's own classes has one type it can be, so
|
|
37
|
+
* naming it says nothing the server would have decided differently -
|
|
38
|
+
* and it keeps the binary encoding, which the text literal gives up.
|
|
39
|
+
* A caller who wants that back for a large numeric array names the type
|
|
40
|
+
* with `new BindParam(DataTypeOIDs._float8, v)`.
|
|
31
41
|
*/
|
|
32
42
|
export declare function isUnspecifiedParam(v: any): boolean;
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* The first value inside `v` that is not itself an array - what an array
|
|
3
|
-
* parameter's element type would be read from. A scalar answers itself.
|
|
4
|
-
*/
|
|
5
|
-
export function arrayLeaf(v) {
|
|
6
|
-
let x = v;
|
|
7
|
-
while (Array.isArray(x))
|
|
8
|
-
x = x[0];
|
|
9
|
-
return x;
|
|
10
|
-
}
|
|
1
|
+
import { arrayLeaf } from './array-leaf.js';
|
|
11
2
|
/**
|
|
12
3
|
* Whether a parameter goes out with no declared type (OID 0), as text,
|
|
13
4
|
* for the server to resolve from wherever it lands.
|
|
@@ -30,11 +21,28 @@ export function arrayLeaf(v) {
|
|
|
30
21
|
* as it does under `pg`. A cast (`$1::text`) or a named type
|
|
31
22
|
* (`new BindParam(DataTypeOIDs.varchar, v)`) says which type is meant.
|
|
32
23
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
24
|
+
* - An array of numbers is the same question, and the answer matters
|
|
25
|
+
* more: `[1, 2]` is `int2[]`, `int4[]`, `int8[]`, `numeric[]`,
|
|
26
|
+
* `float4[]` or `float8[]` depending on where it lands, and unlike
|
|
27
|
+
* their scalars those types have no operators or implicit casts
|
|
28
|
+
* between them. A declared `int4[]` is therefore not merely a guess
|
|
29
|
+
* but a wrong answer wherever the column is one of the other five:
|
|
30
|
+
* `array[1,2]::int8[] = $1` is `42883 operator does not exist:
|
|
31
|
+
* bigint[] = integer[]`, and `numeric[] = double precision[]` the
|
|
32
|
+
* same. The scalars are left declared because they do have those
|
|
33
|
+
* operators - `1::int8 = $1` and `1.5::numeric = $1` both resolve.
|
|
34
|
+
*
|
|
35
|
+
* A scalar number, a boolean, a Buffer, and an array of anything but
|
|
36
|
+
* numbers keep their declared types: an array of booleans, of Buffers
|
|
37
|
+
* or of one of this client's own classes has one type it can be, so
|
|
38
|
+
* naming it says nothing the server would have decided differently -
|
|
39
|
+
* and it keeps the binary encoding, which the text literal gives up.
|
|
40
|
+
* A caller who wants that back for a large numeric array names the type
|
|
41
|
+
* with `new BindParam(DataTypeOIDs._float8, v)`.
|
|
36
42
|
*/
|
|
37
43
|
export function isUnspecifiedParam(v) {
|
|
38
44
|
const x = arrayLeaf(v);
|
|
39
|
-
|
|
45
|
+
if (typeof x === 'string' || x instanceof Date)
|
|
46
|
+
return true;
|
|
47
|
+
return Array.isArray(v) && (typeof x === 'number' || typeof x === 'bigint');
|
|
40
48
|
}
|