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
package/dist/cjs/powdb-shared.js
CHANGED
|
@@ -32,8 +32,10 @@ exports.parsePowdbSemver = parsePowdbSemver;
|
|
|
32
32
|
exports.atLeastVersion = atLeastVersion;
|
|
33
33
|
exports.requireCapability = requireCapability;
|
|
34
34
|
exports.baseTsType = baseTsType;
|
|
35
|
+
exports.powdbEnumLabels = powdbEnumLabels;
|
|
35
36
|
exports.isJsonColumn = isJsonColumn;
|
|
36
37
|
exports.powqlColumnType = powqlColumnType;
|
|
38
|
+
exports.isPowdbDecimalTextColumn = isPowdbDecimalTextColumn;
|
|
37
39
|
exports.isDateColumn = isDateColumn;
|
|
38
40
|
exports.isPowdbDatetimeColumn = isPowdbDatetimeColumn;
|
|
39
41
|
exports.quotePowqlIdent = quotePowqlIdent;
|
|
@@ -239,16 +241,42 @@ function isTsSpace(code) {
|
|
|
239
241
|
code === 0xfeff);
|
|
240
242
|
}
|
|
241
243
|
/**
|
|
242
|
-
*
|
|
244
|
+
* The labels of the enum type this column is declared as, or `undefined` when
|
|
245
|
+
* it is not an enum column of `enums`.
|
|
246
|
+
*
|
|
247
|
+
* An enum column carries its TYPE NAME as `dialectType` / `pgType` and a
|
|
248
|
+
* `tsType` that says nothing useful (`unknown` from `defineSchema`, a union of
|
|
249
|
+
* the labels from introspection), so the column's own metadata cannot answer
|
|
250
|
+
* the question: the schema's `enums` map is the only authority. PowDB has no
|
|
251
|
+
* enum type, so such a column is a `str` holding the label text, which is what
|
|
252
|
+
* PostgreSQL stores and returns. Without this the tsType heuristic in
|
|
253
|
+
* {@link isJsonColumn} declared a `defineSchema` enum column as `json`, and
|
|
254
|
+
* writing a label failed as invalid JSON.
|
|
255
|
+
*/
|
|
256
|
+
function powdbEnumLabels(col, enums) {
|
|
257
|
+
if (!enums || col.isArray)
|
|
258
|
+
return undefined;
|
|
259
|
+
const type = col.dialectType ?? col.pgType;
|
|
260
|
+
return type !== undefined && Object.hasOwn(enums, type) ? enums[type] : undefined;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Does this column map to PowDB's native `json` document type? An enum column
|
|
264
|
+
* of `enums` never does (see {@link powdbEnumLabels}). A Postgres
|
|
243
265
|
* `json`/`jsonb` type (via `dialectType`/`pgType`) is authoritative; otherwise
|
|
244
266
|
* the tsType heuristic (`Record<…>`, `object`, `unknown`, an object/array
|
|
245
267
|
* literal) that the four scalar branches do not claim. Array columns never map
|
|
246
268
|
* to json, a PowDB array only exists INSIDE a json document, so a Postgres
|
|
247
269
|
* array column has no PowDB shape and still throws in {@link powqlColumnType}.
|
|
270
|
+
*
|
|
271
|
+
* `enums` is optional for callers outside Turbine; every call inside the
|
|
272
|
+
* engine passes the schema's map (a source scan in fx-powdb-r2.test.ts
|
|
273
|
+
* checks it).
|
|
248
274
|
*/
|
|
249
|
-
function isJsonColumn(col) {
|
|
275
|
+
function isJsonColumn(col, enums) {
|
|
250
276
|
if (col.isArray)
|
|
251
277
|
return false;
|
|
278
|
+
if (powdbEnumLabels(col, enums))
|
|
279
|
+
return false;
|
|
252
280
|
const dbType = (col.dialectType ?? col.pgType ?? '').toLowerCase();
|
|
253
281
|
if (dbType === 'json' || dbType === 'jsonb')
|
|
254
282
|
return true;
|
|
@@ -266,14 +294,17 @@ function isJsonColumn(col) {
|
|
|
266
294
|
* - `Date` → `int` (epoch micros) - `boolean` → `bool`
|
|
267
295
|
* - integral `number`/`bigint` → `int` - fractional `number` → `float`
|
|
268
296
|
* - JSON / object columns → `json` (native PowDB document type, ≥ 0.12)
|
|
297
|
+
* - an enum column of `enums` → `str` (the label text)
|
|
269
298
|
* - everything else (incl. UUID/PK strings) → `str`
|
|
270
299
|
* Array (non-json) and bytes columns throw, they have no PowDB equivalent.
|
|
271
300
|
*/
|
|
272
|
-
function powqlColumnType(col) {
|
|
301
|
+
function powqlColumnType(col, enums) {
|
|
273
302
|
if (col.isArray) {
|
|
274
303
|
throw new errors_js_1.ValidationError(`Column "${col.name}" is an array, PowDB has no array type. Arrays are unsupported on the PowDB backend.`);
|
|
275
304
|
}
|
|
276
|
-
if (
|
|
305
|
+
if (powdbEnumLabels(col, enums))
|
|
306
|
+
return 'str';
|
|
307
|
+
if (isJsonColumn(col, enums))
|
|
277
308
|
return 'json';
|
|
278
309
|
const ts = baseTsType(col.tsType);
|
|
279
310
|
if (ts === 'Date')
|
|
@@ -291,6 +322,23 @@ function powqlColumnType(col) {
|
|
|
291
322
|
}
|
|
292
323
|
return 'str';
|
|
293
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Is this a `numeric` / `decimal` / `money` column that PowDB stores as `str`?
|
|
327
|
+
*
|
|
328
|
+
* A Postgres-sourced decimal surfaces as a JS string (so its digits survive),
|
|
329
|
+
* and PowDB has no decimal type, so the column is DDL'd as PowQL `str`. Every
|
|
330
|
+
* comparison, ordering and aggregate the engine runs on it is then a TEXT
|
|
331
|
+
* operation, which is why the query generator refuses those on such a column.
|
|
332
|
+
*/
|
|
333
|
+
function isPowdbDecimalTextColumn(col, enums) {
|
|
334
|
+
// An enum type's NAME is free text (`money_kind`), so an enum column is
|
|
335
|
+
// answered before the type-name match below can mistake it for a decimal.
|
|
336
|
+
if (powdbEnumLabels(col, enums))
|
|
337
|
+
return false;
|
|
338
|
+
if (col.isArray || isJsonColumn(col, enums) || baseTsType(col.tsType) !== 'string')
|
|
339
|
+
return false;
|
|
340
|
+
return /numeric|decimal|money/.test((col.dialectType ?? col.pgType ?? '').toLowerCase());
|
|
341
|
+
}
|
|
294
342
|
/** Heuristic: does this numeric column hold fractional values (→ PowQL `float`)? */
|
|
295
343
|
function isFloatColumn(col) {
|
|
296
344
|
const t = (col.dialectType ?? col.pgType ?? '').toLowerCase();
|
|
@@ -486,9 +534,12 @@ function quotePowqlDotted(name) {
|
|
|
486
534
|
* Every PowDB value arrives as a string; NULL arrives as the bareword `"null"`.
|
|
487
535
|
* Metadata resolves the `"null"` ambiguity for nullable non-string columns.
|
|
488
536
|
*/
|
|
489
|
-
function coerceValue(raw, col) {
|
|
537
|
+
function coerceValue(raw, col, enums) {
|
|
538
|
+
// An enum column holds its label as text, read as a string column is.
|
|
539
|
+
if (powdbEnumLabels(col, enums))
|
|
540
|
+
return raw === 'null' && col.nullable ? null : raw;
|
|
490
541
|
const ts = baseTsType(col.tsType);
|
|
491
|
-
const json = isJsonColumn(col);
|
|
542
|
+
const json = isJsonColumn(col, enums);
|
|
492
543
|
// NULL bareword: unambiguous for non-string columns; for `str` we cannot tell a
|
|
493
544
|
// literal "null" from SQL NULL, so a nullable str of value "null" reads as null.
|
|
494
545
|
// For a `json` column the bareword `null` (a legacy-wire rendering shared by an
|
|
@@ -571,7 +622,7 @@ function coerceNativeValue(value, col) {
|
|
|
571
622
|
* cells arrive pre-typed and go through {@link coerceNativeValue} (see F3).
|
|
572
623
|
* Callers on the native transport pass `this.pool.capabilities.nativeRaw`.
|
|
573
624
|
*/
|
|
574
|
-
function rowToEntity(raw, meta, native = false) {
|
|
625
|
+
function rowToEntity(raw, meta, native = false, enums) {
|
|
575
626
|
const byName = new Map(meta.columns.map((c) => [c.name, c]));
|
|
576
627
|
const out = {};
|
|
577
628
|
for (const snake of Object.keys(raw)) {
|
|
@@ -584,8 +635,16 @@ function rowToEntity(raw, meta, native = false) {
|
|
|
584
635
|
else if (native) {
|
|
585
636
|
out[field] = coerceNativeValue(value, col);
|
|
586
637
|
}
|
|
638
|
+
else if (typeof value === 'string') {
|
|
639
|
+
out[field] = coerceValue(value, col, enums);
|
|
640
|
+
}
|
|
641
|
+
else if ((typeof value === 'number' || typeof value === 'bigint') && isDateColumn(col)) {
|
|
642
|
+
// A Date column's micros as a number cell: the Date it stores, as on the
|
|
643
|
+
// other wires, never the raw count (which a filter would then refuse).
|
|
644
|
+
out[field] = new Date(Number(value) / 1000);
|
|
645
|
+
}
|
|
587
646
|
else {
|
|
588
|
-
out[field] =
|
|
647
|
+
out[field] = value;
|
|
589
648
|
}
|
|
590
649
|
}
|
|
591
650
|
return out;
|
package/dist/cjs/powdb.d.ts
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
import { type PgCompatPool, type PgCompatPoolClient, TurbineClient, type TurbineConfig } from './client.js';
|
|
56
56
|
import { type Dialect } from './dialect.js';
|
|
57
57
|
import type { EngineClientConfig } from './engine-config.js';
|
|
58
|
+
import { type TurbineLogger } from './logger.js';
|
|
58
59
|
import type { PowdbExec } from './powdb-introspect.js';
|
|
59
60
|
import { type PowdbCapabilities } from './powdb-shared.js';
|
|
60
61
|
import { type SchemaMetadata } from './schema.js';
|
|
@@ -261,6 +262,8 @@ export declare function capabilitiesFromVersion(version: string | undefined | nu
|
|
|
261
262
|
*/
|
|
262
263
|
export interface PowqlSchemaDDLOptions {
|
|
263
264
|
capabilities?: PowdbCapabilities;
|
|
265
|
+
/** Where a skipped-link warning goes. Defaults to the console logger. */
|
|
266
|
+
logger?: TurbineLogger;
|
|
264
267
|
/**
|
|
265
268
|
* Emit `link Owner.name -> Target on local = target` declarations (PowDB entity
|
|
266
269
|
* links, >= 0.19) for every single-column hasMany / hasOne / belongsTo relation
|
|
@@ -340,6 +343,7 @@ export declare function powqlSchemaDDL(schema: SchemaMetadata, opts?: PowqlSchem
|
|
|
340
343
|
*/
|
|
341
344
|
export declare function applyPowdbLinks(exec: PowdbExec, schema: SchemaMetadata, options?: {
|
|
342
345
|
capabilities?: PowdbCapabilities;
|
|
346
|
+
logger?: TurbineLogger;
|
|
343
347
|
}): Promise<string[]>;
|
|
344
348
|
/**
|
|
345
349
|
* Translate a PowDB error into a typed Turbine error. Handles BOTH transports,
|
package/dist/cjs/powdb.js
CHANGED
|
@@ -106,6 +106,7 @@ const node_async_hooks_1 = require("node:async_hooks");
|
|
|
106
106
|
const client_js_1 = require("./client.js");
|
|
107
107
|
const dialect_js_1 = require("./dialect.js");
|
|
108
108
|
const errors_js_1 = require("./errors.js");
|
|
109
|
+
const logger_js_1 = require("./logger.js");
|
|
109
110
|
const optional_peer_import_cjs_1 = __importDefault(require("./optional-peer-import.cjs"));
|
|
110
111
|
const powdb_shared_js_1 = require("./powdb-shared.js");
|
|
111
112
|
const warn_registry_js_1 = require("./query/warn-registry.js");
|
|
@@ -155,6 +156,48 @@ Object.defineProperty(exports, "rowToEntity", { enumerable: true, get: function
|
|
|
155
156
|
exports.powdbDialect = {
|
|
156
157
|
...dialect_js_1.postgresDialect,
|
|
157
158
|
name: 'powdb',
|
|
159
|
+
// PowqlInterface compiles PowQL itself and refuses what PowDB lacks; these
|
|
160
|
+
// answer for the client paths a PowDB client shares (transactions, raw
|
|
161
|
+
// queries, `tx.$connection()`) and keep every SQL-only feature off.
|
|
162
|
+
capabilities: Object.freeze({
|
|
163
|
+
distinctOn: false,
|
|
164
|
+
positionalJson: false,
|
|
165
|
+
nullsOrderingClause: false,
|
|
166
|
+
nullsSortHigh: false,
|
|
167
|
+
insensitiveInList: false,
|
|
168
|
+
jsonDocumentEquality: 'text',
|
|
169
|
+
jsonExtractTyped: false,
|
|
170
|
+
jsonExactNumericCast: false,
|
|
171
|
+
numericTextComparison: false,
|
|
172
|
+
// PowDB has no foreign keys: declared relations are not enforced, and its
|
|
173
|
+
// own mass-mutation guard already folds with foreignKeys: false.
|
|
174
|
+
enforcesForeignKeys: false,
|
|
175
|
+
partitionLimitPushdown: false,
|
|
176
|
+
utcTimestampRewrite: false,
|
|
177
|
+
paramTypeCasts: false,
|
|
178
|
+
namedEnumTypes: false,
|
|
179
|
+
structuredValueColumns: 'scalars',
|
|
180
|
+
maxBindParameters: Number.POSITIVE_INFINITY,
|
|
181
|
+
maxInsertRows: Number.POSITIVE_INFINITY,
|
|
182
|
+
upsertConflictTarget: 'explicit',
|
|
183
|
+
setClauseOrder: 'snapshot',
|
|
184
|
+
reselectLocksRows: false,
|
|
185
|
+
integerDivision: '/',
|
|
186
|
+
updateExpressions: false,
|
|
187
|
+
bulkUpsertAppliesRepeatedKeys: false,
|
|
188
|
+
readOnlyTransactions: false,
|
|
189
|
+
connectionParameters: false,
|
|
190
|
+
backendCancel: false,
|
|
191
|
+
idleTransactionTimeout: false,
|
|
192
|
+
abortsTransactionOnError: false,
|
|
193
|
+
connectionDriver: 'none',
|
|
194
|
+
preparesEveryStatement: false,
|
|
195
|
+
statementSyntax: null,
|
|
196
|
+
// No foreign keys to declare, inline or otherwise; PowQL DDL comes from
|
|
197
|
+
// powqlSchemaDDL, which never reads this.
|
|
198
|
+
inlineForeignKeys: false,
|
|
199
|
+
unboundedTextKeys: true,
|
|
200
|
+
}),
|
|
158
201
|
// `resultStrategy` is decorative for PowDB, PowqlInterface owns its own write
|
|
159
202
|
// path and never reads it. Set to 'returning' for honesty: writes use PowDB
|
|
160
203
|
// 0.7.0's trailing `returning` keyword (upsert excepted, see PowqlInterface).
|
|
@@ -172,6 +215,11 @@ exports.powdbDialect = {
|
|
|
172
215
|
// earlier, this override keeps the flag truthful if a future path consults it.
|
|
173
216
|
supportsLateralJoin: false,
|
|
174
217
|
supportsPlanCacheMode: false,
|
|
218
|
+
// PowqlInterface reads none of these (it refuses each feature itself); they
|
|
219
|
+
// are set so the flags stay truthful if a shared path consults them.
|
|
220
|
+
rowLockModes: [],
|
|
221
|
+
supportsPercentileAggregates: false,
|
|
222
|
+
supportsBulkUpsert: false,
|
|
175
223
|
beginStatement: () => 'begin',
|
|
176
224
|
commitStatement: () => 'commit',
|
|
177
225
|
rollbackStatement: () => 'rollback',
|
|
@@ -388,7 +436,7 @@ function powqlSchemaDDL(schema, opts = {}) {
|
|
|
388
436
|
new Set(idx.columns).size === pkSet.size &&
|
|
389
437
|
idx.columns.every((c) => pkSet.has(c));
|
|
390
438
|
const fields = meta.columns.map((col) => {
|
|
391
|
-
const powqlType = (0, powdb_shared_js_1.powqlColumnType)(col);
|
|
439
|
+
const powqlType = (0, powdb_shared_js_1.powqlColumnType)(col, schema.enums);
|
|
392
440
|
// Gate `json` columns behind the engine's jsonDocs capability when a
|
|
393
441
|
// caller supplied one, an old engine has no `json` type and would reject
|
|
394
442
|
// the DDL. Pure-function callers (no opts) emit unconditionally.
|
|
@@ -473,8 +521,8 @@ function powqlSchemaDDL(schema, opts = {}) {
|
|
|
473
521
|
(0, powdb_shared_js_1.requireCapability)(caps, 'entityLinks', 'entity link DDL (`emitLinks`)');
|
|
474
522
|
const links = deriveDesiredLinks(schema, (owner, name) => {
|
|
475
523
|
if ((0, warn_registry_js_1.shouldWarnOnce)(warn_registry_js_1.WARN_NS.powdbLinks, `collide:${owner}.${name}`)) {
|
|
476
|
-
|
|
477
|
-
'same name; skipping its link declaration (PowDB hard-errors on a link that shadows a column).');
|
|
524
|
+
(0, logger_js_1.logTo)(opts.logger ?? logger_js_1.consoleLogger, 'warn', `powqlSchemaDDL(emitLinks): relation "${name}" on "${owner}" collides with a column of the ` +
|
|
525
|
+
'same name; skipping its link declaration (PowDB hard-errors on a link that shadows a column).', { code: 'powdb-link-collision', table: owner, relation: name, operation: 'powqlSchemaDDL' });
|
|
478
526
|
}
|
|
479
527
|
});
|
|
480
528
|
for (const link of links)
|
|
@@ -502,6 +550,7 @@ function powqlSchemaDDL(schema, opts = {}) {
|
|
|
502
550
|
*/
|
|
503
551
|
async function applyPowdbLinks(exec, schema, options = {}) {
|
|
504
552
|
const caps = options.capabilities;
|
|
553
|
+
const logger = options.logger ?? logger_js_1.consoleLogger;
|
|
505
554
|
if (caps) {
|
|
506
555
|
(0, powdb_shared_js_1.requireCapability)(caps, 'entityLinks', 'entity link DDL (`applyPowdbLinks`)');
|
|
507
556
|
(0, powdb_shared_js_1.requireCapability)(caps, 'linkIntrospection', 'PowDB `schema links` introspection');
|
|
@@ -510,8 +559,8 @@ async function applyPowdbLinks(exec, schema, options = {}) {
|
|
|
510
559
|
const byOwnerName = new Map(existing.map((l) => [`${l.owner}\u0000${l.name}`, l]));
|
|
511
560
|
const desired = deriveDesiredLinks(schema, (owner, name) => {
|
|
512
561
|
if ((0, warn_registry_js_1.shouldWarnOnce)(warn_registry_js_1.WARN_NS.powdbLinks, `collide:${owner}.${name}`)) {
|
|
513
|
-
|
|
514
|
-
'skipping its link (PowDB hard-errors on a link that shadows a column).');
|
|
562
|
+
(0, logger_js_1.logTo)(logger, 'warn', `applyPowdbLinks: relation "${name}" on "${owner}" collides with a column of the same name; ` +
|
|
563
|
+
'skipping its link (PowDB hard-errors on a link that shadows a column).', { code: 'powdb-link-collision', table: owner, relation: name, operation: 'applyPowdbLinks' });
|
|
515
564
|
}
|
|
516
565
|
});
|
|
517
566
|
const executed = [];
|
|
@@ -520,9 +569,9 @@ async function applyPowdbLinks(exec, schema, options = {}) {
|
|
|
520
569
|
if (found) {
|
|
521
570
|
const same = found.target === link.target && found.localKey === link.localKey && found.targetKey === link.targetKey;
|
|
522
571
|
if (!same && (0, warn_registry_js_1.shouldWarnOnce)(warn_registry_js_1.WARN_NS.powdbLinks, `drift:${link.owner}.${link.name}`)) {
|
|
523
|
-
|
|
572
|
+
(0, logger_js_1.logTo)(logger, 'warn', `applyPowdbLinks: link "${link.name}" on "${link.owner}" is already declared with different ` +
|
|
524
573
|
`endpoints (have ${found.target} on ${found.localKey} = ${found.targetKey}, want ${link.target} on ` +
|
|
525
|
-
`${link.localKey} = ${link.targetKey}); leaving it untouched (PowDB has no drop-link DDL)
|
|
574
|
+
`${link.localKey} = ${link.targetKey}); leaving it untouched (PowDB has no drop-link DDL).`, { code: 'powdb-link-drift', table: link.owner, relation: link.name, operation: 'applyPowdbLinks' });
|
|
526
575
|
}
|
|
527
576
|
continue; // identical → idempotent skip; drift → warned skip
|
|
528
577
|
}
|
|
@@ -768,7 +817,9 @@ function wrapPowdbError(err) {
|
|
|
768
817
|
// evaluate true for every row. Runs before the generic `type mismatch` regex
|
|
769
818
|
// below so the column name and the fix survive into the message.
|
|
770
819
|
{
|
|
771
|
-
|
|
820
|
+
// Every group is bounded: `[^,]+` retried from each "expected " in a long
|
|
821
|
+
// message made this quadratic in the message length.
|
|
822
|
+
const m = /type mismatch for column '([^']{1,256})': expected ([^,]{1,64}), got (\w{1,32})/i.exec(msg);
|
|
772
823
|
if (m) {
|
|
773
824
|
return new errors_js_1.ValidationError(`PowDB rejected a comparison on column "${m[1]}": the column is ${m[2]} but the bound value is ` +
|
|
774
825
|
`${m[3]}. PowQL never coerces across types in a comparison (before engine 0.20 this silently matched ` +
|
|
@@ -905,6 +956,19 @@ function reentrantTransactionError() {
|
|
|
905
956
|
'on the write lock the open transaction holds. Use the `tx` client the callback receives, or start the ' +
|
|
906
957
|
'second transaction after the first completes. (Independent concurrent transactions queue automatically.)');
|
|
907
958
|
}
|
|
959
|
+
/**
|
|
960
|
+
* The error for a plain statement issued through the CLIENT (not the `tx`
|
|
961
|
+
* client) from inside that client's own open transaction callback, on the
|
|
962
|
+
* embedded engine. Its one handle carries one transaction, so the statement
|
|
963
|
+
* could only run inside the transaction (and be rolled back with it) or wait
|
|
964
|
+
* for the transaction to finish, which is itself waiting on this statement.
|
|
965
|
+
*/
|
|
966
|
+
function statementInsideTransactionError() {
|
|
967
|
+
return new errors_js_1.UnsupportedFeatureError('A statement on the client while its own transaction is open', 'powdb', 'This call was made through the client, not the `tx` client, from inside an open $transaction callback. The ' +
|
|
968
|
+
'embedded engine has one handle and one transaction, so the call would either join that transaction (and be ' +
|
|
969
|
+
'rolled back with it) or wait for it forever. Use the `tx` client the callback receives, or make the call ' +
|
|
970
|
+
'after the transaction completes.');
|
|
971
|
+
}
|
|
908
972
|
// ---------------------------------------------------------------------------
|
|
909
973
|
// Single-writer transaction gate, FIFO queueing + re-entrancy detection
|
|
910
974
|
// ---------------------------------------------------------------------------
|
|
@@ -975,9 +1039,15 @@ class PowdbTxGate {
|
|
|
975
1039
|
queueTimeoutMs;
|
|
976
1040
|
/** Tail of the FIFO queue, resolves once every earlier transaction has finished. */
|
|
977
1041
|
tail = Promise.resolve();
|
|
1042
|
+
/** Holds taken and not yet finished, queued ones included. */
|
|
1043
|
+
outstanding = 0;
|
|
978
1044
|
constructor(queueTimeoutMs) {
|
|
979
1045
|
this.queueTimeoutMs = queueTimeoutMs;
|
|
980
1046
|
}
|
|
1047
|
+
/** True while any transaction holds the gate or waits for it. */
|
|
1048
|
+
get busy() {
|
|
1049
|
+
return this.outstanding > 0;
|
|
1050
|
+
}
|
|
981
1051
|
/**
|
|
982
1052
|
* Take a place in the transaction queue. The prologue walks the caller's
|
|
983
1053
|
* marker chain (planted around transaction callbacks by the pool's
|
|
@@ -986,7 +1056,7 @@ class PowdbTxGate {
|
|
|
986
1056
|
* the returned hold carries the fresh marker (`hold.ctx`) for
|
|
987
1057
|
* `wrapTransactionCallback` to scope around the user callback.
|
|
988
1058
|
*/
|
|
989
|
-
async acquire() {
|
|
1059
|
+
async acquire(reentrantError = reentrantTransactionError) {
|
|
990
1060
|
// Walk the WHOLE marker chain, not just the innermost marker: with two
|
|
991
1061
|
// pools, dbA-tx → dbB-tx → dbA-begin leaves dbB's marker innermost, but
|
|
992
1062
|
// the dbA ancestor is still open, queueing the inner dbA begin behind it
|
|
@@ -999,7 +1069,7 @@ class PowdbTxGate {
|
|
|
999
1069
|
parent = parent.parent;
|
|
1000
1070
|
for (let c = parent; c !== undefined; c = c.parent) {
|
|
1001
1071
|
if (c.gate === this && !c.done) {
|
|
1002
|
-
throw
|
|
1072
|
+
throw reentrantError();
|
|
1003
1073
|
}
|
|
1004
1074
|
}
|
|
1005
1075
|
const ctx = { gate: this, done: false, parent };
|
|
@@ -1009,12 +1079,14 @@ class PowdbTxGate {
|
|
|
1009
1079
|
});
|
|
1010
1080
|
const ahead = this.tail;
|
|
1011
1081
|
this.tail = ahead.then(() => finished);
|
|
1082
|
+
this.outstanding++;
|
|
1012
1083
|
const hold = {
|
|
1013
1084
|
ctx,
|
|
1014
1085
|
finish: () => {
|
|
1015
1086
|
if (ctx.done)
|
|
1016
1087
|
return;
|
|
1017
1088
|
ctx.done = true;
|
|
1089
|
+
this.outstanding--;
|
|
1018
1090
|
handOff();
|
|
1019
1091
|
},
|
|
1020
1092
|
};
|
|
@@ -1673,6 +1745,30 @@ class PowdbEmbeddedPool {
|
|
|
1673
1745
|
throw new errors_js_1.ConnectionError('The PowDB embedded pool is closed: disconnect() was already called on this client.');
|
|
1674
1746
|
}
|
|
1675
1747
|
}
|
|
1748
|
+
if (ctl === null && holdRef.hold === null && this.txGate.busy) {
|
|
1749
|
+
// A statement from OUTSIDE the open transaction. The engine is one
|
|
1750
|
+
// handle, so running it now would put it inside that transaction: it
|
|
1751
|
+
// would read uncommitted rows, and a write would be rolled back with the
|
|
1752
|
+
// transaction after being reported as done. It takes its FIFO turn on the
|
|
1753
|
+
// gate instead, as a one-statement transaction of its own would. From
|
|
1754
|
+
// inside the transaction's own callback that wait could never end, so the
|
|
1755
|
+
// gate refuses it there.
|
|
1756
|
+
const hold = await this.txGate.acquire(statementInsideTransactionError);
|
|
1757
|
+
try {
|
|
1758
|
+
if (this.closed) {
|
|
1759
|
+
throw new errors_js_1.ConnectionError('The PowDB embedded pool is closed: disconnect() was already called on this client.');
|
|
1760
|
+
}
|
|
1761
|
+
try {
|
|
1762
|
+
return this.exec(powql, params);
|
|
1763
|
+
}
|
|
1764
|
+
catch (err) {
|
|
1765
|
+
throw wrapPowdbError(err);
|
|
1766
|
+
}
|
|
1767
|
+
}
|
|
1768
|
+
finally {
|
|
1769
|
+
hold.finish();
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1676
1772
|
if ((ctl === 'commit' || ctl === 'rollback') && holdRef.hold === null) {
|
|
1677
1773
|
// This context never acquired the gate, its `begin` never ran (the
|
|
1678
1774
|
// gate timed out / threw re-entrant E017, or no begin was issued at
|
|
@@ -1867,25 +1963,52 @@ async function openEmbeddedPool(target, poolOptions = {}, assumeEngineVersion, i
|
|
|
1867
1963
|
throw err;
|
|
1868
1964
|
throw new errors_js_1.ConnectionError(`PowDB embedded could not open data dir "${dir}": ${err.message}`);
|
|
1869
1965
|
}
|
|
1870
|
-
|
|
1871
|
-
if (
|
|
1872
|
-
|
|
1966
|
+
try {
|
|
1967
|
+
if (syncMode !== undefined) {
|
|
1968
|
+
if (typeof db.setSyncMode !== 'function') {
|
|
1969
|
+
throw new errors_js_1.ConnectionError('embedded `syncMode` requires @zvndev/powdb-embedded ≥ 0.7.1 (the installed addon has no setSyncMode).');
|
|
1970
|
+
}
|
|
1971
|
+
db.setSyncMode(syncMode);
|
|
1972
|
+
}
|
|
1973
|
+
// Native typed wire is feature-detected on the OPENED handle: an addon ≥ 0.14
|
|
1974
|
+
// exposes `queryWithParams`, so nativeRaw turns on (server-gate ≥ 0.13 still
|
|
1975
|
+
// applies via the version); an older addon has no such method → false.
|
|
1976
|
+
const capabilities = capabilitiesFromVersion(assumeEngineVersion ?? resolveEmbeddedVersion(), {
|
|
1977
|
+
hasNativeRaw: typeof db.queryWithParams === 'function',
|
|
1978
|
+
});
|
|
1979
|
+
// A read-only target forces the pool's readonly flag; otherwise honor whatever
|
|
1980
|
+
// `poolOptions` (threaded from `options.readonly`) carried.
|
|
1981
|
+
return new PowdbEmbeddedPool(db, {
|
|
1982
|
+
...poolOptions,
|
|
1983
|
+
capabilities,
|
|
1984
|
+
readonly: Boolean(readonly) || Boolean(poolOptions.readonly),
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
catch (err) {
|
|
1988
|
+
// The caller never receives this handle, so nothing else can close it.
|
|
1989
|
+
try {
|
|
1990
|
+
db.close?.();
|
|
1991
|
+
}
|
|
1992
|
+
catch {
|
|
1993
|
+
// The failure being reported is the useful one.
|
|
1873
1994
|
}
|
|
1874
|
-
|
|
1995
|
+
throw err;
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
/**
|
|
1999
|
+
* Probe a networked pool Turbine just built and wrap it. The pool is closed
|
|
2000
|
+
* when the probe or the wrapper refuses, because the caller never sees it
|
|
2001
|
+
* and its idle sockets would otherwise keep the process alive.
|
|
2002
|
+
*/
|
|
2003
|
+
async function wrapOwnedClientPool(clientPool, poolOptions, assumeEngineVersion) {
|
|
2004
|
+
try {
|
|
2005
|
+
const capabilities = await assertNetworkedVersion(clientPool, assumeEngineVersion);
|
|
2006
|
+
return new PowdbPool(clientPool, undefined, { ...poolOptions, capabilities });
|
|
2007
|
+
}
|
|
2008
|
+
catch (err) {
|
|
2009
|
+
await clientPool.close().catch(() => { });
|
|
2010
|
+
throw err;
|
|
1875
2011
|
}
|
|
1876
|
-
// Native typed wire is feature-detected on the OPENED handle: an addon ≥ 0.14
|
|
1877
|
-
// exposes `queryWithParams`, so nativeRaw turns on (server-gate ≥ 0.13 still
|
|
1878
|
-
// applies via the version); an older addon has no such method → false.
|
|
1879
|
-
const capabilities = capabilitiesFromVersion(assumeEngineVersion ?? resolveEmbeddedVersion(), {
|
|
1880
|
-
hasNativeRaw: typeof db.queryWithParams === 'function',
|
|
1881
|
-
});
|
|
1882
|
-
// A read-only target forces the pool's readonly flag; otherwise honor whatever
|
|
1883
|
-
// `poolOptions` (threaded from `options.readonly`) carried.
|
|
1884
|
-
return new PowdbEmbeddedPool(db, {
|
|
1885
|
-
...poolOptions,
|
|
1886
|
-
capabilities,
|
|
1887
|
-
readonly: Boolean(readonly) || Boolean(poolOptions.readonly),
|
|
1888
|
-
});
|
|
1889
2012
|
}
|
|
1890
2013
|
/**
|
|
1891
2014
|
* Bind Turbine to PowDB. `target` is one of:
|
|
@@ -1916,9 +2039,7 @@ async function turbinePowDB(target, schema, options = {}) {
|
|
|
1916
2039
|
const max = options.connectionLimit ?? 10;
|
|
1917
2040
|
if (typeof target === 'string') {
|
|
1918
2041
|
const mod = options.powdbClientModule ?? (await loadPowdb());
|
|
1919
|
-
|
|
1920
|
-
const capabilities = await assertNetworkedVersion(clientPool, options.assumeEngineVersion);
|
|
1921
|
-
pool = new PowdbPool(clientPool, undefined, { ...poolOptions, capabilities });
|
|
2042
|
+
pool = await wrapOwnedClientPool(new mod.Pool({ ...parsePowdbUrl(target), max }), poolOptions, options.assumeEngineVersion);
|
|
1922
2043
|
owns = true;
|
|
1923
2044
|
}
|
|
1924
2045
|
else if (target instanceof PowdbPool) {
|
|
@@ -1938,26 +2059,36 @@ async function turbinePowDB(target, schema, options = {}) {
|
|
|
1938
2059
|
}
|
|
1939
2060
|
else {
|
|
1940
2061
|
const mod = options.powdbClientModule ?? (await loadPowdb());
|
|
1941
|
-
|
|
1942
|
-
const capabilities = await assertNetworkedVersion(clientPool, options.assumeEngineVersion);
|
|
1943
|
-
pool = new PowdbPool(clientPool, undefined, { ...poolOptions, capabilities });
|
|
2062
|
+
pool = await wrapOwnedClientPool(new mod.Pool({ ...target, max }), poolOptions, options.assumeEngineVersion);
|
|
1944
2063
|
owns = true;
|
|
1945
2064
|
}
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
...clientConfig
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2065
|
+
let client;
|
|
2066
|
+
try {
|
|
2067
|
+
// The PowQL generator is loaded here to keep client.ts free of any PowDB import.
|
|
2068
|
+
const { PowqlInterface } = await Promise.resolve().then(() => __importStar(require('./powql.js')));
|
|
2069
|
+
const queryInterfaceFactory = (p, table, sch, middlewares, opts) => new PowqlInterface(p, table, sch, middlewares, opts);
|
|
2070
|
+
// Forward every client-level option EXCEPT the ones this factory owns (they
|
|
2071
|
+
// configure the pool / transport above, and TurbineClient warns on a config
|
|
2072
|
+
// key it does not recognize). Destructured rather than hand-listed on the way
|
|
2073
|
+
// IN: an allowlist is how `globalFilters` came to be accepted and ignored.
|
|
2074
|
+
const { connectionLimit: _connectionLimit, transactionQueueTimeoutMs: _transactionQueueTimeoutMs, retryStaleReads: _retryStaleReads, assumeEngineVersion: _assumeEngineVersion, readonly: _readonly, powdbClientModule: _powdbClientModule, powdbEmbeddedModule: _powdbEmbeddedModule, ...clientConfig } = options;
|
|
2075
|
+
client = new client_js_1.TurbineClient({
|
|
2076
|
+
...clientConfig,
|
|
2077
|
+
pool,
|
|
2078
|
+
preparedStatements: false,
|
|
2079
|
+
dialect: exports.powdbDialect,
|
|
2080
|
+
queryInterfaceFactory,
|
|
2081
|
+
}, schema);
|
|
2082
|
+
}
|
|
2083
|
+
catch (err) {
|
|
2084
|
+
// A failed factory hands the caller nothing to close, so a pool or embedded
|
|
2085
|
+
// handle it BUILT is closed here (the client constructor refuses a bad
|
|
2086
|
+
// config, a static global filter naming no table for one). A pool the
|
|
2087
|
+
// caller supplied is the caller's and stays open.
|
|
2088
|
+
if (owns)
|
|
2089
|
+
await pool.end().catch(() => { });
|
|
2090
|
+
throw err;
|
|
2091
|
+
}
|
|
1961
2092
|
if (owns) {
|
|
1962
2093
|
// Turbine built this pool / embedded handle, so disconnect()/end() must
|
|
1963
2094
|
// close it. client.ts sees TurbineConfig.pool as EXTERNAL (ownsPool =
|
|
@@ -1966,9 +2097,10 @@ async function turbinePowDB(target, schema, options = {}) {
|
|
|
1966
2097
|
// open until powdb-server's idle timeout (~300s) closed them. Consistent
|
|
1967
2098
|
// with turbineMssql's owned-pool patch.
|
|
1968
2099
|
const baseDisconnect = client.disconnect.bind(client);
|
|
1969
|
-
const close = async () => {
|
|
1970
|
-
await baseDisconnect();
|
|
2100
|
+
const close = async (options) => {
|
|
2101
|
+
const result = options === undefined ? await baseDisconnect() : await baseDisconnect(options);
|
|
1971
2102
|
await pool.end();
|
|
2103
|
+
return result ?? undefined;
|
|
1972
2104
|
};
|
|
1973
2105
|
const patch = client;
|
|
1974
2106
|
patch.disconnect = close;
|
|
@@ -1976,7 +2108,7 @@ async function turbinePowDB(target, schema, options = {}) {
|
|
|
1976
2108
|
}
|
|
1977
2109
|
else {
|
|
1978
2110
|
// Injected pool, the caller owns its lifecycle.
|
|
1979
|
-
client.disconnect = async () => { };
|
|
2111
|
+
client.disconnect = async (options) => (options === undefined ? undefined : { timedOut: false, forcedConnections: 0 });
|
|
1980
2112
|
}
|
|
1981
2113
|
return client;
|
|
1982
2114
|
}
|