@mikro-orm/migrations 7.2.7-dev.11 → 7.2.7-dev.13
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/MigrationRunner.d.ts +5 -0
- package/MigrationRunner.js +47 -4
- package/Migrator.d.ts +1 -0
- package/Migrator.js +10 -2
- package/package.json +3 -3
package/MigrationRunner.d.ts
CHANGED
|
@@ -9,6 +9,11 @@ export declare class MigrationRunner {
|
|
|
9
9
|
protected readonly config: Configuration;
|
|
10
10
|
constructor(driver: AbstractSqlDriver, options: MigrationsOptions, config: Configuration);
|
|
11
11
|
run(migration: Migration, method: 'up' | 'down', afterRun?: (tx?: Transaction) => Promise<void>): Promise<void>;
|
|
12
|
+
/** Runs migrations with FK checks off, for drivers that ignore the switch inside a transaction (SQLite). */
|
|
13
|
+
runWithoutForeignKeys<T>(run: () => Promise<T>): Promise<T>;
|
|
14
|
+
private runWithForeignKeys;
|
|
15
|
+
private setForeignKeys;
|
|
16
|
+
private countForeignKeyViolations;
|
|
12
17
|
private resetSessionSchema;
|
|
13
18
|
setMasterMigration(trx: Transaction): void;
|
|
14
19
|
unsetMasterMigration(): void;
|
package/MigrationRunner.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Utils } from '@mikro-orm/core';
|
|
1
|
+
import { Utils, ValidationError } from '@mikro-orm/core';
|
|
2
2
|
/** Executes individual migration files within optional transaction contexts. */
|
|
3
3
|
export class MigrationRunner {
|
|
4
4
|
driver;
|
|
@@ -8,6 +8,7 @@ export class MigrationRunner {
|
|
|
8
8
|
#helper;
|
|
9
9
|
#masterTransaction;
|
|
10
10
|
#runSchema;
|
|
11
|
+
#foreignKeysOff = false;
|
|
11
12
|
constructor(driver, options, config) {
|
|
12
13
|
this.driver = driver;
|
|
13
14
|
this.options = options;
|
|
@@ -23,16 +24,23 @@ export class MigrationRunner {
|
|
|
23
24
|
if (this.#runSchema) {
|
|
24
25
|
throw new Error('Runtime schema (migrations.schema / migrator.up({ schema })) is only supported with transactional migrations');
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
await this.runWithForeignKeys(async () => {
|
|
28
|
+
const queries = await this.getQueries(migration, method);
|
|
29
|
+
await Utils.runSerial(queries, sql => this.driver.execute(sql));
|
|
30
|
+
await afterRun?.();
|
|
31
|
+
});
|
|
29
32
|
}
|
|
30
33
|
else {
|
|
31
34
|
await this.#connection.transactional(async (tx) => {
|
|
32
35
|
migration.setTransactionContext(tx);
|
|
36
|
+
const violations = await this.countForeignKeyViolations(tx);
|
|
33
37
|
try {
|
|
34
38
|
const queries = await this.getQueries(migration, method);
|
|
35
39
|
await Utils.runSerial(queries, sql => this.driver.execute(sql, undefined, 'all', tx));
|
|
40
|
+
const added = (await this.countForeignKeyViolations(tx)) - violations;
|
|
41
|
+
if (added > 0) {
|
|
42
|
+
throw new ValidationError(`Migration ${migration.name ?? migration.constructor.name} left ${added} rows that violate foreign keys`);
|
|
43
|
+
}
|
|
36
44
|
await afterRun?.(tx);
|
|
37
45
|
}
|
|
38
46
|
finally {
|
|
@@ -41,6 +49,41 @@ export class MigrationRunner {
|
|
|
41
49
|
}, { ctx: this.#masterTransaction });
|
|
42
50
|
}
|
|
43
51
|
}
|
|
52
|
+
/** Runs migrations with FK checks off, for drivers that ignore the switch inside a transaction (SQLite). */
|
|
53
|
+
async runWithoutForeignKeys(run) {
|
|
54
|
+
await this.setForeignKeys(false);
|
|
55
|
+
try {
|
|
56
|
+
return await run();
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
await this.setForeignKeys(true);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// a migration outside a transaction gets no `foreign_key_check`, so it runs with FK checks on
|
|
63
|
+
async runWithForeignKeys(run) {
|
|
64
|
+
if (!this.#foreignKeysOff) {
|
|
65
|
+
return run();
|
|
66
|
+
}
|
|
67
|
+
await this.setForeignKeys(true);
|
|
68
|
+
try {
|
|
69
|
+
await run();
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
await this.setForeignKeys(false);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async setForeignKeys(enabled) {
|
|
76
|
+
await this.driver.execute(enabled ? this.#helper.enableForeignKeysSQL() : this.#helper.disableForeignKeysSQL());
|
|
77
|
+
this.#foreignKeysOff = !enabled;
|
|
78
|
+
}
|
|
79
|
+
async countForeignKeyViolations(ctx) {
|
|
80
|
+
const sql = this.#helper.getForeignKeyCheckSQL();
|
|
81
|
+
// with FK checks on (caller-supplied transaction), the database enforces them itself
|
|
82
|
+
if (!this.#foreignKeysOff || !sql) {
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
return (await this.driver.execute(sql, undefined, 'all', ctx)).length;
|
|
86
|
+
}
|
|
44
87
|
async resetSessionSchema(ctx) {
|
|
45
88
|
if (!this.#runSchema) {
|
|
46
89
|
return;
|
package/Migrator.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export declare class Migrator extends AbstractMigrator<AbstractSqlDriver> {
|
|
|
27
27
|
*/
|
|
28
28
|
createInitial(path?: string, name?: string, blank?: boolean): Promise<MigrationResult>;
|
|
29
29
|
protected runMigrations(method: 'up' | 'down', options?: string | string[] | MigrateOptions): Promise<MigrationInfo[]>;
|
|
30
|
+
private runWithoutForeignKeys;
|
|
30
31
|
/** Whether the introspected schema differs from the snapshot in any way the comparator turns into SQL. */
|
|
31
32
|
private snapshotDiffers;
|
|
32
33
|
getStorage(): MigrationStorage;
|
package/Migrator.js
CHANGED
|
@@ -148,9 +148,9 @@ export class Migrator extends AbstractMigrator {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
async runMigrations(method, options) {
|
|
151
|
-
const
|
|
151
|
+
const ctx = Utils.isObject(options) ? options.transaction : undefined;
|
|
152
|
+
const result = await this.runWithoutForeignKeys(ctx, () => super.runMigrations(method, options));
|
|
152
153
|
if (result.length > 0 && this.options.snapshot && this.options.snapshotOnMigrate) {
|
|
153
|
-
const ctx = Utils.isObject(options) ? options.transaction : undefined;
|
|
154
154
|
const { skipTables, skipViews } = this.config.get('schemaGenerator');
|
|
155
155
|
const schema = await DatabaseSchema.create(this.em.getConnection(), this.em.getPlatform(), this.config, undefined, undefined, undefined, skipTables, skipViews, ctx);
|
|
156
156
|
// keep the snapshot authored by `migration:create` when the migrated DB still matches it
|
|
@@ -169,6 +169,14 @@ export class Migrator extends AbstractMigrator {
|
|
|
169
169
|
}
|
|
170
170
|
return result;
|
|
171
171
|
}
|
|
172
|
+
async runWithoutForeignKeys(ctx, run) {
|
|
173
|
+
// sqlite ignores `pragma foreign_keys` inside a transaction, so a table rebuild would run the FK actions of child rows
|
|
174
|
+
if (ctx || !this.options.transactional || !this.driver.getPlatform().getSchemaHelper().getForeignKeyCheckSQL()) {
|
|
175
|
+
return run();
|
|
176
|
+
}
|
|
177
|
+
await this.init(); // can recreate the runner, which holds the FK state
|
|
178
|
+
return this.runner.runWithoutForeignKeys(run);
|
|
179
|
+
}
|
|
172
180
|
/** Whether the introspected schema differs from the snapshot in any way the comparator turns into SQL. */
|
|
173
181
|
snapshotDiffers(snapshot, schema) {
|
|
174
182
|
const comparator = new SchemaComparator(this.driver.getPlatform());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/migrations",
|
|
3
|
-
"version": "7.2.7-dev.
|
|
3
|
+
"version": "7.2.7-dev.13",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"data-mapper",
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
"copy": "node ../../scripts/copy.mjs"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@mikro-orm/sql": "7.2.7-dev.
|
|
50
|
+
"@mikro-orm/sql": "7.2.7-dev.13"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@mikro-orm/core": "^7.2.6"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@mikro-orm/core": "7.2.7-dev.
|
|
56
|
+
"@mikro-orm/core": "7.2.7-dev.13"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"node": ">= 22.17.0"
|