@vibeorm/adapter-pg 4.2.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -5
- package/dist/batch.d.ts +8 -0
- package/dist/client-turns.d.ts +44 -0
- package/dist/connection-group.d.ts +62 -0
- package/dist/connection-string.d.ts +55 -0
- package/dist/errors.d.ts +8 -0
- package/dist/index.d.ts +42 -5
- package/dist/index.js +1326 -75
- package/dist/index.js.map +13 -9
- package/dist/pool-config.d.ts +25 -0
- package/dist/statement-cache.d.ts +24 -5
- package/dist/timestamp-text.d.ts +34 -0
- package/dist/transaction-sql.d.ts +22 -0
- package/package.json +3 -3
package/dist/pool-config.d.ts
CHANGED
|
@@ -47,12 +47,37 @@ export declare function placePlanCacheMode(params: {
|
|
|
47
47
|
connectionString: string | undefined;
|
|
48
48
|
planCacheMode: PlanCacheMode;
|
|
49
49
|
}): StartupOptionsPlacement;
|
|
50
|
+
/**
|
|
51
|
+
* Validate an `idleTimeout` option value (AW-04): integer milliseconds from
|
|
52
|
+
* 0 through 2,147,483,647. pg-pool passes it to `setTimeout`; larger values
|
|
53
|
+
* overflow Node's signed 32-bit timer range and become a 1 ms timeout.
|
|
54
|
+
*
|
|
55
|
+
* @throws VibeError `VIBE_CONFIG` (`meta.reason: "invalid-idle-timeout"`).
|
|
56
|
+
*/
|
|
57
|
+
export declare function assertIdleTimeout(params: {
|
|
58
|
+
value: unknown;
|
|
59
|
+
}): number;
|
|
60
|
+
/**
|
|
61
|
+
* Validate a `min` option value (V7): an integer from 0 through the pool's
|
|
62
|
+
* `max`. pg-pool never idle-closes a connection while the pool holds `min` or
|
|
63
|
+
* fewer; it does not open them in advance (`adapter.connect()` does).
|
|
64
|
+
*
|
|
65
|
+
* @throws VibeError `VIBE_CONFIG` (`meta.reason: "invalid-pool-min"`).
|
|
66
|
+
*/
|
|
67
|
+
export declare function assertPoolMin(params: {
|
|
68
|
+
value: unknown;
|
|
69
|
+
max: number;
|
|
70
|
+
}): number;
|
|
50
71
|
/** Build the `pg.Pool` constructor config for an adapter-owned pool. */
|
|
51
72
|
export declare function buildPoolConfig(params: {
|
|
52
73
|
connectionString: string | undefined;
|
|
53
74
|
max: number;
|
|
75
|
+
/** Connections pg-pool keeps open however long they idle (pg-pool's `min`). Absent = pg-pool's 0. */
|
|
76
|
+
min?: number;
|
|
54
77
|
statementTimeout?: number;
|
|
55
78
|
connectionTimeout?: number;
|
|
79
|
+
/** Milliseconds an idle pooled connection stays open (pg-pool's `idleTimeoutMillis`; `0` = never closed). Absent = pg-pool's 10 000. */
|
|
80
|
+
idleTimeout?: number;
|
|
56
81
|
planCacheMode?: PlanCacheMode;
|
|
57
82
|
}): Record<string, unknown>;
|
|
58
83
|
//# sourceMappingURL=pool-config.d.ts.map
|
|
@@ -20,12 +20,21 @@
|
|
|
20
20
|
* `max` per connection, permanently. Statements still bind their parameters;
|
|
21
21
|
* only the server-side plan cache is skipped.
|
|
22
22
|
*
|
|
23
|
-
* 2. **
|
|
23
|
+
* 2. **One name never means two texts** (F18, EPIC H). Each adapter used to
|
|
24
24
|
* start its own counter at zero, so two adapters on one pool both sent
|
|
25
25
|
* `vibeorm_0` for different SQL and postgres refused the second
|
|
26
|
-
* ("Prepared statements must be unique").
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* ("Prepared statements must be unique"). Worse, two INDEPENDENT registries
|
|
27
|
+
* (two pools, two processes) whose sessions reach one backend — a pooler
|
|
28
|
+
* that switches backends — could execute another registry's `vibeorm_0`
|
|
29
|
+
* and return that statement's rows without any error. A name is therefore
|
|
30
|
+
* derived from the text itself: `vibeorm_` + the SHA-256 of the exact
|
|
31
|
+
* statement text, base32 (see {@link statementNameFor}). Equal names mean
|
|
32
|
+
* equal texts in every registry, process and adapter version, so the worst
|
|
33
|
+
* a foreign backend can do is refuse a name (26000/42P05), never run another
|
|
34
|
+
* text under it. The registry is still shared per pool, which keeps one
|
|
35
|
+
* budget per pool and stops N adapters from preparing the same text N times.
|
|
36
|
+
* Only the text is hashed: node-postgres sends no parameter types with a
|
|
37
|
+
* named Parse, and result parsers live on the client, not the backend.
|
|
29
38
|
*
|
|
30
39
|
* 3. **A one-off text must not spend the budget.** Because names never evict
|
|
31
40
|
* (property 1), allocating on FIRST sight hands the whole budget to whatever
|
|
@@ -38,6 +47,16 @@
|
|
|
38
47
|
* text or exceed the budget. A hot text loses exactly one prepared
|
|
39
48
|
* execution; a one-off text costs the server nothing.
|
|
40
49
|
*/
|
|
50
|
+
/**
|
|
51
|
+
* The content-addressed prepared-statement name of `text`: `vibeorm_` + the
|
|
52
|
+
* SHA-256 of its UTF-8 bytes in lowercase base32 without padding — 52
|
|
53
|
+
* characters, 60 bytes in total, within PostgreSQL's 63-byte identifier limit
|
|
54
|
+
* (NAMEDATALEN − 1), so the server never truncates two names into one. The same
|
|
55
|
+
* text yields the same name in every registry, process and version.
|
|
56
|
+
*/
|
|
57
|
+
export declare function statementNameFor(params: {
|
|
58
|
+
text: string;
|
|
59
|
+
}): string;
|
|
41
60
|
/** Registry mapping SQL text to the prepared-statement name `pg` should send. */
|
|
42
61
|
export type StatementNameCache = {
|
|
43
62
|
/**
|
|
@@ -55,7 +74,7 @@ export type StatementNameCache = {
|
|
|
55
74
|
};
|
|
56
75
|
/**
|
|
57
76
|
* Create a statement-name registry that allocates at most `max` names
|
|
58
|
-
* (
|
|
77
|
+
* ({@link statementNameFor} of the text), each on the `promoteAfter`-th sighting of its
|
|
59
78
|
* text (default 2). Texts seen fewer times, and texts arriving after the budget
|
|
60
79
|
* is spent, get no name and run unprepared, so the server's prepared-statement
|
|
61
80
|
* retention stays bounded and a stream of one-off texts cannot consume it.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Char-code decoding of PostgreSQL's PLAIN timestamp wire text (performance
|
|
3
|
+
* round 3, AW-03).
|
|
4
|
+
*
|
|
5
|
+
* node-postgres hands every `timestamptz` cell to pg-types' parser
|
|
6
|
+
* (postgres-date: three regular expressions, `parseInt` per field, a split)
|
|
7
|
+
* and every `timestamp` cell to this adapter's `parseZoneLessAsUtc` (a regular
|
|
8
|
+
* expression, two `replace` calls and a template string before `new Date`).
|
|
9
|
+
* The text PostgreSQL prints for the common case has a fixed layout, so one
|
|
10
|
+
* pass over its character codes yields the same instant 2.5–3× cheaper.
|
|
11
|
+
*
|
|
12
|
+
* This function only ACCEPTS or DECLINES: it returns `undefined` for every
|
|
13
|
+
* text outside the plain form, and the caller then runs today's parser
|
|
14
|
+
* unchanged. It never adds a coercion of its own — an accepted text decodes
|
|
15
|
+
* to exactly the instant today's parser returns (differential test
|
|
16
|
+
* `tests/timestamp-text.test.ts`).
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Decode `YYYY-MM-DD HH:MM:SS[.f{1,6}]` — followed by `±HH` or `±HH:MM` when
|
|
20
|
+
* `zoned`, by nothing otherwise — as a `Date`: zone-less text is read as UTC
|
|
21
|
+
* wall-clock time, zoned text at its offset. Fraction digits beyond the third
|
|
22
|
+
* are truncated (as postgres-date and `parseZoneLessAsUtc` both do).
|
|
23
|
+
*
|
|
24
|
+
* Returns `undefined` — "use today's parser" — for anything else: years
|
|
25
|
+
* before 1000 (`Date.UTC` maps 0–99 to 1900–1999), BC dates, `infinity`,
|
|
26
|
+
* offsets with seconds (historic local mean time), date-only text, 7+
|
|
27
|
+
* fraction digits, and out-of-range fields (month 13, February 30, hour 24,
|
|
28
|
+
* second 60), so the fallback keeps every such text's current decoding.
|
|
29
|
+
*/
|
|
30
|
+
export declare function parsePlainTimestampText(params: {
|
|
31
|
+
readonly text: string;
|
|
32
|
+
readonly zoned: boolean;
|
|
33
|
+
}): Date | undefined;
|
|
34
|
+
//# sourceMappingURL=timestamp-text.d.ts.map
|
|
@@ -66,5 +66,27 @@ export type RawTransactionControl = "open" | "close" | null;
|
|
|
66
66
|
export declare function classifyRawTransactionControl(params: {
|
|
67
67
|
text: string;
|
|
68
68
|
}): RawTransactionControl;
|
|
69
|
+
/**
|
|
70
|
+
* Whether raw text WITHOUT bound values is PROVABLY one statement whose result
|
|
71
|
+
* and errors are the same in the extended protocol (a one-Sync batch) as in the
|
|
72
|
+
* simple protocol node-postgres uses for it — so it may ride a batch behind
|
|
73
|
+
* pending control (`BEGIN`, `SAVEPOINT`) like any bound statement.
|
|
74
|
+
*
|
|
75
|
+
* The proof is lexical and conservative:
|
|
76
|
+
* - no `;` anywhere (PostgreSQL's grammar splits statements only on `;`, so a
|
|
77
|
+
* non-blank text without one is ONE statement or a syntax error — the same
|
|
78
|
+
* error in both protocols; a `;` inside a string literal is refused too);
|
|
79
|
+
* - no `$` (a `$1` without values fails with a different SQLSTATE in each
|
|
80
|
+
* protocol; dollar quoting is refused with it);
|
|
81
|
+
* - no comment (`--`, `/*`) and not blank (an empty query has no statement);
|
|
82
|
+
* - not transaction control (`BEGIN`, `COMMIT`, `ROLLBACK`, `SAVEPOINT`,
|
|
83
|
+
* `RELEASE`, `PREPARE TRANSACTION`, …) and not `COPY` (its stdin refusal
|
|
84
|
+
* text differs inside a batch).
|
|
85
|
+
* Anything else keeps today's path: it goes alone, after its control was
|
|
86
|
+
* confirmed.
|
|
87
|
+
*/
|
|
88
|
+
export declare function isSingleStatementText(params: {
|
|
89
|
+
text: string;
|
|
90
|
+
}): boolean;
|
|
69
91
|
export { refuseNestedTransactionOptions } from "@vibeorm/runtime/adapter-kit";
|
|
70
92
|
//# sourceMappingURL=transaction-sql.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibeorm/adapter-pg",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "node-postgres adapter for VibeORM v2 — Bun or Node.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"orm",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"bun": ">=1.2.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@vibeorm/runtime": "
|
|
49
|
-
"@vibeorm/schema": "
|
|
48
|
+
"@vibeorm/runtime": "5.0.0",
|
|
49
|
+
"@vibeorm/schema": "5.0.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"pg": ">=8"
|