ts-prorm-orm 1.2.3 → 2.1.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/CHANGELOG.md +331 -1
- package/README.md +32 -24
- package/dist/compliance/data-classifier.d.ts +6 -0
- package/dist/compliance/data-classifier.js +6 -0
- package/dist/compliance/data-lineage.d.ts +4 -0
- package/dist/compliance/data-lineage.js +4 -0
- package/dist/compliance/data-masker.d.ts +4 -0
- package/dist/compliance/data-masker.js +4 -0
- package/dist/compliance/index.d.ts +4 -0
- package/dist/compliance/index.js +15 -1
- package/dist/compliance/pseudonymization.d.ts +4 -0
- package/dist/compliance/pseudonymization.js +4 -0
- package/dist/compliance/query-firewall.d.ts +9 -9
- package/dist/compliance/query-firewall.js +9 -9
- package/dist/compliance/rate-limiter.d.ts +4 -0
- package/dist/compliance/rate-limiter.js +4 -0
- package/dist/compliance/row-level-security.d.ts +2 -0
- package/dist/compliance/row-level-security.js +2 -0
- package/dist/compliance/security-decorator.d.ts +8 -0
- package/dist/compliance/security-decorator.js +8 -0
- package/dist/compliance/session-isolation.d.ts +4 -0
- package/dist/compliance/session-isolation.js +4 -0
- package/dist/compliance/worm-storage.d.ts +4 -0
- package/dist/compliance/worm-storage.js +4 -0
- package/dist/connection-manager.js +13 -1
- package/dist/core/expressions.d.ts +58 -0
- package/dist/core/expressions.js +83 -0
- package/dist/core/hooks-manager.d.ts +179 -0
- package/dist/core/hooks-manager.js +291 -0
- package/dist/core/types.d.ts +235 -0
- package/dist/core/types.js +9 -0
- package/dist/decorators/audit.d.ts +3 -1
- package/dist/decorators/audit.js +3 -1
- package/dist/decorators/check.d.ts +15 -15
- package/dist/decorators/check.js +15 -15
- package/dist/decorators/collate.d.ts +16 -0
- package/dist/decorators/collate.js +16 -0
- package/dist/decorators/comment.d.ts +3 -1
- package/dist/decorators/comment.js +3 -1
- package/dist/decorators/database-settings.d.ts +6 -0
- package/dist/decorators/database-settings.js +6 -0
- package/dist/decorators/default.d.ts +2 -0
- package/dist/decorators/default.js +2 -0
- package/dist/decorators/encryption.d.ts +7 -1
- package/dist/decorators/encryption.js +7 -1
- package/dist/decorators/engine.d.ts +4 -0
- package/dist/decorators/engine.js +4 -0
- package/dist/decorators/fk-constraints.d.ts +32 -32
- package/dist/decorators/fk-constraints.js +32 -32
- package/dist/decorators/foreign-table.d.ts +1 -1
- package/dist/decorators/generated.d.ts +8 -0
- package/dist/decorators/generated.js +8 -0
- package/dist/decorators/hstore.d.ts +6 -0
- package/dist/decorators/hstore.js +6 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.js +11 -1
- package/dist/decorators/json-column.d.ts +2 -0
- package/dist/decorators/json-column.js +2 -0
- package/dist/decorators/jsonb.d.ts +6 -0
- package/dist/decorators/jsonb.js +6 -0
- package/dist/decorators/permissions.d.ts +12 -0
- package/dist/decorators/permissions.js +12 -0
- package/dist/decorators/procedure.d.ts +4 -2
- package/dist/decorators/procedure.js +4 -2
- package/dist/decorators/query-options.d.ts +24 -0
- package/dist/decorators/query-options.js +24 -0
- package/dist/decorators/range.d.ts +8 -0
- package/dist/decorators/range.js +8 -0
- package/dist/decorators/set-column.d.ts +2 -0
- package/dist/decorators/set-column.js +2 -0
- package/dist/decorators/spatial.d.ts +2 -0
- package/dist/decorators/spatial.js +2 -0
- package/dist/decorators/storage.d.ts +24 -0
- package/dist/decorators/storage.js +24 -0
- package/dist/decorators/timezone.d.ts +7 -7
- package/dist/decorators/timezone.js +7 -7
- package/dist/decorators/trigger.d.ts +3 -1
- package/dist/decorators/trigger.js +3 -1
- package/dist/decorators/uuid.d.ts +6 -0
- package/dist/decorators/uuid.js +6 -0
- package/dist/decorators/view.d.ts +7 -1
- package/dist/decorators/view.js +7 -1
- package/dist/diagrams/chen-diagram.d.ts +15 -12
- package/dist/diagrams/chen-diagram.js +76 -85
- package/dist/diagrams/class-diagram.d.ts +9 -8
- package/dist/diagrams/class-diagram.js +60 -82
- package/dist/diagrams/core/index.d.ts +13 -0
- package/dist/diagrams/core/index.js +33 -0
- package/dist/diagrams/core/layout.d.ts +104 -0
- package/dist/diagrams/core/layout.js +223 -0
- package/dist/diagrams/{svg-dom.d.ts → core/svg.d.ts} +8 -20
- package/dist/diagrams/{svg-dom.js → core/svg.js} +21 -29
- package/dist/diagrams/core/theme.d.ts +84 -0
- package/dist/diagrams/core/theme.js +62 -0
- package/dist/diagrams/dependency-diagram.d.ts +15 -14
- package/dist/diagrams/dependency-diagram.js +71 -105
- package/dist/diagrams/er-diagram.d.ts +13 -26
- package/dist/diagrams/er-diagram.js +180 -259
- package/dist/diagrams/flow-diagram.d.ts +16 -11
- package/dist/diagrams/flow-diagram.js +96 -91
- package/dist/diagrams/gantt-diagram.d.ts +10 -5
- package/dist/diagrams/gantt-diagram.js +77 -103
- package/dist/diagrams/index-diagram.d.ts +10 -10
- package/dist/diagrams/index-diagram.js +106 -116
- package/dist/diagrams/index.d.ts +6 -9
- package/dist/diagrams/index.js +9 -24
- package/dist/diagrams/migration-diagram.d.ts +8 -4
- package/dist/diagrams/migration-diagram.js +189 -161
- package/dist/diagrams/model-diagram.d.ts +34 -34
- package/dist/diagrams/model-diagram.js +106 -485
- package/dist/diagrams/package-diagram.d.ts +9 -6
- package/dist/diagrams/package-diagram.js +64 -101
- package/dist/diagrams/relational-diagram.d.ts +12 -10
- package/dist/diagrams/relational-diagram.js +87 -114
- package/dist/diagrams/schemadoc-diagram.d.ts +8 -8
- package/dist/diagrams/schemadoc-diagram.js +71 -93
- package/dist/diagrams/sequence-diagram.d.ts +10 -10
- package/dist/diagrams/sequence-diagram.js +64 -89
- package/dist/diagrams/state-diagram.d.ts +10 -9
- package/dist/diagrams/state-diagram.js +69 -92
- package/dist/diagrams/tree-diagram.d.ts +11 -5
- package/dist/diagrams/tree-diagram.js +41 -65
- package/dist/dialects/clickhouse/index.js +15 -0
- package/dist/dialects/cockroachdb/index.d.ts +1 -1
- package/dist/dialects/cockroachdb/index.js +32 -63
- package/dist/dialects/db2/index.js +23 -8
- package/dist/dialects/dialect.d.ts +141 -5
- package/dist/dialects/duckdb/index.js +9 -2
- package/dist/dialects/hana/index.js +22 -5
- package/dist/dialects/lock-clause-helper.d.ts +167 -0
- package/dist/dialects/lock-clause-helper.js +316 -0
- package/dist/dialects/mariadb/index.d.ts +7 -4
- package/dist/dialects/mariadb/index.js +36 -60
- package/dist/dialects/mssql/index.js +34 -3
- package/dist/dialects/mysql/index.d.ts +1 -1
- package/dist/dialects/mysql/index.js +17 -45
- package/dist/dialects/oracle/index.d.ts +14 -3
- package/dist/dialects/oracle/index.js +66 -36
- package/dist/dialects/order-expression-helper.d.ts +72 -0
- package/dist/dialects/order-expression-helper.js +154 -0
- package/dist/dialects/partial-index.d.ts +52 -0
- package/dist/dialects/partial-index.js +251 -0
- package/dist/dialects/postgres/index.d.ts +1 -1
- package/dist/dialects/postgres/index.js +43 -68
- package/dist/dialects/redshift/index.js +9 -2
- package/dist/dialects/snowflake/index.js +17 -0
- package/dist/dialects/spanner/index.js +7 -2
- package/dist/dialects/sqlite/driver.d.ts +55 -0
- package/dist/dialects/sqlite/driver.js +102 -0
- package/dist/dialects/sqlite/index.d.ts +1 -1
- package/dist/dialects/sqlite/index.js +49 -27
- package/dist/external-fields/decorator.d.ts +2 -0
- package/dist/external-fields/decorator.js +2 -0
- package/dist/graph/base-graph-dialect.d.ts +24 -3
- package/dist/graph/base-graph-dialect.js +43 -2
- package/dist/graph/dgraph/index.js +6 -0
- package/dist/graph/gremlin/index.d.ts +6 -0
- package/dist/graph/gremlin/index.js +12 -1
- package/dist/graph/index.d.ts +1 -1
- package/dist/graph/neo4j/index.d.ts +2 -0
- package/dist/graph/neo4j/index.js +6 -1
- package/dist/graph/types.d.ts +12 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.js +53 -7
- package/dist/logging/index.d.ts +10 -0
- package/dist/logging/index.js +23 -0
- package/dist/logging/query-logging.d.ts +82 -0
- package/dist/logging/query-logging.js +102 -0
- package/dist/models/associations.d.ts +38 -0
- package/dist/models/associations.js +16 -0
- package/dist/models/decorators.d.ts +55 -19
- package/dist/models/decorators.js +95 -19
- package/dist/models/eager-load.d.ts +99 -0
- package/dist/models/eager-load.js +348 -5
- package/dist/models/indexes.d.ts +3 -2
- package/dist/models/indexes.js +7 -1
- package/dist/models/model.js +69 -43
- package/dist/prorm.d.ts +175 -409
- package/dist/prorm.js +1132 -553
- package/dist/query-builders/order-limit-builder.js +12 -10
- package/dist/query-builders/sql-compiler.d.ts +10 -3
- package/dist/query-builders/sql-compiler.js +14 -43
- package/dist/query-interface.d.ts +2 -1
- package/dist/schema-objects.d.ts +42 -0
- package/dist/schema-objects.js +28 -0
- package/dist/sql-constants.d.ts +44 -0
- package/dist/sql-constants.js +138 -1
- package/dist/types/index.d.ts +387 -17
- package/dist/types/index.js +10 -15
- package/dist/types/query-types.d.ts +26 -0
- package/dist/types/query-types.js +30 -0
- package/package.json +39 -8
- package/dist/decorators/belongs-to-many.js +0 -115
- package/dist/decorators/belongs-to.js +0 -115
- package/dist/decorators/has-many.js +0 -127
- package/dist/decorators/has-one.js +0 -116
- package/dist/diagrams/palette.d.ts +0 -138
- package/dist/diagrams/palette.js +0 -194
- package/dist/hooks/hooks-manager.d.ts +0 -189
- package/dist/hooks/hooks-manager.js +0 -350
- package/dist/hooks/index.d.ts +0 -8
- package/dist/hooks/index.js +0 -37
- /package/dist/{logging.d.ts → logging/logger.d.ts} +0 -0
- /package/dist/{logging.js → logging/logger.js} +0 -0
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
*/
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
50
|
exports.HanaDialect = void 0;
|
|
51
|
+
const partial_index_1 = require("../partial-index");
|
|
51
52
|
// Lazily-loaded `hdb` driver. Required only when a connection is opened, so
|
|
52
53
|
// importing this ORM never loads the hdb driver.
|
|
53
54
|
let hdbModule = null;
|
|
@@ -65,7 +66,9 @@ function loadHdb() {
|
|
|
65
66
|
return hdbModule;
|
|
66
67
|
}
|
|
67
68
|
const query_stream_helper_1 = require("../query-stream-helper");
|
|
69
|
+
const lock_clause_helper_1 = require("../lock-clause-helper");
|
|
68
70
|
const prorm_1 = require("../../prorm");
|
|
71
|
+
const order_expression_helper_1 = require("../order-expression-helper");
|
|
69
72
|
/** HANA requires a LIMIT whenever OFFSET is used; this sentinel stands in for "no limit". */
|
|
70
73
|
const HANA_MAX_LIMIT = 2147483647;
|
|
71
74
|
/**
|
|
@@ -829,6 +832,12 @@ class HanaDialect {
|
|
|
829
832
|
if (options?.unique)
|
|
830
833
|
sql += ' UNIQUE';
|
|
831
834
|
sql += ` INDEX ${this.escapeId(indexName)} ON ${this.quoteTable(tableName)} (${fieldsSql})`;
|
|
835
|
+
// SAP HANA has no partial/filtered indexes (createPartialIndex already
|
|
836
|
+
// throws). `where` was silently dropped here, handing back a full index;
|
|
837
|
+
// fail the same way the dedicated method does.
|
|
838
|
+
if (options?.where) {
|
|
839
|
+
throw (0, partial_index_1.unsupportedPartialIndex)(this.name);
|
|
840
|
+
}
|
|
832
841
|
return sql;
|
|
833
842
|
}
|
|
834
843
|
async addIndex(tableName, indexName, fields, options) {
|
|
@@ -842,6 +851,7 @@ class HanaDialect {
|
|
|
842
851
|
unique: indexDef.unique,
|
|
843
852
|
type: indexDef.type,
|
|
844
853
|
using: indexDef.using,
|
|
854
|
+
where: indexDef.where,
|
|
845
855
|
});
|
|
846
856
|
}
|
|
847
857
|
async dropIndex(tableName, indexName, _options) {
|
|
@@ -1183,12 +1193,18 @@ class HanaDialect {
|
|
|
1183
1193
|
return { sql, values };
|
|
1184
1194
|
}
|
|
1185
1195
|
buildOrderClause(order, _options) {
|
|
1186
|
-
const orderArray = order;
|
|
1187
|
-
if (
|
|
1196
|
+
const orderArray = (0, order_expression_helper_1.normalizeOrderItems)(order);
|
|
1197
|
+
if (orderArray.length === 0) {
|
|
1188
1198
|
return '';
|
|
1189
1199
|
}
|
|
1190
1200
|
const orderParts = [];
|
|
1191
1201
|
for (const item of orderArray) {
|
|
1202
|
+
// Order helpers: asc('name') / desc('name') / random()
|
|
1203
|
+
const orderExpr = (0, order_expression_helper_1.renderOrderExpressionItem)(this, item);
|
|
1204
|
+
if (orderExpr !== null) {
|
|
1205
|
+
orderParts.push(orderExpr);
|
|
1206
|
+
continue;
|
|
1207
|
+
}
|
|
1192
1208
|
if (Array.isArray(item)) {
|
|
1193
1209
|
const field = typeof item[0] === 'string' ? this.escapeId(item[0]) : item[0];
|
|
1194
1210
|
const direction = item[1] ? ` ${item[1]}` : '';
|
|
@@ -1386,9 +1402,10 @@ class HanaDialect {
|
|
|
1386
1402
|
if (options.limit !== undefined || options.offset !== undefined) {
|
|
1387
1403
|
sql += this.buildLimitOffset(options.limit, options.offset);
|
|
1388
1404
|
}
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1405
|
+
// Row-level locking: HANA supports `FOR UPDATE [NOWAIT]` only - no shared
|
|
1406
|
+
// row lock and no SKIP LOCKED, both of which now throw instead of silently
|
|
1407
|
+
// degrading to a plain exclusive lock.
|
|
1408
|
+
sql += (0, lock_clause_helper_1.appendLockClause)(options.lock, lock_clause_helper_1.HANA_LOCK_SPEC);
|
|
1392
1409
|
return { sql, values };
|
|
1393
1410
|
}
|
|
1394
1411
|
/**
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared compiler for `FindOptions.lock` (row-level locking).
|
|
3
|
+
*
|
|
4
|
+
* Every dialect used to re-implement the `lock` option inline inside its own
|
|
5
|
+
* `buildSelectQuery()`, and every one of those copies understood a slightly
|
|
6
|
+
* different subset of the documented `LockOptions` shapes. The object forms
|
|
7
|
+
* (`{ level }`, `{ level, nowait }`, `{ level, skipLocked }`, `{ skipLocked }`)
|
|
8
|
+
* fell through most of them and compiled to *nothing* - the caller asked for a
|
|
9
|
+
* lock, got a plain `SELECT`, and only found out under concurrency. This module
|
|
10
|
+
* centralises the parsing (`normalizeLockOptions`) and the SQL assembly
|
|
11
|
+
* (`buildLockClause`) so a shape can only be dropped by deliberately leaving it
|
|
12
|
+
* out of a dialect's {@link LockClauseSpec} - and a spec that cannot express
|
|
13
|
+
* what was asked for throws instead of silently emitting a weaker lock.
|
|
14
|
+
*
|
|
15
|
+
* Dialects with no row-level locking at all (SQLite and friends) simply never
|
|
16
|
+
* call in here: ignoring `lock` is a deliberate, documented decision for them
|
|
17
|
+
* (SQLite serialises writers anyway), not an oversight.
|
|
18
|
+
*
|
|
19
|
+
* SQL Server is the odd one out - it expresses row locking as a table hint
|
|
20
|
+
* (`FROM t WITH (UPDLOCK, ROWLOCK)`) rather than a trailing clause - so it
|
|
21
|
+
* shares the parsing/validation via {@link buildSqlServerLockHint} while
|
|
22
|
+
* rendering its own syntax.
|
|
23
|
+
*/
|
|
24
|
+
/** The lock levels this ORM knows how to talk about, after normalization. */
|
|
25
|
+
export type NormalizedLockLevel = 'UPDATE' | 'SHARE' | 'KEY SHARE' | 'NO KEY UPDATE';
|
|
26
|
+
/** Model shape (`lock.of`) reduced to the only fields the SQL needs. */
|
|
27
|
+
type LockOfModel = {
|
|
28
|
+
tableName?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
};
|
|
31
|
+
/** A `lock` option after every documented shape has been collapsed into one struct. */
|
|
32
|
+
export interface NormalizedLock {
|
|
33
|
+
level: NormalizedLockLevel;
|
|
34
|
+
nowait: boolean;
|
|
35
|
+
skipLocked: boolean;
|
|
36
|
+
/** The model passed as `lock.of`, if any. Only some dialects can express it. */
|
|
37
|
+
of?: LockOfModel;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* How one dialect renders row locks. A level that is absent from `levels` is
|
|
41
|
+
* one this dialect cannot express, and asking for it throws.
|
|
42
|
+
*/
|
|
43
|
+
export interface LockClauseSpec {
|
|
44
|
+
/** Human-readable dialect name, used in error messages. */
|
|
45
|
+
name: string;
|
|
46
|
+
/**
|
|
47
|
+
* SQL for each supported lock level. A function form lets a dialect pick its
|
|
48
|
+
* syntax based on the requested modifiers (MySQL/MariaDB switch between the
|
|
49
|
+
* legacy `LOCK IN SHARE MODE` and `FOR SHARE`, which is the only one of the
|
|
50
|
+
* two that accepts `NOWAIT`/`SKIP LOCKED`).
|
|
51
|
+
*/
|
|
52
|
+
levels: Partial<Record<NormalizedLockLevel, string | ((lock: NormalizedLock) => string)>>;
|
|
53
|
+
/** Levels that accept `NOWAIT`. Omit entirely if the dialect has no `NOWAIT`. */
|
|
54
|
+
nowaitLevels?: NormalizedLockLevel[];
|
|
55
|
+
/** Levels that accept `SKIP LOCKED`. Omit entirely if the dialect has none. */
|
|
56
|
+
skipLockedLevels?: NormalizedLockLevel[];
|
|
57
|
+
/**
|
|
58
|
+
* Renders `lock.of`. Omitted when the dialect has no table-scoped locking, in
|
|
59
|
+
* which case `of` only signals that a lock was wanted at all (which is
|
|
60
|
+
* exactly how those dialects have always behaved).
|
|
61
|
+
*/
|
|
62
|
+
renderOf?: (model: LockOfModel, escapeId: (id: string) => string) => string;
|
|
63
|
+
/** Levels for which `renderOf` applies. Defaults to every supported level. */
|
|
64
|
+
ofLevels?: NormalizedLockLevel[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Collapse any documented `lock` shape into a {@link NormalizedLock}.
|
|
68
|
+
*
|
|
69
|
+
* Returns `undefined` for a falsy lock (`undefined`, `false`, `null`), which
|
|
70
|
+
* every caller treats as "no locking clause".
|
|
71
|
+
*
|
|
72
|
+
* Accepted shapes:
|
|
73
|
+
* - `true` -> `FOR UPDATE`
|
|
74
|
+
* - `'UPDATE' | 'SHARE' | 'KEY SHARE' | 'NO KEY UPDATE'` (case-insensitive)
|
|
75
|
+
* - `{ of: Model }` -> `FOR UPDATE` scoped to that table
|
|
76
|
+
* - `{ level?, nowait?, skipLocked?, of? }` -> level defaults to `UPDATE`
|
|
77
|
+
*
|
|
78
|
+
* `mode` is accepted as an alias for `level` and `noWait` for `nowait`, since
|
|
79
|
+
* the MariaDB dialect has always documented those spellings.
|
|
80
|
+
*
|
|
81
|
+
* Throws on a level it doesn't recognise rather than quietly emitting no lock.
|
|
82
|
+
*/
|
|
83
|
+
export declare function normalizeLockOptions(lock: unknown): NormalizedLock | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* Build the trailing locking clause for a dialect, e.g. `FOR UPDATE OF "users" NOWAIT`.
|
|
86
|
+
*
|
|
87
|
+
* Returns `''` when there is no lock to apply. Throws when the requested lock
|
|
88
|
+
* cannot be expressed by this dialect - a lock the caller believes they hold
|
|
89
|
+
* but don't is far worse than a loud failure at query-build time.
|
|
90
|
+
*
|
|
91
|
+
* @param lock - the raw `options.lock` value
|
|
92
|
+
* @param spec - the dialect's locking capabilities
|
|
93
|
+
* @param escapeId - the dialect's identifier quoter, used for `lock.of`
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildLockClause(lock: unknown, spec: LockClauseSpec, escapeId?: (id: string) => string): string;
|
|
96
|
+
/**
|
|
97
|
+
* Same as {@link buildLockClause} but returns the clause with a leading space
|
|
98
|
+
* (or `''`), which is how every `buildSelectQuery()` wants to append it.
|
|
99
|
+
*/
|
|
100
|
+
export declare function appendLockClause(lock: unknown, spec: LockClauseSpec, escapeId?: (id: string) => string): string;
|
|
101
|
+
/**
|
|
102
|
+
* PostgreSQL: `FOR UPDATE | NO KEY UPDATE | SHARE | KEY SHARE [OF table] [NOWAIT | SKIP LOCKED]`.
|
|
103
|
+
* The full matrix - every level accepts both modifiers and the `OF` clause.
|
|
104
|
+
*/
|
|
105
|
+
export declare const POSTGRES_LOCK_SPEC: LockClauseSpec;
|
|
106
|
+
/** CockroachDB implements the PostgreSQL locking grammar. */
|
|
107
|
+
export declare const COCKROACHDB_LOCK_SPEC: LockClauseSpec;
|
|
108
|
+
/**
|
|
109
|
+
* MySQL 8.0+: `FOR UPDATE [OF tbl] [NOWAIT | SKIP LOCKED]` and
|
|
110
|
+
* `FOR SHARE [OF tbl] [NOWAIT | SKIP LOCKED]`.
|
|
111
|
+
*
|
|
112
|
+
* A bare shared lock still compiles to the pre-8.0 `LOCK IN SHARE MODE`
|
|
113
|
+
* spelling (which every supported MySQL understands, and which existing
|
|
114
|
+
* `lock: 'SHARE'` callers already get); it only switches to the 8.0 `FOR SHARE`
|
|
115
|
+
* form when a modifier is requested, because `LOCK IN SHARE MODE` accepts
|
|
116
|
+
* neither `NOWAIT` nor `SKIP LOCKED`.
|
|
117
|
+
*/
|
|
118
|
+
export declare const MYSQL_LOCK_SPEC: LockClauseSpec;
|
|
119
|
+
/**
|
|
120
|
+
* MariaDB: `FOR UPDATE` / `LOCK IN SHARE MODE` on every version, with
|
|
121
|
+
* `FOR SHARE` and the `SKIP LOCKED` / `NOWAIT` modifiers from 10.6.
|
|
122
|
+
*
|
|
123
|
+
* MariaDB has no `FOR UPDATE OF <table>`, so `lock.of` only signals that a lock
|
|
124
|
+
* was wanted (matching this dialect's long-standing behaviour).
|
|
125
|
+
*/
|
|
126
|
+
export declare const MARIADB_LOCK_SPEC: LockClauseSpec;
|
|
127
|
+
/**
|
|
128
|
+
* Oracle: `FOR UPDATE [OF column] [NOWAIT | SKIP LOCKED]`.
|
|
129
|
+
*
|
|
130
|
+
* Oracle has no shared row lock (`SHARE`/`KEY SHARE` have no equivalent), and
|
|
131
|
+
* its `OF` names *columns*, not a table - a `lock.of` model can't be turned into
|
|
132
|
+
* one, so `of` is treated as a plain `FOR UPDATE` request exactly as it always
|
|
133
|
+
* has been.
|
|
134
|
+
*/
|
|
135
|
+
export declare const ORACLE_LOCK_SPEC: LockClauseSpec;
|
|
136
|
+
/**
|
|
137
|
+
* Db2: `FOR UPDATE`, plus the `WITH RS` isolation clause for a read-stability
|
|
138
|
+
* (shared) lock. Db2 spells lock-avoidance as `SKIP LOCKED DATA` inside an
|
|
139
|
+
* isolation clause and has no `NOWAIT` at all, so both modifiers throw rather
|
|
140
|
+
* than being approximated.
|
|
141
|
+
*/
|
|
142
|
+
export declare const DB2_LOCK_SPEC: LockClauseSpec;
|
|
143
|
+
/** SAP HANA: `FOR UPDATE [NOWAIT]`. No shared row lock and no `SKIP LOCKED`. */
|
|
144
|
+
export declare const HANA_LOCK_SPEC: LockClauseSpec;
|
|
145
|
+
/**
|
|
146
|
+
* Build the SQL Server locking table hint, e.g. `WITH (UPDLOCK, ROWLOCK)`.
|
|
147
|
+
*
|
|
148
|
+
* T-SQL has no `FOR UPDATE`; row locking is requested with hints on the table
|
|
149
|
+
* reference: `UPDLOCK`/`HOLDLOCK` for the lock itself, `ROWLOCK` to pin the
|
|
150
|
+
* granularity to rows, `READPAST` for `SKIP LOCKED` and `NOWAIT` for `NOWAIT`.
|
|
151
|
+
*
|
|
152
|
+
* Returns `''` when there is no lock to apply.
|
|
153
|
+
*
|
|
154
|
+
* @param lock - the raw `options.lock` value
|
|
155
|
+
* @param tableName - the table the hint will be attached to, so a `lock.of`
|
|
156
|
+
* naming some *other* table can be rejected instead of silently locking the
|
|
157
|
+
* wrong one (a hint only applies to the table reference it sits on).
|
|
158
|
+
*/
|
|
159
|
+
export declare function buildSqlServerLockHint(lock: unknown, tableName?: string): string;
|
|
160
|
+
/**
|
|
161
|
+
* Look up the locking spec for a dialect name. Returns `undefined` for a
|
|
162
|
+
* dialect with no row-level locking (SQLite and friends) and for SQL Server,
|
|
163
|
+
* whose locking is a table hint rather than a trailing clause - callers should
|
|
164
|
+
* treat `undefined` as "emit no trailing lock clause".
|
|
165
|
+
*/
|
|
166
|
+
export declare function getLockSpecForDialect(dialect: string): LockClauseSpec | undefined;
|
|
167
|
+
export {};
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared compiler for `FindOptions.lock` (row-level locking).
|
|
4
|
+
*
|
|
5
|
+
* Every dialect used to re-implement the `lock` option inline inside its own
|
|
6
|
+
* `buildSelectQuery()`, and every one of those copies understood a slightly
|
|
7
|
+
* different subset of the documented `LockOptions` shapes. The object forms
|
|
8
|
+
* (`{ level }`, `{ level, nowait }`, `{ level, skipLocked }`, `{ skipLocked }`)
|
|
9
|
+
* fell through most of them and compiled to *nothing* - the caller asked for a
|
|
10
|
+
* lock, got a plain `SELECT`, and only found out under concurrency. This module
|
|
11
|
+
* centralises the parsing (`normalizeLockOptions`) and the SQL assembly
|
|
12
|
+
* (`buildLockClause`) so a shape can only be dropped by deliberately leaving it
|
|
13
|
+
* out of a dialect's {@link LockClauseSpec} - and a spec that cannot express
|
|
14
|
+
* what was asked for throws instead of silently emitting a weaker lock.
|
|
15
|
+
*
|
|
16
|
+
* Dialects with no row-level locking at all (SQLite and friends) simply never
|
|
17
|
+
* call in here: ignoring `lock` is a deliberate, documented decision for them
|
|
18
|
+
* (SQLite serialises writers anyway), not an oversight.
|
|
19
|
+
*
|
|
20
|
+
* SQL Server is the odd one out - it expresses row locking as a table hint
|
|
21
|
+
* (`FROM t WITH (UPDLOCK, ROWLOCK)`) rather than a trailing clause - so it
|
|
22
|
+
* shares the parsing/validation via {@link buildSqlServerLockHint} while
|
|
23
|
+
* rendering its own syntax.
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.HANA_LOCK_SPEC = exports.DB2_LOCK_SPEC = exports.ORACLE_LOCK_SPEC = exports.MARIADB_LOCK_SPEC = exports.MYSQL_LOCK_SPEC = exports.COCKROACHDB_LOCK_SPEC = exports.POSTGRES_LOCK_SPEC = void 0;
|
|
27
|
+
exports.normalizeLockOptions = normalizeLockOptions;
|
|
28
|
+
exports.buildLockClause = buildLockClause;
|
|
29
|
+
exports.appendLockClause = appendLockClause;
|
|
30
|
+
exports.buildSqlServerLockHint = buildSqlServerLockHint;
|
|
31
|
+
exports.getLockSpecForDialect = getLockSpecForDialect;
|
|
32
|
+
const KNOWN_LEVELS = ['UPDATE', 'SHARE', 'KEY SHARE', 'NO KEY UPDATE'];
|
|
33
|
+
function levelList(spec) {
|
|
34
|
+
return Object.keys(spec.levels).join(', ');
|
|
35
|
+
}
|
|
36
|
+
function parseLevel(value) {
|
|
37
|
+
if (typeof value !== 'string') {
|
|
38
|
+
throw new Error(`Invalid lock level ${JSON.stringify(value)}. Expected one of: ${KNOWN_LEVELS.join(', ')}.`);
|
|
39
|
+
}
|
|
40
|
+
const normalized = value.trim().toUpperCase().replace(/\s+/g, ' ');
|
|
41
|
+
if (KNOWN_LEVELS.includes(normalized)) {
|
|
42
|
+
return normalized;
|
|
43
|
+
}
|
|
44
|
+
throw new Error(`Unknown lock level ${JSON.stringify(value)}. Expected one of: ${KNOWN_LEVELS.join(', ')}.`);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Collapse any documented `lock` shape into a {@link NormalizedLock}.
|
|
48
|
+
*
|
|
49
|
+
* Returns `undefined` for a falsy lock (`undefined`, `false`, `null`), which
|
|
50
|
+
* every caller treats as "no locking clause".
|
|
51
|
+
*
|
|
52
|
+
* Accepted shapes:
|
|
53
|
+
* - `true` -> `FOR UPDATE`
|
|
54
|
+
* - `'UPDATE' | 'SHARE' | 'KEY SHARE' | 'NO KEY UPDATE'` (case-insensitive)
|
|
55
|
+
* - `{ of: Model }` -> `FOR UPDATE` scoped to that table
|
|
56
|
+
* - `{ level?, nowait?, skipLocked?, of? }` -> level defaults to `UPDATE`
|
|
57
|
+
*
|
|
58
|
+
* `mode` is accepted as an alias for `level` and `noWait` for `nowait`, since
|
|
59
|
+
* the MariaDB dialect has always documented those spellings.
|
|
60
|
+
*
|
|
61
|
+
* Throws on a level it doesn't recognise rather than quietly emitting no lock.
|
|
62
|
+
*/
|
|
63
|
+
function normalizeLockOptions(lock) {
|
|
64
|
+
if (!lock) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
if (lock === true) {
|
|
68
|
+
return { level: 'UPDATE', nowait: false, skipLocked: false };
|
|
69
|
+
}
|
|
70
|
+
if (typeof lock === 'string') {
|
|
71
|
+
return { level: parseLevel(lock), nowait: false, skipLocked: false };
|
|
72
|
+
}
|
|
73
|
+
if (typeof lock !== 'object') {
|
|
74
|
+
throw new Error(`Invalid "lock" option: expected true, a lock level string, or an options object, got ${typeof lock}.`);
|
|
75
|
+
}
|
|
76
|
+
const raw = lock;
|
|
77
|
+
const rawLevel = raw.level ?? raw.mode;
|
|
78
|
+
const level = rawLevel === undefined || rawLevel === null ? 'UPDATE' : parseLevel(rawLevel);
|
|
79
|
+
const nowait = raw.nowait === true || raw.noWait === true;
|
|
80
|
+
const skipLocked = raw.skipLocked === true;
|
|
81
|
+
if (nowait && skipLocked) {
|
|
82
|
+
throw new Error('Invalid "lock" option: NOWAIT and SKIP LOCKED are mutually exclusive - set only one of lock.nowait / lock.skipLocked.');
|
|
83
|
+
}
|
|
84
|
+
return { level, nowait, skipLocked, of: raw.of };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Build the trailing locking clause for a dialect, e.g. `FOR UPDATE OF "users" NOWAIT`.
|
|
88
|
+
*
|
|
89
|
+
* Returns `''` when there is no lock to apply. Throws when the requested lock
|
|
90
|
+
* cannot be expressed by this dialect - a lock the caller believes they hold
|
|
91
|
+
* but don't is far worse than a loud failure at query-build time.
|
|
92
|
+
*
|
|
93
|
+
* @param lock - the raw `options.lock` value
|
|
94
|
+
* @param spec - the dialect's locking capabilities
|
|
95
|
+
* @param escapeId - the dialect's identifier quoter, used for `lock.of`
|
|
96
|
+
*/
|
|
97
|
+
function buildLockClause(lock, spec, escapeId = (id) => id) {
|
|
98
|
+
const normalized = normalizeLockOptions(lock);
|
|
99
|
+
if (!normalized) {
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
const levelSql = spec.levels[normalized.level];
|
|
103
|
+
if (levelSql === undefined) {
|
|
104
|
+
throw new Error(`${spec.name} does not support ${normalized.level} row locking. Supported lock levels: ${levelList(spec)}.`);
|
|
105
|
+
}
|
|
106
|
+
let clause = typeof levelSql === 'function' ? levelSql(normalized) : levelSql;
|
|
107
|
+
if (normalized.of && spec.renderOf) {
|
|
108
|
+
const ofLevels = spec.ofLevels ?? Object.keys(spec.levels);
|
|
109
|
+
if (ofLevels.includes(normalized.level)) {
|
|
110
|
+
const ofSql = spec.renderOf(normalized.of, escapeId);
|
|
111
|
+
if (ofSql) {
|
|
112
|
+
clause += ` ${ofSql}`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (normalized.nowait) {
|
|
117
|
+
if (!spec.nowaitLevels?.includes(normalized.level)) {
|
|
118
|
+
throw new Error(`${spec.name} does not support NOWAIT with a ${normalized.level} lock. ` +
|
|
119
|
+
`Remove lock.nowait, or use a lock level that supports it${spec.nowaitLevels?.length ? ` (${spec.nowaitLevels.join(', ')})` : ''}.`);
|
|
120
|
+
}
|
|
121
|
+
clause += ' NOWAIT';
|
|
122
|
+
}
|
|
123
|
+
else if (normalized.skipLocked) {
|
|
124
|
+
if (!spec.skipLockedLevels?.includes(normalized.level)) {
|
|
125
|
+
throw new Error(`${spec.name} does not support SKIP LOCKED with a ${normalized.level} lock. ` +
|
|
126
|
+
`Remove lock.skipLocked, or use a lock level that supports it${spec.skipLockedLevels?.length ? ` (${spec.skipLockedLevels.join(', ')})` : ''}.`);
|
|
127
|
+
}
|
|
128
|
+
clause += ' SKIP LOCKED';
|
|
129
|
+
}
|
|
130
|
+
return clause;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Same as {@link buildLockClause} but returns the clause with a leading space
|
|
134
|
+
* (or `''`), which is how every `buildSelectQuery()` wants to append it.
|
|
135
|
+
*/
|
|
136
|
+
function appendLockClause(lock, spec, escapeId) {
|
|
137
|
+
const clause = buildLockClause(lock, spec, escapeId);
|
|
138
|
+
return clause ? ` ${clause}` : '';
|
|
139
|
+
}
|
|
140
|
+
/* -------------------------------------------------------------------------- */
|
|
141
|
+
/* Per-dialect specs */
|
|
142
|
+
/* -------------------------------------------------------------------------- */
|
|
143
|
+
/**
|
|
144
|
+
* PostgreSQL: `FOR UPDATE | NO KEY UPDATE | SHARE | KEY SHARE [OF table] [NOWAIT | SKIP LOCKED]`.
|
|
145
|
+
* The full matrix - every level accepts both modifiers and the `OF` clause.
|
|
146
|
+
*/
|
|
147
|
+
exports.POSTGRES_LOCK_SPEC = {
|
|
148
|
+
name: 'PostgreSQL',
|
|
149
|
+
levels: {
|
|
150
|
+
UPDATE: 'FOR UPDATE',
|
|
151
|
+
'NO KEY UPDATE': 'FOR NO KEY UPDATE',
|
|
152
|
+
SHARE: 'FOR SHARE',
|
|
153
|
+
'KEY SHARE': 'FOR KEY SHARE',
|
|
154
|
+
},
|
|
155
|
+
nowaitLevels: KNOWN_LEVELS,
|
|
156
|
+
skipLockedLevels: KNOWN_LEVELS,
|
|
157
|
+
// Historically `OF` was emitted even for a model with no tableName (as `OF ""`);
|
|
158
|
+
// keep that byte-for-byte rather than silently dropping the requested scope.
|
|
159
|
+
renderOf: (model, escapeId) => `OF ${escapeId(model.tableName || '')}`,
|
|
160
|
+
};
|
|
161
|
+
/** CockroachDB implements the PostgreSQL locking grammar. */
|
|
162
|
+
exports.COCKROACHDB_LOCK_SPEC = {
|
|
163
|
+
...exports.POSTGRES_LOCK_SPEC,
|
|
164
|
+
name: 'CockroachDB',
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* MySQL 8.0+: `FOR UPDATE [OF tbl] [NOWAIT | SKIP LOCKED]` and
|
|
168
|
+
* `FOR SHARE [OF tbl] [NOWAIT | SKIP LOCKED]`.
|
|
169
|
+
*
|
|
170
|
+
* A bare shared lock still compiles to the pre-8.0 `LOCK IN SHARE MODE`
|
|
171
|
+
* spelling (which every supported MySQL understands, and which existing
|
|
172
|
+
* `lock: 'SHARE'` callers already get); it only switches to the 8.0 `FOR SHARE`
|
|
173
|
+
* form when a modifier is requested, because `LOCK IN SHARE MODE` accepts
|
|
174
|
+
* neither `NOWAIT` nor `SKIP LOCKED`.
|
|
175
|
+
*/
|
|
176
|
+
exports.MYSQL_LOCK_SPEC = {
|
|
177
|
+
name: 'MySQL',
|
|
178
|
+
levels: {
|
|
179
|
+
UPDATE: 'FOR UPDATE',
|
|
180
|
+
SHARE: (lock) => (lock.nowait || lock.skipLocked ? 'FOR SHARE' : 'LOCK IN SHARE MODE'),
|
|
181
|
+
},
|
|
182
|
+
nowaitLevels: ['UPDATE', 'SHARE'],
|
|
183
|
+
skipLockedLevels: ['UPDATE', 'SHARE'],
|
|
184
|
+
renderOf: (model, escapeId) => (model.tableName ? `OF ${escapeId(model.tableName)}` : ''),
|
|
185
|
+
ofLevels: ['UPDATE'],
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* MariaDB: `FOR UPDATE` / `LOCK IN SHARE MODE` on every version, with
|
|
189
|
+
* `FOR SHARE` and the `SKIP LOCKED` / `NOWAIT` modifiers from 10.6.
|
|
190
|
+
*
|
|
191
|
+
* MariaDB has no `FOR UPDATE OF <table>`, so `lock.of` only signals that a lock
|
|
192
|
+
* was wanted (matching this dialect's long-standing behaviour).
|
|
193
|
+
*/
|
|
194
|
+
exports.MARIADB_LOCK_SPEC = {
|
|
195
|
+
name: 'MariaDB',
|
|
196
|
+
levels: {
|
|
197
|
+
UPDATE: 'FOR UPDATE',
|
|
198
|
+
SHARE: (lock) => (lock.nowait || lock.skipLocked ? 'FOR SHARE' : 'LOCK IN SHARE MODE'),
|
|
199
|
+
},
|
|
200
|
+
nowaitLevels: ['UPDATE', 'SHARE'],
|
|
201
|
+
skipLockedLevels: ['UPDATE', 'SHARE'],
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* Oracle: `FOR UPDATE [OF column] [NOWAIT | SKIP LOCKED]`.
|
|
205
|
+
*
|
|
206
|
+
* Oracle has no shared row lock (`SHARE`/`KEY SHARE` have no equivalent), and
|
|
207
|
+
* its `OF` names *columns*, not a table - a `lock.of` model can't be turned into
|
|
208
|
+
* one, so `of` is treated as a plain `FOR UPDATE` request exactly as it always
|
|
209
|
+
* has been.
|
|
210
|
+
*/
|
|
211
|
+
exports.ORACLE_LOCK_SPEC = {
|
|
212
|
+
name: 'Oracle',
|
|
213
|
+
levels: {
|
|
214
|
+
UPDATE: 'FOR UPDATE',
|
|
215
|
+
},
|
|
216
|
+
nowaitLevels: ['UPDATE'],
|
|
217
|
+
skipLockedLevels: ['UPDATE'],
|
|
218
|
+
};
|
|
219
|
+
/**
|
|
220
|
+
* Db2: `FOR UPDATE`, plus the `WITH RS` isolation clause for a read-stability
|
|
221
|
+
* (shared) lock. Db2 spells lock-avoidance as `SKIP LOCKED DATA` inside an
|
|
222
|
+
* isolation clause and has no `NOWAIT` at all, so both modifiers throw rather
|
|
223
|
+
* than being approximated.
|
|
224
|
+
*/
|
|
225
|
+
exports.DB2_LOCK_SPEC = {
|
|
226
|
+
name: 'Db2',
|
|
227
|
+
levels: {
|
|
228
|
+
UPDATE: 'FOR UPDATE',
|
|
229
|
+
SHARE: 'FOR UPDATE WITH RS',
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
/** SAP HANA: `FOR UPDATE [NOWAIT]`. No shared row lock and no `SKIP LOCKED`. */
|
|
233
|
+
exports.HANA_LOCK_SPEC = {
|
|
234
|
+
name: 'SAP HANA',
|
|
235
|
+
levels: {
|
|
236
|
+
UPDATE: 'FOR UPDATE',
|
|
237
|
+
},
|
|
238
|
+
nowaitLevels: ['UPDATE'],
|
|
239
|
+
};
|
|
240
|
+
/* -------------------------------------------------------------------------- */
|
|
241
|
+
/* SQL Server - table hints rather than a trailing clause */
|
|
242
|
+
/* -------------------------------------------------------------------------- */
|
|
243
|
+
const SQLSERVER_LEVEL_HINTS = {
|
|
244
|
+
UPDATE: 'UPDLOCK',
|
|
245
|
+
SHARE: 'HOLDLOCK',
|
|
246
|
+
};
|
|
247
|
+
/**
|
|
248
|
+
* Build the SQL Server locking table hint, e.g. `WITH (UPDLOCK, ROWLOCK)`.
|
|
249
|
+
*
|
|
250
|
+
* T-SQL has no `FOR UPDATE`; row locking is requested with hints on the table
|
|
251
|
+
* reference: `UPDLOCK`/`HOLDLOCK` for the lock itself, `ROWLOCK` to pin the
|
|
252
|
+
* granularity to rows, `READPAST` for `SKIP LOCKED` and `NOWAIT` for `NOWAIT`.
|
|
253
|
+
*
|
|
254
|
+
* Returns `''` when there is no lock to apply.
|
|
255
|
+
*
|
|
256
|
+
* @param lock - the raw `options.lock` value
|
|
257
|
+
* @param tableName - the table the hint will be attached to, so a `lock.of`
|
|
258
|
+
* naming some *other* table can be rejected instead of silently locking the
|
|
259
|
+
* wrong one (a hint only applies to the table reference it sits on).
|
|
260
|
+
*/
|
|
261
|
+
function buildSqlServerLockHint(lock, tableName) {
|
|
262
|
+
const normalized = normalizeLockOptions(lock);
|
|
263
|
+
if (!normalized) {
|
|
264
|
+
return '';
|
|
265
|
+
}
|
|
266
|
+
const levelHint = SQLSERVER_LEVEL_HINTS[normalized.level];
|
|
267
|
+
if (!levelHint) {
|
|
268
|
+
throw new Error(`SQL Server does not support ${normalized.level} row locking. Supported lock levels: UPDATE, SHARE.`);
|
|
269
|
+
}
|
|
270
|
+
if (normalized.of) {
|
|
271
|
+
const ofTable = normalized.of.tableName || normalized.of.name;
|
|
272
|
+
if (ofTable && tableName && ofTable !== tableName) {
|
|
273
|
+
throw new Error(`SQL Server cannot scope a lock to ${JSON.stringify(ofTable)} from a query on ${JSON.stringify(tableName)}: locking is expressed as a table hint, which only applies to the table it is attached to.`);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const hints = [levelHint, 'ROWLOCK'];
|
|
277
|
+
if (normalized.nowait) {
|
|
278
|
+
hints.push('NOWAIT');
|
|
279
|
+
}
|
|
280
|
+
else if (normalized.skipLocked) {
|
|
281
|
+
hints.push('READPAST');
|
|
282
|
+
}
|
|
283
|
+
return `WITH (${hints.join(', ')})`;
|
|
284
|
+
}
|
|
285
|
+
/* -------------------------------------------------------------------------- */
|
|
286
|
+
/* Dialect-name lookup */
|
|
287
|
+
/* -------------------------------------------------------------------------- */
|
|
288
|
+
const SPECS_BY_DIALECT = {
|
|
289
|
+
postgres: exports.POSTGRES_LOCK_SPEC,
|
|
290
|
+
postgresql: exports.POSTGRES_LOCK_SPEC,
|
|
291
|
+
pg: exports.POSTGRES_LOCK_SPEC,
|
|
292
|
+
greenplum: exports.POSTGRES_LOCK_SPEC,
|
|
293
|
+
timescaledb: exports.POSTGRES_LOCK_SPEC,
|
|
294
|
+
yugabytedb: exports.POSTGRES_LOCK_SPEC,
|
|
295
|
+
vertica: exports.POSTGRES_LOCK_SPEC,
|
|
296
|
+
cockroachdb: exports.COCKROACHDB_LOCK_SPEC,
|
|
297
|
+
mysql: exports.MYSQL_LOCK_SPEC,
|
|
298
|
+
tidb: exports.MYSQL_LOCK_SPEC,
|
|
299
|
+
singlestore: exports.MYSQL_LOCK_SPEC,
|
|
300
|
+
mariadb: exports.MARIADB_LOCK_SPEC,
|
|
301
|
+
oracle: exports.ORACLE_LOCK_SPEC,
|
|
302
|
+
db2: exports.DB2_LOCK_SPEC,
|
|
303
|
+
hana: exports.HANA_LOCK_SPEC,
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Look up the locking spec for a dialect name. Returns `undefined` for a
|
|
307
|
+
* dialect with no row-level locking (SQLite and friends) and for SQL Server,
|
|
308
|
+
* whose locking is a table hint rather than a trailing clause - callers should
|
|
309
|
+
* treat `undefined` as "emit no trailing lock clause".
|
|
310
|
+
*/
|
|
311
|
+
function getLockSpecForDialect(dialect) {
|
|
312
|
+
if (typeof dialect !== 'string') {
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
return SPECS_BY_DIALECT[dialect.toLowerCase()];
|
|
316
|
+
}
|
|
@@ -740,10 +740,13 @@ export declare class MariaDBDialect implements Dialect {
|
|
|
740
740
|
*/
|
|
741
741
|
removeIndex(tableName: string, indexName: string): Promise<void>;
|
|
742
742
|
/**
|
|
743
|
-
*
|
|
744
|
-
*
|
|
743
|
+
* Partial (filtered) indexes - not available on MariaDB.
|
|
744
|
+
*
|
|
745
|
+
* The claim that MariaDB 10.0.3 added them is wrong: `CREATE INDEX` has never
|
|
746
|
+
* taken a `WHERE` clause on MariaDB (a live mariadb:11 server answers
|
|
747
|
+
* ER_PARSE_ERROR), so this throws rather than build that statement.
|
|
745
748
|
*/
|
|
746
|
-
createPartialIndex(
|
|
749
|
+
createPartialIndex(_tableName: string, _indexName: string, _fields: string[], _where: string, _options?: IndexOptions): Promise<void>;
|
|
747
750
|
/**
|
|
748
751
|
* Create an index on a table with full options support
|
|
749
752
|
*/
|
|
@@ -753,7 +756,7 @@ export declare class MariaDBDialect implements Dialect {
|
|
|
753
756
|
type?: string;
|
|
754
757
|
using?: string;
|
|
755
758
|
fields: string[];
|
|
756
|
-
where?: WhereOptions;
|
|
759
|
+
where?: WhereOptions | string;
|
|
757
760
|
invisible?: boolean;
|
|
758
761
|
}): Promise<void>;
|
|
759
762
|
/**
|