postgrejs 3.6.0 → 3.7.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 +64 -6
- package/README.md +9 -79
- package/connection/intl-connection.d.ts +5 -3
- package/connection/intl-connection.js +47 -17
- package/connection/pool.d.ts +22 -0
- package/connection/pool.js +45 -3
- package/connection/prepared-statement.js +2 -2
- package/constants.d.ts +60 -0
- package/constants.js +119 -1
- package/data-type-map.js +82 -0
- package/data-types/bit-type.d.ts +5 -0
- package/data-types/bit-type.js +91 -0
- package/data-types/box-type.js +9 -19
- package/data-types/circle-type.js +6 -16
- package/data-types/classes/geometric.d.ts +105 -0
- package/data-types/classes/geometric.js +197 -0
- package/data-types/classes/interval.d.ts +73 -0
- package/data-types/classes/interval.js +181 -0
- package/data-types/classes/numeric.d.ts +37 -0
- package/data-types/classes/numeric.js +47 -0
- package/data-types/classes/range.d.ts +74 -0
- package/data-types/classes/range.js +111 -0
- package/data-types/classes/type-oid.d.ts +34 -0
- package/data-types/classes/type-oid.js +45 -0
- package/data-types/inet-type.d.ts +5 -0
- package/data-types/inet-type.js +286 -0
- package/data-types/interval-type.d.ts +5 -0
- package/data-types/interval-type.js +79 -0
- package/data-types/jsonpath-type.d.ts +3 -0
- package/data-types/jsonpath-type.js +53 -0
- package/data-types/line-type.d.ts +3 -0
- package/data-types/line-type.js +41 -0
- package/data-types/lseg-type.js +9 -19
- package/data-types/macaddr-type.d.ts +5 -0
- package/data-types/macaddr-type.js +86 -0
- package/data-types/numeric-type.js +98 -69
- package/data-types/path-type.d.ts +5 -0
- package/data-types/path-type.js +139 -0
- package/data-types/pg-lsn-type.d.ts +3 -0
- package/data-types/pg-lsn-type.js +58 -0
- package/data-types/point-type.js +8 -13
- package/data-types/range-type.d.ts +23 -0
- package/data-types/range-type.js +342 -0
- package/data-types/snapshot-type.d.ts +5 -0
- package/data-types/snapshot-type.js +96 -0
- package/data-types/tid-type.d.ts +3 -0
- package/data-types/tid-type.js +50 -0
- package/data-types/timetz-type.d.ts +3 -0
- package/data-types/timetz-type.js +184 -0
- package/data-types/tsvector-type.d.ts +5 -0
- package/data-types/tsvector-type.js +216 -0
- package/data-types/xid-type.d.ts +7 -0
- package/data-types/xid-type.js +110 -0
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/interfaces/data-mapping-options.d.ts +26 -0
- package/interfaces/data-type.d.ts +8 -9
- package/package.json +1 -1
- package/protocol/connection-lost-error.d.ts +42 -0
- package/protocol/connection-lost-error.js +56 -0
- package/protocol/pg-socket.d.ts +7 -0
- package/protocol/pg-socket.js +41 -3
- package/util/parse-array.js +17 -2
- package/util/resolve-column-formats.d.ts +2 -1
- package/util/resolve-column-formats.js +35 -8
- package/util/stringify-for-sql.js +37 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DataTypeMap } from '../data-type-map.js';
|
|
1
2
|
import type { DataMappingOptions } from '../interfaces/data-mapping-options.js';
|
|
2
3
|
import { Protocol } from '../protocol/protocol.js';
|
|
3
4
|
import type { Maybe, OID } from '../types.js';
|
|
@@ -23,7 +24,7 @@ export interface ColumnFormatOptions extends DataMappingOptions {
|
|
|
23
24
|
* Returns `columnFormat` untouched when there is nothing to do, so the
|
|
24
25
|
* common case allocates nothing and keeps sending a single format code.
|
|
25
26
|
*/
|
|
26
|
-
export declare function resolveColumnFormats(fields: Maybe<Protocol.RowDescription[]>, options: ColumnFormatOptions): Protocol.DataFormat | Protocol.DataFormat[];
|
|
27
|
+
export declare function resolveColumnFormats(fields: Maybe<Protocol.RowDescription[]>, options: ColumnFormatOptions, typeMap?: DataTypeMap): Protocol.DataFormat | Protocol.DataFormat[];
|
|
27
28
|
/**
|
|
28
29
|
* Whether two `fetchAsString` lists select the same columns. Used to tell
|
|
29
30
|
* a cached set of parsers apart from one built for a different list, which
|
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import { DEFAULT_COLUMN_FORMAT } from '../constants.js';
|
|
2
2
|
import { Protocol } from '../protocol/protocol.js';
|
|
3
3
|
const DataFormat = Protocol.DataFormat;
|
|
4
|
+
/**
|
|
5
|
+
* Whether this client could read the column if it arrived in `format`.
|
|
6
|
+
* Only ever answers no for binary: a column with no registered type at
|
|
7
|
+
* all still decodes as text, into the string the server printed, which is
|
|
8
|
+
* the whole point of asking for it that way.
|
|
9
|
+
*/
|
|
10
|
+
function canDecode(typeMap, oid, format) {
|
|
11
|
+
if (format !== DataFormat.binary)
|
|
12
|
+
return true;
|
|
13
|
+
const reg = typeMap.get(oid);
|
|
14
|
+
return !!reg && typeof reg.decodeBinary === 'function';
|
|
15
|
+
}
|
|
4
16
|
/**
|
|
5
17
|
* Turns `fetchAsString`'s OID list into the positional result format codes
|
|
6
18
|
* a Bind message actually carries.
|
|
@@ -20,28 +32,43 @@ const DataFormat = Protocol.DataFormat;
|
|
|
20
32
|
* Returns `columnFormat` untouched when there is nothing to do, so the
|
|
21
33
|
* common case allocates nothing and keeps sending a single format code.
|
|
22
34
|
*/
|
|
23
|
-
export function resolveColumnFormats(fields, options) {
|
|
35
|
+
export function resolveColumnFormats(fields, options, typeMap) {
|
|
24
36
|
const base = options.columnFormat != null ? options.columnFormat : DEFAULT_COLUMN_FORMAT;
|
|
25
37
|
const asString = options.fetchAsString;
|
|
26
|
-
|
|
38
|
+
// unknownTypesAsString needs the type map to answer "could this be
|
|
39
|
+
// decoded", so it is inert without one - the call sites that have no
|
|
40
|
+
// map in hand are the ones that have no fields either.
|
|
41
|
+
const unknownAsString = !!options.unknownTypesAsString && !!typeMap;
|
|
42
|
+
const named = !!asString && asString.length > 0;
|
|
43
|
+
if (!fields || (!named && !unknownAsString))
|
|
27
44
|
return base;
|
|
28
45
|
const l = fields.length;
|
|
29
46
|
const baseIsArray = Array.isArray(base);
|
|
30
47
|
const out = new Array(l);
|
|
31
48
|
let hit = false;
|
|
32
49
|
let i;
|
|
50
|
+
let oid;
|
|
51
|
+
let format;
|
|
33
52
|
for (i = 0; i < l; i++) {
|
|
34
|
-
|
|
53
|
+
oid = fields[i].dataTypeId;
|
|
54
|
+
format = baseIsArray
|
|
55
|
+
? (base[i] ?? DEFAULT_COLUMN_FORMAT)
|
|
56
|
+
: base;
|
|
57
|
+
if (named && asString.includes(oid)) {
|
|
35
58
|
// fetchAsString names the value the caller wants verbatim, so it
|
|
36
59
|
// overrides an explicit columnFormat for its own columns - the two
|
|
37
60
|
// cannot both be honored and the OID list is the more specific ask.
|
|
38
|
-
|
|
61
|
+
format = DataFormat.text;
|
|
62
|
+
hit = true;
|
|
63
|
+
}
|
|
64
|
+
else if (unknownAsString && !canDecode(typeMap, oid, format)) {
|
|
65
|
+
// Nothing here could read the binary, so the bytes would reach the
|
|
66
|
+
// caller as a Buffer. Text at least arrives as what the server
|
|
67
|
+
// printed.
|
|
68
|
+
format = DataFormat.text;
|
|
39
69
|
hit = true;
|
|
40
70
|
}
|
|
41
|
-
|
|
42
|
-
out[i] = baseIsArray
|
|
43
|
-
? (base[i] ?? DEFAULT_COLUMN_FORMAT)
|
|
44
|
-
: base;
|
|
71
|
+
out[i] = format;
|
|
45
72
|
}
|
|
46
73
|
return hit ? out : base;
|
|
47
74
|
}
|
|
@@ -1,9 +1,41 @@
|
|
|
1
|
+
import { DataTypeOIDs } from '../constants.js';
|
|
2
|
+
import { GlobalTypeMap } from '../data-type-map.js';
|
|
1
3
|
import { UuidType } from '../data-types/uuid-type.js';
|
|
2
4
|
import { escapeLiteral } from './escape-literal.js';
|
|
3
5
|
export function stringifyArrayForSQL(v, options, encode) {
|
|
4
6
|
const arr = v.map(x => stringifyValueForSQL(x, options, encode));
|
|
5
7
|
return 'ARRAY[' + arr.join(',') + ']';
|
|
6
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Which type an object is is asked rather than assumed.
|
|
11
|
+
*
|
|
12
|
+
* Every geometric class, Interval, Range, Date and Buffer has a
|
|
13
|
+
* registered `encodeText()` that writes exactly the literal PostgreSQL
|
|
14
|
+
* reads back, and `determine()` already knows which type each one is -
|
|
15
|
+
* it is what the same value is sent as when it is bound as a parameter.
|
|
16
|
+
* Without asking, all of them became `::json`, and since these classes
|
|
17
|
+
* have a `toJSON()` returning their own literal the result was not even
|
|
18
|
+
* a JSON object but a JSON string holding one, which casts to nothing:
|
|
19
|
+
* `'"(1,2)"'::json` where `'(1,2)'::point` was meant. A Date became its
|
|
20
|
+
* ISO string and a Buffer leaked its bytes as `{"type":"Buffer",...}`.
|
|
21
|
+
*/
|
|
22
|
+
function stringifyObjectForSQL(v, options) {
|
|
23
|
+
// determine() throws for a class that must carry a type OID and does
|
|
24
|
+
// not - a Range built without one - and that throw is deliberate: the
|
|
25
|
+
// alternative is writing a literal for a type nobody chose.
|
|
26
|
+
const oid = GlobalTypeMap.determine(v);
|
|
27
|
+
const dataType = GlobalTypeMap.get(oid);
|
|
28
|
+
// json and jsonb are the fallback below; reaching them through their
|
|
29
|
+
// own encodeText would only add a cast the literal does not need.
|
|
30
|
+
// Anything with no registered text encoder lands there too.
|
|
31
|
+
if (dataType?.encodeText &&
|
|
32
|
+
oid !== DataTypeOIDs.json &&
|
|
33
|
+
oid !== DataTypeOIDs.jsonb)
|
|
34
|
+
return (escapeLiteral(dataType.encodeText(v, options || {})) +
|
|
35
|
+
'::' +
|
|
36
|
+
dataType.name);
|
|
37
|
+
return escapeLiteral(JSON.stringify(v)) + '::json';
|
|
38
|
+
}
|
|
7
39
|
export function stringifyValueForSQL(v, options, encode) {
|
|
8
40
|
if (v == null)
|
|
9
41
|
return 'null';
|
|
@@ -20,6 +52,10 @@ export function stringifyValueForSQL(v, options, encode) {
|
|
|
20
52
|
if (typeof v === 'string' && UuidType.isType(v))
|
|
21
53
|
return escapeLiteral('' + v) + '::uuid';
|
|
22
54
|
if (typeof v === 'object')
|
|
23
|
-
return
|
|
55
|
+
return stringifyObjectForSQL(v, options);
|
|
56
|
+
// A string is deliberately written bare. determine() would answer
|
|
57
|
+
// varchar, but an unadorned literal is `unknown` and takes the type of
|
|
58
|
+
// wherever it lands - `insert into t(n) values('5')` works and
|
|
59
|
+
// `'5'::varchar` would not.
|
|
24
60
|
return escapeLiteral('' + v);
|
|
25
61
|
}
|