@mikro-orm/sql 7.2.0-dev.2 → 7.2.0-dev.20
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/AbstractSqlConnection.d.ts +30 -3
- package/AbstractSqlConnection.js +75 -15
- package/AbstractSqlDriver.d.ts +1 -8
- package/AbstractSqlDriver.js +124 -55
- package/AbstractSqlPlatform.d.ts +4 -2
- package/AbstractSqlPlatform.js +35 -1
- package/SqlEntityManager.d.ts +2 -2
- package/SqlEntityManager.js +5 -4
- package/dialects/mssql/MsSqlNativeQueryBuilder.js +1 -1
- package/dialects/mysql/BaseMySqlPlatform.d.ts +2 -0
- package/dialects/mysql/BaseMySqlPlatform.js +4 -0
- package/dialects/mysql/MySqlSchemaHelper.d.ts +1 -0
- package/dialects/mysql/MySqlSchemaHelper.js +4 -1
- package/dialects/oracledb/OracleNativeQueryBuilder.js +1 -1
- package/dialects/postgresql/BasePostgreSqlPlatform.d.ts +3 -1
- package/dialects/postgresql/BasePostgreSqlPlatform.js +35 -2
- package/dialects/postgresql/PostgreSqlExceptionConverter.js +8 -1
- package/dialects/postgresql/PostgreSqlSchemaHelper.d.ts +22 -1
- package/dialects/postgresql/PostgreSqlSchemaHelper.js +181 -4
- package/dialects/sqlite/BaseSqliteConnection.d.ts +3 -0
- package/dialects/sqlite/BaseSqliteConnection.js +15 -5
- package/dialects/sqlite/SqlitePlatform.d.ts +2 -0
- package/dialects/sqlite/SqlitePlatform.js +4 -0
- package/dialects/sqlite/SqliteSchemaHelper.js +2 -2
- package/package.json +4 -4
- package/plugin/transformer.d.ts +7 -1
- package/plugin/transformer.js +60 -1
- package/query/CriteriaNodeFactory.js +4 -0
- package/query/NativeQueryBuilder.js +1 -1
- package/query/ObjectCriteriaNode.d.ts +1 -0
- package/query/ObjectCriteriaNode.js +30 -5
- package/query/QueryBuilder.d.ts +40 -7
- package/query/QueryBuilder.js +181 -37
- package/query/QueryBuilderHelper.d.ts +5 -0
- package/query/QueryBuilderHelper.js +39 -9
- package/schema/DatabaseSchema.d.ts +4 -0
- package/schema/DatabaseSchema.js +107 -1
- package/schema/DatabaseTable.d.ts +15 -1
- package/schema/DatabaseTable.js +113 -19
- package/schema/SchemaComparator.d.ts +3 -0
- package/schema/SchemaComparator.js +123 -10
- package/schema/SchemaHelper.d.ts +26 -1
- package/schema/SchemaHelper.js +67 -9
- package/schema/SqlSchemaGenerator.d.ts +4 -0
- package/schema/SqlSchemaGenerator.js +59 -22
- package/typings.d.ts +20 -2
package/schema/SchemaHelper.js
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { isRaw, Utils, } from '@mikro-orm/core';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Flattens `;\n` boundaries and drops blank lines so the schema-generator's statement splitter
|
|
4
|
+
* doesn't break the routine or trigger DDL apart — it treats both as statement/group separators.
|
|
5
|
+
* Blank lines go first, otherwise a `;` followed by one would keep its newline. Like
|
|
6
|
+
* `normalizeViewDefinition`, this is not string-literal aware, so a blank line inside a multi-line
|
|
7
|
+
* literal is dropped too. Other whitespace is preserved.
|
|
8
|
+
*/
|
|
3
9
|
export function stripStatementNewlines(body) {
|
|
4
|
-
return body
|
|
10
|
+
return body
|
|
11
|
+
.split('\n')
|
|
12
|
+
.filter(line => line.trim() !== '')
|
|
13
|
+
.join('\n')
|
|
14
|
+
.replace(/;[\t ]*\r?\n/g, '; ');
|
|
5
15
|
}
|
|
6
16
|
/**
|
|
7
17
|
* Strips SQL line comments and blank lines from a view definition. Comments are dropped by the
|
|
@@ -157,13 +167,14 @@ export class SchemaHelper {
|
|
|
157
167
|
tableName = this.quote(tableName);
|
|
158
168
|
const keyName = this.quote(index.keyName);
|
|
159
169
|
const defer = index.deferMode ? ` deferrable initially ${index.deferMode}` : '';
|
|
160
|
-
|
|
170
|
+
const using = this.getIndexAccessMethodClause(index);
|
|
171
|
+
let sql = `create ${index.unique ? 'unique ' : ''}index ${keyName} on ${tableName}${using}`;
|
|
161
172
|
if (index.unique && index.constraint) {
|
|
162
173
|
sql = `alter table ${tableName} add constraint ${keyName} unique`;
|
|
163
174
|
}
|
|
164
175
|
if (index.columnNames.some(column => column.includes('.'))) {
|
|
165
176
|
// JSON columns can have unique index but not unique constraint, and we need to distinguish those, so we can properly drop them
|
|
166
|
-
sql = `create ${index.unique ? 'unique ' : ''}index ${keyName} on ${tableName}`;
|
|
177
|
+
sql = `create ${index.unique ? 'unique ' : ''}index ${keyName} on ${tableName}${using}`;
|
|
167
178
|
const columns = this.platform.getJsonIndexDefinition(index);
|
|
168
179
|
return `${sql} (${columns.join(', ')})${this.getCreateIndexSuffix(index)}${this.getIndexWhereClause(index)}${defer}`;
|
|
169
180
|
}
|
|
@@ -182,6 +193,18 @@ export class SchemaHelper {
|
|
|
182
193
|
getCreateIndexSuffix(_index) {
|
|
183
194
|
return '';
|
|
184
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* Normalized index access method (e.g. `gin` on PostgreSQL), empty string when the
|
|
198
|
+
* platform default applies. Used for both DDL emission and index diffing.
|
|
199
|
+
*/
|
|
200
|
+
getIndexAccessMethod(_index) {
|
|
201
|
+
return '';
|
|
202
|
+
}
|
|
203
|
+
/** Emits the access method between the table name and the column list (e.g. ` using gin`). */
|
|
204
|
+
getIndexAccessMethodClause(index) {
|
|
205
|
+
const method = this.getIndexAccessMethod(index);
|
|
206
|
+
return method ? ` using ${method}` : '';
|
|
207
|
+
}
|
|
185
208
|
/**
|
|
186
209
|
* Default emits ` where <predicate>` for partial indexes. Only Oracle overrides this to
|
|
187
210
|
* return `''` (it emulates partials via CASE-WHEN columns). MySQL sidesteps the whole path
|
|
@@ -436,7 +459,8 @@ export class SchemaHelper {
|
|
|
436
459
|
this.append(ret, this.alterTableColumn(column, diff.fromTable, changedProperties));
|
|
437
460
|
}
|
|
438
461
|
for (const { column, changedProperties } of Object.values(diff.changedColumns).filter(diff => diff.changedProperties.has('comment'))) {
|
|
439
|
-
if (
|
|
462
|
+
if (this.hasInlineColumnComment() &&
|
|
463
|
+
['type', 'nullable', 'autoincrement', 'unsigned', 'default', 'enumItems', 'collation'].some(t => changedProperties.has(t))) {
|
|
440
464
|
continue; // will be handled via column update
|
|
441
465
|
}
|
|
442
466
|
ret.push(this.getChangeColumnCommentSQL(tableName, column, schemaName));
|
|
@@ -480,6 +504,7 @@ export class SchemaHelper {
|
|
|
480
504
|
if ('changedComment' in diff) {
|
|
481
505
|
ret.push(this.alterTableComment(diff.toTable, diff.changedComment));
|
|
482
506
|
}
|
|
507
|
+
this.append(ret, this.getRlsAlterSQL(diff, safe));
|
|
483
508
|
return ret;
|
|
484
509
|
}
|
|
485
510
|
/** Returns SQL to add columns to an existing table. */
|
|
@@ -489,7 +514,13 @@ export class SchemaHelper {
|
|
|
489
514
|
return `add ${this.createTableColumn(column, table)}`;
|
|
490
515
|
})
|
|
491
516
|
.join(', ');
|
|
492
|
-
|
|
517
|
+
const ret = [`alter table ${table.getQuotedName()} ${adds}`];
|
|
518
|
+
if (!this.hasInlineColumnComment()) {
|
|
519
|
+
for (const column of columns.filter(column => column.comment)) {
|
|
520
|
+
ret.push(this.getChangeColumnCommentSQL(table.name, column, table.schema));
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return ret;
|
|
493
524
|
}
|
|
494
525
|
getDropColumnsSQL(tableName, columns, schemaName) {
|
|
495
526
|
const name = this.quote(this.getTableName(tableName, schemaName));
|
|
@@ -504,6 +535,10 @@ export class SchemaHelper {
|
|
|
504
535
|
const defaultName = this.platform.getDefaultPrimaryName(table.name, pkIndex.columnNames);
|
|
505
536
|
return pkIndex?.keyName !== defaultName;
|
|
506
537
|
}
|
|
538
|
+
/** Returns the `constraint <name> ` prefix for a primary key definition, empty when the server assigns the default name on its own. */
|
|
539
|
+
getPrimaryKeyConstraintPrefix(table, index) {
|
|
540
|
+
return this.hasNonDefaultPrimaryKeyName(table) ? `constraint ${this.quote(index.keyName)} ` : '';
|
|
541
|
+
}
|
|
507
542
|
/* v8 ignore next */
|
|
508
543
|
castColumn(name, type) {
|
|
509
544
|
return '';
|
|
@@ -608,6 +643,22 @@ export class SchemaHelper {
|
|
|
608
643
|
getChangeColumnCommentSQL(tableName, to, schemaName) {
|
|
609
644
|
return '';
|
|
610
645
|
}
|
|
646
|
+
/** Whether the column comment is part of the column declaration, as opposed to a separate statement. */
|
|
647
|
+
hasInlineColumnComment() {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
/** Row level security DDL for a freshly created table (enable/force + create policies). Postgres only. */
|
|
651
|
+
getRlsCreateSQL(table) {
|
|
652
|
+
return [];
|
|
653
|
+
}
|
|
654
|
+
/** Drops removed/changed row level security policies; emitted in the pre-alter phase, before any column drop or type alter a policy expression can block. Postgres only. */
|
|
655
|
+
getRlsDropSQL(diff, safe) {
|
|
656
|
+
return [];
|
|
657
|
+
}
|
|
658
|
+
/** Row level security DDL for a table difference (enable/disable/force transitions + policy creation). Postgres only. */
|
|
659
|
+
getRlsAlterSQL(diff, safe) {
|
|
660
|
+
return [];
|
|
661
|
+
}
|
|
611
662
|
async getNamespaces(connection, ctx) {
|
|
612
663
|
return [];
|
|
613
664
|
}
|
|
@@ -745,7 +796,7 @@ export class SchemaHelper {
|
|
|
745
796
|
const primaryKey = table.getPrimaryKey();
|
|
746
797
|
const createPrimary = !table.getColumns().some(c => c.autoincrement && c.primary) || this.hasNonDefaultPrimaryKeyName(table);
|
|
747
798
|
if (createPrimary && primaryKey) {
|
|
748
|
-
const name = this.
|
|
799
|
+
const name = this.getPrimaryKeyConstraintPrefix(table, primaryKey);
|
|
749
800
|
sql += `, ${name}primary key (${primaryKey.columnNames.map(c => this.quote(c)).join(', ')})`;
|
|
750
801
|
}
|
|
751
802
|
sql += ')';
|
|
@@ -763,6 +814,8 @@ export class SchemaHelper {
|
|
|
763
814
|
for (const trigger of table.getTriggers()) {
|
|
764
815
|
this.append(ret, this.createTrigger(table, trigger));
|
|
765
816
|
}
|
|
817
|
+
// RLS policies can reference other tables, so they are deferred until every table exists (see the
|
|
818
|
+
// callers of getRlsCreateSQL in SqlSchemaGenerator) rather than emitted inline here
|
|
766
819
|
}
|
|
767
820
|
return ret;
|
|
768
821
|
}
|
|
@@ -828,7 +881,7 @@ export class SchemaHelper {
|
|
|
828
881
|
const columns = index.columnNames.map(c => this.quote(c)).join(', ');
|
|
829
882
|
const defer = index.deferMode ? ` deferrable initially ${index.deferMode}` : '';
|
|
830
883
|
if (index.primary) {
|
|
831
|
-
const keyName = this.
|
|
884
|
+
const keyName = this.getPrimaryKeyConstraintPrefix(table, index);
|
|
832
885
|
return `alter table ${table.getQuotedName()} add ${keyName}primary key (${columns})${defer}`;
|
|
833
886
|
}
|
|
834
887
|
if (index.type === 'fulltext') {
|
|
@@ -861,7 +914,7 @@ export class SchemaHelper {
|
|
|
861
914
|
const events = trigger.events.map(e => e.toUpperCase()).join(' OR ');
|
|
862
915
|
const forEach = trigger.forEach === 'statement' ? 'STATEMENT' : 'ROW';
|
|
863
916
|
const when = trigger.when ? ` when (${trigger.when})` : '';
|
|
864
|
-
return `create trigger ${this.quote(trigger.name)} ${timing} ${events} on ${table.getQuotedName()} for each ${forEach}${when} begin ${trigger.body}
|
|
917
|
+
return `create trigger ${this.quote(trigger.name)} ${timing} ${events} on ${table.getQuotedName()} for each ${forEach}${when} begin ${this.normalizeTriggerBody(trigger.body)} end`;
|
|
865
918
|
}
|
|
866
919
|
/**
|
|
867
920
|
* Generates SQL to drop a database trigger from a table.
|
|
@@ -885,6 +938,11 @@ export class SchemaHelper {
|
|
|
885
938
|
async getAllRoutines(_connection, _schemas = []) {
|
|
886
939
|
return [];
|
|
887
940
|
}
|
|
941
|
+
/** Flattens internal `;\n` so the statement splitter doesn't tear the DDL, and ensures exactly one trailing `;` for the enclosing `begin ... end` block. */
|
|
942
|
+
normalizeTriggerBody(body) {
|
|
943
|
+
const trimmed = stripStatementNewlines(body).trim();
|
|
944
|
+
return /;\s*$/.test(trimmed) ? trimmed : `${trimmed};`;
|
|
945
|
+
}
|
|
888
946
|
/** Wraps the body in `BEGIN ... END` if not already, and flattens internal `;\n` so the schema-generator's statement splitter doesn't tear the DDL. */
|
|
889
947
|
wrapRoutineBody(body) {
|
|
890
948
|
const trimmed = stripStatementNewlines(body).trim();
|
|
@@ -54,6 +54,10 @@ export declare class SqlSchemaGenerator extends AbstractSchemaGenerator<Abstract
|
|
|
54
54
|
wrap?: boolean;
|
|
55
55
|
ctx?: Transaction;
|
|
56
56
|
}): Promise<void>;
|
|
57
|
+
/** Splits the SQL on the separator, keeping the separators that fall inside a string literal. */
|
|
58
|
+
private splitOutsideLiterals;
|
|
59
|
+
/** Whether the statement has to be the first one in a query batch, e.g. `create trigger` on MSSQL. */
|
|
60
|
+
protected startsBatch(_statement: string): boolean;
|
|
57
61
|
dropTableIfExists(name: string, schema?: string): Promise<void>;
|
|
58
62
|
private wrapSchema;
|
|
59
63
|
private append;
|
|
@@ -94,6 +94,10 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
94
94
|
this.append(ret, fks, true);
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
|
+
// RLS policies are deferred until every table exists, so a policy expression can reference another table
|
|
98
|
+
for (const table of toSchema.getTables()) {
|
|
99
|
+
this.append(ret, this.helper.getRlsCreateSQL(table));
|
|
100
|
+
}
|
|
97
101
|
const sortedViews = this.sortViewsByDependencies(toSchema.getViews());
|
|
98
102
|
for (const view of sortedViews) {
|
|
99
103
|
this.appendViewCreation(ret, view);
|
|
@@ -308,22 +312,6 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
308
312
|
for (const newTable of Object.values(schemaDiff.newTables)) {
|
|
309
313
|
this.append(ret, this.helper.createTable(newTable, true), true);
|
|
310
314
|
}
|
|
311
|
-
if (this.helper.supportsSchemaConstraints()) {
|
|
312
|
-
for (const newTable of Object.values(schemaDiff.newTables)) {
|
|
313
|
-
const sql = [];
|
|
314
|
-
if (this.options.createForeignKeyConstraints) {
|
|
315
|
-
const fks = Object.values(newTable.getForeignKeys()).map(fk => this.helper.createForeignKey(newTable, fk));
|
|
316
|
-
this.append(sql, fks);
|
|
317
|
-
}
|
|
318
|
-
for (const check of newTable.getChecks()) {
|
|
319
|
-
this.append(sql, this.helper.createCheck(newTable, check));
|
|
320
|
-
}
|
|
321
|
-
for (const trigger of newTable.getTriggers()) {
|
|
322
|
-
this.append(sql, this.helper.createTrigger(newTable, trigger));
|
|
323
|
-
}
|
|
324
|
-
this.append(ret, sql, true);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
315
|
if (options.dropTables && !options.safe) {
|
|
328
316
|
for (const table of Object.values(schemaDiff.removedTables)) {
|
|
329
317
|
// Drop triggers before the table so driver-specific cleanup runs (e.g. PostgreSQL function removal)
|
|
@@ -353,6 +341,24 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
353
341
|
for (const changedTable of alteredTables) {
|
|
354
342
|
this.append(ret, this.helper.getPostAlterTable(changedTable, options.safe), true);
|
|
355
343
|
}
|
|
344
|
+
// after the alters, so a new table's FK can reference a unique constraint an existing table gains in the same diff
|
|
345
|
+
if (this.helper.supportsSchemaConstraints()) {
|
|
346
|
+
for (const newTable of Object.values(schemaDiff.newTables)) {
|
|
347
|
+
const sql = [];
|
|
348
|
+
if (this.options.createForeignKeyConstraints) {
|
|
349
|
+
const fks = Object.values(newTable.getForeignKeys()).map(fk => this.helper.createForeignKey(newTable, fk));
|
|
350
|
+
this.append(sql, fks);
|
|
351
|
+
}
|
|
352
|
+
for (const check of newTable.getChecks()) {
|
|
353
|
+
this.append(sql, this.helper.createCheck(newTable, check));
|
|
354
|
+
}
|
|
355
|
+
for (const trigger of newTable.getTriggers()) {
|
|
356
|
+
this.append(sql, this.helper.createTrigger(newTable, trigger));
|
|
357
|
+
}
|
|
358
|
+
this.append(sql, this.helper.getRlsCreateSQL(newTable));
|
|
359
|
+
this.append(ret, sql, true);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
356
362
|
if (!options.safe && this.platform.supportsNativeEnums()) {
|
|
357
363
|
for (const removedNativeEnum of schemaDiff.removedNativeEnums) {
|
|
358
364
|
this.append(ret, this.helper.getDropNativeEnumSQL(removedNativeEnum.name, removedNativeEnum.schema));
|
|
@@ -409,6 +415,9 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
409
415
|
}
|
|
410
416
|
preAlterTable(diff, safe) {
|
|
411
417
|
const ret = [];
|
|
418
|
+
// removed/changed policies must be dropped before any column type alter, including the pre-alter
|
|
419
|
+
// uuid-to-text cast on postgres — a policy expression blocks type changes on the columns it references
|
|
420
|
+
this.append(ret, this.helper.getRlsDropSQL(diff, safe));
|
|
412
421
|
this.append(ret, this.helper.getPreAlterTable(diff, safe));
|
|
413
422
|
for (const foreignKey of Object.values(diff.removedForeignKeys)) {
|
|
414
423
|
ret.push(this.helper.dropForeignKey(diff.toTable.getShortestName(), foreignKey.constraintName));
|
|
@@ -439,18 +448,23 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
439
448
|
}
|
|
440
449
|
async execute(sql, options = {}) {
|
|
441
450
|
options.wrap ??= false;
|
|
442
|
-
const lines = this.wrapSchema(sql, options)
|
|
451
|
+
const lines = this.splitOutsideLiterals(this.wrapSchema(sql, options), '\n');
|
|
443
452
|
const groups = [];
|
|
444
453
|
let i = 0;
|
|
445
454
|
for (const line of lines) {
|
|
446
|
-
|
|
455
|
+
const stmt = line.trim();
|
|
456
|
+
if (stmt === '') {
|
|
447
457
|
if (groups[i]?.length > 0) {
|
|
448
458
|
i++;
|
|
449
459
|
}
|
|
450
460
|
continue;
|
|
451
461
|
}
|
|
462
|
+
// same boundary an empty line creates, for statements that have to start their own batch
|
|
463
|
+
if (groups[i]?.length > 0 && this.startsBatch(stmt)) {
|
|
464
|
+
i++;
|
|
465
|
+
}
|
|
452
466
|
groups[i] ??= [];
|
|
453
|
-
groups[i].push(
|
|
467
|
+
groups[i].push(stmt);
|
|
454
468
|
}
|
|
455
469
|
if (groups.length === 0) {
|
|
456
470
|
return;
|
|
@@ -463,14 +477,37 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
463
477
|
return;
|
|
464
478
|
}
|
|
465
479
|
const statements = groups.flatMap(group => {
|
|
466
|
-
return group
|
|
467
|
-
.join('\n')
|
|
468
|
-
.split(';\n')
|
|
480
|
+
return this.splitOutsideLiterals(group.join('\n'), ';\n')
|
|
469
481
|
.map(s => s.trim())
|
|
470
482
|
.filter(s => s);
|
|
471
483
|
});
|
|
472
484
|
await Utils.runSerial(statements, stmt => this.driver.execute(stmt));
|
|
473
485
|
}
|
|
486
|
+
/** Splits the SQL on the separator, keeping the separators that fall inside a string literal. */
|
|
487
|
+
splitOutsideLiterals(sql, separator) {
|
|
488
|
+
const [idOpen, idClose] = this.platform.quoteIdentifier('');
|
|
489
|
+
// mysql escapes quotes as `\'`, the other dialects double them, which pairs up on its own
|
|
490
|
+
const esc = this.platform.quoteValue(`'`).includes(`\\'`) ? '\\\\.|' : '';
|
|
491
|
+
// complete literals, quoted identifiers and `--` comments, so that an apostrophe inside an
|
|
492
|
+
// identifier or a comment is not mistaken for one opening a literal
|
|
493
|
+
const tokens = new RegExp(`'(?:${esc}[^'])*'|\\${idOpen}[^\\${idClose}]*\\${idClose}|--[^\n]*`, 'g');
|
|
494
|
+
const parts = [];
|
|
495
|
+
for (const chunk of sql.split(separator)) {
|
|
496
|
+
const prev = parts.at(-1);
|
|
497
|
+
// whatever quote is left once the complete tokens are gone opened a literal we are still inside of
|
|
498
|
+
if (prev?.replace(tokens, '').includes(`'`)) {
|
|
499
|
+
parts[parts.length - 1] = prev + separator + chunk;
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
parts.push(chunk);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return parts;
|
|
506
|
+
}
|
|
507
|
+
/** Whether the statement has to be the first one in a query batch, e.g. `create trigger` on MSSQL. */
|
|
508
|
+
startsBatch(_statement) {
|
|
509
|
+
return false;
|
|
510
|
+
}
|
|
474
511
|
async dropTableIfExists(name, schema) {
|
|
475
512
|
const sql = this.helper.dropTableIfExists(name, schema);
|
|
476
513
|
return this.execute(sql);
|
package/typings.d.ts
CHANGED
|
@@ -114,6 +114,15 @@ export interface CheckDef<T = unknown> {
|
|
|
114
114
|
definition?: string;
|
|
115
115
|
columnName?: string;
|
|
116
116
|
}
|
|
117
|
+
/** Resolved row level security policy for schema operations (all callbacks resolved to strings). */
|
|
118
|
+
export interface SqlPolicyDef {
|
|
119
|
+
name: string;
|
|
120
|
+
command: 'select' | 'insert' | 'update' | 'delete' | 'all';
|
|
121
|
+
type: 'permissive' | 'restrictive';
|
|
122
|
+
roles: string[];
|
|
123
|
+
using?: string;
|
|
124
|
+
check?: string;
|
|
125
|
+
}
|
|
117
126
|
/** Resolved trigger definition for schema operations (all callbacks resolved to strings). */
|
|
118
127
|
export interface SqlTriggerDef {
|
|
119
128
|
name: string;
|
|
@@ -191,6 +200,13 @@ export interface TableDifference {
|
|
|
191
200
|
addedTriggers: Dictionary<SqlTriggerDef>;
|
|
192
201
|
changedTriggers: Dictionary<SqlTriggerDef>;
|
|
193
202
|
removedTriggers: Dictionary<SqlTriggerDef>;
|
|
203
|
+
addedPolicies: Dictionary<SqlPolicyDef>;
|
|
204
|
+
/** Changed policies surface as `removedPolicies` + `addedPolicies` pairs (drop + recreate). */
|
|
205
|
+
removedPolicies: Dictionary<SqlPolicyDef>;
|
|
206
|
+
/** New RLS enable state, present only when it changed. */
|
|
207
|
+
changedRlsEnabled?: boolean;
|
|
208
|
+
/** New RLS force state, present only when it changed. */
|
|
209
|
+
changedRlsForced?: boolean;
|
|
194
210
|
addedForeignKeys: Dictionary<ForeignKey>;
|
|
195
211
|
changedForeignKeys: Dictionary<ForeignKey>;
|
|
196
212
|
removedForeignKeys: Dictionary<ForeignKey>;
|
|
@@ -277,6 +293,8 @@ export interface IQueryBuilder<T> {
|
|
|
277
293
|
with(name: string, query: AnyQueryBuilder | NativeQueryBuilder | RawQueryFragment, options?: CteOptions): this;
|
|
278
294
|
withRecursive(name: string, query: AnyQueryBuilder | NativeQueryBuilder | RawQueryFragment, options?: CteOptions): this;
|
|
279
295
|
scheduleFilterCheck(path: string): void;
|
|
296
|
+
/** @internal */
|
|
297
|
+
ensureTPTJoins(): void;
|
|
280
298
|
withSchema(schema: string): this;
|
|
281
299
|
}
|
|
282
300
|
export interface ICriteriaNodeProcessOptions {
|
|
@@ -368,9 +386,9 @@ type MaybeGenerated<TValue, TOptions, TProcessOnCreate extends boolean> = TOptio
|
|
|
368
386
|
} ? TValue | null : TOptions extends {
|
|
369
387
|
autoincrement: true;
|
|
370
388
|
} ? Generated<TValue> : TOptions extends {
|
|
371
|
-
default:
|
|
389
|
+
default: unknown;
|
|
372
390
|
} ? Generated<TValue> : TOptions extends {
|
|
373
|
-
defaultRaw:
|
|
391
|
+
defaultRaw: unknown;
|
|
374
392
|
} ? Generated<TValue> : TProcessOnCreate extends false ? TValue : TOptions extends {
|
|
375
393
|
onCreate: Function;
|
|
376
394
|
} ? Generated<TValue> : TValue;
|