postgrejs 3.12.0 → 3.12.1

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 (183) hide show
  1. package/connection/bind-param.d.ts +21 -0
  2. package/connection/bind-param.js +21 -0
  3. package/connection/connection.d.ts +136 -0
  4. package/connection/connection.js +132 -5
  5. package/connection/copy-stream.d.ts +2 -0
  6. package/connection/copy-stream.js +2 -0
  7. package/connection/cursor.d.ts +67 -5
  8. package/connection/cursor.js +88 -15
  9. package/connection/intl-connection.d.ts +14 -0
  10. package/connection/intl-connection.js +95 -15
  11. package/connection/large-object.d.ts +18 -0
  12. package/connection/large-object.js +17 -0
  13. package/connection/logical-replication.d.ts +15 -0
  14. package/connection/logical-replication.js +6 -0
  15. package/connection/pool.d.ts +80 -0
  16. package/connection/pool.js +82 -9
  17. package/connection/portal.d.ts +37 -0
  18. package/connection/portal.js +29 -0
  19. package/connection/prepared-statement.d.ts +68 -0
  20. package/connection/prepared-statement.js +71 -2
  21. package/constants.d.ts +18 -0
  22. package/constants.js +18 -0
  23. package/data-type-map.d.ts +38 -0
  24. package/data-type-map.js +38 -0
  25. package/data-types/bit-type.d.ts +4 -0
  26. package/data-types/bit-type.js +4 -0
  27. package/data-types/bool-type.d.ts +2 -0
  28. package/data-types/bool-type.js +2 -0
  29. package/data-types/box-type.d.ts +2 -0
  30. package/data-types/box-type.js +2 -0
  31. package/data-types/bytea-type.d.ts +2 -0
  32. package/data-types/bytea-type.js +2 -0
  33. package/data-types/char-type.d.ts +2 -0
  34. package/data-types/char-type.js +2 -0
  35. package/data-types/circle-type.d.ts +2 -0
  36. package/data-types/circle-type.js +2 -0
  37. package/data-types/date-type.d.ts +2 -0
  38. package/data-types/date-type.js +2 -0
  39. package/data-types/float4-type.d.ts +2 -0
  40. package/data-types/float4-type.js +2 -0
  41. package/data-types/float8-type.d.ts +2 -0
  42. package/data-types/float8-type.js +2 -0
  43. package/data-types/inet-type.d.ts +4 -0
  44. package/data-types/inet-type.js +4 -0
  45. package/data-types/int2-type.d.ts +2 -0
  46. package/data-types/int2-type.js +2 -0
  47. package/data-types/int2-vector-type.d.ts +2 -0
  48. package/data-types/int2-vector-type.js +2 -0
  49. package/data-types/int4-type.d.ts +2 -0
  50. package/data-types/int4-type.js +2 -0
  51. package/data-types/int8-type.d.ts +2 -0
  52. package/data-types/int8-type.js +2 -0
  53. package/data-types/interval-type.d.ts +9 -0
  54. package/data-types/interval-type.js +9 -0
  55. package/data-types/json-type.d.ts +2 -0
  56. package/data-types/json-type.js +2 -0
  57. package/data-types/jsonb-type.d.ts +2 -0
  58. package/data-types/jsonb-type.js +2 -0
  59. package/data-types/jsonpath-type.d.ts +2 -0
  60. package/data-types/jsonpath-type.js +2 -0
  61. package/data-types/line-type.d.ts +2 -0
  62. package/data-types/line-type.js +2 -0
  63. package/data-types/lseg-type.d.ts +2 -0
  64. package/data-types/lseg-type.js +2 -0
  65. package/data-types/macaddr-type.d.ts +4 -0
  66. package/data-types/macaddr-type.js +4 -0
  67. package/data-types/money-type.d.ts +1 -0
  68. package/data-types/money-type.js +17 -10
  69. package/data-types/numeric-type.d.ts +2 -0
  70. package/data-types/numeric-type.js +2 -0
  71. package/data-types/oid-type.d.ts +2 -0
  72. package/data-types/oid-type.js +2 -0
  73. package/data-types/oid-vector-type.d.ts +1 -0
  74. package/data-types/oid-vector-type.js +1 -0
  75. package/data-types/path-type.d.ts +4 -0
  76. package/data-types/path-type.js +4 -0
  77. package/data-types/pg-lsn-type.d.ts +2 -0
  78. package/data-types/pg-lsn-type.js +2 -0
  79. package/data-types/point-type.d.ts +2 -0
  80. package/data-types/point-type.js +2 -0
  81. package/data-types/range-type.d.ts +4 -0
  82. package/data-types/range-type.js +4 -0
  83. package/data-types/snapshot-type.d.ts +4 -0
  84. package/data-types/snapshot-type.js +4 -0
  85. package/data-types/tid-type.d.ts +2 -0
  86. package/data-types/tid-type.js +2 -0
  87. package/data-types/time-type.d.ts +2 -0
  88. package/data-types/time-type.js +2 -0
  89. package/data-types/timestamp-type.d.ts +2 -0
  90. package/data-types/timestamp-type.js +2 -0
  91. package/data-types/timestamptz-type.d.ts +2 -0
  92. package/data-types/timestamptz-type.js +2 -0
  93. package/data-types/timetz-type.d.ts +2 -0
  94. package/data-types/timetz-type.js +2 -0
  95. package/data-types/tsvector-type.d.ts +4 -0
  96. package/data-types/tsvector-type.js +4 -0
  97. package/data-types/uuid-type.d.ts +2 -0
  98. package/data-types/uuid-type.js +2 -0
  99. package/data-types/varchar-type.d.ts +2 -0
  100. package/data-types/varchar-type.js +2 -0
  101. package/data-types/xid-type.d.ts +6 -0
  102. package/data-types/xid-type.js +6 -0
  103. package/interfaces/command-result.d.ts +7 -0
  104. package/interfaces/copy-from-rows-options.d.ts +4 -0
  105. package/interfaces/data-mapping-options.d.ts +6 -0
  106. package/interfaces/data-type.d.ts +37 -0
  107. package/interfaces/database-connection-params.d.ts +31 -0
  108. package/interfaces/field-info.d.ts +8 -0
  109. package/interfaces/function-call-options.d.ts +1 -0
  110. package/interfaces/function-call-result.d.ts +6 -0
  111. package/interfaces/pipeline-request.d.ts +2 -0
  112. package/interfaces/query-options.d.ts +7 -0
  113. package/interfaces/query-result.d.ts +7 -0
  114. package/interfaces/script-execute-options.d.ts +4 -0
  115. package/interfaces/script-result.d.ts +1 -0
  116. package/interfaces/statement-prepare-options.d.ts +1 -0
  117. package/package.json +5 -5
  118. package/protocol/backend.d.ts +6 -0
  119. package/protocol/backend.js +35 -5
  120. package/protocol/cert-signature.d.ts +8 -0
  121. package/protocol/cert-signature.js +8 -0
  122. package/protocol/database-error.d.ts +8 -0
  123. package/protocol/database-error.js +8 -0
  124. package/protocol/frontend.d.ts +16 -0
  125. package/protocol/frontend.js +13 -6
  126. package/protocol/pg-socket.d.ts +10 -0
  127. package/protocol/pg-socket.js +14 -7
  128. package/protocol/pgoutput.d.ts +15 -0
  129. package/protocol/pgoutput.js +7 -0
  130. package/protocol/protocol.d.ts +50 -2
  131. package/protocol/protocol.js +17 -1
  132. package/protocol/sasl.d.ts +22 -0
  133. package/protocol/sasl.js +21 -0
  134. package/protocol/smart-buffer.d.ts +4 -0
  135. package/safe-event-emitter.d.ts +7 -0
  136. package/safe-event-emitter.js +7 -0
  137. package/types.d.ts +21 -0
  138. package/util/array-calculatedim.d.ts +10 -0
  139. package/util/array-calculatedim.js +10 -0
  140. package/util/bigint-methods.d.ts +7 -0
  141. package/util/bigint-methods.js +9 -0
  142. package/util/config-from-env.d.ts +10 -0
  143. package/util/config-from-env.js +10 -0
  144. package/util/connection-config.d.ts +17 -0
  145. package/util/connection-config.js +17 -0
  146. package/util/copy-from-rows.d.ts +12 -0
  147. package/util/copy-from-rows.js +9 -0
  148. package/util/decimal-as-string.d.ts +6 -0
  149. package/util/decimal-as-string.js +6 -0
  150. package/util/decode-binaryarray.d.ts +9 -0
  151. package/util/decode-binaryarray.js +9 -0
  152. package/util/escape-literal.d.ts +11 -0
  153. package/util/escape-literal.js +13 -0
  154. package/util/fast-parseint.d.ts +14 -0
  155. package/util/fast-parseint.js +14 -0
  156. package/util/format-datetime.d.ts +26 -0
  157. package/util/format-datetime.js +26 -0
  158. package/util/get-parsers.d.ts +9 -0
  159. package/util/get-parsers.js +9 -0
  160. package/util/hex-text.d.ts +13 -21
  161. package/util/hex-text.js +24 -21
  162. package/util/local-date.d.ts +2 -41
  163. package/util/local-date.js +39 -41
  164. package/util/parse-array.d.ts +8 -0
  165. package/util/parse-array.js +8 -0
  166. package/util/parse-bytea.d.ts +15 -0
  167. package/util/parse-bytea.js +15 -0
  168. package/util/parse-datetime.d.ts +26 -0
  169. package/util/parse-datetime.js +26 -0
  170. package/util/parse-row.d.ts +23 -2
  171. package/util/parse-row.js +56 -36
  172. package/util/parse-time.d.ts +10 -0
  173. package/util/parse-time.js +10 -0
  174. package/util/resolve-column-formats.d.ts +1 -0
  175. package/util/row-decoder.d.ts +32 -0
  176. package/util/row-decoder.js +22 -0
  177. package/util/stringify-arrayliteral.d.ts +33 -0
  178. package/util/stringify-arrayliteral.js +220 -20
  179. package/util/stringify-for-sql.d.ts +17 -0
  180. package/util/stringify-for-sql.js +17 -0
  181. package/util/wrap-row-description.d.ts +10 -0
  182. package/util/wrap-row-description.js +10 -0
  183. package/CHANGELOG.md +0 -1453
