postgrejs 3.3.0 → 3.5.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 (40) hide show
  1. package/CHANGELOG.md +55 -1
  2. package/README.md +68 -7
  3. package/connection/connection.d.ts +134 -0
  4. package/connection/connection.js +213 -2
  5. package/connection/cursor.d.ts +8 -0
  6. package/connection/cursor.js +17 -0
  7. package/connection/intl-connection.d.ts +118 -3
  8. package/connection/intl-connection.js +615 -31
  9. package/connection/pool.d.ts +16 -0
  10. package/connection/pool.js +24 -0
  11. package/connection/prepared-statement.d.ts +64 -1
  12. package/connection/prepared-statement.js +95 -5
  13. package/data-types/float4-type.js +2 -1
  14. package/data-types/float8-type.js +2 -1
  15. package/data-types/int2-type.js +2 -1
  16. package/data-types/int4-type.js +2 -1
  17. package/data-types/int8-type.js +2 -1
  18. package/data-types/numeric-type.js +7 -0
  19. package/data-types/oid-type.js +2 -1
  20. package/index.d.ts +3 -0
  21. package/index.js +3 -0
  22. package/interfaces/batch-result.d.ts +42 -0
  23. package/interfaces/batch-result.js +1 -0
  24. package/interfaces/copy-from-rows-options.d.ts +58 -0
  25. package/interfaces/copy-from-rows-options.js +1 -0
  26. package/interfaces/database-connection-params.d.ts +25 -0
  27. package/interfaces/pipeline-request.d.ts +16 -0
  28. package/interfaces/pipeline-request.js +1 -0
  29. package/interfaces/query-options.d.ts +6 -0
  30. package/package.json +5 -2
  31. package/protocol/database-error.d.ts +16 -0
  32. package/protocol/database-error.js +15 -0
  33. package/protocol/pg-socket.d.ts +76 -0
  34. package/protocol/pg-socket.js +130 -12
  35. package/util/assert-integer.d.ts +43 -0
  36. package/util/assert-integer.js +58 -0
  37. package/util/copy-from-rows.d.ts +56 -0
  38. package/util/copy-from-rows.js +95 -0
  39. package/util/encode-copy-binary.d.ts +48 -0
  40. package/util/encode-copy-binary.js +112 -0
@@ -1,5 +1,9 @@
1
1
  import { ConnectionState } from '../constants.js';
2
+ import type { DataTypeMap } from '../data-type-map.js';
3
+ import type { BatchResult } from '../interfaces/batch-result.js';
4
+ import type { CopyFromRowsOptions, CopyFromRowsResult } from '../interfaces/copy-from-rows-options.js';
2
5
  import type { ConnectionConfiguration } from '../interfaces/database-connection-params.js';
6
+ import type { FieldInfo } from '../interfaces/field-info.js';
3
7
  import type { FunctionCallOptions } from '../interfaces/function-call-options.js';
4
8
  import type { FunctionCallResult } from '../interfaces/function-call-result.js';
5
9
  import type { QueryOptions } from '../interfaces/query-options.js';
@@ -9,10 +13,25 @@ import type { ScriptResult } from '../interfaces/script-result.js';
9
13
  import { PgSocket } from '../protocol/pg-socket.js';
10
14
  import { Protocol } from '../protocol/protocol.js';
11
15
  import { SafeEventEmitter } from '../safe-event-emitter.js';
12
- import type { Maybe, OID } from '../types.js';
16
+ import type { AnyParseFunction, Maybe, OID } from '../types.js';
17
+ import { type CopyRowSource } from '../util/copy-from-rows.js';
13
18
  import type { Connection } from './connection.js';
14
19
  import { CopyFromStream, CopyToStream } from './copy-stream.js';
