postgrejs 2.12.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 (215) hide show
  1. package/CHANGELOG.md +814 -0
  2. package/LICENSE +21 -0
  3. package/README.md +200 -0
  4. package/cjs/connection/bind-param.js +10 -0
  5. package/cjs/connection/connection.js +279 -0
  6. package/cjs/connection/cursor.js +93 -0
  7. package/cjs/connection/intl-connection.js +243 -0
  8. package/cjs/connection/pool.js +226 -0
  9. package/cjs/connection/portal.js +148 -0
  10. package/cjs/connection/prepared-statement.js +217 -0
  11. package/cjs/constants.js +250 -0
  12. package/cjs/data-type-map.js +119 -0
  13. package/cjs/data-types/bool-type.js +27 -0
  14. package/cjs/data-types/box-type.js +52 -0
  15. package/cjs/data-types/bytea-type.js +29 -0
  16. package/cjs/data-types/char-type.js +27 -0
  17. package/cjs/data-types/circle-type.js +48 -0
  18. package/cjs/data-types/date-type.js +67 -0
  19. package/cjs/data-types/float4-type.js +25 -0
  20. package/cjs/data-types/float8-type.js +25 -0
  21. package/cjs/data-types/int2-type.js +26 -0
  22. package/cjs/data-types/int2-vector-type.js +38 -0
  23. package/cjs/data-types/int4-type.js +26 -0
  24. package/cjs/data-types/int8-type.js +31 -0
  25. package/cjs/data-types/json-type.js +38 -0
  26. package/cjs/data-types/jsonb-type.js +42 -0
  27. package/cjs/data-types/lseg-type.js +52 -0
  28. package/cjs/data-types/numeric-type.js +125 -0
  29. package/cjs/data-types/oid-type.js +32 -0
  30. package/cjs/data-types/point-type.js +39 -0
  31. package/cjs/data-types/time-type.js +54 -0
  32. package/cjs/data-types/timestamp-type.js +81 -0
  33. package/cjs/data-types/timestamptz-type.js +73 -0
  34. package/cjs/data-types/uuid-type.js +39 -0
  35. package/cjs/data-types/varchar-type.js +27 -0
  36. package/cjs/index.js +41 -0
  37. package/cjs/interfaces/command-result.js +2 -0
  38. package/cjs/interfaces/data-mapping-options.js +2 -0
  39. package/cjs/interfaces/data-type.js +2 -0
  40. package/cjs/interfaces/database-connection-params.js +2 -0
  41. package/cjs/interfaces/field-info.js +2 -0
  42. package/cjs/interfaces/query-options.js +2 -0
  43. package/cjs/interfaces/query-result.js +2 -0
  44. package/cjs/interfaces/script-execute-options.js +2 -0
  45. package/cjs/interfaces/script-result.js +2 -0
  46. package/cjs/interfaces/statement-prepare-options.js +2 -0
  47. package/cjs/package.json +3 -0
  48. package/cjs/protocol/backend.js +256 -0
  49. package/cjs/protocol/buffer-reader.js +78 -0
  50. package/cjs/protocol/database-error.js +17 -0
  51. package/cjs/protocol/frontend.js +218 -0
  52. package/cjs/protocol/pg-socket.js +345 -0
  53. package/cjs/protocol/protocol.js +71 -0
  54. package/cjs/protocol/sasl.js +108 -0
  55. package/cjs/protocol/smart-buffer.js +195 -0
  56. package/cjs/safe-event-emitter.js +17 -0
  57. package/cjs/types.js +2 -0
  58. package/cjs/util/array-calculatedim.js +19 -0
  59. package/cjs/util/bigint-methods.js +42 -0
  60. package/cjs/util/config-from-env.js +30 -0
  61. package/cjs/util/connection-config.js +65 -0
  62. package/cjs/util/convert-row-to-object.js +13 -0
  63. package/cjs/util/decode-binaryarray.js +39 -0
  64. package/cjs/util/encode-binaryarray.js +45 -0
  65. package/cjs/util/escape-literal.js +27 -0
  66. package/cjs/util/fast-parseint.js +32 -0
  67. package/cjs/util/get-parsers.js +42 -0
  68. package/cjs/util/parse-array.js +61 -0
  69. package/cjs/util/parse-datetime.js +38 -0
  70. package/cjs/util/parse-row.js +11 -0
  71. package/cjs/util/parse-time.js +29 -0
  72. package/cjs/util/stringify-arrayliteral.js +38 -0
  73. package/cjs/util/stringify-for-sql.js +30 -0
  74. package/cjs/util/wrap-row-description.js +35 -0
  75. package/esm/connection/bind-param.js +6 -0
  76. package/esm/connection/connection.js +275 -0
  77. package/esm/connection/cursor.js +86 -0
  78. package/esm/connection/intl-connection.js +238 -0
  79. package/esm/connection/pool.js +222 -0
  80. package/esm/connection/portal.js +144 -0
  81. package/esm/connection/prepared-statement.js +213 -0
  82. package/esm/constants.js +247 -0
  83. package/esm/data-type-map.js +115 -0
  84. package/esm/data-types/bool-type.js +24 -0
  85. package/esm/data-types/box-type.js +49 -0
  86. package/esm/data-types/bytea-type.js +23 -0
  87. package/esm/data-types/char-type.js +24 -0
  88. package/esm/data-types/circle-type.js +45 -0
  89. package/esm/data-types/date-type.js +64 -0
  90. package/esm/data-types/float4-type.js +22 -0
  91. package/esm/data-types/float8-type.js +22 -0
  92. package/esm/data-types/int2-type.js +23 -0
  93. package/esm/data-types/int2-vector-type.js +35 -0
  94. package/esm/data-types/int4-type.js +23 -0
  95. package/esm/data-types/int8-type.js +28 -0
  96. package/esm/data-types/json-type.js +35 -0
  97. package/esm/data-types/jsonb-type.js +39 -0
  98. package/esm/data-types/lseg-type.js +49 -0
  99. package/esm/data-types/numeric-type.js +121 -0
  100. package/esm/data-types/oid-type.js +29 -0
  101. package/esm/data-types/point-type.js +36 -0
  102. package/esm/data-types/time-type.js +51 -0
  103. package/esm/data-types/timestamp-type.js +78 -0
  104. package/esm/data-types/timestamptz-type.js +70 -0
  105. package/esm/data-types/uuid-type.js +36 -0
  106. package/esm/data-types/varchar-type.js +24 -0
  107. package/esm/index.js +25 -0
  108. package/esm/interfaces/command-result.js +1 -0
  109. package/esm/interfaces/data-mapping-options.js +1 -0
  110. package/esm/interfaces/data-type.js +1 -0
  111. package/esm/interfaces/database-connection-params.js +1 -0
  112. package/esm/interfaces/field-info.js +1 -0
  113. package/esm/interfaces/query-options.js +1 -0
  114. package/esm/interfaces/query-result.js +1 -0
  115. package/esm/interfaces/script-execute-options.js +1 -0
  116. package/esm/interfaces/script-result.js +1 -0
  117. package/esm/interfaces/statement-prepare-options.js +1 -0
  118. package/esm/protocol/backend.js +252 -0
  119. package/esm/protocol/buffer-reader.js +74 -0
  120. package/esm/protocol/database-error.js +13 -0
  121. package/esm/protocol/frontend.js +214 -0
  122. package/esm/protocol/pg-socket.js +338 -0
  123. package/esm/protocol/protocol.js +68 -0
  124. package/esm/protocol/sasl.js +102 -0
  125. package/esm/protocol/smart-buffer.js +168 -0
  126. package/esm/safe-event-emitter.js +13 -0
  127. package/esm/types.js +1 -0
  128. package/esm/util/array-calculatedim.js +15 -0
  129. package/esm/util/bigint-methods.js +37 -0
  130. package/esm/util/config-from-env.js +26 -0
  131. package/esm/util/connection-config.js +57 -0
  132. package/esm/util/convert-row-to-object.js +9 -0
  133. package/esm/util/decode-binaryarray.js +35 -0
  134. package/esm/util/encode-binaryarray.js +41 -0
  135. package/esm/util/escape-literal.js +23 -0
  136. package/esm/util/fast-parseint.js +28 -0
  137. package/esm/util/get-parsers.js +38 -0
  138. package/esm/util/parse-array.js +57 -0
  139. package/esm/util/parse-datetime.js +34 -0
  140. package/esm/util/parse-row.js +7 -0
  141. package/esm/util/parse-time.js +25 -0
  142. package/esm/util/stringify-arrayliteral.js +34 -0
  143. package/esm/util/stringify-for-sql.js +25 -0
  144. package/esm/util/wrap-row-description.js +31 -0
  145. package/package.json +54 -0
  146. package/typings/connection/bind-param.d.ts +6 -0
  147. package/typings/connection/connection.d.ts +110 -0
  148. package/typings/connection/cursor.d.ts +25 -0
  149. package/typings/connection/intl-connection.d.ts +40 -0
  150. package/typings/connection/pool.d.ts +52 -0
  151. package/typings/connection/portal.d.ts +23 -0
  152. package/typings/connection/prepared-statement.d.ts +27 -0
  153. package/typings/constants.d.ts +130 -0
  154. package/typings/data-type-map.d.ts +11 -0
  155. package/typings/data-types/bool-type.d.ts +3 -0
  156. package/typings/data-types/box-type.d.ts +3 -0
  157. package/typings/data-types/bytea-type.d.ts +3 -0
  158. package/typings/data-types/char-type.d.ts +3 -0
  159. package/typings/data-types/circle-type.d.ts +3 -0
  160. package/typings/data-types/date-type.d.ts +3 -0
  161. package/typings/data-types/float4-type.d.ts +3 -0
  162. package/typings/data-types/float8-type.d.ts +3 -0
  163. package/typings/data-types/int2-type.d.ts +3 -0
  164. package/typings/data-types/int2-vector-type.d.ts +3 -0
  165. package/typings/data-types/int4-type.d.ts +3 -0
  166. package/typings/data-types/int8-type.d.ts +3 -0
  167. package/typings/data-types/json-type.d.ts +3 -0
  168. package/typings/data-types/jsonb-type.d.ts +3 -0
  169. package/typings/data-types/lseg-type.d.ts +3 -0
  170. package/typings/data-types/numeric-type.d.ts +12 -0
  171. package/typings/data-types/oid-type.d.ts +4 -0
  172. package/typings/data-types/point-type.d.ts +3 -0
  173. package/typings/data-types/time-type.d.ts +3 -0
  174. package/typings/data-types/timestamp-type.d.ts +3 -0
  175. package/typings/data-types/timestamptz-type.d.ts +3 -0
  176. package/typings/data-types/uuid-type.d.ts +3 -0
  177. package/typings/data-types/varchar-type.d.ts +3 -0
  178. package/typings/index.d.ts +25 -0
  179. package/typings/interfaces/command-result.d.ts +28 -0
  180. package/typings/interfaces/data-mapping-options.d.ts +9 -0
  181. package/typings/interfaces/data-type.d.ts +31 -0
  182. package/typings/interfaces/database-connection-params.d.ts +38 -0
  183. package/typings/interfaces/field-info.d.ts +46 -0
  184. package/typings/interfaces/query-options.d.ts +46 -0
  185. package/typings/interfaces/query-result.d.ts +8 -0
  186. package/typings/interfaces/script-execute-options.d.ts +26 -0
  187. package/typings/interfaces/script-result.d.ts +15 -0
  188. package/typings/interfaces/statement-prepare-options.d.ts +13 -0
  189. package/typings/protocol/backend.d.ts +9 -0
  190. package/typings/protocol/buffer-reader.d.ts +18 -0
  191. package/typings/protocol/database-error.d.ts +20 -0
  192. package/typings/protocol/frontend.d.ts +59 -0
  193. package/typings/protocol/pg-socket.d.ts +51 -0
  194. package/typings/protocol/protocol.d.ts +180 -0
  195. package/typings/protocol/sasl.d.ts +13 -0
  196. package/typings/protocol/smart-buffer.d.ts +39 -0
  197. package/typings/safe-event-emitter.d.ts +5 -0
  198. package/typings/types.d.ts +15 -0
  199. package/typings/util/array-calculatedim.d.ts +1 -0
  200. package/typings/util/bigint-methods.d.ts +3 -0
  201. package/typings/util/config-from-env.d.ts +2 -0
  202. package/typings/util/connection-config.d.ts +3 -0
  203. package/typings/util/convert-row-to-object.d.ts +2 -0
  204. package/typings/util/decode-binaryarray.d.ts +4 -0
  205. package/typings/util/encode-binaryarray.d.ts +5 -0
  206. package/typings/util/escape-literal.d.ts +1 -0
  207. package/typings/util/fast-parseint.d.ts +1 -0
  208. package/typings/util/get-parsers.d.ts +4 -0
  209. package/typings/util/parse-array.d.ts +5 -0
  210. package/typings/util/parse-datetime.d.ts +1 -0
  211. package/typings/util/parse-row.d.ts +3 -0
  212. package/typings/util/parse-time.d.ts +3 -0
  213. package/typings/util/stringify-arrayliteral.d.ts +3 -0
  214. package/typings/util/stringify-for-sql.d.ts +4 -0
  215. package/typings/util/wrap-row-description.d.ts +5 -0