@@ -1,6 +1,27 @@
1
1
  import type { OID } from '../types.js';
2
+ /**
3
+ * A parameter with its type named, for the cases where the value cannot
4
+ * say what it is.
5
+ *
6
+ * An ordinary parameter is sent untyped and the server resolves it from
7
+ * where it lands, which is what makes a string work as a `json`, a
8
+ * `uuid` or an enum without being told. This is for when that is not
9
+ * enough: a value with no context to be resolved from (`$1 is null`),
10
+ * or a large numeric array, which keeps the binary encoding only when
11
+ * its type is declared.
12
+ *
13
+ * ```ts
14
+ * await connection.query('insert into t (v) values ($1)', {
15
+ * params: [new BindParam(DataTypeOIDs._float8, bigArray)],
16
+ * });
17
+ * ```
18
+ */
2
19
  export declare class BindParam {
3
20
  oid: OID;
4
21
  value: any;
22
+ /**
23
+ * @param oid The type to declare for this parameter.
24
+ * @param value The value itself.
25
+ */
5
26
  constructor(oid: OID, value: any);
6
27
  }
@@ -1,6 +1,27 @@
1
+ /**
2
+ * A parameter with its type named, for the cases where the value cannot
3
+ * say what it is.
4
+ *
5
+ * An ordinary parameter is sent untyped and the server resolves it from
6
+ * where it lands, which is what makes a string work as a `json`, a
7
+ * `uuid` or an enum without being told. This is for when that is not
8
+ * enough: a value with no context to be resolved from (`$1 is null`),
9
+ * or a large numeric array, which keeps the binary encoding only when
10
+ * its type is declared.
11
+ *
12
+ * ```ts
13
+ * await connection.query('insert into t (v) values ($1)', {
14
+ * params: [new BindParam(DataTypeOIDs._float8, bigArray)],
15
+ * });
16
+ * ```
17
+ */
1
18
  export class BindParam {
2
19
  oid;
3
20
  value;
21
+ /**
22
+ * @param oid The type to declare for this parameter.
23
+ * @param value The value itself.
24
+ */
4
25
  constructor(oid, value) {
5
26
  this.oid = oid;
6
27
  this.value = value;
@@ -21,14 +21,48 @@ import { IntlConnection } from './intl-connection.js';
21
21
  import { LargeObject } from './large-object.js';
22
22
  import type { Pool } from './pool.js';
23
23
  import { PreparedStatement } from './prepared-statement.js';
24
+ /** One `NOTIFY` as the server delivered it: its channel, payload and sender. */
24
25
  export type NotificationMessage = Protocol.NotificationResponseMessage;
26
+ /** What `listen()` calls with each notification on its channel. */
25
27
  export type NotificationCallback = (msg: NotificationMessage) => any;
28
+ /**
29
+ * One session on one server.
30
+ *
31
+ * Built either from a configuration object, a connection string, or
32
+ * nothing at all - in which case the environment answers for it, the
33
+ * same variables `psql` reads (`PGHOST`, `PGDATABASE`, `PGUSER`, and the
34
+ * rest). `connect()` opens it and `close()` ends it; a connection taken
35
+ * from a `Pool` returns there instead.
36
+ *
37
+ * ```ts
38
+ * const connection = new Connection('postgres://localhost/mydb');
39
+ * await connection.connect();
40
+ * const result = await connection.query('select * from customers where id = $1', {
41
+ * params: [42],
42
+ * });
43
+ * await connection.close();
44
+ * ```
45
+ *
46
+ * `await using` closes it at the end of the scope, and every query
47
+ * method accepts an `AbortSignal`.
48
+ *
49
+ * Emits `connecting`, `ready`, `close`, `terminate`, `error`, `notice`
50
+ * and `debug`.
51
+ */
26
52
  export declare class Connection extends SafeEventEmitter implements AsyncDisposable {
27
53
  protected _pool?: Pool;
28
54
  protected _intlCon: IntlConnection;
29
55
  protected _notificationListeners?: SafeEventEmitter;
30
56
  protected _closing: boolean;
57
+ /**
58
+ * @param pool The pool this connection belongs to.
59
+ * @param intlCon The internals it is a handle on.
60
+ */
31
61
  constructor(pool: Pool, intlCon: IntlConnection);
62
+ /**
63
+ * @param config How to reach the server - an object, a connection
64
+ * string, or nothing to take it all from the environment.
65
+ */
32
66
  constructor(config?: ConnectionConfiguration | string);
33
67
  /**
34
68
  * Returns configuration object
@@ -64,6 +98,12 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
64
98
  * Returns the secret key of the current session
65
99
  */
66
100
  get secretKey(): Maybe<Buffer>;
101
+ /**
102
+ * How many queries this connection is running right now.
103
+ *
104
+ * More than one only when they were pipelined; a connection answers
105
+ * them in order either way.
106
+ */
67
107
  get runningQueryCount(): number;
68
108
  /**
69
109
  * Connects to the server
@@ -101,6 +141,30 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
101
141
  callFunction(functionId: OID, args: Maybe<Buffer>[], options?: FunctionCallOptions & {
102
142
  signal?: AbortSignal;
103
143
  }): Promise<FunctionCallResult>;
144
+ /**
145
+ * Runs one statement and returns its result.
146
+ *
147
+ * Parameters are sent separately from the SQL - `$1`, `$2` and so on -
148
+ * so nothing has to be escaped into the text. A statement seen a few
149
+ * times is prepared and reused on this connection without being asked
150
+ * for, and `cursor: true` returns a `Cursor` instead of the rows.
151
+ *
152
+ * ```ts
153
+ * const result = await connection.query(
154
+ * 'select id, name from customers where city = $1',
155
+ * { params: ['Berlin'], objectRows: true },
156
+ * );
157
+ * result.rows; // [{ id: 1, name: '...' }, ...]
158
+ * ```
159
+ *
160
+ * A statement built with the `sql` tag carries its own parameters and
161
+ * is passed on its own.
162
+ *
163
+ * @param sql The statement, or one built with the `sql` tag.
164
+ * @param options Parameters, row shape, type mapping, cursor, signal.
165
+ * @returns The rows, the command tag, and what the columns were.
166
+ * @throws DatabaseError When the server refuses the statement.
167
+ */
104
168
  query(sql: string | QueryRequest, options?: QueryOptions): Promise<QueryResult>;
105
169
  /**
106
170
  * Runs a `COPY ... TO STDOUT` and returns its output as a stream of the
@@ -233,7 +297,54 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
233
297
  * @param options Applied to every statement.
234
298
  */
235
299
  pipeline(requests: (string | QueryRequest | PipelineRequest)[], options?: QueryOptions): Promise<QueryResult[]>;
300
+ /**
301
+ * Bulk-loads rows into a table over `COPY ... FROM STDIN`, in
302
+ * PostgreSQL's binary format.
303
+ *
304
+ * The fastest way to write many rows: one statement carrying a stream
305
+ * of them, instead of an INSERT or a bind per row. Values are encoded
306
+ * from their JavaScript types against the table's own columns, so
307
+ * nothing has to be formatted by the caller.
308
+ *
309
+ * ```ts
310
+ * await connection.copyFromRows('customers', [
311
+ * [1, 'Ada', new Date()],
312
+ * [2, 'Grace', new Date()],
313
+ * ]);
314
+ * ```
315
+ *
316
+ * `source` can be an array, an iterable, or an async iterable - a
317
+ * stream of rows is never held whole.
318
+ *
319
+ * @param table The destination table, optionally schema-qualified.
320
+ * @param source The rows to load.
321
+ * @param options Which columns, how to encode them, a signal.
322
+ * @returns How many rows the server took.
323
+ * @throws DatabaseError When a row is refused, which ends the copy.
324
+ */
236
325
  copyFromRows(table: string, source: CopyRowSource, options?: CopyFromRowsOptions): Promise<CopyFromRowsResult>;
326
+ /**
327
+ * Opens a `COPY ... FROM STDIN` and hands back the stream to write it
328
+ * into, for a payload the caller formats itself.
329
+ *
330
+ * `copyFromRows()` is the one to reach for when the rows are
331
+ * JavaScript values; this is for bytes already in the format the
332
+ * statement names - CSV a caller produced, or a binary payload from
333
+ * somewhere else.
334
+ *
335
+ * ```ts
336
+ * const stream = await connection.copyFrom(
337
+ * 'copy customers from stdin (format csv)',
338
+ * );
339
+ * stream.write('1,Ada\n');
340
+ * await stream.end();
341
+ * ```
342
+ *
343
+ * @param sql The `COPY ... FROM STDIN` statement.
344
+ * @returns A writable stream; `end()` completes the copy and resolves
345
+ * with what the server took.
346
+ * @throws DatabaseError When the statement itself is refused.
347
+ */
237
348
  copyFrom(sql: string): Promise<CopyFromStream>;
238
349
  /**
239
350
  * Creates a PreparedStatement instance
@@ -368,8 +479,33 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
368
479
  * releaseSavepoint().
369
480
  */
370
481
  releaseSavepoint(name: string, immediate?: boolean): Promise<void>;
482
+ /**
483
+ * Subscribes to a `NOTIFY` channel, sending `LISTEN` the first time
484
+ * this connection hears of it.
485
+ *
486
+ * Several callbacks can share a channel; only the first costs a round
487
+ * trip. The channel name is quoted for the server, so it may be
488
+ * anything a string can hold.
489
+ *
490
+ * ```ts
491
+ * await connection.listen('order_placed', msg => {
492
+ * console.log(msg.payload);
493
+ * });
494
+ * ```
495
+ *
496
+ * @param channel The channel to subscribe to.
497
+ * @param callback Called with each notification on it.
498
+ */
371
499
  listen(channel: string, callback: NotificationCallback): Promise<void>;
500
+ /**
501
+ * Drops every callback on one channel and sends `UNLISTEN` for it.
502
+ *
503
+ * Does nothing when the channel was never listened to.
504
+ *
505
+ * @param channel The channel to unsubscribe from.
506
+ */
372
507
  unListen(channel: string): Promise<void>;
508
+ /** Drops every callback on every channel, with one `UNLISTEN *`. */
373
509
  unListenAll(): Promise<void>;
374
510
  /**
375
511
  * Whether a statement asked for the wire to itself - `pipeline: false`
@@ -1,3 +1,4 @@
1
+ import { updateErrorMessage } from '@jsopen/objects';
1
2
  import { ConnectionState, DataTypeOIDs } from '../constants.js';
2
3
  import { SafeEventEmitter } from '../safe-event-emitter.js';
3
4
  import { withAbortSignal } from '../util/abort-signal.js';
@@ -12,6 +13,30 @@ import { PreparedStatement } from './prepared-statement.js';
12
13
  const CAPTURE_STACK_TRACE_LIMIT = 5;
13
14
  /** Names the savepoint a nested transaction() scope takes. */
14
15
  let transactionScopeCounter = 0;
16
+ /**
17
+ * One session on one server.
18
+ *
19
+ * Built either from a configuration object, a connection string, or
20
+ * nothing at all - in which case the environment answers for it, the
21
+ * same variables `psql` reads (`PGHOST`, `PGDATABASE`, `PGUSER`, and the
22
+ * rest). `connect()` opens it and `close()` ends it; a connection taken
23
+ * from a `Pool` returns there instead.
24
+ *
25
+ * ```ts
26
+ * const connection = new Connection('postgres://localhost/mydb');
27
+ * await connection.connect();
28
+ * const result = await connection.query('select * from customers where id = $1', {
29
+ * params: [42],
30
+ * });
31
+ * await connection.close();
32
+ * ```
33
+ *
34
+ * `await using` closes it at the end of the scope, and every query
35
+ * method accepts an `AbortSignal`.
36
+ *
37
+ * Emits `connecting`, `ready`, `close`, `terminate`, `error`, `notice`
38
+ * and `debug`.
39
+ */
15
40
  export class Connection extends SafeEventEmitter {
16
41
  _pool;
17
42
  _intlCon;
@@ -78,6 +103,12 @@ export class Connection extends SafeEventEmitter {
78
103
  get secretKey() {
79
104
  return this._intlCon.secretKey;
80
105
  }
106
+ /**
107
+ * How many queries this connection is running right now.
108
+ *
109
+ * More than one only when they were pipelined; a connection answers
110
+ * them in order either way.
111
+ */
81
112
  get runningQueryCount() {
82
113
  return this._intlCon.runningQueryCount;
83
114
  }
@@ -187,6 +218,30 @@ export class Connection extends SafeEventEmitter {
187
218
  callFunction(functionId, args, options) {
188
219
  return withAbortSignal(options?.signal, () => this._intlCon.cancel(), () => this._captureErrorStack(this._intlCon.callFunction(functionId, args, options), this.callFunction));
189
220
  }
221
+ /**
222
+ * Runs one statement and returns its result.
223
+ *
224
+ * Parameters are sent separately from the SQL - `$1`, `$2` and so on -
225
+ * so nothing has to be escaped into the text. A statement seen a few
226
+ * times is prepared and reused on this connection without being asked
227
+ * for, and `cursor: true` returns a `Cursor` instead of the rows.
228
+ *
229
+ * ```ts
230
+ * const result = await connection.query(
231
+ * 'select id, name from customers where city = $1',
232
+ * { params: ['Berlin'], objectRows: true },
233
+ * );
234
+ * result.rows; // [{ id: 1, name: '...' }, ...]
235
+ * ```
236
+ *
237
+ * A statement built with the `sql` tag carries its own parameters and
238
+ * is passed on its own.
239
+ *
240
+ * @param sql The statement, or one built with the `sql` tag.
241
+ * @param options Parameters, row shape, type mapping, cursor, signal.
242
+ * @returns The rows, the command tag, and what the columns were.
243
+ * @throws DatabaseError When the server refuses the statement.
244
+ */
190
245
  async query(sql, options) {
191
246
  if (sql instanceof QueryRequest) {
192
247
  if (options?.params)
@@ -389,6 +444,31 @@ export class Connection extends SafeEventEmitter {
389
444
  throw this._handleError(e, i != null && normalized[i] ? normalized[i].sql : normalized[0].sql);
390
445
  });
391
446
  }
447
+ /**
448
+ * Bulk-loads rows into a table over `COPY ... FROM STDIN`, in
449
+ * PostgreSQL's binary format.
450
+ *
451
+ * The fastest way to write many rows: one statement carrying a stream
452
+ * of them, instead of an INSERT or a bind per row. Values are encoded
453
+ * from their JavaScript types against the table's own columns, so
454
+ * nothing has to be formatted by the caller.
455
+ *
456
+ * ```ts
457
+ * await connection.copyFromRows('customers', [
458
+ * [1, 'Ada', new Date()],
459
+ * [2, 'Grace', new Date()],
460
+ * ]);
461
+ * ```
462
+ *
463
+ * `source` can be an array, an iterable, or an async iterable - a
464
+ * stream of rows is never held whole.
465
+ *
466
+ * @param table The destination table, optionally schema-qualified.
467
+ * @param source The rows to load.
468
+ * @param options Which columns, how to encode them, a signal.
469
+ * @returns How many rows the server took.
470
+ * @throws DatabaseError When a row is refused, which ends the copy.
471
+ */
392
472
  async copyFromRows(table, source, options) {
393
473
  /* c8 ignore start */
394
474
  if (this.listenerCount('debug')) {
@@ -404,6 +484,28 @@ export class Connection extends SafeEventEmitter {
404
484
  throw this._handleError(e, `COPY ${table} FROM STDIN (FORMAT binary)`);
405
485
  });
406
486
  }
487
+ /**
488
+ * Opens a `COPY ... FROM STDIN` and hands back the stream to write it
489
+ * into, for a payload the caller formats itself.
490
+ *
491
+ * `copyFromRows()` is the one to reach for when the rows are
492
+ * JavaScript values; this is for bytes already in the format the
493
+ * statement names - CSV a caller produced, or a binary payload from
494
+ * somewhere else.
495
+ *
496
+ * ```ts
497
+ * const stream = await connection.copyFrom(
498
+ * 'copy customers from stdin (format csv)',
499
+ * );
500
+ * stream.write('1,Ada\n');
501
+ * await stream.end();
502
+ * ```
503
+ *
504
+ * @param sql The `COPY ... FROM STDIN` statement.
505
+ * @returns A writable stream; `end()` completes the copy and resolves
506
+ * with what the server took.
507
+ * @throws DatabaseError When the statement itself is refused.
508
+ */
407
509
  async copyFrom(sql) {
408
510
  /* c8 ignore start */
409
511
  if (this.listenerCount('debug')) {
@@ -625,22 +727,45 @@ export class Connection extends SafeEventEmitter {
625
727
  releaseSavepoint(name, immediate) {
626
728
  return this._captureErrorStack(this._intlCon.releaseSavepoint(name, immediate));
627
729
  }
730
+ /**
731
+ * Subscribes to a `NOTIFY` channel, sending `LISTEN` the first time
732
+ * this connection hears of it.
733
+ *
734
+ * Several callbacks can share a channel; only the first costs a round
735
+ * trip. The channel name is quoted for the server, so it may be
736
+ * anything a string can hold.
737
+ *
738
+ * ```ts
739
+ * await connection.listen('order_placed', msg => {
740
+ * console.log(msg.payload);
741
+ * });
742
+ * ```
743
+ *
744
+ * @param channel The channel to subscribe to.
745
+ * @param callback Called with each notification on it.
746
+ */
747
+ /* This used to test whether ANY channel had a listener rather than
748
+ this one, so a second channel added after the first never had its
749
+ own LISTEN sent and never received anything - verified live, only
750
+ the first channel ever appeared in pg_stat_activity's query text. */
628
751
  async listen(channel, callback) {
629
752
  channel = normalizeChannelName(channel);
630
753
  if (!this._notificationListeners) {
631
754
  this._notificationListeners = new SafeEventEmitter();
632
755
  this._intlCon.on('notification', (msg) => this._handleNotification(msg));
633
756
  }
634
- // Bug: this used to check whether ANY channel already had a listener,
635
- // not this one specifically - so a second, different channel added
636
- // after the first never got its own LISTEN sent at all, and never
637
- // received a notification for it (verified live: only the first
638
- // channel ever showed up in pg_stat_activity's query text).
639
757
  const alreadyListening = !!this._notificationListeners.listenerCount(channel);
640
758
  this._notificationListeners.on(channel, callback);
641
759
  if (!alreadyListening)
642
760
  await this._captureErrorStack(this.query('LISTEN ' + escapeIdentifier(channel)));
643
761
  }
762
+ /**
763
+ * Drops every callback on one channel and sends `UNLISTEN` for it.
764
+ *
765
+ * Does nothing when the channel was never listened to.
766
+ *
767
+ * @param channel The channel to unsubscribe from.
768
+ */
644
769
  async unListen(channel) {
645
770
  channel = normalizeChannelName(channel);
646
771
  if (this._notificationListeners?.listenerCount(channel)) {
@@ -648,6 +773,7 @@ export class Connection extends SafeEventEmitter {
648
773
  await this._captureErrorStack(this.query('UNLISTEN ' + escapeIdentifier(channel)));
649
774
  }
650
775
  }
776
+ /** Drops every callback on every channel, with one `UNLISTEN *`. */
651
777
  async unListenAll() {
652
778
  if (this._notificationListeners?.eventNames().length) {
653
779
  this._notificationListeners.removeAllListeners();
@@ -780,6 +906,7 @@ export class Connection extends SafeEventEmitter {
780
906
  err.message += `\n${String(err.lineNr - 1).padStart(3)}| ${lines[err.lineNr - 2]}`;
781
907
  err.message += `\n${String(err.lineNr).padStart(3)}| ${err.line}\n .${'-'.repeat(Math.max(err.colNr - 1, 0))}^`;
782
908
  }
909
+ updateErrorMessage(err, err.message);
783
910
  return err;
784
911
  }
785
912
  /**
@@ -27,6 +27,7 @@ export declare class CopyToStream extends Readable {
27
27
  protected _discarding: boolean;
28
28
  protected _settled: boolean;
29
29
  protected _paused: boolean;
30
+ /** @param socket The socket the copy is running on. */
30
31
  constructor(socket: PgSocket);
31
32
  /**
32
33
  * Handles the copy's backend messages. Passed straight to
@@ -68,6 +69,7 @@ export declare class CopyFromStream extends Writable {
68
69
  protected _completed?: (err?: Error) => void;
69
70
  protected _copyEnded: boolean;
70
71
  protected _settled: boolean;
72
+ /** @param socket The socket the copy is running on. */
71
73
  constructor(socket: PgSocket);
72
74
  /**
73
75
  * Handles the copy's backend messages. Passed straight to
@@ -27,6 +27,7 @@ export class CopyToStream extends Readable {
27
27
  _discarding = false;
28
28
  _settled = false;
29
29
  _paused = false;
30
+ /** @param socket The socket the copy is running on. */
30
31
  constructor(socket) {
31
32
  super();
32
33
  this._socket = socket;
@@ -148,6 +149,7 @@ export class CopyFromStream extends Writable {
148
149
  _completed;
149
150
  _copyEnded = false;
150
151
  _settled = false;
152
+ /** @param socket The socket the copy is running on. */
151
153
  constructor(socket) {
152
154
  super();
153
155
  this._socket = socket;
@@ -4,6 +4,32 @@ import { SafeEventEmitter } from '../safe-event-emitter.js';
4
4
  import type { AnyParseFunction, Maybe, Row } from '../types.js';
5
5
  import type { Portal } from './portal.js';
6
6
  import type { PreparedStatement } from './prepared-statement.js';
7
+ /**
8
+ * A result read a batch at a time instead of all at once.
9
+ *
10
+ * Returned by `Connection.query()`/`PreparedStatement.execute()` when
11
+ * `cursor: true` is passed, and backed by a server-side portal: rows are
12
+ * fetched `fetchCount` at a time (100 by default) as they are asked for,
13
+ * so a result larger than memory can be read through without ever
14
+ * holding it.
15
+ *
16
+ * The cursor closes itself when the rows run out, and `for await`
17
+ * closes it however the loop ends. Anything else - breaking out of a
18
+ * manual `next()` loop, an error in the middle - wants `close()`, or
19
+ * `await using`, which calls it.
20
+ *
21
+ * ```ts
22
+ * const result = await connection.query('select * from big_table', {
23
+ * cursor: true,
24
+ * fetchCount: 500,
25
+ * });
26
+ * for await (const row of result.cursor!) {
27
+ * // one row at a time; 500 arrive per round trip
28
+ * }
29
+ * ```
30
+ *
31
+ * Emits `fetch` with each batch as it arrives, and `close` once.
32
+ */
7
33
  export declare class Cursor extends SafeEventEmitter implements AsyncDisposable {
8
34
  private readonly _statement;
9
35
  private readonly _portal;
@@ -13,21 +39,57 @@ export declare class Cursor extends SafeEventEmitter implements AsyncDisposable
13
39
  private _taskQueue;
14
40
  private _rows;
15
41
  private _closed;
42
+ /** What the columns of every row this cursor returns are. */
16
43
  readonly fields: FieldInfo[];
17
44
  constructor(statement: PreparedStatement, portal: Portal, fields: FieldInfo[], parsers: AnyParseFunction[], queryOptions: QueryOptions);
45
+ /**
46
+ * The shape of the rows this cursor hands back - `'array'`,
47
+ * `'object'`, or `'custom'` when a `RowDecoder` of the caller's own is
48
+ * producing them.
49
+ */
18
50
  get rowType(): 'array' | 'object' | 'custom';
51
+ /**
52
+ * Whether the cursor is finished: the rows ran out, `close()` was
53
+ * called, or the portal was lost.
54
+ */
19
55
  get isClosed(): boolean;
56
+ /**
57
+ * The next row, or `undefined` once there are none left.
58
+ *
59
+ * Fetches a batch from the server when the current one is used up, and
60
+ * closes the cursor when the server answers with nothing.
61
+ *
62
+ * @returns The next row, or `undefined` at the end.
63
+ */
20
64
  next(): Promise<Maybe<Row>>;
65
+ /**
66
+ * Up to `nRows` rows, fetching as many batches as it takes.
67
+ *
68
+ * Shorter than asked for only at the end of the result, and empty once
69
+ * the cursor is closed - which is how the end is told apart from a
70
+ * batch boundary.
71
+ *
72
+ * @param nRows How many rows to read at most.
73
+ * @returns The rows read, in order.
74
+ */
21
75
  fetch(nRows: number): Promise<Row[]>;
76
+ /**
77
+ * Closes the cursor and releases the portal behind it.
78
+ *
79
+ * Idempotent, and called automatically when the rows run out or a
80
+ * `for await` loop ends. Emits `close`.
81
+ */
22
82
  close(): Promise<void>;
83
+ /** Reads one batch from the portal and queues it up for the callers. */
23
84
  private _fetchRows;
24
85
  /**
25
- * Iterates the remaining rows, fetching a batch at a time, and closes
26
- * the cursor when the loop ends - whether it ran out of rows, broke
27
- * early, or the body threw. Nothing is decoded ahead of what is asked
28
- * for, so this streams a result larger than memory the same way next()
29
- * does one row at a time.
86
+ * Iterates the remaining rows, a batch at a time, and closes the cursor
87
+ * when the loop ends - whether it ran out of rows, broke early, or the
88
+ * body threw.
89
+ *
90
+ * @returns An iterator over the rows left to read.
30
91
  */
31
92
  [Symbol.asyncIterator](): AsyncIterableIterator<Row>;
93
+ /** Closes the cursor, so `await using` can own one. */
32
94
  [Symbol.asyncDispose](): Promise<void>;
33
95
  }