15
20
  export declare class IntlConnection extends SafeEventEmitter {
21
+ /**
22
+ * Server-side prepared statements this connection has built, keyed by
23
+ * the SQL text and its parameter OIDs - both, because the OIDs are part
24
+ * of what was parsed, not just how it is bound.
25
+ *
26
+ * A Map, relied on for its insertion order: re-inserting on every hit
27
+ * makes the first entry the least recently used, which is what gets
28
+ * closed when the cache is full. Statements belong to the session, so
29
+ * this is per connection and dies with it.
30
+ */
31
+ private _preparedCache;
32
+ /** SQL seen once but not yet prepared - see PREPARE_AFTER_USES. */
33
+ private _preparedCandidates;
34
+ private _preparedCounter;
16
35
  private _executeReusedParserCache;
17
36
  protected _refCount: number;
18
37
  protected _transactionDepth: number;
@@ -136,6 +155,21 @@ export declare class IntlConnection extends SafeEventEmitter {
136
155
  * Runs a COPY ... FROM STDIN and hands back a stream to feed it.
137
156
  * Resolves once the server is ready for data.
138
157
  */
158
+ /**
159
+ * Streams rows into a table with `COPY ... FROM STDIN (FORMAT binary)`,
160
+ * encoding each value with its own type's binary encoder.
161
+ *
162
+ * Binary COPY performs no conversion server-side, so the destination
163
+ * column types have to be known exactly. They are read from the server
164
+ * unless the caller supplies them: a Describe of `select <columns> from
165
+ * <table> where false` against the unnamed statement returns a
166
+ * RowDescription carrying each column's OID, which costs one round trip
167
+ * and leaves nothing to close (the next Parse replaces the unnamed
168
+ * statement). Letting PostgreSQL resolve the name is the reason to do it
169
+ * this way rather than reading the catalog here - schemas, quoting,
170
+ * search_path and views then behave exactly as they will for the COPY.
171
+ */
172
+ copyFromRows(table: string, source: CopyRowSource, options?: CopyFromRowsOptions): Promise<CopyFromRowsResult>;
139
173
  copyFrom(sql: string): Promise<CopyFromStream>;
140
174
  protected _execute(sql: string, options?: ScriptExecuteOptions, cb?: (event: string, ...args: any[]) => void): Promise<ScriptResult>;
141
175
  /**
@@ -145,7 +179,48 @@ export declare class IntlConnection extends SafeEventEmitter {
145
179
  * +close()'s 7 round trips whenever there's no cursor and no explicit/
146
180
  * active transaction to wrap (see Connection.query() for that gating).
147
181
  */
148
- queryOnce(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions): Promise<QueryResult>;
182
+ /**
183
+ * Runs a one-shot extended query, reusing a server-side prepared
184
+ * statement when this connection has run the same SQL before.
185
+ *
186
+ * A repeated query then costs Bind/Execute instead of
187
+ * Parse/Bind/Describe/Execute, which the server can answer without
188
+ * planning again - fifty concurrent calls of one statement measured
189
+ * 0.97ms against 3.13ms, and socket reads dropped from 38 to 8.
190
+ *
191
+ * Nothing is prepared on first sight: SQL has to be seen
192
+ * PREPARE_AFTER_USES times before it earns a name, so a query that runs
193
+ * once costs exactly what it costs today.
194
+ *
195
+ * A cached statement can be invalidated under us - `alter table` between
196
+ * two calls makes PostgreSQL answer 0A000, "cached plan must not change
197
+ * result type". That is caught here: the entry is dropped and the query
198
+ * runs again unprepared, so a migration against a live connection
199
+ * recovers instead of failing every call from then on.
200
+ */
201
+ queryCached(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions): Promise<QueryResult>;
202
+ /**
203
+ * The savepoint rollbackOnError calls for, or undefined when this call
204
+ * needs none: outside a transaction there is nothing to roll back to,
205
+ * and a statement that is itself a transaction command manages its own
206
+ * boundaries (wrapping COMMIT in a savepoint would be nonsense).
207
+ */
208
+ protected _inlineSavepointFor(sql: string, options: QueryOptions): Maybe<string>;
209
+ protected _queryCached(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint: Maybe<string>): Promise<QueryResult>;
210
+ /**
211
+ * Counts one more use of this SQL and says whether it has now been seen
212
+ * often enough to be worth preparing under a name.
213
+ */
214
+ protected _earnsAName(key: string): boolean;
215
+ /** Closes the least recently used statement once the cache is full. */
216
+ protected _evictPreparedIfFull(): Promise<void>;
217
+ /**
218
+ * Closes an evicted statement server-side. Close answers CloseComplete
219
+ * but no ReadyForQuery, so the Sync goes separately and both are awaited
220
+ * together - the same shape PreparedStatement._close() uses.
221
+ */
222
+ protected _closePreparedStatement(name: string): Promise<void>;
223
+ queryOnce(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint?: string): Promise<QueryResult>;
149
224
  /**
150
225
  * Parse+Describe(statement)+Sync as a single round trip - used by
151
226
  * PreparedStatement.prepare() instead of a separately-awaited Parse then
@@ -164,7 +239,47 @@ export declare class IntlConnection extends SafeEventEmitter {
164
239
  * the RowDescription fields prepareOnce() already fetched instead of
165
240
  * re-Describing a fresh portal on every call.
166
241
  */
167
- executeReused(statementName: string, cachedFields: Protocol.RowDescription[] | undefined, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions): Promise<QueryResult>;
242
+ /**
243
+ * Parsers and wrapped field descriptions for a statement whose
244
+ * RowDescription prepare() already fetched, memoised per RowDescription
245
+ * so repeated executes of the same statement don't rebuild them.
246
+ * Shared by executeReused() and executeBatchReused().
247
+ */
248
+ protected _resolveReusedParsers(cachedFields: Protocol.RowDescription[], typeMap: DataTypeMap, options: QueryOptions): {
249
+ parsers: AnyParseFunction[];
250
+ resultFields: FieldInfo[];
251
+ };
252
+ /**
253
+ * Executes one prepared statement once per parameter set, as a single
254
+ * Bind/Execute stream closed by one Sync (see
255
+ * PgSocket.sendBatchBindExecuteMessages() for the wire shape and what
256
+ * the single Sync implies).
257
+ *
258
+ * Sets map to results positionally: the server answers each Execute with
259
+ * its own CommandComplete, and rows that arrive before one belong to the
260
+ * set it closes. When the server rejects a set, everything behind it is
261
+ * discarded unexecuted - the completed prefix is attached to the thrown
262
+ * error as `batchResults`, and the rejected set's index as `failedIndex`,
263
+ * so a caller can tell how far the batch actually got.
264
+ */
265
+ /**
266
+ * Runs several different statements as one Parse/Bind/Describe/Execute
267
+ * stream closed by a single Sync (see PgSocket.sendPipelineMessages() for
268
+ * the wire shape and what that framing implies).
269
+ *
270
+ * The counterpart to executeBatchReused(): that one runs a single
271
+ * prepared statement over many parameter sets, this one runs many
272
+ * statements once each. Results map to statements positionally - the
273
+ * server answers each Execute with its own CommandComplete, and any rows
274
+ * that arrive before one belong to the statement it closes.
275
+ */
276
+ executePipeline(requests: {
277
+ sql: string;
278
+ params?: any[];
279
+ paramTypes?: Maybe<OID>[];
280
+ }[], options: QueryOptions): Promise<QueryResult[]>;
281
+ executeBatchReused(statementName: string, cachedFields: Protocol.RowDescription[] | undefined, paramTypes: Maybe<Maybe<OID>[]>, paramSets: Maybe<any>[][], options: QueryOptions): Promise<BatchResult>;
282
+ executeReused(statementName: string, cachedFields: Protocol.RowDescription[] | undefined, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint?: string): Promise<QueryResult>;
168
283
  emit(event: string | symbol, ...args: any[]): boolean;
169
284
  protected _onError(err: Error): void;
170
285
  }