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
|
@@ -9,6 +9,8 @@ exports.createOrderBuilder = createOrderBuilder;
|
|
|
9
9
|
exports.createOrderLimitBuilder = createOrderLimitBuilder;
|
|
10
10
|
exports.buildOrder = buildOrder;
|
|
11
11
|
exports.buildLimitOffset = buildLimitOffset;
|
|
12
|
+
const operators_1 = require("../operators");
|
|
13
|
+
const order_expression_helper_1 = require("../dialects/order-expression-helper");
|
|
12
14
|
/**
|
|
13
15
|
* OrderBuilder class for building ORDER BY clauses
|
|
14
16
|
*/
|
|
@@ -45,18 +47,18 @@ class OrderBuilder {
|
|
|
45
47
|
return item;
|
|
46
48
|
}
|
|
47
49
|
// Handle OrderExpression from order helper functions (asc, desc, random)
|
|
48
|
-
if (
|
|
49
|
-
const
|
|
50
|
-
if (direction === 'RANDOM') {
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return 'RAND()';
|
|
55
|
-
}
|
|
56
|
-
// Default to RANDOM() (SQLite/PostgreSQL)
|
|
50
|
+
if ((0, operators_1.isOrderExpression)(item)) {
|
|
51
|
+
const dialectName = this.options.dialect?.name;
|
|
52
|
+
if (!dialectName && item.direction === 'RANDOM') {
|
|
53
|
+
// Standalone builder with no dialect configured: there is nothing to
|
|
54
|
+
// look the random function up by, so keep the historical default
|
|
55
|
+
// rather than throwing.
|
|
57
56
|
return 'RANDOM()';
|
|
58
57
|
}
|
|
59
|
-
|
|
58
|
+
// Otherwise render through the same shared helper the dialects' own
|
|
59
|
+
// buildOrderClause() uses, so `order: [desc('name')]` / `random()`
|
|
60
|
+
// produce identical SQL whichever of the two paths a query takes.
|
|
61
|
+
return (0, order_expression_helper_1.renderOrderExpression)({ name: dialectName, escapeId: (id) => this.escapeId(id) }, item);
|
|
60
62
|
}
|
|
61
63
|
// Handle array: ['field', 'ASC'] or [['field', 'ASC'], ['field2', 'DESC']]
|
|
62
64
|
if (Array.isArray(item)) {
|
|
@@ -468,11 +468,18 @@ export declare class SqlCompiler {
|
|
|
468
468
|
*/
|
|
469
469
|
private compileFrameBound;
|
|
470
470
|
/**
|
|
471
|
-
* Compile lock options for row-level locking
|
|
472
|
-
*
|
|
471
|
+
* Compile lock options for row-level locking.
|
|
472
|
+
*
|
|
473
|
+
* Delegates to the shared dialect lock compiler so this and each dialect's
|
|
474
|
+
* own `buildSelectQuery()` can never disagree about what a given `lock` shape
|
|
475
|
+
* means. Supports `true`, a level string, and the
|
|
476
|
+
* `{ level, nowait, skipLocked, of }` object form; throws when the named
|
|
477
|
+
* dialect cannot express the requested lock.
|
|
478
|
+
*
|
|
473
479
|
* @param lock - Lock options
|
|
474
480
|
* @param dialect - The database dialect
|
|
475
|
-
* @returns The compiled lock SQL clause
|
|
481
|
+
* @returns The compiled lock SQL clause, or an empty string for no lock and
|
|
482
|
+
* for dialects with no trailing locking clause (SQLite, SQL Server, ...)
|
|
476
483
|
*/
|
|
477
484
|
compileLockOptions(lock: any, dialect?: string): string;
|
|
478
485
|
/**
|
|
@@ -15,6 +15,7 @@ exports.jsonKeys = jsonKeys;
|
|
|
15
15
|
exports.jsonLength = jsonLength;
|
|
16
16
|
exports.jsonContains = jsonContains;
|
|
17
17
|
exports.jsonSearch = jsonSearch;
|
|
18
|
+
const lock_clause_helper_1 = require("../dialects/lock-clause-helper");
|
|
18
19
|
const operators_1 = require("../operators");
|
|
19
20
|
/**
|
|
20
21
|
* Default compiler options
|
|
@@ -1816,55 +1817,25 @@ class SqlCompiler {
|
|
|
1816
1817
|
return bound === 1 ? '1 FOLLOWING' : `${bound} FOLLOWING`;
|
|
1817
1818
|
}
|
|
1818
1819
|
/**
|
|
1819
|
-
* Compile lock options for row-level locking
|
|
1820
|
-
*
|
|
1820
|
+
* Compile lock options for row-level locking.
|
|
1821
|
+
*
|
|
1822
|
+
* Delegates to the shared dialect lock compiler so this and each dialect's
|
|
1823
|
+
* own `buildSelectQuery()` can never disagree about what a given `lock` shape
|
|
1824
|
+
* means. Supports `true`, a level string, and the
|
|
1825
|
+
* `{ level, nowait, skipLocked, of }` object form; throws when the named
|
|
1826
|
+
* dialect cannot express the requested lock.
|
|
1827
|
+
*
|
|
1821
1828
|
* @param lock - Lock options
|
|
1822
1829
|
* @param dialect - The database dialect
|
|
1823
|
-
* @returns The compiled lock SQL clause
|
|
1830
|
+
* @returns The compiled lock SQL clause, or an empty string for no lock and
|
|
1831
|
+
* for dialects with no trailing locking clause (SQLite, SQL Server, ...)
|
|
1824
1832
|
*/
|
|
1825
1833
|
compileLockOptions(lock, dialect = 'postgres') {
|
|
1826
|
-
|
|
1834
|
+
const spec = (0, lock_clause_helper_1.getLockSpecForDialect)(dialect);
|
|
1835
|
+
if (!spec) {
|
|
1827
1836
|
return '';
|
|
1828
1837
|
}
|
|
1829
|
-
|
|
1830
|
-
let nowait = false;
|
|
1831
|
-
let skipLocked = false;
|
|
1832
|
-
// Extract lock configuration
|
|
1833
|
-
if (lock === true) {
|
|
1834
|
-
lockType = 'UPDATE';
|
|
1835
|
-
}
|
|
1836
|
-
else if (typeof lock === 'string') {
|
|
1837
|
-
lockType = lock;
|
|
1838
|
-
}
|
|
1839
|
-
else if (typeof lock === 'object') {
|
|
1840
|
-
lockType = lock.level || lock;
|
|
1841
|
-
nowait = lock.nowait === true;
|
|
1842
|
-
skipLocked = lock.skipLocked === true;
|
|
1843
|
-
}
|
|
1844
|
-
// Build base lock clause
|
|
1845
|
-
let lockClause = '';
|
|
1846
|
-
if (lockType === 'UPDATE' || lockType === 'UPDATE') {
|
|
1847
|
-
lockClause = 'FOR UPDATE';
|
|
1848
|
-
}
|
|
1849
|
-
else if (lockType === 'SHARE') {
|
|
1850
|
-
if (dialect === 'mysql') {
|
|
1851
|
-
lockClause = 'LOCK IN SHARE MODE';
|
|
1852
|
-
}
|
|
1853
|
-
else {
|
|
1854
|
-
lockClause = 'FOR SHARE';
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
|
-
else if (lockType === 'KEY SHARE') {
|
|
1858
|
-
lockClause = 'FOR KEY SHARE';
|
|
1859
|
-
}
|
|
1860
|
-
// Add NOWAIT or SKIP LOCKED (PostgreSQL and MySQL 8.0+)
|
|
1861
|
-
if (nowait && (dialect === 'postgres' || dialect === 'mysql')) {
|
|
1862
|
-
lockClause += ' NOWAIT';
|
|
1863
|
-
}
|
|
1864
|
-
else if (skipLocked && (dialect === 'postgres' || dialect === 'mysql')) {
|
|
1865
|
-
lockClause += ' SKIP LOCKED';
|
|
1866
|
-
}
|
|
1867
|
-
return lockClause;
|
|
1838
|
+
return (0, lock_clause_helper_1.buildLockClause)(lock, spec);
|
|
1868
1839
|
}
|
|
1869
1840
|
/**
|
|
1870
1841
|
* Compile OVER clause with partition, order, and window frame
|
|
@@ -57,7 +57,8 @@ export interface ConstraintDefinition {
|
|
|
57
57
|
};
|
|
58
58
|
onDelete?: string;
|
|
59
59
|
onUpdate?: string;
|
|
60
|
-
where
|
|
60
|
+
/** Partial-index predicate; see `IndexOptions.where` in `src/dialects/dialect.ts`. */
|
|
61
|
+
where?: WhereOptions | string;
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
63
64
|
* Bulk operation options
|
package/dist/schema-objects.d.ts
CHANGED
|
@@ -16,6 +16,9 @@ export type SqlDialectName = 'mysql' | 'mariadb' | 'postgres' | 'cockroachdb' |
|
|
|
16
16
|
export declare class UnsupportedSchemaObjectError extends Error {
|
|
17
17
|
constructor(object: string, dialect: string, hint?: string);
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* A named sequence: its start, increment, bounds and caching.
|
|
21
|
+
*/
|
|
19
22
|
export interface SequenceOptions {
|
|
20
23
|
/** Value the sequence starts at (default 1) */
|
|
21
24
|
start?: number;
|
|
@@ -32,8 +35,18 @@ export interface SequenceOptions {
|
|
|
32
35
|
/** Emit IF NOT EXISTS where supported */
|
|
33
36
|
ifNotExists?: boolean;
|
|
34
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Builds `CREATE SEQUENCE` for the dialect.
|
|
40
|
+
*/
|
|
35
41
|
export declare function buildCreateSequenceSQL(name: string, options: SequenceOptions, dialect: SqlDialectName, quoteId: (id: string) => string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Builds `DROP SEQUENCE` for the dialect.
|
|
44
|
+
*/
|
|
36
45
|
export declare function buildDropSequenceSQL(name: string, dialect: SqlDialectName, quoteId: (id: string) => string, ifExists?: boolean): string;
|
|
46
|
+
/**
|
|
47
|
+
* A row-level security policy: who it applies to, which command, and the
|
|
48
|
+
* expressions that decide visibility (`using`) and writability (`withCheck`).
|
|
49
|
+
*/
|
|
37
50
|
export interface PolicyOptions {
|
|
38
51
|
/** Table the policy applies to */
|
|
39
52
|
table: string;
|
|
@@ -48,9 +61,23 @@ export interface PolicyOptions {
|
|
|
48
61
|
/** Roles the policy applies to */
|
|
49
62
|
to?: string[];
|
|
50
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Builds the statement that turns row-level security on for a table. Until
|
|
66
|
+
* this runs, policies are defined but not enforced.
|
|
67
|
+
*/
|
|
51
68
|
export declare function buildEnableRowLevelSecuritySQL(table: string, dialect: SqlDialectName, quoteTable: (t: string) => string, enable?: boolean): string;
|
|
69
|
+
/**
|
|
70
|
+
* Builds `CREATE POLICY` for a row-level security rule.
|
|
71
|
+
*/
|
|
52
72
|
export declare function buildCreatePolicySQL(options: PolicyOptions, dialect: SqlDialectName, quoteId: (id: string) => string, quoteTable: (t: string) => string): string;
|
|
73
|
+
/**
|
|
74
|
+
* Builds `DROP POLICY`.
|
|
75
|
+
*/
|
|
53
76
|
export declare function buildDropPolicySQL(name: string, table: string, dialect: SqlDialectName, quoteId: (id: string) => string, quoteTable: (t: string) => string, ifExists?: boolean): string;
|
|
77
|
+
/**
|
|
78
|
+
* A full-text index: the columns it covers, the language configuration, and
|
|
79
|
+
* any per-column weighting the engine supports.
|
|
80
|
+
*/
|
|
54
81
|
export interface FullTextIndexOptions {
|
|
55
82
|
/** Index name */
|
|
56
83
|
name: string;
|
|
@@ -61,7 +88,14 @@ export interface FullTextIndexOptions {
|
|
|
61
88
|
/** Text search configuration (PostgreSQL), e.g. 'english' */
|
|
62
89
|
language?: string;
|
|
63
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* Builds the engine's full-text index statement — a GIN index over a tsvector
|
|
93
|
+
* on PostgreSQL, `FULLTEXT` on MySQL, an FTS5 virtual table on SQLite.
|
|
94
|
+
*/
|
|
64
95
|
export declare function buildCreateFullTextIndexSQL(options: FullTextIndexOptions, dialect: SqlDialectName, quoteId: (id: string) => string, quoteTable: (t: string) => string): string;
|
|
96
|
+
/**
|
|
97
|
+
* A trigger: when it fires, on which events, and the body it runs.
|
|
98
|
+
*/
|
|
65
99
|
export interface TriggerDefinition {
|
|
66
100
|
name: string;
|
|
67
101
|
table: string;
|
|
@@ -74,5 +108,13 @@ export interface TriggerDefinition {
|
|
|
74
108
|
/** Condition guarding the trigger */
|
|
75
109
|
when?: string;
|
|
76
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Builds the statements a trigger needs. Some engines want a separate
|
|
113
|
+
* function or procedure before the trigger itself, so this returns a list
|
|
114
|
+
* rather than one statement.
|
|
115
|
+
*/
|
|
77
116
|
export declare function buildCreateTriggerStatements(trigger: TriggerDefinition, dialect: SqlDialectName, quoteId: (id: string) => string, quoteTable: (t: string) => string): string[];
|
|
117
|
+
/**
|
|
118
|
+
* Builds `DROP TRIGGER`.
|
|
119
|
+
*/
|
|
78
120
|
export declare function buildDropTriggerSQL(name: string, table: string, dialect: SqlDialectName, quoteId: (id: string) => string, quoteTable: (t: string) => string, ifExists?: boolean): string;
|
package/dist/schema-objects.js
CHANGED
|
@@ -54,6 +54,9 @@ class UnsupportedSchemaObjectError extends Error {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
exports.UnsupportedSchemaObjectError = UnsupportedSchemaObjectError;
|
|
57
|
+
/**
|
|
58
|
+
* Builds `CREATE SEQUENCE` for the dialect.
|
|
59
|
+
*/
|
|
57
60
|
function buildCreateSequenceSQL(name, options, dialect, quoteId) {
|
|
58
61
|
if (isSqliteFamily(dialect)) {
|
|
59
62
|
throw new UnsupportedSchemaObjectError('CREATE SEQUENCE', dialect, 'SQLite has no sequences - use an INTEGER PRIMARY KEY AUTOINCREMENT column instead.');
|
|
@@ -83,6 +86,9 @@ function buildCreateSequenceSQL(name, options, dialect, quoteId) {
|
|
|
83
86
|
parts.push('CYCLE');
|
|
84
87
|
return parts.join(' ');
|
|
85
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Builds `DROP SEQUENCE` for the dialect.
|
|
91
|
+
*/
|
|
86
92
|
function buildDropSequenceSQL(name, dialect, quoteId, ifExists = true) {
|
|
87
93
|
if (isSqliteFamily(dialect) || dialect === 'mysql') {
|
|
88
94
|
throw new UnsupportedSchemaObjectError('DROP SEQUENCE', dialect);
|
|
@@ -91,6 +97,10 @@ function buildDropSequenceSQL(name, dialect, quoteId, ifExists = true) {
|
|
|
91
97
|
const guard = ifExists && dialect !== 'oracle' ? 'IF EXISTS ' : '';
|
|
92
98
|
return `DROP SEQUENCE ${guard}${quoteId(name)}`;
|
|
93
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Builds the statement that turns row-level security on for a table. Until
|
|
102
|
+
* this runs, policies are defined but not enforced.
|
|
103
|
+
*/
|
|
94
104
|
function buildEnableRowLevelSecuritySQL(table, dialect, quoteTable, enable = true) {
|
|
95
105
|
if (!isPostgresFamily(dialect)) {
|
|
96
106
|
throw new UnsupportedSchemaObjectError('Row-level security', dialect, dialect === 'mssql'
|
|
@@ -99,6 +109,9 @@ function buildEnableRowLevelSecuritySQL(table, dialect, quoteTable, enable = tru
|
|
|
99
109
|
}
|
|
100
110
|
return `ALTER TABLE ${quoteTable(table)} ${enable ? 'ENABLE' : 'DISABLE'} ROW LEVEL SECURITY`;
|
|
101
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Builds `CREATE POLICY` for a row-level security rule.
|
|
114
|
+
*/
|
|
102
115
|
function buildCreatePolicySQL(options, dialect, quoteId, quoteTable) {
|
|
103
116
|
if (!isPostgresFamily(dialect)) {
|
|
104
117
|
throw new UnsupportedSchemaObjectError('CREATE POLICY', dialect);
|
|
@@ -114,12 +127,19 @@ function buildCreatePolicySQL(options, dialect, quoteId, quoteTable) {
|
|
|
114
127
|
sql += ` WITH CHECK (${options.withCheck})`;
|
|
115
128
|
return sql;
|
|
116
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Builds `DROP POLICY`.
|
|
132
|
+
*/
|
|
117
133
|
function buildDropPolicySQL(name, table, dialect, quoteId, quoteTable, ifExists = true) {
|
|
118
134
|
if (!isPostgresFamily(dialect)) {
|
|
119
135
|
throw new UnsupportedSchemaObjectError('DROP POLICY', dialect);
|
|
120
136
|
}
|
|
121
137
|
return `DROP POLICY ${ifExists ? 'IF EXISTS ' : ''}${quoteId(name)} ON ${quoteTable(table)}`;
|
|
122
138
|
}
|
|
139
|
+
/**
|
|
140
|
+
* Builds the engine's full-text index statement — a GIN index over a tsvector
|
|
141
|
+
* on PostgreSQL, `FULLTEXT` on MySQL, an FTS5 virtual table on SQLite.
|
|
142
|
+
*/
|
|
123
143
|
function buildCreateFullTextIndexSQL(options, dialect, quoteId, quoteTable) {
|
|
124
144
|
const { name, table, columns, language = 'english' } = options;
|
|
125
145
|
if (!columns.length) {
|
|
@@ -145,6 +165,11 @@ function buildCreateFullTextIndexSQL(options, dialect, quoteId, quoteTable) {
|
|
|
145
165
|
}
|
|
146
166
|
throw new UnsupportedSchemaObjectError('Full-text index', dialect);
|
|
147
167
|
}
|
|
168
|
+
/**
|
|
169
|
+
* Builds the statements a trigger needs. Some engines want a separate
|
|
170
|
+
* function or procedure before the trigger itself, so this returns a list
|
|
171
|
+
* rather than one statement.
|
|
172
|
+
*/
|
|
148
173
|
function buildCreateTriggerStatements(trigger, dialect, quoteId, quoteTable) {
|
|
149
174
|
const { name, table, timing, event, body, forEach = 'ROW', when } = trigger;
|
|
150
175
|
if (isPostgresFamily(dialect)) {
|
|
@@ -188,6 +213,9 @@ function buildCreateTriggerStatements(trigger, dialect, quoteId, quoteTable) {
|
|
|
188
213
|
}
|
|
189
214
|
throw new UnsupportedSchemaObjectError('CREATE TRIGGER', dialect);
|
|
190
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Builds `DROP TRIGGER`.
|
|
218
|
+
*/
|
|
191
219
|
function buildDropTriggerSQL(name, table, dialect, quoteId, quoteTable, ifExists = true) {
|
|
192
220
|
const guard = ifExists ? 'IF EXISTS ' : '';
|
|
193
221
|
if (isMysqlFamily(dialect) || isSqliteFamily(dialect)) {
|
package/dist/sql-constants.d.ts
CHANGED
|
@@ -113,6 +113,14 @@ export interface PostgresConstants {
|
|
|
113
113
|
SEARCH_PATH: SearchPath;
|
|
114
114
|
AUTOCOMMIT: Autocommit;
|
|
115
115
|
CACHE: Cache;
|
|
116
|
+
/**
|
|
117
|
+
* Optional: PostgreSQL has no `SET FOREIGN_KEY_CHECKS`. The session-level
|
|
118
|
+
* equivalent is `session_replication_role`, which is present on true
|
|
119
|
+
* PostgreSQL and CockroachDB but absent from some PostgreSQL-derived engines
|
|
120
|
+
* (Redshift does not enforce foreign keys at all), so this is deliberately
|
|
121
|
+
* optional rather than a required member with a fake value.
|
|
122
|
+
*/
|
|
123
|
+
FOREIGN_KEY_CHECKS?: ForeignKeyChecks;
|
|
116
124
|
}
|
|
117
125
|
/**
|
|
118
126
|
* SQLite SQL constants
|
|
@@ -193,6 +201,10 @@ export declare const COCKROACHDB: CockroachDBConstants;
|
|
|
193
201
|
* Amazon Redshift SQL constants
|
|
194
202
|
* Redshift is derived from PostgreSQL 8.0.2 and only supports the
|
|
195
203
|
* SERIALIZABLE (default) and READ COMMITTED isolation levels.
|
|
204
|
+
*
|
|
205
|
+
* No FOREIGN_KEY_CHECKS: Redshift treats foreign keys as informational only -
|
|
206
|
+
* it never enforces them and has no `session_replication_role` - so there is
|
|
207
|
+
* nothing to turn off.
|
|
196
208
|
*/
|
|
197
209
|
export declare const REDSHIFT: RedshiftConstants;
|
|
198
210
|
/**
|
|
@@ -225,6 +237,38 @@ export declare const SQL: SQLConstants;
|
|
|
225
237
|
* 'cockroachdb', 'redshift', 'db2', 'snowflake', 'clickhouse')
|
|
226
238
|
*/
|
|
227
239
|
export declare function getConstantsForDialect(dialect: string): MySQLConstants | PostgresConstants | SQLiteConstants | DB2Constants | SnowflakeConstants | ClickHouseConstants;
|
|
240
|
+
/** Which end of the switch is wanted. */
|
|
241
|
+
export type ForeignKeyChecksMode = 'disable' | 'enable';
|
|
242
|
+
/**
|
|
243
|
+
* Raised when a dialect has no session-level foreign key switch.
|
|
244
|
+
*
|
|
245
|
+
* Mirrors `UnsupportedSchemaObjectError` in ./schema-objects: name the database
|
|
246
|
+
* and say what to do instead, rather than returning SQL that fails at the
|
|
247
|
+
* server. Declared here (not imported) to keep this module dependency-free.
|
|
248
|
+
*/
|
|
249
|
+
export declare class UnsupportedForeignKeyChecksError extends Error {
|
|
250
|
+
constructor(dialect: string, hint?: string);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* SQL that turns foreign key enforcement off/on for the current session.
|
|
254
|
+
*
|
|
255
|
+
* Every family has its own statement and they are not interchangeable:
|
|
256
|
+
* SQLite/Turso use a PRAGMA, the MySQL family a session variable, and the
|
|
257
|
+
* PostgreSQL family `session_replication_role`. Handing MySQL's
|
|
258
|
+
* `SET FOREIGN_KEY_CHECKS` to anything else - which is what the default branch
|
|
259
|
+
* used to do for every unlisted dialect, PostgreSQL included - produces a
|
|
260
|
+
* syntax error at the server, and the caller only finds out at runtime.
|
|
261
|
+
*
|
|
262
|
+
* The PostgreSQL form needs superuser, or a role granted
|
|
263
|
+
* `SET ON PARAMETER session_replication_role` (PostgreSQL 15+); on an ordinary
|
|
264
|
+
* application role the server answers `permission denied to set parameter`.
|
|
265
|
+
*
|
|
266
|
+
* @throws {UnsupportedForeignKeyChecksError} when the dialect has no
|
|
267
|
+
* session-level equivalent (SQL Server, Oracle and Db2 are per-table or
|
|
268
|
+
* per-constraint; Redshift, Snowflake, ClickHouse and friends do not enforce
|
|
269
|
+
* foreign keys at all).
|
|
270
|
+
*/
|
|
271
|
+
export declare function getForeignKeyChecksSQL(dialect: string, mode: ForeignKeyChecksMode): string;
|
|
228
272
|
/**
|
|
229
273
|
* Transaction isolation level enum
|
|
230
274
|
*/
|
package/dist/sql-constants.js
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* like foreign key checks, transaction isolation levels, etc.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.IsolationLevelEnum = exports.SQL = exports.CLICKHOUSE = exports.SNOWFLAKE = exports.DB2 = exports.REDSHIFT = exports.COCKROACHDB = exports.SQLITE = exports.POSTGRES = exports.MARIADB = exports.MYSQL = void 0;
|
|
8
|
+
exports.IsolationLevelEnum = exports.UnsupportedForeignKeyChecksError = exports.SQL = exports.CLICKHOUSE = exports.SNOWFLAKE = exports.DB2 = exports.REDSHIFT = exports.COCKROACHDB = exports.SQLITE = exports.POSTGRES = exports.MARIADB = exports.MYSQL = void 0;
|
|
9
9
|
exports.getConstantsForDialect = getConstantsForDialect;
|
|
10
|
+
exports.getForeignKeyChecksSQL = getForeignKeyChecksSQL;
|
|
10
11
|
/**
|
|
11
12
|
* MySQL/MariaDB SQL constants
|
|
12
13
|
*/
|
|
@@ -87,6 +88,22 @@ exports.POSTGRES = {
|
|
|
87
88
|
on: 'SET SESSION statement_cache_mode = ON',
|
|
88
89
|
off: 'SET SESSION statement_cache_mode = OFF',
|
|
89
90
|
},
|
|
91
|
+
/**
|
|
92
|
+
* PostgreSQL suppresses foreign key (and trigger) enforcement for the session
|
|
93
|
+
* by pretending to be a replication target. There is no `SET
|
|
94
|
+
* FOREIGN_KEY_CHECKS` - that is MySQL syntax and PostgreSQL rejects it with a
|
|
95
|
+
* syntax error.
|
|
96
|
+
*
|
|
97
|
+
* Requires superuser, or (PostgreSQL 15+) a role that has been granted
|
|
98
|
+
* `SET ON PARAMETER session_replication_role`. On a plain application role
|
|
99
|
+
* the server raises `permission denied to set parameter`; that error is left
|
|
100
|
+
* to surface rather than being swallowed, because silently continuing with
|
|
101
|
+
* foreign keys still enforced is the failure mode this replaced.
|
|
102
|
+
*/
|
|
103
|
+
FOREIGN_KEY_CHECKS: {
|
|
104
|
+
disable: "SET session_replication_role = 'replica'",
|
|
105
|
+
enable: "SET session_replication_role = 'origin'",
|
|
106
|
+
},
|
|
90
107
|
};
|
|
91
108
|
/**
|
|
92
109
|
* SQLite SQL constants
|
|
@@ -150,11 +167,21 @@ exports.COCKROACHDB = {
|
|
|
150
167
|
on: 'SET SESSION statement_cache_mode = ON',
|
|
151
168
|
off: 'SET SESSION statement_cache_mode = OFF',
|
|
152
169
|
},
|
|
170
|
+
/** CockroachDB implements `session_replication_role` (v22.2+) with the same
|
|
171
|
+
* `replica`/`origin` values as PostgreSQL. */
|
|
172
|
+
FOREIGN_KEY_CHECKS: {
|
|
173
|
+
disable: "SET session_replication_role = 'replica'",
|
|
174
|
+
enable: "SET session_replication_role = 'origin'",
|
|
175
|
+
},
|
|
153
176
|
};
|
|
154
177
|
/**
|
|
155
178
|
* Amazon Redshift SQL constants
|
|
156
179
|
* Redshift is derived from PostgreSQL 8.0.2 and only supports the
|
|
157
180
|
* SERIALIZABLE (default) and READ COMMITTED isolation levels.
|
|
181
|
+
*
|
|
182
|
+
* No FOREIGN_KEY_CHECKS: Redshift treats foreign keys as informational only -
|
|
183
|
+
* it never enforces them and has no `session_replication_role` - so there is
|
|
184
|
+
* nothing to turn off.
|
|
158
185
|
*/
|
|
159
186
|
exports.REDSHIFT = {
|
|
160
187
|
ISOLATION_LEVEL: {
|
|
@@ -284,10 +311,120 @@ function getConstantsForDialect(dialect) {
|
|
|
284
311
|
return exports.SNOWFLAKE;
|
|
285
312
|
case 'clickhouse':
|
|
286
313
|
return exports.CLICKHOUSE;
|
|
314
|
+
// Derived dialects report their own name but run the parent server's
|
|
315
|
+
// session SQL. Without these, `getConstantsForDialect('timescaledb')` fell
|
|
316
|
+
// through to the MySQL constants and handed MySQL syntax to a PostgreSQL
|
|
317
|
+
// server.
|
|
318
|
+
case 'timescaledb':
|
|
319
|
+
case 'greenplum':
|
|
320
|
+
case 'yugabytedb':
|
|
321
|
+
return exports.POSTGRES;
|
|
322
|
+
case 'turso':
|
|
323
|
+
return exports.SQLITE;
|
|
324
|
+
case 'tidb':
|
|
325
|
+
return exports.MYSQL;
|
|
287
326
|
default:
|
|
288
327
|
return exports.MYSQL;
|
|
289
328
|
}
|
|
290
329
|
}
|
|
330
|
+
// ==================== Foreign key checks ====================
|
|
331
|
+
/**
|
|
332
|
+
* Dialects whose session-level foreign key switch is SQLite's PRAGMA.
|
|
333
|
+
* Turso/libSQL is SQLite over the wire and shares the pragma verbatim.
|
|
334
|
+
*/
|
|
335
|
+
const SQLITE_FK_DIALECTS = new Set(['sqlite', 'turso']);
|
|
336
|
+
/**
|
|
337
|
+
* Dialects that implement MySQL's `SET FOREIGN_KEY_CHECKS` session variable.
|
|
338
|
+
*
|
|
339
|
+
* TiDB implements the variable for MySQL compatibility. SingleStore and
|
|
340
|
+
* Databricks extend the MySQL dialect class in this codebase but do not support
|
|
341
|
+
* enforced foreign keys at all, so they are deliberately absent - an explicit
|
|
342
|
+
* error naming the database beats a statement the server rejects.
|
|
343
|
+
*/
|
|
344
|
+
const MYSQL_FK_DIALECTS = new Set(['mysql', 'mariadb', 'tidb']);
|
|
345
|
+
/**
|
|
346
|
+
* Dialects that implement PostgreSQL's `session_replication_role`.
|
|
347
|
+
*
|
|
348
|
+
* TimescaleDB and Greenplum are PostgreSQL servers; YugabyteDB and CockroachDB
|
|
349
|
+
* reimplement the parameter with the same `replica`/`origin` values. Trino,
|
|
350
|
+
* CrateDB, QuestDB, Exasol, Vertica and Redshift extend the Postgres dialect
|
|
351
|
+
* class here but are separate engines with no such parameter (Redshift never
|
|
352
|
+
* enforces foreign keys in the first place), so they are left out.
|
|
353
|
+
*/
|
|
354
|
+
const POSTGRES_FK_DIALECTS = new Set([
|
|
355
|
+
'postgres',
|
|
356
|
+
'timescaledb',
|
|
357
|
+
'greenplum',
|
|
358
|
+
'yugabytedb',
|
|
359
|
+
'cockroachdb',
|
|
360
|
+
]);
|
|
361
|
+
/**
|
|
362
|
+
* Why a given dialect cannot switch foreign key enforcement for a whole
|
|
363
|
+
* session, and what to do instead. Used to build the thrown error message.
|
|
364
|
+
*/
|
|
365
|
+
const FK_CHECKS_UNSUPPORTED_HINTS = {
|
|
366
|
+
mssql: 'Use ALTER TABLE <table> NOCHECK CONSTRAINT ALL per table instead.',
|
|
367
|
+
oracle: 'Use ALTER TABLE <table> DISABLE CONSTRAINT <name> per constraint instead.',
|
|
368
|
+
db2: 'Use SET INTEGRITY FOR <table> OFF / IMMEDIATE CHECKED per table instead.',
|
|
369
|
+
redshift: 'Redshift treats foreign keys as informational only and never enforces them.',
|
|
370
|
+
snowflake: 'Snowflake does not enforce foreign keys, so there is nothing to disable.',
|
|
371
|
+
clickhouse: 'ClickHouse has no foreign key constraints.',
|
|
372
|
+
duckdb: 'DuckDB has no session-level switch; drop and recreate the constraint instead.',
|
|
373
|
+
singlestore: 'SingleStore does not support enforced foreign key constraints.',
|
|
374
|
+
databricks: 'Databricks foreign keys are informational only and are never enforced.',
|
|
375
|
+
spanner: 'Spanner has no session-level switch; drop and recreate the constraint instead.',
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Raised when a dialect has no session-level foreign key switch.
|
|
379
|
+
*
|
|
380
|
+
* Mirrors `UnsupportedSchemaObjectError` in ./schema-objects: name the database
|
|
381
|
+
* and say what to do instead, rather than returning SQL that fails at the
|
|
382
|
+
* server. Declared here (not imported) to keep this module dependency-free.
|
|
383
|
+
*/
|
|
384
|
+
class UnsupportedForeignKeyChecksError extends Error {
|
|
385
|
+
constructor(dialect, hint) {
|
|
386
|
+
super(`Session-level foreign key checks are not supported on ${dialect}` +
|
|
387
|
+
`${hint ? `. ${hint}` : ''}`);
|
|
388
|
+
this.name = 'UnsupportedForeignKeyChecksError';
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
exports.UnsupportedForeignKeyChecksError = UnsupportedForeignKeyChecksError;
|
|
392
|
+
/**
|
|
393
|
+
* SQL that turns foreign key enforcement off/on for the current session.
|
|
394
|
+
*
|
|
395
|
+
* Every family has its own statement and they are not interchangeable:
|
|
396
|
+
* SQLite/Turso use a PRAGMA, the MySQL family a session variable, and the
|
|
397
|
+
* PostgreSQL family `session_replication_role`. Handing MySQL's
|
|
398
|
+
* `SET FOREIGN_KEY_CHECKS` to anything else - which is what the default branch
|
|
399
|
+
* used to do for every unlisted dialect, PostgreSQL included - produces a
|
|
400
|
+
* syntax error at the server, and the caller only finds out at runtime.
|
|
401
|
+
*
|
|
402
|
+
* The PostgreSQL form needs superuser, or a role granted
|
|
403
|
+
* `SET ON PARAMETER session_replication_role` (PostgreSQL 15+); on an ordinary
|
|
404
|
+
* application role the server answers `permission denied to set parameter`.
|
|
405
|
+
*
|
|
406
|
+
* @throws {UnsupportedForeignKeyChecksError} when the dialect has no
|
|
407
|
+
* session-level equivalent (SQL Server, Oracle and Db2 are per-table or
|
|
408
|
+
* per-constraint; Redshift, Snowflake, ClickHouse and friends do not enforce
|
|
409
|
+
* foreign keys at all).
|
|
410
|
+
*/
|
|
411
|
+
function getForeignKeyChecksSQL(dialect, mode) {
|
|
412
|
+
if (SQLITE_FK_DIALECTS.has(dialect)) {
|
|
413
|
+
return mode === 'disable' ? exports.SQLITE.PRAGMA.foreign_keys.off : exports.SQLITE.PRAGMA.foreign_keys.on;
|
|
414
|
+
}
|
|
415
|
+
if (MYSQL_FK_DIALECTS.has(dialect)) {
|
|
416
|
+
return exports.MYSQL.FOREIGN_KEY_CHECKS[mode];
|
|
417
|
+
}
|
|
418
|
+
if (POSTGRES_FK_DIALECTS.has(dialect)) {
|
|
419
|
+
// COCKROACHDB carries its own copy of the constant; both resolve to the
|
|
420
|
+
// same `session_replication_role` statement.
|
|
421
|
+
const constants = dialect === 'cockroachdb' ? exports.COCKROACHDB : exports.POSTGRES;
|
|
422
|
+
const checks = constants.FOREIGN_KEY_CHECKS;
|
|
423
|
+
if (checks)
|
|
424
|
+
return checks[mode];
|
|
425
|
+
}
|
|
426
|
+
throw new UnsupportedForeignKeyChecksError(dialect, FK_CHECKS_UNSUPPORTED_HINTS[dialect]);
|
|
427
|
+
}
|
|
291
428
|
/**
|
|
292
429
|
* Transaction isolation level enum
|
|
293
430
|
*/
|