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/dialect.js
CHANGED
|
@@ -6,47 +6,107 @@
|
|
|
6
6
|
* PostgreSQL-native by default, but query generation now depends on this
|
|
7
7
|
* contract for the SQL primitives that vary across MySQL and SQLite.
|
|
8
8
|
*/
|
|
9
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
-
}
|
|
15
|
-
Object.defineProperty(o, k2, desc);
|
|
16
|
-
}) : (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
o[k2] = m[k];
|
|
19
|
-
}));
|
|
20
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
-
}) : function(o, v) {
|
|
23
|
-
o["default"] = v;
|
|
24
|
-
});
|
|
25
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
-
var ownKeys = function(o) {
|
|
27
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
-
var ar = [];
|
|
29
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
-
return ar;
|
|
31
|
-
};
|
|
32
|
-
return ownKeys(o);
|
|
33
|
-
};
|
|
34
|
-
return function (mod) {
|
|
35
|
-
if (mod && mod.__esModule) return mod;
|
|
36
|
-
var result = {};
|
|
37
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
-
__setModuleDefault(result, mod);
|
|
39
|
-
return result;
|
|
40
|
-
};
|
|
41
|
-
})();
|
|
42
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
10
|
exports.postgresDialect = void 0;
|
|
11
|
+
exports.maxBindParameters = maxBindParameters;
|
|
12
|
+
exports.onConflictAction = onConflictAction;
|
|
44
13
|
const errors_js_1 = require("./errors.js");
|
|
45
14
|
const utils_js_1 = require("./query/utils.js");
|
|
46
15
|
const schema_js_1 = require("./schema.js");
|
|
16
|
+
/** The bind-parameter limit for one statement on this dialect, or `undefined` when it has none. */
|
|
17
|
+
function maxBindParameters(dialect) {
|
|
18
|
+
const limit = dialect.capabilities.maxBindParameters;
|
|
19
|
+
return Number.isFinite(limit) ? limit : undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* PostgreSQL's multi-row `INSERT INTO t (cols) ...` with no conflict clause and
|
|
23
|
+
* no RETURNING: the shared body of `createMany` and its `onConflict` form.
|
|
24
|
+
*
|
|
25
|
+
* The default is `SELECT * FROM UNNEST($1::text[], ...)`, one bound array per
|
|
26
|
+
* COLUMN. The row-major form (`requireRowValues`) is required when a target
|
|
27
|
+
* column is itself array-typed, because the UNNEST transpose flattens nested
|
|
28
|
+
* arrays: one placeholder per cell instead of per column.
|
|
29
|
+
*/
|
|
30
|
+
function pgBulkInsertBody(dialect, input) {
|
|
31
|
+
if (!input.columnArrayTypes || input.columnArrayTypes.length !== input.columns.length) {
|
|
32
|
+
throw new errors_js_1.ValidationError(`createMany bulk insert into "${input.table}": columnArrayTypes must supply one UNNEST cast ` +
|
|
33
|
+
`per column, got ${input.columnArrayTypes?.length ?? 0} for ${input.columns.length} columns ` +
|
|
34
|
+
`(${input.columns.join(', ')}). Schema metadata is missing a pgType for at least one column; ` +
|
|
35
|
+
'regenerate it with `npx turbine generate`.');
|
|
36
|
+
}
|
|
37
|
+
if (input.requireRowValues) {
|
|
38
|
+
const params = [];
|
|
39
|
+
const tuples = input.rowValues.map((row) => {
|
|
40
|
+
const cells = input.columns.map((_, i) => {
|
|
41
|
+
params.push(row[i]);
|
|
42
|
+
// No cast: PostgreSQL infers each parameter's type from the INSERT
|
|
43
|
+
// target column, which is what single-row `create` already relies on
|
|
44
|
+
// and is what makes arrays and enums both work here. The casts in
|
|
45
|
+
// `columnArrayTypes` are ARRAY-OF-column-type, correct for the
|
|
46
|
+
// UNNEST transpose but wrong for an individual cell.
|
|
47
|
+
return dialect.paramPlaceholder(params.length);
|
|
48
|
+
});
|
|
49
|
+
return `(${cells.join(', ')})`;
|
|
50
|
+
});
|
|
51
|
+
return { sql: `INSERT INTO ${input.table} (${input.columns.join(', ')}) VALUES ${tuples.join(', ')}`, params };
|
|
52
|
+
}
|
|
53
|
+
const columnArrays = input.columns.map((_, columnIndex) => input.rowValues.map((row) => row[columnIndex]));
|
|
54
|
+
const unnestArgs = input.columns.map((_, i) => `${dialect.paramPlaceholder(i + 1)}::${input.columnArrayTypes[i]}`);
|
|
55
|
+
return {
|
|
56
|
+
sql: `INSERT INTO ${input.table} (${input.columns.join(', ')}) SELECT * FROM UNNEST(${unnestArgs.join(', ')})`,
|
|
57
|
+
params: columnArrays,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* `DO NOTHING`, or `DO UPDATE SET ... [WHERE ...]`: the action of an
|
|
62
|
+
* `ON CONFLICT (target)` clause, shared by PostgreSQL and SQLite, whose
|
|
63
|
+
* grammars agree here. The update compiles after the row values are bound.
|
|
64
|
+
*/
|
|
65
|
+
function onConflictAction(input, params, refs) {
|
|
66
|
+
if (!input.update)
|
|
67
|
+
return 'DO NOTHING';
|
|
68
|
+
const update = input.update(params, refs);
|
|
69
|
+
return `DO UPDATE SET ${update.setClauses.join(', ')}${update.where ? ` WHERE ${update.where}` : ''}`;
|
|
70
|
+
}
|
|
47
71
|
/** PostgreSQL implementation of the dialect contract. */
|
|
48
72
|
exports.postgresDialect = {
|
|
49
73
|
name: 'postgresql',
|
|
74
|
+
capabilities: Object.freeze({
|
|
75
|
+
distinctOn: true,
|
|
76
|
+
positionalJson: true,
|
|
77
|
+
nullsOrderingClause: true,
|
|
78
|
+
nullsSortHigh: true,
|
|
79
|
+
insensitiveInList: true,
|
|
80
|
+
jsonDocumentEquality: 'jsonb',
|
|
81
|
+
jsonExtractTyped: false,
|
|
82
|
+
jsonExactNumericCast: true,
|
|
83
|
+
numericTextComparison: false,
|
|
84
|
+
enforcesForeignKeys: true,
|
|
85
|
+
partitionLimitPushdown: true,
|
|
86
|
+
utcTimestampRewrite: true,
|
|
87
|
+
paramTypeCasts: true,
|
|
88
|
+
namedEnumTypes: true,
|
|
89
|
+
structuredValueColumns: 'pg-scalars',
|
|
90
|
+
// Counted in a 16-bit field.
|
|
91
|
+
maxBindParameters: 65535,
|
|
92
|
+
maxInsertRows: Number.POSITIVE_INFINITY,
|
|
93
|
+
upsertConflictTarget: 'explicit',
|
|
94
|
+
setClauseOrder: 'snapshot',
|
|
95
|
+
reselectLocksRows: false,
|
|
96
|
+
integerDivision: '/',
|
|
97
|
+
updateExpressions: true,
|
|
98
|
+
bulkUpsertAppliesRepeatedKeys: false,
|
|
99
|
+
readOnlyTransactions: true,
|
|
100
|
+
connectionParameters: true,
|
|
101
|
+
backendCancel: true,
|
|
102
|
+
idleTransactionTimeout: true,
|
|
103
|
+
abortsTransactionOnError: true,
|
|
104
|
+
connectionDriver: 'pg-compatible',
|
|
105
|
+
preparesEveryStatement: false,
|
|
106
|
+
statementSyntax: 'postgresql',
|
|
107
|
+
inlineForeignKeys: true,
|
|
108
|
+
unboundedTextKeys: true,
|
|
109
|
+
}),
|
|
50
110
|
resultStrategy: 'returning',
|
|
51
111
|
supportsReturning: true,
|
|
52
112
|
supportsUpsertUpdateWhere: true,
|
|
@@ -64,6 +124,9 @@ exports.postgresDialect = {
|
|
|
64
124
|
supportsAdvisoryLock: true,
|
|
65
125
|
supportsPlanCacheMode: true,
|
|
66
126
|
supportsLateralJoin: true,
|
|
127
|
+
rowLockModes: ['update', 'noKeyUpdate', 'share', 'keyShare'],
|
|
128
|
+
supportsPercentileAggregates: true,
|
|
129
|
+
supportsBulkUpsert: true,
|
|
67
130
|
explainQuery: { prefix: 'EXPLAIN' },
|
|
68
131
|
paramPlaceholder(index) {
|
|
69
132
|
return `$${index}`;
|
|
@@ -116,40 +179,21 @@ exports.postgresDialect = {
|
|
|
116
179
|
return `INSERT INTO ${input.table} (${input.columns.join(', ')}) VALUES (${input.valuePlaceholders.join(', ')})${this.buildReturningClause(input.returning)}`;
|
|
117
180
|
},
|
|
118
181
|
buildBulkInsertStatement(input) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// target column, which is what single-row `create` already relies on
|
|
135
|
-
// and is what makes arrays and enums both work here. The casts in
|
|
136
|
-
// `columnArrayTypes` are ARRAY-OF-column-type, correct for the
|
|
137
|
-
// UNNEST transpose below but wrong for an individual cell.
|
|
138
|
-
return this.paramPlaceholder(params.length);
|
|
139
|
-
});
|
|
140
|
-
return `(${cells.join(', ')})`;
|
|
141
|
-
});
|
|
142
|
-
let rowSql = `INSERT INTO ${input.table} (${input.columns.join(', ')}) VALUES ${tuples.join(', ')}`;
|
|
143
|
-
if (input.skipDuplicates)
|
|
144
|
-
rowSql += ' ON CONFLICT DO NOTHING';
|
|
145
|
-
return { sql: `${rowSql}${this.buildReturningClause(input.returning)}`, params };
|
|
146
|
-
}
|
|
147
|
-
const columnArrays = input.columns.map((_, columnIndex) => input.rowValues.map((row) => row[columnIndex]));
|
|
148
|
-
const unnestArgs = input.columns.map((_, i) => `${this.paramPlaceholder(i + 1)}::${input.columnArrayTypes[i]}`);
|
|
149
|
-
let sql = `INSERT INTO ${input.table} (${input.columns.join(', ')}) SELECT * FROM UNNEST(${unnestArgs.join(', ')})`;
|
|
150
|
-
if (input.skipDuplicates)
|
|
151
|
-
sql += ' ON CONFLICT DO NOTHING';
|
|
152
|
-
return { sql: `${sql}${this.buildReturningClause(input.returning)}`, params: columnArrays };
|
|
182
|
+
const body = pgBulkInsertBody(this, input);
|
|
183
|
+
const conflict = input.skipDuplicates ? ' ON CONFLICT DO NOTHING' : '';
|
|
184
|
+
return { sql: `${body.sql}${conflict}${this.buildReturningClause(input.returning)}`, params: body.params };
|
|
185
|
+
},
|
|
186
|
+
buildBulkUpsertStatement(input) {
|
|
187
|
+
// `INSERT ... SELECT * FROM UNNEST(...) ON CONFLICT ... DO UPDATE ... WHERE
|
|
188
|
+
// ... RETURNING` is valid as is: PostgreSQL has no parse ambiguity between
|
|
189
|
+
// the SELECT and the conflict clause.
|
|
190
|
+
const body = pgBulkInsertBody(this, input);
|
|
191
|
+
return {
|
|
192
|
+
sql: `${body.sql} ON CONFLICT (${input.conflictColumns.join(', ')}) ` +
|
|
193
|
+
onConflictAction(input, body.params, { target: input.table, incoming: 'EXCLUDED' }) +
|
|
194
|
+
this.buildReturningClause(input.returning),
|
|
195
|
+
params: body.params,
|
|
196
|
+
};
|
|
153
197
|
},
|
|
154
198
|
buildDefaultValuesInsertStatement(input) {
|
|
155
199
|
const conflict = input.skipDuplicates ? ' ON CONFLICT DO NOTHING' : '';
|
|
@@ -382,13 +426,10 @@ exports.postgresDialect = {
|
|
|
382
426
|
}
|
|
383
427
|
}
|
|
384
428
|
},
|
|
385
|
-
//
|
|
386
|
-
//
|
|
387
|
-
//
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
return introspectPostgresCatalog(options);
|
|
392
|
-
},
|
|
393
|
-
},
|
|
429
|
+
// No `introspector`: `introspect()` reads the PostgreSQL catalog itself when a
|
|
430
|
+
// dialect has none. A field here would have to reach introspect.ts through a
|
|
431
|
+
// dynamic import (introspect.ts imports this dialect), and a bundler without
|
|
432
|
+
// code splitting inlines that import WHOLE, which put the entire catalog
|
|
433
|
+
// reader into the serverless entry and every engine entry (4 to 6 kB brotli
|
|
434
|
+
// each) for a function none of them call at runtime.
|
|
394
435
|
};
|
|
@@ -26,20 +26,21 @@ import type { TurbineConfig } from './client.js';
|
|
|
26
26
|
* the engine from its own SQL.
|
|
27
27
|
* - `connectionString`, `host`, `port`, `database`, `user`, `password`, `ssl`,
|
|
28
28
|
* `poolSize`, `idleTimeoutMs`, `connectionTimeoutMs`, `max`,
|
|
29
|
-
* `idleTimeoutMillis`, `connectionTimeoutMillis`: pg
|
|
30
|
-
* pool-tuning fields, ignored by `TurbineClient` whenever
|
|
31
|
-
* always is here). Each engine takes its connection
|
|
32
|
-
* argument instead, in that driver's own vocabulary.
|
|
29
|
+
* `idleTimeoutMillis`, `connectionTimeoutMillis`, `maxLifetimeSeconds`: pg
|
|
30
|
+
* connection and pool-tuning fields, ignored by `TurbineClient` whenever
|
|
31
|
+
* `pool` is set (it always is here). Each engine takes its connection
|
|
32
|
+
* target as its first argument instead, in that driver's own vocabulary.
|
|
33
33
|
* - `replicas`: entries are Postgres connection strings or pg-compatible
|
|
34
34
|
* pools, which `TurbineClient` opens as `pg.Pool`s. There is no engine
|
|
35
35
|
* equivalent to route reads to.
|
|
36
36
|
*
|
|
37
37
|
* Everything else is forwarded, including options that are Postgres-only by
|
|
38
|
-
* CAPABILITY rather than by plumbing (`jsonEncoding: 'positional'
|
|
38
|
+
* CAPABILITY rather than by plumbing (`jsonEncoding: 'positional'`,
|
|
39
|
+
* `statementTimeoutMs`, `planCacheMode`). Those throw
|
|
39
40
|
* a typed `UnsupportedFeatureError` (E017) when used, which is a better answer
|
|
40
41
|
* than an option the type system says does not exist.
|
|
41
42
|
*/
|
|
42
|
-
type EngineOwnedConfigKey = 'pool' | 'dialect' | 'preparedStatements' | 'connectionString' | 'host' | 'port' | 'database' | 'user' | 'password' | 'ssl' | 'poolSize' | 'idleTimeoutMs' | 'connectionTimeoutMs' | 'max' | 'idleTimeoutMillis' | 'connectionTimeoutMillis' | 'replicas';
|
|
43
|
+
type EngineOwnedConfigKey = 'pool' | 'dialect' | 'preparedStatements' | 'connectionString' | 'host' | 'port' | 'database' | 'user' | 'password' | 'ssl' | 'poolSize' | 'idleTimeoutMs' | 'connectionTimeoutMs' | 'max' | 'idleTimeoutMillis' | 'connectionTimeoutMillis' | 'maxLifetimeSeconds' | 'replicas';
|
|
43
44
|
/**
|
|
44
45
|
* The client-level options every engine factory accepts and forwards to
|
|
45
46
|
* `TurbineClient` unchanged: all of {@link TurbineConfig} minus the connection
|
package/dist/cjs/errors.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export declare const TurbineErrorCode: {
|
|
|
24
24
|
readonly EXCLUSION_VIOLATION: "TURBINE_E016";
|
|
25
25
|
readonly UNSUPPORTED_FEATURE: "TURBINE_E017";
|
|
26
26
|
readonly READ_ONLY: "TURBINE_E018";
|
|
27
|
+
readonly TRANSACTION_ROLLED_BACK: "TURBINE_E019";
|
|
28
|
+
readonly INVARIANT_VIOLATION: "TURBINE_E020";
|
|
27
29
|
};
|
|
28
30
|
export type TurbineErrorCode = (typeof TurbineErrorCode)[keyof typeof TurbineErrorCode];
|
|
29
31
|
/** Base error class for all Turbine errors */
|
|
@@ -198,7 +200,10 @@ export declare function describeTargetForMessage(target: unknown): string;
|
|
|
198
200
|
* `[TURBINE_E001] findUniqueOrThrow on "users" found no record matching where: {"id":1}`
|
|
199
201
|
*
|
|
200
202
|
* The full `where` object, `table`, and `operation` are always available as
|
|
201
|
-
* structured properties on the error instance regardless of mode.
|
|
203
|
+
* structured properties on the error instance regardless of mode. `where`
|
|
204
|
+
* carries the caller's raw values, so under 'safe' it is NON-ENUMERABLE:
|
|
205
|
+
* `err.where` reads it, while `JSON.stringify`, `util.inspect` and error
|
|
206
|
+
* serializers that copy own enumerable fields leave it out.
|
|
202
207
|
*/
|
|
203
208
|
export declare class NotFoundError extends TurbineError {
|
|
204
209
|
static readonly CODE: "TURBINE_E001";
|
|
@@ -213,21 +218,37 @@ export declare class NotFoundError extends TurbineError {
|
|
|
213
218
|
message?: string;
|
|
214
219
|
});
|
|
215
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* What a {@link TimeoutError} says about the statement it interrupted.
|
|
223
|
+
*
|
|
224
|
+
* - `'not-executed'`: the statement made no change. It was never sent (the
|
|
225
|
+
* deadline passed while waiting for a connection), or the server confirmed
|
|
226
|
+
* it was cancelled. Safe to retry.
|
|
227
|
+
* - `'unknown'`: the statement may still have completed. A write retried on
|
|
228
|
+
* this outcome can be applied twice; check the database first.
|
|
229
|
+
*
|
|
230
|
+
* A read changes nothing whatever this says, so a read is always safe to retry.
|
|
231
|
+
*/
|
|
232
|
+
export type TimeoutOutcome = 'not-executed' | 'unknown';
|
|
216
233
|
/** Thrown when a query or transaction exceeds the configured timeout */
|
|
217
234
|
export declare class TimeoutError extends TurbineError {
|
|
218
235
|
static readonly CODE: "TURBINE_E002";
|
|
219
236
|
readonly timeoutMs: number;
|
|
237
|
+
/** Whether the interrupted statement can have taken effect. See {@link TimeoutOutcome}. */
|
|
238
|
+
readonly outcome: TimeoutOutcome;
|
|
220
239
|
/**
|
|
221
240
|
* @param timeoutMs the client-side timeout budget in ms. Pass `0` when the
|
|
222
241
|
* duration is unknown (e.g. a server-side `statement_timeout` cancellation
|
|
223
242
|
* surfaced via `wrapPgError`, where Turbine did not set the deadline).
|
|
224
243
|
* @param context human label for the operation ("Query", "Transaction").
|
|
225
244
|
* @param options optional `message` override and pg `cause` to preserve, used
|
|
226
|
-
* when wrapping a driver error rather than a client-side timer expiry
|
|
245
|
+
* when wrapping a driver error rather than a client-side timer expiry, and
|
|
246
|
+
* the `outcome` (default `'unknown'`, the only answer that is never wrong).
|
|
227
247
|
*/
|
|
228
248
|
constructor(timeoutMs: number, context?: string, options?: {
|
|
229
249
|
message?: string;
|
|
230
250
|
cause?: unknown;
|
|
251
|
+
outcome?: TimeoutOutcome;
|
|
231
252
|
});
|
|
232
253
|
}
|
|
233
254
|
/** Thrown when query arguments fail validation (unknown column, invalid operator, etc.) */
|
|
@@ -421,6 +442,33 @@ export declare class SerializationFailureError extends TurbineError {
|
|
|
421
442
|
cause?: unknown;
|
|
422
443
|
});
|
|
423
444
|
}
|
|
445
|
+
/**
|
|
446
|
+
* A row lock could not be taken. A locking read with `noWait` found a row
|
|
447
|
+
* locked by another transaction (PostgreSQL 55P03, MySQL 3572), or a lock wait
|
|
448
|
+
* outlasted the server's lock timeout (PostgreSQL 55P03 under `lock_timeout`,
|
|
449
|
+
* MySQL 1205, SQL Server 1222).
|
|
450
|
+
*
|
|
451
|
+
* A {@link SerializationFailureError}: same code (E013) and `isRetryable`, so
|
|
452
|
+
* code that already retries E013 retries this too. Retry after a backoff, or
|
|
453
|
+
* read with `skipLocked` to move on to the rows that are free.
|
|
454
|
+
*
|
|
455
|
+
* On PostgreSQL the failed statement aborts the transaction it ran in. To keep
|
|
456
|
+
* the outer transaction alive, take the lock in a nested `tx.$transaction(...)`
|
|
457
|
+
* (a savepoint) and catch the error outside it.
|
|
458
|
+
*/
|
|
459
|
+
export declare class LockNotAvailableError extends SerializationFailureError {
|
|
460
|
+
constructor(opts?: {
|
|
461
|
+
message?: string;
|
|
462
|
+
cause?: unknown;
|
|
463
|
+
});
|
|
464
|
+
/**
|
|
465
|
+
* `instanceof` across two copies of this module. The code alone cannot tell
|
|
466
|
+
* this class from its parent (both E013), so another copy's instance must
|
|
467
|
+
* also carry this class's own brand. A caller's subclass answers only for
|
|
468
|
+
* its own instances, as {@link TurbineError[Symbol.hasInstance]} does.
|
|
469
|
+
*/
|
|
470
|
+
static [Symbol.hasInstance](value: unknown): boolean;
|
|
471
|
+
}
|
|
424
472
|
/** Thrown when a CHECK constraint is violated (pg code 23514) */
|
|
425
473
|
export declare class CheckConstraintError extends TurbineError {
|
|
426
474
|
static readonly CODE: "TURBINE_E011";
|
|
@@ -542,18 +590,86 @@ export declare class ReadOnlyError extends TurbineError {
|
|
|
542
590
|
* fail-fast flag), so NOTHING can write here and writes must route to the
|
|
543
591
|
* primary. `'rbac'`: the database is writable but THIS connection's role may
|
|
544
592
|
* not write (per-connection permission), so re-authenticating may suffice.
|
|
593
|
+
* `'transaction'`: the transaction is read-only (`$transaction({ readOnly:
|
|
594
|
+
* true })`, `BEGIN READ ONLY`, or a read replica, where every transaction
|
|
595
|
+
* is), so the write belongs in a read-write transaction on the primary.
|
|
545
596
|
*/
|
|
546
|
-
readonly reason:
|
|
597
|
+
readonly reason: ReadOnlyReason;
|
|
547
598
|
/**
|
|
548
599
|
* @param detail human-readable description of the refused write (the engine
|
|
549
|
-
* message, or a local fail-fast description). A
|
|
550
|
-
*
|
|
600
|
+
* message, or a local fail-fast description). A hint naming where the
|
|
601
|
+
* write belongs is always appended.
|
|
551
602
|
* @param options optional driver `cause` to preserve when wrapping a refusal,
|
|
552
603
|
* and the refusal `reason` (default `'snapshot'`).
|
|
553
604
|
*/
|
|
554
605
|
constructor(detail: string, options?: {
|
|
555
606
|
cause?: unknown;
|
|
556
|
-
reason?:
|
|
607
|
+
reason?: ReadOnlyReason;
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
/** Why a {@link ReadOnlyError} write was refused. */
|
|
611
|
+
export type ReadOnlyReason = 'snapshot' | 'rbac' | 'transaction';
|
|
612
|
+
/**
|
|
613
|
+
* Thrown when work the caller expected to be saved was rolled back instead:
|
|
614
|
+
* a `$transaction` or `transaction()` whose COMMIT the server answered with
|
|
615
|
+
* ROLLBACK, a transaction that cannot commit because a statement inside it was
|
|
616
|
+
* cut short by its `timeout`, or a nested `tx.$transaction(...)` block that
|
|
617
|
+
* could not be kept for the same reasons.
|
|
618
|
+
*
|
|
619
|
+
* PostgreSQL aborts a transaction at its first error. Catching that error
|
|
620
|
+
* inside the callback does not undo the abort, so the callback returns, the
|
|
621
|
+
* COMMIT ends as a ROLLBACK, and none of the transaction's writes are saved.
|
|
622
|
+
* The first failure is attached as `cause`. Nothing was committed, so the
|
|
623
|
+
* whole transaction can be run again once the cause is dealt with; to keep the
|
|
624
|
+
* rest of the work after an expected failure, run the statement that can fail
|
|
625
|
+
* in its own nested `tx.$transaction(...)`.
|
|
626
|
+
*
|
|
627
|
+
* NOT retryable on its own: the failure that caused it is not known to be
|
|
628
|
+
* transient. When that first failure WAS a deadlock or a serialization
|
|
629
|
+
* conflict, the retryable class (`DeadlockError`, `SerializationFailureError`)
|
|
630
|
+
* is thrown instead, so `$retry` re-runs the transaction.
|
|
631
|
+
*/
|
|
632
|
+
export declare class TransactionRolledBackError extends TurbineError {
|
|
633
|
+
static readonly CODE: "TURBINE_E019";
|
|
634
|
+
/**
|
|
635
|
+
* @param message what was rolled back and how to keep the work next time.
|
|
636
|
+
* @param options the first failure inside the transaction, as `cause`.
|
|
637
|
+
*/
|
|
638
|
+
constructor(message: string, options?: {
|
|
639
|
+
cause?: unknown;
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* The sentence every {@link InvariantError} message ends with, before the docs
|
|
644
|
+
* link. Exported so a test can assert it without restating it.
|
|
645
|
+
*/
|
|
646
|
+
export declare const INVARIANT_REPORT_HINT: string;
|
|
647
|
+
/**
|
|
648
|
+
* Turbine detected a bug in itself: a branch that no argument can reach was
|
|
649
|
+
* reached, or two internal paths that must agree did not (the SQL-template
|
|
650
|
+
* cache's build and param-collect paths, for example).
|
|
651
|
+
*
|
|
652
|
+
* Not caused by the arguments, so rewriting the call is not the fix, and not
|
|
653
|
+
* retryable: the same call fails the same way. `invariant` is a stable id for
|
|
654
|
+
* the broken rule (`'sql-cache-lockstep'`, `'sql-cache-param-count'`, ...), so
|
|
655
|
+
* a report or an alert can group on it. The message names no row or parameter
|
|
656
|
+
* value.
|
|
657
|
+
*
|
|
658
|
+
* Thrown in place of executing a statement Turbine knows is wrong, which is
|
|
659
|
+
* what makes the checks behind it safe to run in production.
|
|
660
|
+
*/
|
|
661
|
+
export declare class InvariantError extends TurbineError {
|
|
662
|
+
static readonly CODE: "TURBINE_E020";
|
|
663
|
+
/** Stable id of the broken invariant, e.g. `'sql-cache-lockstep'`. */
|
|
664
|
+
readonly invariant: string;
|
|
665
|
+
/**
|
|
666
|
+
* @param invariant stable id of the broken rule.
|
|
667
|
+
* @param message what disagreed, with no row or parameter value in it. The
|
|
668
|
+
* report hint is appended once.
|
|
669
|
+
* @param options the error that exposed the broken rule, as `cause`.
|
|
670
|
+
*/
|
|
671
|
+
constructor(invariant: string, message: string, options?: {
|
|
672
|
+
cause?: unknown;
|
|
557
673
|
});
|
|
558
674
|
}
|
|
559
675
|
/**
|
|
@@ -593,9 +709,13 @@ export declare function isStaleConnectionError(err: unknown): boolean;
|
|
|
593
709
|
* 23P01 (exclusion_violation) -> ExclusionConstraintError
|
|
594
710
|
* 40P01 (deadlock_detected) -> DeadlockError (retryable)
|
|
595
711
|
* 40001 (serialization_failure) -> SerializationFailureError (retryable)
|
|
712
|
+
* 55P03 (lock_not_available) -> LockNotAvailableError (retryable, E013); also
|
|
713
|
+
* MySQL 3572 / 1205 and SQL Server 1222
|
|
596
714
|
* 57014 (query_canceled) -> TimeoutError (server-side statement_timeout)
|
|
597
715
|
* 28P01 / 28000 (auth refused) -> ConnectionError, with a remediation hint
|
|
598
716
|
* 3D000 (no such database) -> ConnectionError, with a remediation hint
|
|
717
|
+
* 42P05 / 26000 (prepared statement name clash or miss, a transaction-mode
|
|
718
|
+
* pooler) -> ConnectionError, with a remediation hint
|
|
599
719
|
* connection-class codes -> ConnectionError (see CONNECTION_ERROR_CODES)
|
|
600
720
|
* 22xxx (data exception) -> ValidationError naming the column (when the
|
|
601
721
|
* server did) and the SQLSTATE; driver text
|