@@ -0,0 +1,78 @@
1
+ import { DataTypeOIDs } from '../constants.js';
2
+ import { parseDateTime } from '../util/parse-datetime.js';
3
+ const timeShift = 946684800000;
4
+ const timeMul = 4294967296;
5
+ export const TimestampType = {
6
+ name: 'timestamp',
7
+ oid: DataTypeOIDs.timestamp,
8
+ jsType: 'Date',
9
+ parseBinary(v, options) {
10
+ const fetchAsString = options.fetchAsString && options.fetchAsString.includes(DataTypeOIDs.timestamp);
11
+ const hi = v.readInt32BE();
12
+ const lo = v.readUInt32BE(4);
13
+ if (lo === 0xffffffff && hi === 0x7fffffff)
14
+ return fetchAsString ? 'infinity' : Infinity;
15
+ if (lo === 0x00000000 && hi === -0x80000000)
16
+ return fetchAsString ? '-infinity' : -Infinity;
17
+ // Shift from 2000 to 1970
18
+ let d = new Date((lo + hi * timeMul) / 1000 + timeShift);
19
+ if (fetchAsString || !options.utcDates)
20
+ d = new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
21
+ return fetchAsString ? dateToTimestampString(d) : d;
22
+ },
23
+ encodeBinary(buf, v, options) {
24
+ if (typeof v === 'string')
25
+ v = parseDateTime(v, true, false, options.utcDates);
26
+ if (v === Infinity) {
27
+ buf.writeInt32BE(0x7fffffff); // hi
28
+ buf.writeUInt32BE(0xffffffff); // lo
29
+ return;
30
+ }
31
+ if (v === -Infinity) {
32
+ buf.writeInt32BE(-0x80000000); // hi
33
+ buf.writeUInt32BE(0x00000000); // lo
34
+ return;
35
+ }
36
+ if (!(v instanceof Date))
37
+ v = new Date(v);
38
+ // Postgresql ignores timezone data so we are
39
+ let n = options.utcDates ? v.getTime() : v.getTime() - v.getTimezoneOffset() * 60 * 1000;
40
+ n = (n - timeShift) * 1000;
41
+ const hi = Math.floor(n / timeMul);
42
+ const lo = n - hi * timeMul;
43
+ buf.writeInt32BE(hi);
44
+ buf.writeUInt32BE(lo);
45
+ },
46
+ parseText(v, options) {
47
+ if (options.fetchAsString && options.fetchAsString.includes(DataTypeOIDs.timestamp))
48
+ return v;
49
+ return parseDateTime(v, true, false, options.utcDates);
50
+ },
51
+ isType(v) {
52
+ return (v instanceof Date &&
53
+ !(v.getFullYear() === 1970 && v.getMonth() === 0 && v.getDate() === 1) &&
54
+ !(v.getHours() === 0 && v.getMinutes() === 0 && v.getSeconds() === 0 && v.getMilliseconds() === 0));
55
+ },
56
+ };
57
+ function padZero(v) {
58
+ return v < 9 ? '0' + v : '' + v;
59
+ }
60
+ function dateToTimestampString(d) {
61
+ return (d.getFullYear() +
62
+ '-' +
63
+ padZero(d.getMonth() + 1) +
64
+ '-' +
65
+ padZero(d.getDate()) +
66
+ ' ' +
67
+ padZero(d.getHours()) +
68
+ ':' +
69
+ padZero(d.getMinutes()) +
70
+ ':' +
71
+ padZero(d.getSeconds()));
72
+ }
73
+ export const ArrayTimestampType = {
74
+ ...TimestampType,
75
+ name: '_timestamp',
76
+ oid: DataTypeOIDs._timestamp,
77
+ elementsOID: DataTypeOIDs.timestamp,
78
+ };
@@ -0,0 +1,70 @@
1
+ import { DataTypeOIDs } from '../constants.js';
2
+ import { parseDateTime } from '../util/parse-datetime.js';
3
+ const timeShift = 946684800000;
4
+ const timeMul = 4294967296;
5
+ export const TimestamptzType = {
6
+ name: 'timestamptz',
7
+ oid: DataTypeOIDs.timestamptz,
8
+ jsType: 'Date',
9
+ parseBinary(v, options) {
10
+ const fetchAsString = options.fetchAsString && options.fetchAsString.includes(DataTypeOIDs.timestamptz);
11
+ const hi = v.readInt32BE();
12
+ const lo = v.readUInt32BE(4);
13
+ if (lo === 0xffffffff && hi === 0x7fffffff)
14
+ return fetchAsString ? 'infinity' : Infinity;
15
+ if (lo === 0x00000000 && hi === -0x80000000)
16
+ return fetchAsString ? '-infinity' : -Infinity;
17
+ // Shift from 2000 to 1970
18
+ let d = new Date((lo + hi * timeMul) / 1000 + timeShift);
19
+ if (fetchAsString || !options.utcDates)
20
+ d = new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
21
+ return fetchAsString ? dateToTimestamptzString(d) : d;
22
+ },
23
+ encodeBinary(buf, v, options) {
24
+ if (typeof v === 'string')
25
+ v = parseDateTime(v, true, true, options.utcDates);
26
+ if (v === Infinity) {
27
+ buf.writeInt32BE(0x7fffffff); // hi
28
+ buf.writeUInt32BE(0xffffffff); // lo
29
+ return;
30
+ }
31
+ if (v === -Infinity) {
32
+ buf.writeInt32BE(-0x80000000); // hi
33
+ buf.writeUInt32BE(0x00000000); // lo
34
+ return;
35
+ }
36
+ if (!(v instanceof Date))
37
+ v = new Date(v);
38
+ let n = v.getTime();
39
+ n = (n - timeShift) * 1000;
40
+ const hi = Math.floor(n / timeMul);
41
+ const lo = n - hi * timeMul;
42
+ buf.writeInt32BE(hi);
43
+ buf.writeUInt32BE(lo);
44
+ },
45
+ parseText(v, options) {
46
+ const d = parseDateTime(v, true, true, options.utcDates);
47
+ if (options.fetchAsString && options.fetchAsString.includes(DataTypeOIDs.timestamptz)) {
48
+ if (d instanceof Date)
49
+ return dateToTimestamptzString(d);
50
+ if (d === Infinity)
51
+ return 'infinity';
52
+ if (d === -Infinity)
53
+ return '-infinity';
54
+ return '';
55
+ }
56
+ return d;
57
+ },
58
+ isType(v) {
59
+ return v instanceof Date;
60
+ },
61
+ };
62
+ function dateToTimestamptzString(d) {
63
+ return d.toISOString().replace('T', ' ');
64
+ }
65
+ export const ArrayTimestamptzType = {
66
+ ...TimestamptzType,
67
+ name: '_timestamptz',
68
+ oid: DataTypeOIDs._timestamptz,
69
+ elementsOID: DataTypeOIDs.timestamptz,
70
+ };
@@ -0,0 +1,36 @@
1
+ import { DataTypeOIDs } from '../constants.js';
2
+ const GUID_PATTERN = /^[0-9a-fA-F]{8}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{4}-?[0-9a-fA-F]{12}$/;
3
+ export const UuidType = {
4
+ name: 'uuid',
5
+ oid: DataTypeOIDs.uuid,
6
+ jsType: 'String',
7
+ parseBinary(v) {
8
+ return (v.toString('hex', 0, 4) +
9
+ '-' +
10
+ v.toString('hex', 4, 6) +
11
+ '-' +
12
+ v.toString('hex', 6, 8) +
13
+ '-' +
14
+ v.toString('hex', 8, 10) +
15
+ '-' +
16
+ v.toString('hex', 10, 16));
17
+ },
18
+ encodeBinary(buf, v) {
19
+ if (!GUID_PATTERN.test(v))
20
+ throw new Error(`"${v}" is not a valid guid value`);
21
+ const b = Buffer.from(v.replace(/-/g, ''), 'hex');
22
+ buf.writeBuffer(b);
23
+ },
24
+ parseText(v) {
25
+ return v;
26
+ },
27
+ isType(v) {
28
+ return typeof v === 'string' && GUID_PATTERN.test(v);
29
+ },
30
+ };
31
+ export const ArrayUuidType = {
32
+ ...UuidType,
33
+ name: '_uuid',
34
+ oid: DataTypeOIDs._uuid,
35
+ elementsOID: DataTypeOIDs.uuid,
36
+ };
@@ -0,0 +1,24 @@
1
+ import { DataTypeOIDs } from '../constants.js';
2
+ export const VarcharType = {
3
+ name: 'varchar',
4
+ oid: DataTypeOIDs.varchar,
5
+ jsType: 'string',
6
+ parseBinary(v) {
7
+ return v.toString('utf8');
8
+ },
9
+ encodeBinary(buf, v) {
10
+ buf.writeString('' + v, 'utf8');
11
+ },
12
+ parseText(v) {
13
+ return '' + v;
14
+ },
15
+ isType(v) {
16
+ return typeof v === 'string';
17
+ },
18
+ };
19
+ export const ArrayVarcharType = {
20
+ ...VarcharType,
21
+ name: '_varchar',
22
+ oid: DataTypeOIDs._varchar,
23
+ elementsOID: DataTypeOIDs.varchar,
24
+ };
package/esm/index.js ADDED
@@ -0,0 +1,25 @@
1
+ export * from './constants.js';
2
+ export * from './data-type-map.js';
3
+ export * from './types.js';
4
+ export * from './connection/bind-param.js';
5
+ export * from './connection/connection.js';
6
+ export * from './connection/cursor.js';
7
+ export * from './connection/pool.js';
8
+ export * from './connection/prepared-statement.js';
9
+ export * from './interfaces/command-result.js';
10
+ export * from './interfaces/data-mapping-options.js';
11
+ export * from './interfaces/data-type.js';
12
+ export * from './interfaces/database-connection-params.js';
13
+ export * from './interfaces/field-info.js';
14
+ export * from './interfaces/query-options.js';
15
+ export * from './interfaces/query-result.js';
16
+ export * from './interfaces/script-execute-options.js';
17
+ export * from './interfaces/script-result.js';
18
+ export * from './interfaces/statement-prepare-options.js';
19
+ export * from './util/connection-config.js';
20
+ export * from './util/escape-literal.js';
21
+ export * from './util/parse-datetime.js';
22
+ export * from './util/stringify-arrayliteral.js';
23
+ export * from './util/stringify-for-sql.js';
24
+ export * from './protocol/smart-buffer.js';
25
+ export * from './protocol/database-error.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,252 @@
1
+ import { BufferReader } from './buffer-reader.js';
2
+ import { Protocol } from './protocol.js';
3
+ // 1 byte message type, 4 byte frame length
4
+ const HEADER_LENGTH = 5;
5
+ const ErrorFieldTypes = {
6
+ M: 'message',
7
+ S: 'severity',
8
+ V: 'severity',
9
+ C: 'code',
10
+ D: 'detail',
11
+ H: 'hint',
12
+ P: 'position',
13
+ p: 'internalPosition',
14
+ q: 'internalQuery',
15
+ W: 'where',
16
+ s: 'schema',
17
+ t: 'table',
18
+ c: 'column',
19
+ d: 'dataType',
20
+ n: 'constraint',
21
+ F: 'file',
22
+ L: 'line',
23
+ R: 'routine',
24
+ };
25
+ export class Backend {
26
+ reset() {
27
+ this._buf = undefined;
28
+ }
29
+ parse(data, callback) {
30
+ if (this._buf) {
31
+ data = Buffer.concat([this._buf, data]);
32
+ this._buf = undefined;
33
+ }
34
+ const io = new BufferReader(data);
35
+ let offsetBookmark;
36
+ while (io.length - io.offset >= HEADER_LENGTH) {
37
+ offsetBookmark = io.offset;
38
+ const code = io.readUInt8();
39
+ const len = io.readUInt32BE();
40
+ // Check if frame data not received yet
41
+ if (io.length - io.offset < len - 4) {
42
+ io.offset = offsetBookmark;
43
+ this._buf = io.readBuffer();
44
+ return;
45
+ }
46
+ const parser = MessageParsers[code];
47
+ const v = parser && parser(io, code, len);
48
+ callback(code, v);
49
+ // Set offset to next message
50
+ io.offset = offsetBookmark + len + 1;
51
+ }
52
+ if (io.offset < io.length)
53
+ this._buf = io.readBuffer(io.length - io.offset);
54
+ }
55
+ }
56
+ const MessageParsers = {
57
+ [Protocol.BackendMessageCode.Authentication]: parseAuthentication,
58
+ [Protocol.BackendMessageCode.BackendKeyData]: parseBackendKeyData,
59
+ [Protocol.BackendMessageCode.CommandComplete]: parseCommandComplete,
60
+ [Protocol.BackendMessageCode.CopyData]: parseCopyData,
61
+ [Protocol.BackendMessageCode.CopyInResponse]: parseCopyResponse,
62
+ [Protocol.BackendMessageCode.CopyOutResponse]: parseCopyResponse,
63
+ [Protocol.BackendMessageCode.CopyBothResponse]: parseCopyResponse,
64
+ [Protocol.BackendMessageCode.DataRow]: parseDataRow,
65
+ [Protocol.BackendMessageCode.ErrorResponse]: parseErrorResponse,
66
+ [Protocol.BackendMessageCode.NoticeResponse]: parseErrorResponse,
67
+ [Protocol.BackendMessageCode.NotificationResponse]: parseNotificationResponse,
68
+ [Protocol.BackendMessageCode.FunctionCallResponse]: parseFunctionCallResponse,
69
+ [Protocol.BackendMessageCode.NegotiateProtocolVersion]: parseNegotiateProtocolVersion,
70
+ [Protocol.BackendMessageCode.ParameterDescription]: parseParameterDescription,
71
+ [Protocol.BackendMessageCode.ParameterStatus]: parseParameterStatus,
72
+ [Protocol.BackendMessageCode.ReadyForQuery]: parseReadyForQuery,
73
+ [Protocol.BackendMessageCode.RowDescription]: parseRowDescription,
74
+ };
75
+ function parseAuthentication(io, code, len) {
76
+ const kind = io.readUInt32BE();
77
+ switch (kind) {
78
+ case 0:
79
+ return; // AuthenticationOk
80
+ case 2:
81
+ return {
82
+ kind: 'KerberosV5',
83
+ };
84
+ case 3:
85
+ return {
86
+ kind: 'CleartextPassword',
87
+ };
88
+ case 5:
89
+ return {
90
+ kind: 'MD5Password',
91
+ salt: io.readBuffer(len - 8),
92
+ };
93
+ case 6:
94
+ return {
95
+ kind: 'SCMCredential',
96
+ };
97
+ case 7:
98
+ return {
99
+ kind: 'GSS',
100
+ };
101
+ case 9:
102
+ return {
103
+ kind: 'SSPI',
104
+ };
105
+ case 8:
106
+ return {
107
+ kind: 'GSSContinue',
108
+ data: io.readBuffer(len - 8),
109
+ };
110
+ case 10: {
111
+ const out = {
112
+ kind: 'SASL',
113
+ mechanisms: [],
114
+ };
115
+ let mechanism;
116
+ while ((mechanism = io.readCString())) {
117
+ out.mechanisms.push(mechanism);
118
+ }
119
+ return out;
120
+ }
121
+ case 11:
122
+ return {
123
+ kind: 'SASLContinue',
124
+ data: io.readLString(len - 8, 'utf8'),
125
+ };
126
+ case 12:
127
+ return {
128
+ kind: 'SASLFinal',
129
+ data: io.readLString(len - 8, 'utf8'),
130
+ };
131
+ default:
132
+ throw new Error(`Unknown authentication kind (${kind})`);
133
+ }
134
+ }
135
+ function parseBackendKeyData(io) {
136
+ return {
137
+ processID: io.readUInt32BE(),
138
+ secretKey: io.readUInt32BE(),
139
+ };
140
+ }
141
+ function parseCommandComplete(io) {
142
+ return {
143
+ command: io.readCString('utf8'),
144
+ };
145
+ }
146
+ function parseCopyData(io, code, len) {
147
+ return {
148
+ data: io.readBuffer(len - 4),
149
+ };
150
+ }
151
+ function parseCopyResponse(io) {
152
+ const out = {
153
+ overallFormat: io.readUInt8() === 0 ? Protocol.DataFormat.text : Protocol.DataFormat.binary,
154
+ columnCount: io.readUInt16BE(),
155
+ };
156
+ if (out.columnCount) {
157
+ out.columnFormats = [];
158
+ for (let i = 0; i < out.columnCount; i++) {
159
+ out.columnFormats.push(io.readUInt16BE() === 0 ? Protocol.DataFormat.text : Protocol.DataFormat.binary);
160
+ }
161
+ }
162
+ return out;
163
+ }
164
+ function parseDataRow(io) {
165
+ const out = {
166
+ columnCount: io.readUInt16BE(),
167
+ };
168
+ if (out.columnCount) {
169
+ out.columns = [];
170
+ for (let i = 0; i < out.columnCount; i++) {
171
+ // The length of the column value, in bytes (this count does not include itself).
172
+ // Can be zero. As a special case, -1 indicates a NULL column value.
173
+ // No value bytes follow in the NULL case.
174
+ const l = io.readInt32BE();
175
+ if (l < 0)
176
+ out.columns.push(null);
177
+ else
178
+ out.columns.push(io.readBuffer(l));
179
+ }
180
+ }
181
+ return out;
182
+ }
183
+ function parseErrorResponse(io) {
184
+ const out = {};
185
+ let fieldType;
186
+ while ((fieldType = io.readLString(1)) !== '\0') {
187
+ const value = io.readCString('utf8');
188
+ const key = ErrorFieldTypes[fieldType];
189
+ if (key)
190
+ out[key] = value;
191
+ }
192
+ return out;
193
+ }
194
+ function parseNotificationResponse(io) {
195
+ return {
196
+ processId: io.readUInt32BE(),
197
+ channel: io.readCString(),
198
+ payload: io.readCString(),
199
+ };
200
+ }
201
+ function parseFunctionCallResponse(io, code, len) {
202
+ return {
203
+ result: io.readBuffer(len - 4),
204
+ };
205
+ }
206
+ function parseNegotiateProtocolVersion(io) {
207
+ return {
208
+ supportedVersionMinor: io.readUInt32BE(),
209
+ numberOfNotSupportedVersions: io.readUInt32BE(),
210
+ option: io.readCString('utf8'),
211
+ };
212
+ }
213
+ function parseParameterDescription(io) {
214
+ const out = {
215
+ parameterCount: io.readUInt32BE(),
216
+ parameterIds: [],
217
+ };
218
+ for (let i = 0; i < out.parameterCount; i++) {
219
+ out.parameterIds.push(io.readUInt32BE());
220
+ }
221
+ return out;
222
+ }
223
+ function parseParameterStatus(io) {
224
+ return {
225
+ name: io.readCString('utf8'),
226
+ value: io.readCString('utf8'),
227
+ };
228
+ }
229
+ function parseReadyForQuery(io) {
230
+ return {
231
+ status: io.readLString(1),
232
+ };
233
+ }
234
+ function parseRowDescription(io) {
235
+ const fieldCount = io.readUInt16BE();
236
+ const out = {
237
+ fields: [],
238
+ };
239
+ for (let i = 0; i < fieldCount; i++) {
240
+ const field = {
241
+ fieldName: io.readCString('utf8'),
242
+ tableId: io.readInt32BE(),
243
+ columnId: io.readInt16BE(),
244
+ dataTypeId: io.readInt32BE(),
245
+ fixedSize: io.readInt16BE(),
246
+ modifier: io.readInt32BE(),
247
+ format: io.readInt16BE() === 0 ? Protocol.DataFormat.text : Protocol.DataFormat.binary,
248
+ };
249
+ out.fields.push(field);
250
+ }
251
+ return out;
252
+ }
@@ -0,0 +1,74 @@
1
+ export class BufferReader {
2
+ constructor(buffer) {
3
+ this.offset = 0;
4
+ this.buffer = buffer;
5
+ }
6
+ get length() {
7
+ return this.buffer.length;
8
+ }
9
+ readUInt8() {
10
+ this._checkReadable(1);
11
+ const v = this.buffer.readUInt8(this.offset);
12
+ this.offset++;
13
+ return v;
14
+ }
15
+ readUInt16BE() {
16
+ this._checkReadable(2);
17
+ const v = this.buffer.readUInt16BE(this.offset);
18
+ this.offset += 2;
19
+ return v;
20
+ }
21
+ readInt16BE() {
22
+ this._checkReadable(2);
23
+ const v = this.buffer.readInt16BE(this.offset);
24
+ this.offset += 2;
25
+ return v;
26
+ }
27
+ readUInt32BE() {
28
+ this._checkReadable(4);
29
+ const v = this.buffer.readUInt32BE(this.offset);
30
+ this.offset += 4;
31
+ return v;
32
+ }
33
+ readInt32BE() {
34
+ this._checkReadable(4);
35
+ const v = this.buffer.readInt32BE(this.offset);
36
+ this.offset += 4;
37
+ return v;
38
+ }
39
+ readCString(encoding) {
40
+ const idx = this.buffer.indexOf(0, this.offset);
41
+ const v = this.buffer.toString(encoding, this.offset, idx);
42
+ this.offset = idx + 1;
43
+ return v;
44
+ }
45
+ readLString(len, encoding) {
46
+ if (len < 0)
47
+ return null;
48
+ this._checkReadable(len);
49
+ const v = this.buffer.toString(encoding, this.offset, this.offset + len);
50
+ this.offset += len;
51
+ return v;
52
+ }
53
+ readBuffer(len) {
54
+ if (len)
55
+ this._checkReadable(len);
56
+ const end = len !== undefined ? this.offset + len : this.length;
57
+ const buf = this.buffer.slice(this.offset, end);
58
+ this.offset = end;
59
+ return buf;
60
+ }
61
+ moveBy(n) {
62
+ return this.moveTo(this.offset + n);
63
+ }
64
+ moveTo(pos) {
65
+ if (pos >= this.length)
66
+ throw new Error('Eof in buffer detected');
67
+ this.offset = pos;
68
+ return this;
69
+ }
70
+ _checkReadable(size) {
71
+ if (this.offset + size - 1 >= this.length)
72
+ throw new Error('Eof in buffer detected');
73
+ }
74
+ }
@@ -0,0 +1,13 @@
1
+ export class DatabaseError extends Error {
2
+ constructor(msg) {
3
+ super(msg.message);
4
+ Object.assign(this, {
5
+ ...msg,
6
+ line: undefined,
7
+ file: undefined,
8
+ routine: undefined,
9
+ });
10
+ if (msg.position)
11
+ this.position = parseInt(msg.position, 10) || undefined;
12
+ }
13
+ }