turbine-orm 0.81.0 → 0.90.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 +26 -25
- package/dist/checkout.d.ts +27 -2
- package/dist/checkout.js +75 -4
- package/dist/cjs/checkout.d.ts +27 -2
- package/dist/cjs/checkout.js +76 -3
- package/dist/cjs/cli/code-first-tags.d.ts +62 -0
- package/dist/cjs/cli/code-first-tags.js +124 -0
- package/dist/cjs/cli/compile-query.js +9 -0
- package/dist/cjs/cli/config.d.ts +35 -6
- package/dist/cjs/cli/config.js +17 -1
- package/dist/cjs/cli/destructive.d.ts +7 -4
- package/dist/cjs/cli/destructive.js +224 -20
- package/dist/cjs/cli/error-catalog.js +36 -0
- package/dist/cjs/cli/error-text.d.ts +15 -0
- package/dist/cjs/cli/error-text.js +40 -0
- package/dist/cjs/cli/index.d.ts +62 -4
- package/dist/cjs/cli/index.js +568 -108
- package/dist/cjs/cli/local-server-guard.d.ts +53 -0
- package/dist/cjs/cli/local-server-guard.js +119 -0
- package/dist/cjs/cli/local-server-output.d.ts +41 -0
- package/dist/cjs/cli/local-server-output.js +103 -0
- package/dist/cjs/cli/mcp.d.ts +8 -0
- package/dist/cjs/cli/mcp.js +121 -32
- package/dist/cjs/cli/migrate.d.ts +113 -5
- package/dist/cjs/cli/migrate.js +270 -21
- package/dist/cjs/cli/observe.d.ts +6 -1
- package/dist/cjs/cli/observe.js +85 -55
- package/dist/cjs/cli/pii-predicate-guard.d.ts +43 -23
- package/dist/cjs/cli/pii-predicate-guard.js +98 -37
- package/dist/cjs/cli/prisma-resolve.js +17 -13
- package/dist/cjs/cli/prisma-schema.js +12 -4
- package/dist/cjs/cli/studio-ui.generated.js +1 -1
- package/dist/cjs/cli/studio.d.ts +14 -2
- package/dist/cjs/cli/studio.js +244 -69
- package/dist/cjs/cli/ui.d.ts +1 -1
- package/dist/cjs/client.d.ts +558 -85
- package/dist/cjs/client.js +1270 -395
- package/dist/cjs/connection-guard.d.ts +13 -0
- package/dist/cjs/connection-guard.js +28 -0
- package/dist/cjs/connection-url.d.ts +51 -16
- package/dist/cjs/connection-url.js +67 -34
- package/dist/cjs/diagnostics.d.ts +81 -0
- package/dist/cjs/diagnostics.js +147 -0
- package/dist/cjs/dialect.d.ts +449 -20
- package/dist/cjs/dialect.js +117 -76
- package/dist/cjs/engine-config.d.ts +7 -6
- package/dist/cjs/errors.d.ts +126 -6
- package/dist/cjs/errors.js +256 -13
- package/dist/cjs/generate.d.ts +57 -7
- package/dist/cjs/generate.js +635 -279
- package/dist/cjs/global-filters-config.d.ts +59 -0
- package/dist/cjs/global-filters-config.js +367 -0
- package/dist/cjs/index.d.ts +9 -4
- package/dist/cjs/index.js +10 -2
- package/dist/cjs/introspect.d.ts +31 -6
- package/dist/cjs/introspect.js +108 -50
- package/dist/cjs/log-codes.d.ts +12 -0
- package/dist/cjs/log-codes.js +77 -0
- package/dist/cjs/logger.d.ts +87 -0
- package/dist/cjs/logger.js +98 -0
- package/dist/cjs/mssql.d.ts +8 -5
- package/dist/cjs/mssql.js +352 -65
- package/dist/cjs/mysql.d.ts +3 -5
- package/dist/cjs/mysql.js +420 -70
- package/dist/cjs/nested-write.d.ts +3 -0
- package/dist/cjs/nested-write.js +179 -114
- package/dist/cjs/pipeline-submittable.d.ts +12 -0
- package/dist/cjs/pipeline-submittable.js +118 -44
- package/dist/cjs/pipeline.js +21 -26
- package/dist/cjs/powdb-introspect.d.ts +5 -2
- package/dist/cjs/powdb-introspect.js +20 -15
- package/dist/cjs/powdb-shared.d.ts +36 -5
- package/dist/cjs/powdb-shared.js +67 -8
- package/dist/cjs/powdb.d.ts +4 -0
- package/dist/cjs/powdb.js +183 -51
- package/dist/cjs/powql.d.ts +394 -51
- package/dist/cjs/powql.js +1829 -284
- package/dist/cjs/prisma-compat.d.ts +23 -15
- package/dist/cjs/prisma-compat.js +507 -372
- package/dist/cjs/query/aggregates.d.ts +17 -1
- package/dist/cjs/query/aggregates.js +261 -29
- package/dist/cjs/query/batched-loader.d.ts +25 -6
- package/dist/cjs/query/batched-loader.js +103 -20
- package/dist/cjs/query/builder.d.ts +325 -184
- package/dist/cjs/query/builder.js +1452 -490
- package/dist/cjs/query/column-ref.d.ts +61 -0
- package/dist/cjs/query/column-ref.js +73 -0
- package/dist/cjs/query/compound-unique.d.ts +21 -0
- package/dist/cjs/query/compound-unique.js +98 -18
- package/dist/cjs/query/deferred.d.ts +53 -16
- package/dist/cjs/query/expr.d.ts +217 -0
- package/dist/cjs/query/expr.js +859 -0
- package/dist/cjs/query/filters.d.ts +155 -53
- package/dist/cjs/query/filters.js +613 -76
- package/dist/cjs/query/index.d.ts +2 -0
- package/dist/cjs/query/index.js +7 -1
- package/dist/cjs/query/json-value.d.ts +43 -0
- package/dist/cjs/query/json-value.js +59 -0
- package/dist/cjs/query/normalize-args.d.ts +87 -0
- package/dist/cjs/query/normalize-args.js +527 -0
- package/dist/cjs/query/option-surface.d.ts +16 -4
- package/dist/cjs/query/option-surface.js +57 -14
- package/dist/cjs/query/relation-names.d.ts +14 -0
- package/dist/cjs/query/relation-names.js +77 -18
- package/dist/cjs/query/relations.d.ts +30 -3
- package/dist/cjs/query/relations.js +219 -63
- package/dist/cjs/query/row-lock.d.ts +49 -0
- package/dist/cjs/query/row-lock.js +138 -0
- package/dist/cjs/query/sql-comment.d.ts +161 -0
- package/dist/cjs/query/sql-comment.js +381 -0
- package/dist/cjs/query/stream-idle.d.ts +132 -0
- package/dist/cjs/query/stream-idle.js +212 -0
- package/dist/cjs/query/table-client.d.ts +101 -0
- package/dist/cjs/query/table-client.js +74 -0
- package/dist/cjs/query/types.d.ts +677 -298
- package/dist/cjs/query/utils.d.ts +105 -6
- package/dist/cjs/query/utils.js +426 -19
- package/dist/cjs/query/warn-registry.d.ts +18 -0
- package/dist/cjs/query/warn-registry.js +18 -0
- package/dist/cjs/query/where-compile.d.ts +138 -14
- package/dist/cjs/query/where-compile.js +513 -29
- package/dist/cjs/query/where.d.ts +159 -59
- package/dist/cjs/query/where.js +716 -246
- package/dist/cjs/query/writes.d.ts +112 -50
- package/dist/cjs/query/writes.js +1498 -200
- package/dist/cjs/query-events.d.ts +4 -2
- package/dist/cjs/query-events.js +3 -1
- package/dist/cjs/realtime.d.ts +7 -3
- package/dist/cjs/realtime.js +13 -2
- package/dist/cjs/schema-builder.d.ts +55 -4
- package/dist/cjs/schema-builder.js +382 -18
- package/dist/cjs/schema-metadata.d.ts +21 -1
- package/dist/cjs/schema-metadata.js +29 -7
- package/dist/cjs/schema-sql.d.ts +75 -5
- package/dist/cjs/schema-sql.js +497 -45
- package/dist/cjs/schema.d.ts +26 -5
- package/dist/cjs/schema.js +110 -13
- package/dist/cjs/sql-placeholders.d.ts +56 -0
- package/dist/cjs/sql-placeholders.js +204 -0
- package/dist/cjs/sqlite.d.ts +75 -20
- package/dist/cjs/sqlite.js +593 -95
- package/dist/cjs/supplied-pool-types.d.ts +48 -0
- package/dist/cjs/supplied-pool-types.js +256 -0
- package/dist/cjs/transaction-control.d.ts +51 -0
- package/dist/cjs/transaction-control.js +316 -0
- package/dist/cjs/transaction-state.d.ts +342 -0
- package/dist/cjs/transaction-state.js +707 -0
- package/dist/cjs/typed-sql.d.ts +37 -3
- package/dist/cjs/typed-sql.js +102 -8
- package/dist/cli/code-first-tags.d.ts +62 -0
- package/dist/cli/code-first-tags.js +120 -0
- package/dist/cli/compile-query.js +9 -0
- package/dist/cli/config.d.ts +35 -6
- package/dist/cli/config.js +16 -1
- package/dist/cli/destructive.d.ts +7 -4
- package/dist/cli/destructive.js +224 -20
- package/dist/cli/error-catalog.js +36 -0
- package/dist/cli/error-text.d.ts +15 -0
- package/dist/cli/error-text.js +37 -0
- package/dist/cli/index.d.ts +62 -4
- package/dist/cli/index.js +569 -112
- package/dist/cli/local-server-guard.d.ts +53 -0
- package/dist/cli/local-server-guard.js +113 -0
- package/dist/cli/local-server-output.d.ts +41 -0
- package/dist/cli/local-server-output.js +98 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +121 -34
- package/dist/cli/migrate.d.ts +113 -5
- package/dist/cli/migrate.js +261 -21
- package/dist/cli/observe.d.ts +6 -1
- package/dist/cli/observe.js +84 -54
- package/dist/cli/pii-predicate-guard.d.ts +43 -23
- package/dist/cli/pii-predicate-guard.js +100 -35
- package/dist/cli/prisma-resolve.js +15 -11
- package/dist/cli/prisma-schema.js +12 -4
- package/dist/cli/studio-ui.generated.js +1 -1
- package/dist/cli/studio.d.ts +14 -2
- package/dist/cli/studio.js +246 -71
- package/dist/cli/ui.d.ts +1 -1
- package/dist/client.d.ts +558 -85
- package/dist/client.js +1275 -400
- package/dist/connection-guard.d.ts +13 -0
- package/dist/connection-guard.js +27 -0
- package/dist/connection-url.d.ts +51 -16
- package/dist/connection-url.js +63 -34
- package/dist/diagnostics.d.ts +81 -0
- package/dist/diagnostics.js +144 -0
- package/dist/dialect.d.ts +449 -20
- package/dist/dialect.js +115 -43
- package/dist/engine-config.d.ts +7 -6
- package/dist/errors.d.ts +126 -6
- package/dist/errors.js +252 -12
- package/dist/generate.d.ts +57 -7
- package/dist/generate.js +635 -281
- package/dist/global-filters-config.d.ts +59 -0
- package/dist/global-filters-config.js +361 -0
- package/dist/index.d.ts +9 -4
- package/dist/index.js +4 -2
- package/dist/introspect.d.ts +31 -6
- package/dist/introspect.js +106 -50
- package/dist/log-codes.d.ts +12 -0
- package/dist/log-codes.js +74 -0
- package/dist/logger.d.ts +87 -0
- package/dist/logger.js +93 -0
- package/dist/mssql.d.ts +8 -5
- package/dist/mssql.js +354 -67
- package/dist/mysql.d.ts +3 -5
- package/dist/mysql.js +423 -73
- package/dist/nested-write.d.ts +3 -0
- package/dist/nested-write.js +177 -112
- package/dist/pipeline-submittable.d.ts +12 -0
- package/dist/pipeline-submittable.js +117 -44
- package/dist/pipeline.js +21 -26
- package/dist/powdb-introspect.d.ts +5 -2
- package/dist/powdb-introspect.js +21 -16
- package/dist/powdb-shared.d.ts +36 -5
- package/dist/powdb-shared.js +65 -8
- package/dist/powdb.d.ts +4 -0
- package/dist/powdb.js +183 -51
- package/dist/powql.d.ts +394 -51
- package/dist/powql.js +1836 -291
- package/dist/prisma-compat.d.ts +23 -15
- package/dist/prisma-compat.js +508 -373
- package/dist/query/aggregates.d.ts +17 -1
- package/dist/query/aggregates.js +263 -32
- package/dist/query/batched-loader.d.ts +25 -6
- package/dist/query/batched-loader.js +101 -21
- package/dist/query/builder.d.ts +325 -184
- package/dist/query/builder.js +1458 -495
- package/dist/query/column-ref.d.ts +61 -0
- package/dist/query/column-ref.js +66 -0
- package/dist/query/compound-unique.d.ts +21 -0
- package/dist/query/compound-unique.js +97 -19
- package/dist/query/deferred.d.ts +53 -16
- package/dist/query/expr.d.ts +217 -0
- package/dist/query/expr.js +848 -0
- package/dist/query/filters.d.ts +155 -53
- package/dist/query/filters.js +597 -72
- package/dist/query/index.d.ts +2 -0
- package/dist/query/index.js +4 -0
- package/dist/query/json-value.d.ts +43 -0
- package/dist/query/json-value.js +54 -0
- package/dist/query/normalize-args.d.ts +87 -0
- package/dist/query/normalize-args.js +517 -0
- package/dist/query/option-surface.d.ts +16 -4
- package/dist/query/option-surface.js +56 -13
- package/dist/query/relation-names.d.ts +14 -0
- package/dist/query/relation-names.js +77 -19
- package/dist/query/relations.d.ts +30 -3
- package/dist/query/relations.js +220 -67
- package/dist/query/row-lock.d.ts +49 -0
- package/dist/query/row-lock.js +131 -0
- package/dist/query/sql-comment.d.ts +161 -0
- package/dist/query/sql-comment.js +374 -0
- package/dist/query/stream-idle.d.ts +132 -0
- package/dist/query/stream-idle.js +203 -0
- package/dist/query/table-client.d.ts +101 -0
- package/dist/query/table-client.js +70 -0
- package/dist/query/types.d.ts +677 -298
- package/dist/query/utils.d.ts +105 -6
- package/dist/query/utils.js +414 -18
- package/dist/query/warn-registry.d.ts +18 -0
- package/dist/query/warn-registry.js +18 -0
- package/dist/query/where-compile.d.ts +138 -14
- package/dist/query/where-compile.js +508 -31
- package/dist/query/where.d.ts +159 -59
- package/dist/query/where.js +711 -248
- package/dist/query/writes.d.ts +112 -50
- package/dist/query/writes.js +1496 -202
- package/dist/query-events.d.ts +4 -2
- package/dist/query-events.js +3 -1
- package/dist/realtime.d.ts +7 -3
- package/dist/realtime.js +13 -2
- package/dist/schema-builder.d.ts +55 -4
- package/dist/schema-builder.js +381 -18
- package/dist/schema-metadata.d.ts +21 -1
- package/dist/schema-metadata.js +28 -7
- package/dist/schema-sql.d.ts +75 -5
- package/dist/schema-sql.js +494 -44
- package/dist/schema.d.ts +26 -5
- package/dist/schema.js +109 -13
- package/dist/sql-placeholders.d.ts +56 -0
- package/dist/sql-placeholders.js +200 -0
- package/dist/sqlite.d.ts +75 -20
- package/dist/sqlite.js +597 -99
- package/dist/supplied-pool-types.d.ts +48 -0
- package/dist/supplied-pool-types.js +247 -0
- package/dist/transaction-control.d.ts +51 -0
- package/dist/transaction-control.js +311 -0
- package/dist/transaction-state.d.ts +342 -0
- package/dist/transaction-state.js +696 -0
- package/dist/typed-sql.d.ts +37 -3
- package/dist/typed-sql.js +100 -8
- package/package.json +7 -4
- package/skills/turbine-orm/SKILL.md +56 -6
|
@@ -22,10 +22,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.pipelineClientNeedsDiscard = pipelineClientNeedsDiscard;
|
|
25
|
+
exports.batchMayWrite = batchMayWrite;
|
|
25
26
|
exports.runPipelined = runPipelined;
|
|
26
27
|
exports.supportsExtendedPipeline = supportsExtendedPipeline;
|
|
27
28
|
const _pg_1 = __importDefault(require("pg"));
|
|
28
29
|
const errors_js_1 = require("./errors.js");
|
|
30
|
+
const transaction_state_js_1 = require("./transaction-state.js");
|
|
29
31
|
// Read off pg's own module object (`pg.Result` IS `pg/lib/result`, `pg.utils`
|
|
30
32
|
// IS `pg/lib/utils`) rather than imported by subpath, so the whole driver comes
|
|
31
33
|
// through the one `#pg` alias that edge bundles swap out (see src/pg-edge.ts).
|
|
@@ -94,6 +96,16 @@ function restoreListeners(emitter, snapshot) {
|
|
|
94
96
|
// ---------------------------------------------------------------------------
|
|
95
97
|
// Core pipeline execution
|
|
96
98
|
// ---------------------------------------------------------------------------
|
|
99
|
+
/** A statement that only reads: its transform may run after COMMIT, since there is nothing to undo. */
|
|
100
|
+
const READ_ONLY_STATEMENT = /^\s*select\b/i;
|
|
101
|
+
/**
|
|
102
|
+
* Whether a transactional batch must hold its COMMIT until the transforms have
|
|
103
|
+
* run. Anything that is not a plain SELECT counts as a write, so a statement
|
|
104
|
+
* this cannot classify costs a round trip rather than correctness.
|
|
105
|
+
*/
|
|
106
|
+
function batchMayWrite(queries) {
|
|
107
|
+
return queries.some((q) => !READ_ONLY_STATEMENT.test(q.sql));
|
|
108
|
+
}
|
|
97
109
|
/**
|
|
98
110
|
* Execute multiple queries using the Postgres extended-query pipeline protocol.
|
|
99
111
|
*
|
|
@@ -120,11 +132,20 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
120
132
|
// State machine
|
|
121
133
|
// -----------------------------------------------------------------------
|
|
122
134
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
135
|
+
* True when the batch is sent as BEGIN + queries + Sync and the COMMIT
|
|
136
|
+
* follows only once every transform has succeeded (see
|
|
137
|
+
* {@link PipelineRunOptions.transactional}).
|
|
126
138
|
*/
|
|
127
|
-
const
|
|
139
|
+
const holdCommit = transactional && batchMayWrite(queries);
|
|
140
|
+
/**
|
|
141
|
+
* Where the exchange is: the batch itself, or the single follow-up
|
|
142
|
+
* statement (the held COMMIT, or the recovery ROLLBACK) sent after it.
|
|
143
|
+
*/
|
|
144
|
+
let phase = 'batch';
|
|
145
|
+
/** The command tag the held COMMIT came back with (`ROLLBACK` when the server rolled back). */
|
|
146
|
+
let commitTag;
|
|
147
|
+
/** Transformed results, computed before a held COMMIT is sent. */
|
|
148
|
+
let transformed;
|
|
128
149
|
/**
|
|
129
150
|
* Expected readyForQuery events:
|
|
130
151
|
* - Transactional: 1 (single Sync at end)
|
|
@@ -150,20 +171,17 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
150
171
|
let cleaned = false;
|
|
151
172
|
/** Transaction status reported by the most recent ReadyForQuery. */
|
|
152
173
|
let txStatus;
|
|
153
|
-
/** Whether the recovery ROLLBACK has already been sent (it is sent at most once). */
|
|
154
|
-
let rollbackSent = false;
|
|
155
174
|
/**
|
|
156
175
|
* Map commandComplete index to the corresponding results[] index.
|
|
157
176
|
* In transactional mode: index 0 = BEGIN, 1..N = queries, N+1 = COMMIT
|
|
158
|
-
* In non-transactional mode:
|
|
177
|
+
* (absent when the COMMIT is held). In non-transactional mode: 1:1.
|
|
178
|
+
* Follow-up statements belong to no query.
|
|
159
179
|
*/
|
|
160
180
|
function commandToQueryIndex(cmdIdx) {
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
return cmdIdx;
|
|
181
|
+
if (phase !== 'batch')
|
|
182
|
+
return null;
|
|
183
|
+
const qIdx = transactional ? cmdIdx - 1 : cmdIdx;
|
|
184
|
+
return qIdx >= 0 && qIdx < queries.length ? qIdx : null;
|
|
167
185
|
}
|
|
168
186
|
/** Get the current query-results index for row data */
|
|
169
187
|
function currentQueryIndex() {
|
|
@@ -222,30 +240,56 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
222
240
|
return true;
|
|
223
241
|
if (txStatus === undefined && !(transactional && pipelineError))
|
|
224
242
|
return true;
|
|
225
|
-
if (!transactional
|
|
226
|
-
//
|
|
227
|
-
//
|
|
228
|
-
|
|
229
|
-
if (txStatus === 'E' || txStatus === 'T') {
|
|
230
|
-
Object.defineProperty(client, PIPELINE_DISCARD, { value: true, enumerable: false, configurable: true });
|
|
231
|
-
}
|
|
243
|
+
if (!transactional) {
|
|
244
|
+
// Non-transactional mode opens no transaction of its own, so there is
|
|
245
|
+
// nothing to roll back. Hand the client back marked for disposal.
|
|
246
|
+
markDiscardIfInTransaction();
|
|
232
247
|
return true;
|
|
233
248
|
}
|
|
234
|
-
|
|
249
|
+
return !sendFollowUp('ROLLBACK', 'rollback');
|
|
250
|
+
}
|
|
251
|
+
/** Mark the client for disposal when the backend still reports an open or failed transaction. */
|
|
252
|
+
function markDiscardIfInTransaction() {
|
|
253
|
+
if (txStatus === 'E' || txStatus === 'T') {
|
|
254
|
+
Object.defineProperty(client, PIPELINE_DISCARD, { value: true, enumerable: false, configurable: true });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Send one statement after the batch (the held COMMIT or the recovery
|
|
259
|
+
* ROLLBACK) with its own Sync; its ReadyForQuery finishes the exchange.
|
|
260
|
+
* Returns false when the socket would not take it, in which case the
|
|
261
|
+
* connection is marked for disposal, since it cannot be repaired from here.
|
|
262
|
+
*/
|
|
263
|
+
function sendFollowUp(text, next) {
|
|
264
|
+
phase = next;
|
|
235
265
|
try {
|
|
236
|
-
connection.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
266
|
+
connection.stream.cork?.();
|
|
267
|
+
try {
|
|
268
|
+
connection.parse({ text, name: '' });
|
|
269
|
+
connection.bind({ portal: '', statement: '', values: [], valueMapper: prepareValue });
|
|
270
|
+
connection.execute({ portal: '', rows: 0 });
|
|
271
|
+
connection.sync();
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
connection.stream.uncork?.();
|
|
275
|
+
}
|
|
276
|
+
return true;
|
|
241
277
|
}
|
|
242
|
-
catch {
|
|
243
|
-
// The socket would not take the rollback, so this connection cannot be
|
|
244
|
-
// repaired from here. Mark it and let the caller drop it.
|
|
278
|
+
catch (err) {
|
|
245
279
|
Object.defineProperty(client, PIPELINE_DISCARD, { value: true, enumerable: false, configurable: true });
|
|
246
|
-
|
|
280
|
+
if (!pipelineError)
|
|
281
|
+
pipelineError = err instanceof Error ? err : new Error(String(err));
|
|
282
|
+
return false;
|
|
247
283
|
}
|
|
248
284
|
}
|
|
285
|
+
/** Run every query's transform, in order; the first throw propagates. */
|
|
286
|
+
function transformAll() {
|
|
287
|
+
const out = [];
|
|
288
|
+
for (let i = 0; i < queries.length; i++) {
|
|
289
|
+
out.push(queries[i].transform(results[i]));
|
|
290
|
+
}
|
|
291
|
+
return out;
|
|
292
|
+
}
|
|
249
293
|
function finalize() {
|
|
250
294
|
cleanup();
|
|
251
295
|
if (transactional && pipelineError) {
|
|
@@ -288,14 +332,14 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
288
332
|
}));
|
|
289
333
|
return;
|
|
290
334
|
}
|
|
291
|
-
// All succeeded
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
for (let i = 0; i < queries.length; i++) {
|
|
295
|
-
const q = queries[i];
|
|
296
|
-
transformed.push(q.transform(results[i]));
|
|
297
|
-
}
|
|
335
|
+
// All succeeded. A held COMMIT ran the transforms before committing;
|
|
336
|
+
// a read-only batch runs them now (there is nothing to undo).
|
|
337
|
+
if (transformed) {
|
|
298
338
|
resolve(transformed);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
try {
|
|
342
|
+
resolve(transformAll());
|
|
299
343
|
}
|
|
300
344
|
catch (err) {
|
|
301
345
|
reject(err);
|
|
@@ -328,6 +372,8 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
328
372
|
}
|
|
329
373
|
}
|
|
330
374
|
function onCommandComplete(msg) {
|
|
375
|
+
if (phase === 'commit')
|
|
376
|
+
commitTag = msg.command ?? msg.text;
|
|
331
377
|
const qIdx = currentQueryIndex();
|
|
332
378
|
if (qIdx !== null && qIdx >= 0 && qIdx < results.length) {
|
|
333
379
|
results[qIdx].addCommandComplete(msg);
|
|
@@ -374,15 +420,41 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
374
420
|
}
|
|
375
421
|
function onReadyForQuery(msg) {
|
|
376
422
|
txStatus = msg?.status;
|
|
377
|
-
//
|
|
423
|
+
// A follow-up statement's own ReadyForQuery is not one of the batch's, so
|
|
378
424
|
// it must not advance the counter that decides when the batch is done.
|
|
379
|
-
if (
|
|
425
|
+
if (phase === 'rollback') {
|
|
426
|
+
markDiscardIfInTransaction();
|
|
427
|
+
finalize();
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (phase === 'commit') {
|
|
431
|
+
// PostgreSQL answers COMMIT in a failed transaction with the tag
|
|
432
|
+
// ROLLBACK and no error. Nothing here sends COMMIT after an error, but
|
|
433
|
+
// the answer is checked rather than assumed.
|
|
434
|
+
if (!pipelineError && commitTag === 'ROLLBACK')
|
|
435
|
+
pipelineError = (0, transaction_state_js_1.rolledBackError)(undefined, 'transaction');
|
|
436
|
+
markDiscardIfInTransaction();
|
|
380
437
|
finalize();
|
|
381
438
|
return;
|
|
382
439
|
}
|
|
383
440
|
rfqCount++;
|
|
384
441
|
if (rfqCount < expectedRfq)
|
|
385
442
|
return;
|
|
443
|
+
if (holdCommit && !pipelineError && txStatus !== 'E') {
|
|
444
|
+
try {
|
|
445
|
+
transformed = transformAll();
|
|
446
|
+
}
|
|
447
|
+
catch (err) {
|
|
448
|
+
// A transform refused its result: roll the batch's writes back.
|
|
449
|
+
pipelineError = err instanceof Error ? err : new Error(String(err));
|
|
450
|
+
if (!sendFollowUp('ROLLBACK', 'rollback'))
|
|
451
|
+
finalize();
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (!sendFollowUp('COMMIT', 'commit'))
|
|
455
|
+
finalize();
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
386
458
|
if (settleTransactionState())
|
|
387
459
|
finalize();
|
|
388
460
|
}
|
|
@@ -429,7 +501,8 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
429
501
|
if (transactional) {
|
|
430
502
|
// ---- Transactional mode ----
|
|
431
503
|
// BEGIN + N×(parse+bind+describe+execute) + COMMIT + sync
|
|
432
|
-
// One sync = one ReadyForQuery
|
|
504
|
+
// One sync = one ReadyForQuery. A batch that may write leaves the
|
|
505
|
+
// COMMIT out here and sends it after the transforms (holdCommit).
|
|
433
506
|
// BEGIN
|
|
434
507
|
connection.parse({ text: 'BEGIN', name: '' });
|
|
435
508
|
connection.bind({ portal: '', statement: '', values: [], valueMapper: prepareValue });
|
|
@@ -446,10 +519,11 @@ async function runPipelined(client, queries, options = {}) {
|
|
|
446
519
|
connection.describe({ type: 'P', name: '' });
|
|
447
520
|
connection.execute({ portal: '', rows: 0 });
|
|
448
521
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
522
|
+
if (!holdCommit) {
|
|
523
|
+
connection.parse({ text: 'COMMIT', name: '' });
|
|
524
|
+
connection.bind({ portal: '', statement: '', values: [], valueMapper: prepareValue });
|
|
525
|
+
connection.execute({ portal: '', rows: 0 });
|
|
526
|
+
}
|
|
453
527
|
// Single Sync
|
|
454
528
|
connection.sync();
|
|
455
529
|
}
|
package/dist/cjs/pipeline.js
CHANGED
|
@@ -22,10 +22,21 @@
|
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
23
|
exports.executePipeline = executePipeline;
|
|
24
24
|
exports.pipelineSupported = pipelineSupported;
|
|
25
|
+
const checkout_js_1 = require("./checkout.js");
|
|
25
26
|
const connection_guard_js_1 = require("./connection-guard.js");
|
|
26
27
|
const dialect_js_1 = require("./dialect.js");
|
|
27
28
|
const errors_js_1 = require("./errors.js");
|
|
28
29
|
const pipeline_submittable_js_1 = require("./pipeline-submittable.js");
|
|
30
|
+
const transaction_state_js_1 = require("./transaction-state.js");
|
|
31
|
+
/**
|
|
32
|
+
* Run one deferred query on the batch's connection. An engine without
|
|
33
|
+
* RETURNING (MySQL) attaches a `reselect` plan that runs the write and then
|
|
34
|
+
* fetches its row; sending `q.sql` alone would hand the transform a row-less
|
|
35
|
+
* result, which a single-row write reads as "not found".
|
|
36
|
+
*/
|
|
37
|
+
function runOne(client, q) {
|
|
38
|
+
return q.reselect ? q.reselect((sql, params) => client.query(sql, params)) : client.query(q.sql, q.params);
|
|
39
|
+
}
|
|
29
40
|
/**
|
|
30
41
|
* Execute queries sequentially on an already-acquired connection.
|
|
31
42
|
* This is the fallback path for clients that don't support the extended-query
|
|
@@ -55,19 +66,16 @@ async function runSequential(client, queries, dialect, options = {}) {
|
|
|
55
66
|
for (const q of queries) {
|
|
56
67
|
let raw;
|
|
57
68
|
try {
|
|
58
|
-
raw = await client
|
|
69
|
+
raw = await runOne(client, q);
|
|
59
70
|
}
|
|
60
71
|
catch (err) {
|
|
61
72
|
throw (0, errors_js_1.wrapPgError)(err);
|
|
62
73
|
}
|
|
74
|
+
// Transformed BEFORE the COMMIT, so a transform that refuses its result
|
|
75
|
+
// (a `...OrThrow` miss, an optimistic-lock conflict) rolls the batch back.
|
|
63
76
|
results.push(q.transform(raw));
|
|
64
77
|
}
|
|
65
|
-
|
|
66
|
-
await client.query(dialect.commitStatement());
|
|
67
|
-
}
|
|
68
|
-
catch (err) {
|
|
69
|
-
throw (0, errors_js_1.wrapPgError)(err);
|
|
70
|
-
}
|
|
78
|
+
await (0, transaction_state_js_1.commitTransaction)(client, dialect.commitStatement());
|
|
71
79
|
return results;
|
|
72
80
|
}
|
|
73
81
|
catch (err) {
|
|
@@ -145,7 +153,7 @@ async function runIndependent(client, queries) {
|
|
|
145
153
|
const q = queries[i];
|
|
146
154
|
let raw;
|
|
147
155
|
try {
|
|
148
|
-
raw = await client
|
|
156
|
+
raw = await runOne(client, q);
|
|
149
157
|
}
|
|
150
158
|
catch (err) {
|
|
151
159
|
const wrapped = (0, errors_js_1.wrapPgError)(err);
|
|
@@ -192,24 +200,11 @@ async function executePipeline(pool, queries, options) {
|
|
|
192
200
|
if (queries.length === 0) {
|
|
193
201
|
return [];
|
|
194
202
|
}
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
//
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
// so a caller switching on `.code` silently receives a value from a foreign
|
|
201
|
-
// namespace. The transaction and nested-write checkouts were wrapped for this
|
|
202
|
-
// reason; this was the last sibling still bare.
|
|
203
|
-
let client;
|
|
204
|
-
try {
|
|
205
|
-
client = await pool.connect();
|
|
206
|
-
}
|
|
207
|
-
catch (err) {
|
|
208
|
-
throw (0, errors_js_1.wrapPgError)(err);
|
|
209
|
-
}
|
|
210
|
-
// Guarded for the checkout window, see connection-guard.ts: a connection that
|
|
211
|
-
// dies mid-batch emits 'error', which with no listener exits the process.
|
|
212
|
-
const checkout = (0, connection_guard_js_1.guardCheckout)(client);
|
|
203
|
+
// One client, reused for both capability check and execution. The shared
|
|
204
|
+
// checkout types a connection-level failure (wrong password, TLS, refused,
|
|
205
|
+
// an exhausted pool) and guards the checkout window: a connection that dies
|
|
206
|
+
// mid-batch emits 'error', which with no listener exits the process.
|
|
207
|
+
const { client, checkout } = await (0, checkout_js_1.acquireConnection)(pool);
|
|
213
208
|
try {
|
|
214
209
|
if ((0, pipeline_submittable_js_1.supportsExtendedPipeline)(client)) {
|
|
215
210
|
// Real pipeline path, uses extended-query protocol wire methods
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* shape the SQL introspectors produce, so a code-first PowDB database can be
|
|
14
14
|
* introspected for bootstrap/verification. It is transport-agnostic: the caller
|
|
15
15
|
* supplies an `exec(powql)` that returns row objects **keyed by column name**.
|
|
16
|
-
* - Embedded / owned pool: `exec = async (q) => ({ rows: await db.
|
|
17
|
-
* using a live `turbinePowDB` client
|
|
16
|
+
* - Embedded / owned pool: `exec = async (q) => ({ rows: await db.rawUnsafe(q) })`
|
|
17
|
+
* using a live `turbinePowDB` client.
|
|
18
18
|
* - Networked: the raw `@zvndev/powdb-client` returns POSITIONAL rows
|
|
19
19
|
* (`{ columns: string[], rows: string[][] }`), so zip them into records.
|
|
20
20
|
* A bare `(await client.query(q)).rows` would hand this function `string[][]`
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
* wired to a networked `exec`, and `cli/config.ts` teaching the generate
|
|
67
67
|
* funnel to construct a PowDB client instead of a `pg` client for `powdb://`.
|
|
68
68
|
*/
|
|
69
|
+
import { type TurbineLogger } from './logger.js';
|
|
69
70
|
import { type PowdbCapabilities } from './powdb-shared.js';
|
|
70
71
|
import type { SchemaMetadata } from './schema.js';
|
|
71
72
|
/** A minimal rows-returning executor over a PowDB connection (embedded or networked). */
|
|
@@ -86,6 +87,8 @@ export interface PowdbIntrospectOptions {
|
|
|
86
87
|
* to run ungated; the pool paths that know the version pass it through.
|
|
87
88
|
*/
|
|
88
89
|
capabilities?: PowdbCapabilities;
|
|
90
|
+
/** Where a table without a usable primary key is reported. Defaults to the console logger. */
|
|
91
|
+
logger?: TurbineLogger;
|
|
89
92
|
}
|
|
90
93
|
/**
|
|
91
94
|
* Read a live PowDB database into {@link SchemaMetadata} via `schema` +
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* shape the SQL introspectors produce, so a code-first PowDB database can be
|
|
15
15
|
* introspected for bootstrap/verification. It is transport-agnostic: the caller
|
|
16
16
|
* supplies an `exec(powql)` that returns row objects **keyed by column name**.
|
|
17
|
-
* - Embedded / owned pool: `exec = async (q) => ({ rows: await db.
|
|
18
|
-
* using a live `turbinePowDB` client
|
|
17
|
+
* - Embedded / owned pool: `exec = async (q) => ({ rows: await db.rawUnsafe(q) })`
|
|
18
|
+
* using a live `turbinePowDB` client.
|
|
19
19
|
* - Networked: the raw `@zvndev/powdb-client` returns POSITIONAL rows
|
|
20
20
|
* (`{ columns: string[], rows: string[][] }`), so zip them into records.
|
|
21
21
|
* A bare `(await client.query(q)).rows` would hand this function `string[][]`
|
|
@@ -71,6 +71,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
71
71
|
exports.introspectPowdbDatabase = introspectPowdbDatabase;
|
|
72
72
|
const errors_js_1 = require("./errors.js");
|
|
73
73
|
const introspect_js_1 = require("./introspect.js");
|
|
74
|
+
const logger_js_1 = require("./logger.js");
|
|
74
75
|
const powdb_shared_js_1 = require("./powdb-shared.js");
|
|
75
76
|
const schema_js_1 = require("./schema.js");
|
|
76
77
|
/** Coerce a wire cell to string (legacy wire cells are strings; native cells may be typed). */
|
|
@@ -136,7 +137,9 @@ async function introspectPowdbDatabase(exec, options = {}) {
|
|
|
136
137
|
}
|
|
137
138
|
// include / exclude + default bookkeeping-table exclusions (F12).
|
|
138
139
|
const tableNames = (0, introspect_js_1.applyTableFilters)(candidateTables, options);
|
|
139
|
-
|
|
140
|
+
// Keyed by catalog names, so prototype-less: a table or column named
|
|
141
|
+
// `__proto__`, `constructor` or `toString` is data, never a prototype member.
|
|
142
|
+
const tables = (0, introspect_js_1.nullRecord)();
|
|
140
143
|
for (const tableName of tableNames) {
|
|
141
144
|
// `describe` needs the table name in bare-identifier position → quote it so
|
|
142
145
|
// a reserved-word / non-bare table name (`order`) does not become a parse
|
|
@@ -157,11 +160,11 @@ async function introspectPowdbDatabase(exec, options = {}) {
|
|
|
157
160
|
index: asString(r.index),
|
|
158
161
|
}));
|
|
159
162
|
const columns = [];
|
|
160
|
-
const columnMap =
|
|
161
|
-
const reverseColumnMap =
|
|
163
|
+
const columnMap = (0, introspect_js_1.nullRecord)();
|
|
164
|
+
const reverseColumnMap = (0, introspect_js_1.nullRecord)();
|
|
162
165
|
const dateColumns = new Set();
|
|
163
|
-
const dialectTypes =
|
|
164
|
-
const pgTypes =
|
|
166
|
+
const dialectTypes = (0, introspect_js_1.nullRecord)();
|
|
167
|
+
const pgTypes = (0, introspect_js_1.nullRecord)();
|
|
165
168
|
const allColumns = [];
|
|
166
169
|
const uniqueColumns = [];
|
|
167
170
|
const indexes = [];
|
|
@@ -209,15 +212,17 @@ async function introspectPowdbDatabase(exec, options = {}) {
|
|
|
209
212
|
});
|
|
210
213
|
}
|
|
211
214
|
}
|
|
215
|
+
// Two columns resolving to one field would fold into one property on read.
|
|
216
|
+
(0, introspect_js_1.assertDistinctColumnFields)(tableName, columns);
|
|
212
217
|
// Primary key: first non-nullable unique column, preferring one named `id`.
|
|
213
218
|
let primaryKey = [];
|
|
214
219
|
if (pkCandidates.length > 0) {
|
|
215
220
|
primaryKey = [pkCandidates.includes('id') ? 'id' : pkCandidates[0]];
|
|
216
221
|
}
|
|
217
222
|
else {
|
|
218
|
-
|
|
223
|
+
(0, logger_js_1.logTo)(options.logger ?? logger_js_1.consoleLogger, 'warn', `PowDB introspection: table "${(0, introspect_js_1.printableCatalogName)(tableName)}" has no non-nullable unique column; ` +
|
|
219
224
|
'primaryKey is [] (single-row operations will fail). Supply a primary key via code-first ' +
|
|
220
|
-
'`defineSchema` metadata if this table needs findUnique/update/delete by id.');
|
|
225
|
+
'`defineSchema` metadata if this table needs findUnique/update/delete by id.', { code: 'powdb-introspect-no-primary-key', table: tableName });
|
|
221
226
|
}
|
|
222
227
|
tables[tableName] = {
|
|
223
228
|
name: tableName,
|
|
@@ -233,7 +238,7 @@ async function introspectPowdbDatabase(exec, options = {}) {
|
|
|
233
238
|
// Populated below from `schema links` when the engine supports link
|
|
234
239
|
// introspection (>= 0.19.1); stays `{}` otherwise (PowDB has no declared
|
|
235
240
|
// foreign keys, so pre-link introspection reports no relations).
|
|
236
|
-
relations:
|
|
241
|
+
relations: (0, introspect_js_1.nullRecord)(),
|
|
237
242
|
indexes,
|
|
238
243
|
};
|
|
239
244
|
}
|
|
@@ -243,7 +248,7 @@ async function introspectPowdbDatabase(exec, options = {}) {
|
|
|
243
248
|
if (options.capabilities?.linkIntrospection) {
|
|
244
249
|
await introspectPowdbLinks(exec, tables);
|
|
245
250
|
}
|
|
246
|
-
return { tables, enums:
|
|
251
|
+
return { tables, enums: (0, introspect_js_1.nullRecord)() };
|
|
247
252
|
}
|
|
248
253
|
/**
|
|
249
254
|
* Read `schema links` and populate {@link TableMetadata.relations}: the first
|
|
@@ -278,8 +283,8 @@ async function introspectPowdbLinks(exec, tables) {
|
|
|
278
283
|
cardinality: asString(r.cardinality),
|
|
279
284
|
}));
|
|
280
285
|
for (const link of linkRows) {
|
|
281
|
-
const owner = tables[link.owner];
|
|
282
|
-
const target = tables[link.target];
|
|
286
|
+
const owner = Object.hasOwn(tables, link.owner) ? tables[link.owner] : undefined;
|
|
287
|
+
const target = Object.hasOwn(tables, link.target) ? tables[link.target] : undefined;
|
|
283
288
|
// A link referencing a filtered-out (include/exclude) table is skipped: we
|
|
284
289
|
// cannot describe the target, so the relation would be unusable.
|
|
285
290
|
if (!owner || !target)
|
|
@@ -324,13 +329,13 @@ async function introspectPowdbLinks(exec, tables) {
|
|
|
324
329
|
}
|
|
325
330
|
/** True when `name` already names a relation OR a column field/name on `meta`. */
|
|
326
331
|
function relationNameTaken(meta, name) {
|
|
327
|
-
if (meta.relations
|
|
332
|
+
if (Object.hasOwn(meta.relations, name))
|
|
328
333
|
return true;
|
|
329
334
|
return meta.columns.some((c) => c.field === name || c.name === name);
|
|
330
335
|
}
|
|
331
336
|
/** Add a relation to a table's relations map (keyed by its camelCase name). */
|
|
332
337
|
function addRelation(meta, rel) {
|
|
333
|
-
if (meta.relations
|
|
338
|
+
if (Object.hasOwn(meta.relations, rel.name))
|
|
334
339
|
return; // never clobber an existing relation
|
|
335
340
|
meta.relations[rel.name] = rel;
|
|
336
341
|
}
|
|
@@ -233,15 +233,36 @@ export type PowqlType = 'str' | 'int' | 'float' | 'bool' | 'json';
|
|
|
233
233
|
* asserts the equivalence over a corpus rather than asserting my reading of it.
|
|
234
234
|
*/
|
|
235
235
|
export declare function baseTsType(tsType: string): string;
|
|
236
|
+
/** A schema's enum types (`SchemaMetadata.enums`): type name to labels, in declaration order. */
|
|
237
|
+
export type PowdbEnums = Readonly<Record<string, readonly string[]>>;
|
|
236
238
|
/**
|
|
237
|
-
*
|
|
239
|
+
* The labels of the enum type this column is declared as, or `undefined` when
|
|
240
|
+
* it is not an enum column of `enums`.
|
|
241
|
+
*
|
|
242
|
+
* An enum column carries its TYPE NAME as `dialectType` / `pgType` and a
|
|
243
|
+
* `tsType` that says nothing useful (`unknown` from `defineSchema`, a union of
|
|
244
|
+
* the labels from introspection), so the column's own metadata cannot answer
|
|
245
|
+
* the question: the schema's `enums` map is the only authority. PowDB has no
|
|
246
|
+
* enum type, so such a column is a `str` holding the label text, which is what
|
|
247
|
+
* PostgreSQL stores and returns. Without this the tsType heuristic in
|
|
248
|
+
* {@link isJsonColumn} declared a `defineSchema` enum column as `json`, and
|
|
249
|
+
* writing a label failed as invalid JSON.
|
|
250
|
+
*/
|
|
251
|
+
export declare function powdbEnumLabels(col: ColumnMetadata, enums: PowdbEnums | undefined): readonly string[] | undefined;
|
|
252
|
+
/**
|
|
253
|
+
* Does this column map to PowDB's native `json` document type? An enum column
|
|
254
|
+
* of `enums` never does (see {@link powdbEnumLabels}). A Postgres
|
|
238
255
|
* `json`/`jsonb` type (via `dialectType`/`pgType`) is authoritative; otherwise
|
|
239
256
|
* the tsType heuristic (`Record<…>`, `object`, `unknown`, an object/array
|
|
240
257
|
* literal) that the four scalar branches do not claim. Array columns never map
|
|
241
258
|
* to json, a PowDB array only exists INSIDE a json document, so a Postgres
|
|
242
259
|
* array column has no PowDB shape and still throws in {@link powqlColumnType}.
|
|
260
|
+
*
|
|
261
|
+
* `enums` is optional for callers outside Turbine; every call inside the
|
|
262
|
+
* engine passes the schema's map (a source scan in fx-powdb-r2.test.ts
|
|
263
|
+
* checks it).
|
|
243
264
|
*/
|
|
244
|
-
export declare function isJsonColumn(col: ColumnMetadata): boolean;
|
|
265
|
+
export declare function isJsonColumn(col: ColumnMetadata, enums?: PowdbEnums): boolean;
|
|
245
266
|
/**
|
|
246
267
|
* Map a Turbine column to the PowQL DDL type used in `defineSchema` →
|
|
247
268
|
* `type T { … }`. Turbine never emits PowDB's `uuid`/`datetime`/`bytes` types,
|
|
@@ -249,10 +270,20 @@ export declare function isJsonColumn(col: ColumnMetadata): boolean;
|
|
|
249
270
|
* - `Date` → `int` (epoch micros) - `boolean` → `bool`
|
|
250
271
|
* - integral `number`/`bigint` → `int` - fractional `number` → `float`
|
|
251
272
|
* - JSON / object columns → `json` (native PowDB document type, ≥ 0.12)
|
|
273
|
+
* - an enum column of `enums` → `str` (the label text)
|
|
252
274
|
* - everything else (incl. UUID/PK strings) → `str`
|
|
253
275
|
* Array (non-json) and bytes columns throw, they have no PowDB equivalent.
|
|
254
276
|
*/
|
|
255
|
-
export declare function powqlColumnType(col: ColumnMetadata): PowqlType;
|
|
277
|
+
export declare function powqlColumnType(col: ColumnMetadata, enums?: PowdbEnums): PowqlType;
|
|
278
|
+
/**
|
|
279
|
+
* Is this a `numeric` / `decimal` / `money` column that PowDB stores as `str`?
|
|
280
|
+
*
|
|
281
|
+
* A Postgres-sourced decimal surfaces as a JS string (so its digits survive),
|
|
282
|
+
* and PowDB has no decimal type, so the column is DDL'd as PowQL `str`. Every
|
|
283
|
+
* comparison, ordering and aggregate the engine runs on it is then a TEXT
|
|
284
|
+
* operation, which is why the query generator refuses those on such a column.
|
|
285
|
+
*/
|
|
286
|
+
export declare function isPowdbDecimalTextColumn(col: ColumnMetadata, enums?: PowdbEnums): boolean;
|
|
256
287
|
/**
|
|
257
288
|
* Is a column stored as `int` epoch micros but surfaced as a JS `Date`?
|
|
258
289
|
*
|
|
@@ -325,7 +356,7 @@ export declare function quotePowqlDotted(name: string): string;
|
|
|
325
356
|
* Every PowDB value arrives as a string; NULL arrives as the bareword `"null"`.
|
|
326
357
|
* Metadata resolves the `"null"` ambiguity for nullable non-string columns.
|
|
327
358
|
*/
|
|
328
|
-
export declare function coerceValue(raw: string, col: ColumnMetadata): unknown;
|
|
359
|
+
export declare function coerceValue(raw: string, col: ColumnMetadata, enums?: PowdbEnums): unknown;
|
|
329
360
|
/**
|
|
330
361
|
* Coerce a single cell that arrived over the NATIVE typed wire (decoded from a
|
|
331
362
|
* {@link PowdbWireValue}, so already a JS `bigint`/`number`/`boolean`/`string`/
|
|
@@ -354,7 +385,7 @@ export declare function coerceNativeValue(value: unknown, col: ColumnMetadata):
|
|
|
354
385
|
* cells arrive pre-typed and go through {@link coerceNativeValue} (see F3).
|
|
355
386
|
* Callers on the native transport pass `this.pool.capabilities.nativeRaw`.
|
|
356
387
|
*/
|
|
357
|
-
export declare function rowToEntity(raw: Record<string, unknown>, meta: TableMetadata, native?: boolean): Record<string, unknown>;
|
|
388
|
+
export declare function rowToEntity(raw: Record<string, unknown>, meta: TableMetadata, native?: boolean, enums?: PowdbEnums): Record<string, unknown>;
|
|
358
389
|
/**
|
|
359
390
|
* True when `err` is the stale-wire-frame {@link ConnectionError} produced by
|
|
360
391
|
* {@link wrapPowdbError} (its `.cause` is a `protocol_error` PowDBError, or the
|