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.
Files changed (66) hide show
  1. package/CHANGELOG.md +64 -6
  2. package/README.md +9 -79
  3. package/connection/intl-connection.d.ts +5 -3
  4. package/connection/intl-connection.js +47 -17
  5. package/connection/pool.d.ts +22 -0
  6. package/connection/pool.js +45 -3
  7. package/connection/prepared-statement.js +2 -2
  8. package/constants.d.ts +60 -0
  9. package/constants.js +119 -1
  10. package/data-type-map.js +82 -0
  11. package/data-types/bit-type.d.ts +5 -0
  12. package/data-types/bit-type.js +91 -0
  13. package/data-types/box-type.js +9 -19
  14. package/data-types/circle-type.js +6 -16
  15. package/data-types/classes/geometric.d.ts +105 -0
  16. package/data-types/classes/geometric.js +197 -0
  17. package/data-types/classes/interval.d.ts +73 -0
  18. package/data-types/classes/interval.js +181 -0
  19. package/data-types/classes/numeric.d.ts +37 -0
  20. package/data-types/classes/numeric.js +47 -0
  21. package/data-types/classes/range.d.ts +74 -0
  22. package/data-types/classes/range.js +111 -0
  23. package/data-types/classes/type-oid.d.ts +34 -0
  24. package/data-types/classes/type-oid.js +45 -0
  25. package/data-types/inet-type.d.ts +5 -0
  26. package/data-types/inet-type.js +286 -0
  27. package/data-types/interval-type.d.ts +5 -0
  28. package/data-types/interval-type.js +79 -0
  29. package/data-types/jsonpath-type.d.ts +3 -0
  30. package/data-types/jsonpath-type.js +53 -0
  31. package/data-types/line-type.d.ts +3 -0
  32. package/data-types/line-type.js +41 -0
  33. package/data-types/lseg-type.js +9 -19
  34. package/data-types/macaddr-type.d.ts +5 -0
  35. package/data-types/macaddr-type.js +86 -0
  36. package/data-types/numeric-type.js +98 -69
  37. package/data-types/path-type.d.ts +5 -0
  38. package/data-types/path-type.js +139 -0
  39. package/data-types/pg-lsn-type.d.ts +3 -0
  40. package/data-types/pg-lsn-type.js +58 -0
  41. package/data-types/point-type.js +8 -13
  42. package/data-types/range-type.d.ts +23 -0
  43. package/data-types/range-type.js +342 -0
  44. package/data-types/snapshot-type.d.ts +5 -0
  45. package/data-types/snapshot-type.js +96 -0
  46. package/data-types/tid-type.d.ts +3 -0
  47. package/data-types/tid-type.js +50 -0
  48. package/data-types/timetz-type.d.ts +3 -0
  49. package/data-types/timetz-type.js +184 -0
  50. package/data-types/tsvector-type.d.ts +5 -0
  51. package/data-types/tsvector-type.js +216 -0
  52. package/data-types/xid-type.d.ts +7 -0
  53. package/data-types/xid-type.js +110 -0
  54. package/index.d.ts +5 -0
  55. package/index.js +5 -0
  56. package/interfaces/data-mapping-options.d.ts +26 -0
  57. package/interfaces/data-type.d.ts +8 -9
  58. package/package.json +1 -1
  59. package/protocol/connection-lost-error.d.ts +42 -0
  60. package/protocol/connection-lost-error.js +56 -0
  61. package/protocol/pg-socket.d.ts +7 -0
  62. package/protocol/pg-socket.js +41 -3
  63. package/util/parse-array.js +17 -2
  64. package/util/resolve-column-formats.d.ts +2 -1
  65. package/util/resolve-column-formats.js +35 -8
  66. package/util/stringify-for-sql.js +37 -1
package/constants.js CHANGED
@@ -30,6 +30,7 @@ export const DataTypeOIDs = {
30
30
  oidvector: 30,
31
31
  json: 114,
32
32
  xml: 142,
33
+ pg_node_tree: 194,
33
34
  point: 600,
34
35
  lseg: 601,
35
36
  path: 602,
@@ -45,6 +46,7 @@ export const DataTypeOIDs = {
45
46
  money: 790,
46
47
  macaddr: 829,
47
48
  inet: 869,
49
+ aclitem: 1033,
48
50
  bpchar: 1042,
49
51
  varchar: 1043,
50
52
  date: 1082,
@@ -73,14 +75,40 @@ export const DataTypeOIDs = {
73
75
  anyelement: 2283,
74
76
  anynonarray: 2776,
75
77
  uuid: 2950,
78
+ txid_snapshot: 2970,
79
+ pg_lsn: 3220,
80
+ pg_ndistinct: 3361,
81
+ pg_dependencies: 3402,
82
+ tsvector: 3614,
83
+ tsquery: 3615,
84
+ gtsvector: 3642,
85
+ regconfig: 3734,
86
+ regdictionary: 3769,
76
87
  jsonb: 3802,
77
88
  anyrange: 3831,
78
89
  int4range: 3904,
79
90
  numrange: 3906,
80
91
  tsrange: 3908,
92
+ tstzrange: 3910,
93
+ /** @deprecated Misspelling of `tstzrange`, kept so it keeps resolving. */
81
94
  rstzrange: 3910,
82
95
  daterange: 3912,
83
96
  int8range: 3926,
97
+ jsonpath: 4072,
98
+ regnamespace: 4089,
99
+ regrole: 4096,
100
+ regcollation: 4191,
101
+ int4multirange: 4451,
102
+ nummultirange: 4532,
103
+ tsmultirange: 4533,
104
+ tstzmultirange: 4534,
105
+ datemultirange: 4535,
106
+ int8multirange: 4536,
107
+ pg_brin_bloom_summary: 4600,
108
+ pg_brin_minmax_multi_summary: 4601,
109
+ pg_mcv_list: 5017,
110
+ pg_snapshot: 5038,
111
+ xid8: 5069,
84
112
  _xml: 143,
85
113
  _json: 199,
86
114
  _xid8: 271,
@@ -113,6 +141,7 @@ export const DataTypeOIDs = {
113
141
  _float8: 1022,
114
142
  _polygon: 1027,
115
143
  _oid: 1028,
144
+ _aclitem: 1034,
116
145
  _macaddr: 1040,
117
146
  _inet: 1041,
118
147
  _timestamp: 1115,
@@ -125,8 +154,39 @@ export const DataTypeOIDs = {
125
154
  _timetz: 1270,
126
155
  _bit: 1561,
127
156
  _varbit: 1563,
157
+ _refcursor: 2201,
158
+ _regprocedure: 2207,
159
+ _regoper: 2208,
160
+ _regoperator: 2209,
161
+ _regclass: 2210,
162
+ _regtype: 2211,
163
+ _record: 2287,
164
+ _txid_snapshot: 2949,
128
165
  _uuid: 2951,
166
+ _pg_lsn: 3221,
167
+ _tsvector: 3643,
168
+ _gtsvector: 3644,
169
+ _tsquery: 3645,
170
+ _regconfig: 3735,
171
+ _regdictionary: 3770,
129
172
  _jsonb: 3807,
173
+ _int4range: 3905,
174
+ _numrange: 3907,
175
+ _tsrange: 3909,
176
+ _tstzrange: 3911,
177
+ _daterange: 3913,
178
+ _int8range: 3927,
179
+ _jsonpath: 4073,
180
+ _regnamespace: 4090,
181
+ _regrole: 4097,
182
+ _regcollation: 4192,
183
+ _pg_snapshot: 5039,
184
+ _int4multirange: 6150,
185
+ _nummultirange: 6151,
186
+ _tsmultirange: 6152,
187
+ _tstzmultirange: 6153,
188
+ _datemultirange: 6155,
189
+ _int8multirange: 6157,
130
190
  };
131
191
  export const DataTypeNames = {
132
192
  [DataTypeOIDs.bool]: 'bool',
@@ -146,6 +206,7 @@ export const DataTypeNames = {
146
206
  [DataTypeOIDs.oidvector]: 'oidvector',
147
207
  [DataTypeOIDs.json]: 'json',
148
208
  [DataTypeOIDs.xml]: 'xml',
209
+ [DataTypeOIDs.pg_node_tree]: 'pg_node_tree',
149
210
  [DataTypeOIDs.point]: 'point',
150
211
  [DataTypeOIDs.lseg]: 'lseg',
151
212
  [DataTypeOIDs.path]: 'path',
@@ -161,6 +222,7 @@ export const DataTypeNames = {
161
222
  [DataTypeOIDs.money]: 'money',
162
223
  [DataTypeOIDs.macaddr]: 'macaddr',
163
224
  [DataTypeOIDs.inet]: 'inet',
225
+ [DataTypeOIDs.aclitem]: 'aclitem',
164
226
  [DataTypeOIDs.bpchar]: 'bpchar',
165
227
  [DataTypeOIDs.varchar]: 'varchar',
166
228
  [DataTypeOIDs.date]: 'date',
@@ -189,14 +251,38 @@ export const DataTypeNames = {
189
251
  [DataTypeOIDs.anyelement]: 'anyelement',
190
252
  [DataTypeOIDs.anynonarray]: 'anynonarray',
191
253
  [DataTypeOIDs.uuid]: 'uuid',
254
+ [DataTypeOIDs.txid_snapshot]: 'txid_snapshot',
255
+ [DataTypeOIDs.pg_lsn]: 'pg_lsn',
256
+ [DataTypeOIDs.pg_ndistinct]: 'pg_ndistinct',
257
+ [DataTypeOIDs.pg_dependencies]: 'pg_dependencies',
258
+ [DataTypeOIDs.tsvector]: 'tsvector',
259
+ [DataTypeOIDs.tsquery]: 'tsquery',
260
+ [DataTypeOIDs.gtsvector]: 'gtsvector',
261
+ [DataTypeOIDs.regconfig]: 'regconfig',
262
+ [DataTypeOIDs.regdictionary]: 'regdictionary',
192
263
  [DataTypeOIDs.jsonb]: 'jsonb',
193
264
  [DataTypeOIDs.anyrange]: 'anyrange',
194
265
  [DataTypeOIDs.int4range]: 'int4range',
195
266
  [DataTypeOIDs.numrange]: 'numrange',
196
267
  [DataTypeOIDs.tsrange]: 'tsrange',
197
- [DataTypeOIDs.rstzrange]: 'rstzrange',
268
+ [DataTypeOIDs.tstzrange]: 'tstzrange',
198
269
  [DataTypeOIDs.daterange]: 'daterange',
199
270
  [DataTypeOIDs.int8range]: 'int8range',
271
+ [DataTypeOIDs.jsonpath]: 'jsonpath',
272
+ [DataTypeOIDs.regnamespace]: 'regnamespace',
273
+ [DataTypeOIDs.regrole]: 'regrole',
274
+ [DataTypeOIDs.regcollation]: 'regcollation',
275
+ [DataTypeOIDs.int4multirange]: 'int4multirange',
276
+ [DataTypeOIDs.nummultirange]: 'nummultirange',
277
+ [DataTypeOIDs.tsmultirange]: 'tsmultirange',
278
+ [DataTypeOIDs.tstzmultirange]: 'tstzmultirange',
279
+ [DataTypeOIDs.datemultirange]: 'datemultirange',
280
+ [DataTypeOIDs.int8multirange]: 'int8multirange',
281
+ [DataTypeOIDs.pg_brin_bloom_summary]: 'pg_brin_bloom_summary',
282
+ [DataTypeOIDs.pg_brin_minmax_multi_summary]: 'pg_brin_minmax_multi_summary',
283
+ [DataTypeOIDs.pg_mcv_list]: 'pg_mcv_list',
284
+ [DataTypeOIDs.pg_snapshot]: 'pg_snapshot',
285
+ [DataTypeOIDs.xid8]: 'xid8',
200
286
  [DataTypeOIDs._xml]: '_xml',
201
287
  [DataTypeOIDs._json]: '_json',
202
288
  [DataTypeOIDs._xid8]: '_xid8',
@@ -229,6 +315,7 @@ export const DataTypeNames = {
229
315
  [DataTypeOIDs._float8]: '_float8',
230
316
  [DataTypeOIDs._polygon]: '_polygon',
231
317
  [DataTypeOIDs._oid]: '_oid',
318
+ [DataTypeOIDs._aclitem]: '_aclitem',
232
319
  [DataTypeOIDs._macaddr]: '_macaddr',
233
320
  [DataTypeOIDs._inet]: '_inet',
234
321
  [DataTypeOIDs._timestamp]: '_timestamp',
@@ -241,6 +328,37 @@ export const DataTypeNames = {
241
328
  [DataTypeOIDs._timetz]: '_timetz',
242
329
  [DataTypeOIDs._bit]: '_bit',
243
330
  [DataTypeOIDs._varbit]: '_varbit',
331
+ [DataTypeOIDs._refcursor]: '_refcursor',
332
+ [DataTypeOIDs._regprocedure]: '_regprocedure',
333
+ [DataTypeOIDs._regoper]: '_regoper',
334
+ [DataTypeOIDs._regoperator]: '_regoperator',
335
+ [DataTypeOIDs._regclass]: '_regclass',
336
+ [DataTypeOIDs._regtype]: '_regtype',
337
+ [DataTypeOIDs._record]: '_record',
338
+ [DataTypeOIDs._txid_snapshot]: '_txid_snapshot',
244
339
  [DataTypeOIDs._uuid]: '_uuid',
340
+ [DataTypeOIDs._pg_lsn]: '_pg_lsn',
341
+ [DataTypeOIDs._tsvector]: '_tsvector',
342
+ [DataTypeOIDs._gtsvector]: '_gtsvector',
343
+ [DataTypeOIDs._tsquery]: '_tsquery',
344
+ [DataTypeOIDs._regconfig]: '_regconfig',
345
+ [DataTypeOIDs._regdictionary]: '_regdictionary',
245
346
  [DataTypeOIDs._jsonb]: '_jsonb',
347
+ [DataTypeOIDs._int4range]: '_int4range',
348
+ [DataTypeOIDs._numrange]: '_numrange',
349
+ [DataTypeOIDs._tsrange]: '_tsrange',
350
+ [DataTypeOIDs._tstzrange]: '_tstzrange',
351
+ [DataTypeOIDs._daterange]: '_daterange',
352
+ [DataTypeOIDs._int8range]: '_int8range',
353
+ [DataTypeOIDs._jsonpath]: '_jsonpath',
354
+ [DataTypeOIDs._regnamespace]: '_regnamespace',
355
+ [DataTypeOIDs._regrole]: '_regrole',
356
+ [DataTypeOIDs._regcollation]: '_regcollation',
357
+ [DataTypeOIDs._pg_snapshot]: '_pg_snapshot',
358
+ [DataTypeOIDs._int4multirange]: '_int4multirange',
359
+ [DataTypeOIDs._nummultirange]: '_nummultirange',
360
+ [DataTypeOIDs._tsmultirange]: '_tsmultirange',
361
+ [DataTypeOIDs._tstzmultirange]: '_tstzmultirange',
362
+ [DataTypeOIDs._datemultirange]: '_datemultirange',
363
+ [DataTypeOIDs._int8multirange]: '_int8multirange',
246
364
  };
package/data-type-map.js CHANGED
@@ -1,28 +1,43 @@
1
1
  import { DataTypeOIDs } from './constants.js';
2
+ import { ArrayBitType, ArrayVarbitType, BitType, VarbitType, } from './data-types/bit-type.js';
2
3
  import { ArrayBoolType, BoolType } from './data-types/bool-type.js';
3
4
  import { ArrayBoxType, BoxType } from './data-types/box-type.js';
4
5
  import { ArrayByteaType, ByteaType } from './data-types/bytea-type.js';
5
6
  import { ArrayCharType, CharType } from './data-types/char-type.js';
6
7
  import { ArrayCircleType, CircleType } from './data-types/circle-type.js';
8
+ import { getTypeOid, REQUIRES_TYPE_OID, } from './data-types/classes/type-oid.js';
7
9
  import { ArrayDateType, DateType } from './data-types/date-type.js';
8
10
  import { ArrayFloat4Type, Float4Type } from './data-types/float4-type.js';
9
11
  import { ArrayFloat8Type, Float8Type } from './data-types/float8-type.js';
12
+ import { ArrayCidrType, ArrayInetType, CidrType, InetType, } from './data-types/inet-type.js';
10
13
  import { ArrayInt2Type, Int2Type } from './data-types/int2-type.js';
11
14
  import { ArrayInt2VectorType, Int2VectorType, } from './data-types/int2-vector-type.js';
12
15
  import { ArrayInt4Type, Int4Type } from './data-types/int4-type.js';
13
16
  import { ArrayInt8Type, Int8Type } from './data-types/int8-type.js';
17
+ import { ArrayIntervalType, IntervalType } from './data-types/interval-type.js';
14
18
  import { ArrayJsonType, JsonType } from './data-types/json-type.js';
15
19
  import { ArrayJsonbType, JsonbType } from './data-types/jsonb-type.js';
20
+ import { ArrayJsonPathType, JsonPathType } from './data-types/jsonpath-type.js';
21
+ import { ArrayLineType, LineType } from './data-types/line-type.js';
16
22
  import { ArrayLsegType, LsegType } from './data-types/lseg-type.js';
23
+ import { ArrayMacaddr8Type, ArrayMacaddrType, Macaddr8Type, MacaddrType, } from './data-types/macaddr-type.js';
17
24
  import { ArrayNumericType, NumericType } from './data-types/numeric-type.js';
18
25
  import { ArrayOidType, OidType } from './data-types/oid-type.js';
19
26
  import { ArrayOidVectorType, OidVectorType, } from './data-types/oid-vector-type.js';
27
+ import { ArrayPathType, ArrayPolygonType, PathType, PolygonType, } from './data-types/path-type.js';
28
+ import { ArrayPgLsnType, PgLsnType } from './data-types/pg-lsn-type.js';
20
29
  import { ArrayPointType, PointType } from './data-types/point-type.js';
30
+ import { RangeTypes } from './data-types/range-type.js';
31
+ import { ArrayPgSnapshotType, ArrayTxidSnapshotType, PgSnapshotType, TxidSnapshotType, } from './data-types/snapshot-type.js';
32
+ import { ArrayTidType, TidType } from './data-types/tid-type.js';
21
33
  import { ArrayTimeType, TimeType } from './data-types/time-type.js';
22
34
  import { ArrayTimestampType, TimestampType, } from './data-types/timestamp-type.js';
23
35
  import { ArrayTimestamptzType, TimestamptzType, } from './data-types/timestamptz-type.js';
36
+ import { ArrayTimeTzType, TimeTzType } from './data-types/timetz-type.js';
37
+ import { ArrayTsQueryType, ArrayTsVectorType, TsQueryType, TsVectorType, } from './data-types/tsvector-type.js';
24
38
  import { ArrayUuidType, UuidType } from './data-types/uuid-type.js';
25
39
  import { ArrayVarcharType, VarcharType } from './data-types/varchar-type.js';
40
+ import { ArrayCidType, ArrayXid8Type, ArrayXidType, CidType, Xid8Type, XidType, } from './data-types/xid-type.js';
26
41
  export class DataTypeMap {
27
42
  _itemsByOID = {};
28
43
  _items = [];
@@ -60,6 +75,25 @@ export class DataTypeMap {
60
75
  determine(value) {
61
76
  if (value == null)
62
77
  return DataTypeOIDs.unknown;
78
+ if (typeof value === 'object') {
79
+ // A value that already knows which type it came from says so,
80
+ // rather than being matched by shape - which is the only thing
81
+ // that can work when several types share one JavaScript class.
82
+ const carried = getTypeOid(value);
83
+ if (carried !== undefined)
84
+ return carried;
85
+ const ctor = value
86
+ .constructor;
87
+ if (ctor && ctor[REQUIRES_TYPE_OID]) {
88
+ // Checked before the walk below rather than after it: JsonType
89
+ // takes any object, so left to the walk this value would quietly
90
+ // go out declared `json` and come back looking right.
91
+ throw new TypeError(`A ${ctor.name} carries no type OID, and ` +
92
+ 'which PostgreSQL type it is cannot be told from the value - ' +
93
+ 'give it one (`new Range(lower, upper, bounds, oid)`) or name ' +
94
+ 'it at the call site (`new BindParam(oid, value)`)');
95
+ }
96
+ }
63
97
  const valueIsArray = Array.isArray(value);
64
98
  let i;
65
99
  let t;
@@ -97,6 +131,9 @@ GlobalTypeMap.register([CircleType, ArrayCircleType]);
97
131
  GlobalTypeMap.register([PointType, ArrayPointType]);
98
132
  GlobalTypeMap.register([LsegType, ArrayLsegType]);
99
133
  GlobalTypeMap.register([BoxType, ArrayBoxType]);
134
+ GlobalTypeMap.register([LineType, ArrayLineType]);
135
+ GlobalTypeMap.register([PathType, ArrayPathType]);
136
+ GlobalTypeMap.register([PolygonType, ArrayPolygonType]);
100
137
  GlobalTypeMap.register([Int2VectorType, ArrayInt2VectorType]);
101
138
  GlobalTypeMap.register({
102
139
  ...VarcharType,
@@ -138,10 +175,55 @@ GlobalTypeMap.register({
138
175
  oid: DataTypeOIDs._xml,
139
176
  elementsOID: DataTypeOIDs.xml,
140
177
  });
178
+ // `refcursor` is a cursor's name and `pg_node_tree` a catalog blob, and
179
+ // both are literally text on the wire - `refcursor`'s own typsend is
180
+ // textsend. Registered before varchar the way bpchar and the rest are,
181
+ // and marked uninferrable on top of that: a plain string is not evidence
182
+ // of either, and sending one declared `refcursor` where `text` was meant
183
+ // would be refused by the server.
184
+ GlobalTypeMap.register({
185
+ ...VarcharType,
186
+ name: 'refcursor',
187
+ oid: DataTypeOIDs.refcursor,
188
+ inferrable: false,
189
+ });
190
+ GlobalTypeMap.register({
191
+ ...ArrayVarcharType,
192
+ name: '_refcursor',
193
+ oid: DataTypeOIDs._refcursor,
194
+ elementsOID: DataTypeOIDs.refcursor,
195
+ inferrable: false,
196
+ });
197
+ // pg_node_tree has no array type of its own.
198
+ GlobalTypeMap.register({
199
+ ...VarcharType,
200
+ name: 'pg_node_tree',
201
+ oid: DataTypeOIDs.pg_node_tree,
202
+ inferrable: false,
203
+ });
141
204
  GlobalTypeMap.register([VarcharType, ArrayVarcharType]);
142
205
  GlobalTypeMap.register([UuidType, ArrayUuidType]);
143
206
  GlobalTypeMap.register([CharType, ArrayCharType]);
144
207
  GlobalTypeMap.register([TimestamptzType, ArrayTimestamptzType]);
145
208
  GlobalTypeMap.register([TimeType, ArrayTimeType]);
209
+ GlobalTypeMap.register([TimeTzType, ArrayTimeTzType]);
146
210
  GlobalTypeMap.register([DateType, ArrayDateType]);
147
211
  GlobalTypeMap.register([TimestampType, ArrayTimestampType]);
212
+ GlobalTypeMap.register([IntervalType, ArrayIntervalType]);
213
+ GlobalTypeMap.register(RangeTypes);
214
+ GlobalTypeMap.register([InetType, ArrayInetType]);
215
+ GlobalTypeMap.register([CidrType, ArrayCidrType]);
216
+ GlobalTypeMap.register([BitType, ArrayBitType]);
217
+ GlobalTypeMap.register([VarbitType, ArrayVarbitType]);
218
+ GlobalTypeMap.register([JsonPathType, ArrayJsonPathType]);
219
+ GlobalTypeMap.register([TsVectorType, ArrayTsVectorType]);
220
+ GlobalTypeMap.register([TsQueryType, ArrayTsQueryType]);
221
+ GlobalTypeMap.register([XidType, ArrayXidType]);
222
+ GlobalTypeMap.register([Xid8Type, ArrayXid8Type]);
223
+ GlobalTypeMap.register([CidType, ArrayCidType]);
224
+ GlobalTypeMap.register([TidType, ArrayTidType]);
225
+ GlobalTypeMap.register([PgLsnType, ArrayPgLsnType]);
226
+ GlobalTypeMap.register([PgSnapshotType, ArrayPgSnapshotType]);
227
+ GlobalTypeMap.register([TxidSnapshotType, ArrayTxidSnapshotType]);
228
+ GlobalTypeMap.register([MacaddrType, ArrayMacaddrType]);
229
+ GlobalTypeMap.register([Macaddr8Type, ArrayMacaddr8Type]);
@@ -0,0 +1,5 @@
1
+ import type { DataType } from '../interfaces/data-type.js';
2
+ export declare const BitType: DataType;
3
+ export declare const ArrayBitType: DataType;
4
+ export declare const VarbitType: DataType;
5
+ export declare const ArrayVarbitType: DataType;
@@ -0,0 +1,91 @@
1
+ import { DataTypeOIDs } from '../constants.js';
2
+ /**
3
+ * `bit` and `varbit` are one type on the wire - the length is a property
4
+ * of the column, not of the value - so they share a codec and differ
5
+ * only in which OID they register under.
6
+ *
7
+ * Both decode to a string of `0` and `1`, which is what the type is:
8
+ * PostgreSQL prints it that way, accepts it back that way, and the
9
+ * alternatives are all worse. A number loses leading zeroes and anything
10
+ * past 53 bits; a Buffer loses the bit count, so `1` and `10000000`
11
+ * become the same eight padded bits. `pg` leaves it a string too.
12
+ */
13
+ /** Every byte's eight bits, so decoding is one lookup per byte. */
14
+ const BYTE_BITS = new Array(256);
15
+ for (let i = 0; i < 256; i++)
16
+ BYTE_BITS[i] = i.toString(2).padStart(8, '0');
17
+ const BIT_PATTERN = /^[01]*$/;
18
+ /**
19
+ * An int32 bit count, then the bits themselves packed most-significant
20
+ * first and the last byte zero-padded. A zero-length value is the count
21
+ * and nothing else.
22
+ */
23
+ function decode(v, offset) {
24
+ const bits = v.readInt32BE(offset);
25
+ const whole = bits >> 3;
26
+ const start = offset + 4;
27
+ let out = '';
28
+ let i;
29
+ for (i = 0; i < whole; i++)
30
+ out += BYTE_BITS[v[start + i]];
31
+ const rest = bits & 7;
32
+ if (rest)
33
+ out += BYTE_BITS[v[start + whole]].slice(0, rest);
34
+ return out;
35
+ }
36
+ function encode(buf, v, name) {
37
+ if (typeof v !== 'string' || !BIT_PATTERN.test(v))
38
+ throw new Error(`"${v}" is not a valid ${name} value - a string of 0 and 1 is`);
39
+ const bits = v.length;
40
+ buf.writeInt32BE(bits);
41
+ const bytes = Buffer.alloc((bits + 7) >> 3);
42
+ let i;
43
+ for (i = 0; i < bits; i++)
44
+ if (v.charCodeAt(i) === 49)
45
+ bytes[i >> 3] |= 128 >> (i & 7);
46
+ buf.writeBytes(bytes);
47
+ }
48
+ function createType(name, oid) {
49
+ return {
50
+ name,
51
+ oid,
52
+ jsType: 'string',
53
+ // `0` and `1` are ordinary characters, and a string of them is far
54
+ // more often text than a bit string - inferring this type would send
55
+ // `bit` where `text` was meant. See inet-type.ts.
56
+ inferrable: false,
57
+ encodeText(v) {
58
+ return '' + v;
59
+ },
60
+ encodeBinary(buf, v) {
61
+ encode(buf, v, name);
62
+ },
63
+ decodeBinary(v, offset = 0) {
64
+ return decode(v, offset);
65
+ },
66
+ decodeText(v) {
67
+ return v;
68
+ },
69
+ // Two characters, both ASCII - see inet-type.ts for why 'latin1'.
70
+ decodeTextBuffer(buf, offset, len) {
71
+ return buf.toString('latin1', offset, offset + len);
72
+ },
73
+ isType(v) {
74
+ return typeof v === 'string' && BIT_PATTERN.test(v);
75
+ },
76
+ };
77
+ }
78
+ export const BitType = createType('bit', DataTypeOIDs.bit);
79
+ export const ArrayBitType = {
80
+ ...BitType,
81
+ name: '_bit',
82
+ oid: DataTypeOIDs._bit,
83
+ elementsOID: DataTypeOIDs.bit,
84
+ };
85
+ export const VarbitType = createType('varbit', DataTypeOIDs.varbit);
86
+ export const ArrayVarbitType = {
87
+ ...VarbitType,
88
+ name: '_varbit',
89
+ oid: DataTypeOIDs._varbit,
90
+ elementsOID: DataTypeOIDs.varbit,
91
+ };
@@ -1,11 +1,12 @@
1
1
  import { DataTypeOIDs } from '../constants.js';
2
+ import { Box, TwoPoints } from './classes/geometric.js';
2
3
  const BOX_PATTERN1 = /^\( *\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\) *, *\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\) *\)$/;
3
4
  const BOX_PATTERN2 = /^\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\) *, *\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\)$/;
4
5
  const BOX_PATTERN3 = /^(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *, *(-?\d+\.?\d*)$/;
5
6
  export const BoxType = {
6
7
  name: 'box',
7
8
  oid: DataTypeOIDs.box,
8
- jsType: 'object',
9
+ jsType: 'Box',
9
10
  arraySeparator: ';',
10
11
  encodeText(v) {
11
12
  return `(${v.x1},${v.y1}),(${v.x2},${v.y2})`;
@@ -17,34 +18,23 @@ export const BoxType = {
17
18
  buf.writeDoubleBE(v.y2);
18
19
  },
19
20
  decodeBinary(v, offset = 0) {
20
- return {
21
- x1: v.readDoubleBE(offset),
22
- y1: v.readDoubleBE(offset + 8),
23
- x2: v.readDoubleBE(offset + 16),
24
- y2: v.readDoubleBE(offset + 24),
25
- };
21
+ return new Box(v.readDoubleBE(offset), v.readDoubleBE(offset + 8), v.readDoubleBE(offset + 16), v.readDoubleBE(offset + 24));
26
22
  },
27
23
  decodeText(v) {
28
24
  const m = v.match(BOX_PATTERN1) || v.match(BOX_PATTERN2) || v.match(BOX_PATTERN3);
29
25
  if (!m)
30
26
  return undefined;
31
- return {
32
- x1: parseFloat(m[1]),
33
- y1: parseFloat(m[2]),
34
- x2: parseFloat(m[3]),
35
- y2: parseFloat(m[4]),
36
- };
27
+ return new Box(parseFloat(m[1]), parseFloat(m[2]), parseFloat(m[3]), parseFloat(m[4]));
37
28
  },
38
29
  decodeTextBuffer(buf, offset, len, options) {
39
30
  return BoxType.decodeText(buf.toString('latin1', offset, offset + len), options);
40
31
  },
32
+ // A plain object of the four numbers is still accepted - it is what
33
+ // this type returned before these classes existed - but only a plain
34
+ // one: box and lseg carry the same four, so an instance of the other
35
+ // must not be claimed here.
41
36
  isType(v) {
42
- return (typeof v === 'object' &&
43
- Object.keys(v).length === 4 &&
44
- typeof v.x1 === 'number' &&
45
- typeof v.y1 === 'number' &&
46
- typeof v.x2 === 'number' &&
47
- typeof v.y2 === 'number');
37
+ return v instanceof Box || TwoPoints.isTwoPointsLike(v);
48
38
  },
49
39
  };
50
40
  export const ArrayBoxType = {
@@ -1,4 +1,5 @@
1
1
  import { DataTypeOIDs } from '../constants.js';
2
+ import { Circle } from './classes/geometric.js';
2
3
  const CIRCLE_PATTERN1 = /^< *\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\) *, *(-?\d+\.?\d*) *>$/;
3
4
  const CIRCLE_PATTERN2 = /^\( *\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\) *, *(-?\d+\.?\d*) *\)$/;
4
5
  const CIRCLE_PATTERN3 = /^\( *(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *\) *, *(-?\d+\.?\d*)$/;
@@ -6,7 +7,7 @@ const CIRCLE_PATTERN4 = /^(-?\d+\.?\d*) *, *(-?\d+\.?\d*) *, *(-?\d+\.?\d*)$/;
6
7
  export const CircleType = {
7
8
  name: 'circle',
8
9
  oid: DataTypeOIDs.circle,
9
- jsType: 'object',
10
+ jsType: 'Circle',
10
11
  encodeText(v) {
11
12
  return `<(${v.x},${v.y}),${v.r}>`;
12
13
  },
@@ -16,11 +17,7 @@ export const CircleType = {
16
17
  buf.writeDoubleBE(v.r);
17
18
  },
18
19
  decodeBinary(v, offset = 0) {
19
- return {
20
- x: v.readDoubleBE(offset),
21
- y: v.readDoubleBE(offset + 8),
22
- r: v.readDoubleBE(offset + 16),
23
- };
20
+ return new Circle(v.readDoubleBE(offset), v.readDoubleBE(offset + 8), v.readDoubleBE(offset + 16));
24
21
  },
25
22
  decodeText(v) {
26
23
  const m = v.match(CIRCLE_PATTERN1) ||
@@ -29,22 +26,15 @@ export const CircleType = {
29
26
  v.match(CIRCLE_PATTERN4);
30
27
  if (!m)
31
28
  return undefined;
32
- return {
33
- x: parseFloat(m[1]),
34
- y: parseFloat(m[2]),
35
- r: parseFloat(m[3]),
36
- };
29
+ return new Circle(parseFloat(m[1]), parseFloat(m[2]), parseFloat(m[3]));
37
30
  },
38
31
  // See box-type.ts's decodeTextBuffer comment - same rationale.
39
32
  decodeTextBuffer(buf, offset, len, options) {
40
33
  return CircleType.decodeText(buf.toString('latin1', offset, offset + len), options);
41
34
  },
35
+ // See point-type.ts: the plain object shape is still accepted.
42
36
  isType(v) {
43
- return (typeof v === 'object' &&
44
- Object.keys(v).length === 3 &&
45
- typeof v.x === 'number' &&
46
- typeof v.y === 'number' &&
47
- typeof v.r === 'number');
37
+ return v instanceof Circle || Circle.isCircleLike(v);
48
38
  },
49
39
  };
50
40
  export const ArrayCircleType = {
@@ -0,0 +1,105 @@
1
+ /** A `point`: one position. */
2
+ export declare class Point {
3
+ x: number;
4
+ y: number;
5
+ constructor(x?: number, y?: number);
6
+ /** As PostgreSQL prints it, so it casts back through `::point`. */
7
+ toString(): string;
8
+ toJSON(): string;
9
+ static isPointLike(v: any): boolean;
10
+ }
11
+ /** A `circle`: a centre and a radius. */
12
+ export declare class Circle {
13
+ x: number;
14
+ y: number;
15
+ r: number;
16
+ constructor(x?: number, y?: number, r?: number);
17
+ /** As PostgreSQL prints it, so it casts back through `::circle`. */
18
+ toString(): string;
19
+ toJSON(): string;
20
+ static isCircleLike(v: any): boolean;
21
+ }
22
+ /**
23
+ * Two corners, which is how both `box` and `lseg` are carried - and why
24
+ * they are two classes rather than one shared shape. They were
25
+ * indistinguishable as plain objects: both types' isType() accepted
26
+ * `{x1, y1, x2, y2}`, so `determine()` answered `box` for every one of
27
+ * them and an lseg parameter could not be expressed at all.
28
+ */
29
+ declare abstract class TwoPoints {
30
+ x1: number;
31
+ y1: number;
32
+ x2: number;
33
+ y2: number;
34
+ constructor(x1?: number, y1?: number, x2?: number, y2?: number);
35
+ toJSON(): string;
36
+ static isTwoPointsLike(v: any): boolean;
37
+ }
38
+ /** A `box`: a rectangle given by two opposite corners. */
39
+ export declare class Box extends TwoPoints {
40
+ /** As PostgreSQL prints it, so it casts back through `::box`. */
41
+ toString(): string;
42
+ }
43
+ /** An `lseg`: the straight line between two points. */
44
+ export declare class LineSegment extends TwoPoints {
45
+ /** As PostgreSQL prints it, so it casts back through `::lseg`. */
46
+ toString(): string;
47
+ }
48
+ /**
49
+ * A `line`: the infinite line Ax + By + C = 0.
50
+ *
51
+ * PostgreSQL stores and prints the three coefficients whatever form the
52
+ * literal took - `line '((0,0),(1,1))'` comes back as `{1,-1,0}` - so
53
+ * that is what this carries. A pair of points would be a second, lossy
54
+ * spelling of the same thing, since a line through them is not the
55
+ * points.
56
+ */
57
+ export declare class Line {
58
+ a: number;
59
+ b: number;
60
+ c: number;
61
+ constructor(a?: number, b?: number, c?: number);
62
+ /** As PostgreSQL prints it, so it casts back through `::line`. */
63
+ toString(): string;
64
+ toJSON(): string;
65
+ static isLineLike(v: any): boolean;
66
+ }
67
+ /**
68
+ * The list of points `path` and `polygon` share. They are two classes
69
+ * rather than one for the same reason `Box` and `LineSegment` are: the
70
+ * values are indistinguishable by shape, so only the class can say which
71
+ * type a parameter is meant for.
72
+ */
73
+ declare abstract class PointList {
74
+ points: Point[];
75
+ /** Plain `{x, y}` objects are accepted and kept as Points. */
76
+ constructor(points?: (Point | {
77
+ x: number;
78
+ y: number;
79
+ })[]);
80
+ toJSON(): string;
81
+ protected join(): string;
82
+ }
83
+ /**
84
+ * A `path`: a series of points, open or closed.
85
+ *
86
+ * Closed is the default because it is PostgreSQL's - a literal written
87
+ * without brackets, `path '1,2,3,4'`, comes back closed. The flag is
88
+ * part of the value and not a formatting choice: the server stores it
89
+ * and prints `[...]` for an open path against `(...)` for a closed one.
90
+ */
91
+ export declare class Path extends PointList {
92
+ isClosed: boolean;
93
+ constructor(points?: (Point | {
94
+ x: number;
95
+ y: number;
96
+ })[], isClosed?: boolean);
97
+ /** As PostgreSQL prints it, so it casts back through `::path`. */
98
+ toString(): string;
99
+ }
100
+ /** A `polygon`: a closed series of points. */
101
+ export declare class Polygon extends PointList {
102
+ /** As PostgreSQL prints it, so it casts back through `::polygon`. */
103
+ toString(): string;
104
+ }
105
+ export { PointList, TwoPoints };