@mikro-orm/migrations 7.0.0-dev.33 → 7.0.0-dev.331
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/JSMigrationGenerator.js +3 -3
- package/Migration.d.ts +4 -5
- package/Migration.js +9 -9
- package/MigrationGenerator.d.ts +1 -1
- package/MigrationGenerator.js +5 -6
- package/MigrationRunner.d.ts +2 -4
- package/MigrationRunner.js +12 -12
- package/MigrationStorage.d.ts +11 -10
- package/MigrationStorage.js +49 -42
- package/Migrator.d.ts +18 -56
- package/Migrator.js +138 -213
- package/README.md +7 -4
- package/TSMigrationGenerator.js +2 -2
- package/index.d.ts +1 -1
- package/index.js +0 -1
- package/package.json +32 -33
- package/typings.d.ts +1 -1
package/JSMigrationGenerator.js
CHANGED
|
@@ -9,12 +9,12 @@ export class JSMigrationGenerator extends MigrationGenerator {
|
|
|
9
9
|
ret += `const { Migration } = require('@mikro-orm/migrations');\n\n`;
|
|
10
10
|
ret += `class ${className} extends Migration {\n\n`;
|
|
11
11
|
ret += ` async up() {\n`;
|
|
12
|
-
diff.up.forEach(sql => ret += this.createStatement(sql, 4));
|
|
12
|
+
diff.up.forEach(sql => (ret += this.createStatement(sql, 4)));
|
|
13
13
|
ret += ` }\n\n`;
|
|
14
|
-
/* v8 ignore next
|
|
14
|
+
/* v8 ignore next */
|
|
15
15
|
if (diff.down.length > 0) {
|
|
16
16
|
ret += ` async down() {\n`;
|
|
17
|
-
diff.down.forEach(sql => ret += this.createStatement(sql, 4));
|
|
17
|
+
diff.down.forEach(sql => (ret += this.createStatement(sql, 4)));
|
|
18
18
|
ret += ` }\n\n`;
|
|
19
19
|
}
|
|
20
20
|
ret += `}\n`;
|
package/Migration.d.ts
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { type Configuration, type RawQueryFragment, type Transaction } from '@mikro-orm/core';
|
|
2
|
-
import type { AbstractSqlDriver, EntityManager, NativeQueryBuilder } from '@mikro-orm/
|
|
1
|
+
import { type AnyEntity, type Configuration, type EntityData, type RawQueryFragment, type Transaction } from '@mikro-orm/core';
|
|
2
|
+
import type { AbstractSqlDriver, EntityManager, NativeQueryBuilder } from '@mikro-orm/sql';
|
|
3
3
|
export type Query = string | NativeQueryBuilder | RawQueryFragment;
|
|
4
4
|
export declare abstract class Migration {
|
|
5
|
+
#private;
|
|
5
6
|
protected readonly driver: AbstractSqlDriver;
|
|
6
7
|
protected readonly config: Configuration;
|
|
7
|
-
private readonly queries;
|
|
8
8
|
protected ctx?: Transaction;
|
|
9
|
-
private em?;
|
|
10
9
|
constructor(driver: AbstractSqlDriver, config: Configuration);
|
|
11
10
|
abstract up(): Promise<void> | void;
|
|
12
11
|
down(): Promise<void> | void;
|
|
@@ -18,7 +17,7 @@ export declare abstract class Migration {
|
|
|
18
17
|
* Executes a raw SQL query. Accepts a string SQL, `raw()` SQL fragment, or a native query builder instance.
|
|
19
18
|
* The `params` parameter is respected only if you use string SQL in the first parameter.
|
|
20
19
|
*/
|
|
21
|
-
execute(sql: Query, params?: unknown[]): Promise<
|
|
20
|
+
execute(sql: Query, params?: unknown[]): Promise<EntityData<AnyEntity>[]>;
|
|
22
21
|
/**
|
|
23
22
|
* Creates a cached `EntityManager` instance for this migration, which will respect
|
|
24
23
|
* the current transaction context.
|
package/Migration.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export class Migration {
|
|
2
2
|
driver;
|
|
3
3
|
config;
|
|
4
|
-
queries = [];
|
|
4
|
+
#queries = [];
|
|
5
5
|
ctx;
|
|
6
|
-
em;
|
|
6
|
+
#em;
|
|
7
7
|
constructor(driver, config) {
|
|
8
8
|
this.driver = driver;
|
|
9
9
|
this.config = config;
|
|
@@ -15,10 +15,10 @@ export class Migration {
|
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
17
|
addSql(sql) {
|
|
18
|
-
this
|
|
18
|
+
this.#queries.push(sql);
|
|
19
19
|
}
|
|
20
20
|
reset() {
|
|
21
|
-
this
|
|
21
|
+
this.#queries.length = 0;
|
|
22
22
|
this.ctx = undefined;
|
|
23
23
|
}
|
|
24
24
|
setTransactionContext(ctx) {
|
|
@@ -36,13 +36,13 @@ export class Migration {
|
|
|
36
36
|
* the current transaction context.
|
|
37
37
|
*/
|
|
38
38
|
getEntityManager() {
|
|
39
|
-
if (!this
|
|
40
|
-
this
|
|
41
|
-
this
|
|
39
|
+
if (!this.#em) {
|
|
40
|
+
this.#em = this.driver.createEntityManager();
|
|
41
|
+
this.#em.setTransactionContext(this.ctx);
|
|
42
42
|
}
|
|
43
|
-
return this
|
|
43
|
+
return this.#em;
|
|
44
44
|
}
|
|
45
45
|
getQueries() {
|
|
46
|
-
return this
|
|
46
|
+
return this.#queries;
|
|
47
47
|
}
|
|
48
48
|
}
|
package/MigrationGenerator.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IMigrationGenerator, type MaybePromise, type MigrationsOptions, type NamingStrategy } from '@mikro-orm/core';
|
|
2
|
-
import type { AbstractSqlDriver } from '@mikro-orm/
|
|
2
|
+
import type { AbstractSqlDriver } from '@mikro-orm/sql';
|
|
3
3
|
export declare abstract class MigrationGenerator implements IMigrationGenerator {
|
|
4
4
|
protected readonly driver: AbstractSqlDriver;
|
|
5
5
|
protected readonly namingStrategy: NamingStrategy;
|
package/MigrationGenerator.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Utils, } from '@mikro-orm/core';
|
|
2
|
-
import { writeFile } from 'node:fs/promises';
|
|
3
1
|
export class MigrationGenerator {
|
|
4
2
|
driver;
|
|
5
3
|
namingStrategy;
|
|
@@ -13,15 +11,16 @@ export class MigrationGenerator {
|
|
|
13
11
|
* @inheritDoc
|
|
14
12
|
*/
|
|
15
13
|
async generate(diff, path, name) {
|
|
14
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
16
15
|
/* v8 ignore next */
|
|
17
16
|
const defaultPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path;
|
|
18
|
-
path =
|
|
19
|
-
|
|
20
|
-
const timestamp = new Date().toISOString().replace(/[-T:]|\.\d{3}z$/
|
|
17
|
+
path = fs.normalizePath(this.driver.config.get('baseDir'), path ?? defaultPath);
|
|
18
|
+
fs.ensureDir(path);
|
|
19
|
+
const timestamp = new Date().toISOString().replace(/[-T:]|\.\d{3}z$/gi, '');
|
|
21
20
|
const className = this.namingStrategy.classToMigrationName(timestamp, name);
|
|
22
21
|
const fileName = `${this.options.fileName(timestamp, name)}.${this.options.emit}`;
|
|
23
22
|
const ret = await this.generateMigrationFile(className, diff);
|
|
24
|
-
await writeFile(path + '/' + fileName, ret, { flush: true });
|
|
23
|
+
await fs.writeFile(path + '/' + fileName, ret, { flush: true });
|
|
25
24
|
return [ret, fileName];
|
|
26
25
|
}
|
|
27
26
|
/**
|
package/MigrationRunner.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { type Configuration, type MigrationsOptions, type Transaction } from '@mikro-orm/core';
|
|
2
|
-
import type { AbstractSqlDriver } from '@mikro-orm/
|
|
2
|
+
import type { AbstractSqlDriver } from '@mikro-orm/sql';
|
|
3
3
|
import type { Migration } from './Migration.js';
|
|
4
4
|
export declare class MigrationRunner {
|
|
5
|
+
#private;
|
|
5
6
|
protected readonly driver: AbstractSqlDriver;
|
|
6
7
|
protected readonly options: MigrationsOptions;
|
|
7
8
|
protected readonly config: Configuration;
|
|
8
|
-
private readonly connection;
|
|
9
|
-
private readonly helper;
|
|
10
|
-
private masterTransaction?;
|
|
11
9
|
constructor(driver: AbstractSqlDriver, options: MigrationsOptions, config: Configuration);
|
|
12
10
|
run(migration: Migration, method: 'up' | 'down'): Promise<void>;
|
|
13
11
|
setMasterMigration(trx: Transaction): void;
|
package/MigrationRunner.js
CHANGED
|
@@ -3,15 +3,15 @@ export class MigrationRunner {
|
|
|
3
3
|
driver;
|
|
4
4
|
options;
|
|
5
5
|
config;
|
|
6
|
-
connection;
|
|
7
|
-
helper;
|
|
8
|
-
masterTransaction;
|
|
6
|
+
#connection;
|
|
7
|
+
#helper;
|
|
8
|
+
#masterTransaction;
|
|
9
9
|
constructor(driver, options, config) {
|
|
10
10
|
this.driver = driver;
|
|
11
11
|
this.options = options;
|
|
12
12
|
this.config = config;
|
|
13
|
-
this
|
|
14
|
-
this
|
|
13
|
+
this.#connection = this.driver.getConnection();
|
|
14
|
+
this.#helper = this.driver.getPlatform().getSchemaHelper();
|
|
15
15
|
}
|
|
16
16
|
async run(migration, method) {
|
|
17
17
|
migration.reset();
|
|
@@ -20,26 +20,26 @@ export class MigrationRunner {
|
|
|
20
20
|
await Utils.runSerial(queries, sql => this.driver.execute(sql));
|
|
21
21
|
}
|
|
22
22
|
else {
|
|
23
|
-
await this
|
|
23
|
+
await this.#connection.transactional(async (tx) => {
|
|
24
24
|
migration.setTransactionContext(tx);
|
|
25
25
|
const queries = await this.getQueries(migration, method);
|
|
26
26
|
await Utils.runSerial(queries, sql => this.driver.execute(sql, undefined, 'all', tx));
|
|
27
|
-
}, { ctx: this
|
|
27
|
+
}, { ctx: this.#masterTransaction });
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
setMasterMigration(trx) {
|
|
31
|
-
this
|
|
31
|
+
this.#masterTransaction = trx;
|
|
32
32
|
}
|
|
33
33
|
unsetMasterMigration() {
|
|
34
|
-
|
|
34
|
+
this.#masterTransaction = undefined;
|
|
35
35
|
}
|
|
36
36
|
async getQueries(migration, method) {
|
|
37
37
|
await migration[method]();
|
|
38
38
|
const charset = this.config.get('charset');
|
|
39
39
|
let queries = migration.getQueries();
|
|
40
|
-
queries.unshift(...this
|
|
41
|
-
queries.push(...this
|
|
42
|
-
queries = queries.filter(sql =>
|
|
40
|
+
queries.unshift(...this.#helper.getSchemaBeginning(charset, this.options.disableForeignKeys).split('\n'));
|
|
41
|
+
queries.push(...this.#helper.getSchemaEnd(this.options.disableForeignKeys).split('\n'));
|
|
42
|
+
queries = queries.filter(sql => typeof sql !== 'string' || sql.trim().length > 0);
|
|
43
43
|
return queries;
|
|
44
44
|
}
|
|
45
45
|
}
|
package/MigrationStorage.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { type AbstractSqlDriver } from '@mikro-orm/
|
|
3
|
-
import type { MigrationParams, UmzugStorage } from 'umzug';
|
|
1
|
+
import { type MigrationsOptions, type Transaction, type EntitySchema } from '@mikro-orm/core';
|
|
2
|
+
import { type AbstractSqlDriver } from '@mikro-orm/sql';
|
|
4
3
|
import type { MigrationRow } from './typings.js';
|
|
5
|
-
export declare class MigrationStorage
|
|
4
|
+
export declare class MigrationStorage {
|
|
5
|
+
#private;
|
|
6
6
|
protected readonly driver: AbstractSqlDriver;
|
|
7
7
|
protected readonly options: MigrationsOptions;
|
|
8
|
-
private readonly connection;
|
|
9
|
-
private readonly helper;
|
|
10
|
-
private masterTransaction?;
|
|
11
|
-
private readonly platform;
|
|
12
8
|
constructor(driver: AbstractSqlDriver, options: MigrationsOptions);
|
|
13
9
|
executed(): Promise<string[]>;
|
|
14
|
-
logMigration(params:
|
|
15
|
-
|
|
10
|
+
logMigration(params: {
|
|
11
|
+
name: string;
|
|
12
|
+
}): Promise<void>;
|
|
13
|
+
unlogMigration(params: {
|
|
14
|
+
name: string;
|
|
15
|
+
}): Promise<void>;
|
|
16
16
|
getExecutedMigrations(): Promise<MigrationRow[]>;
|
|
17
17
|
ensureTable(): Promise<void>;
|
|
18
18
|
setMasterMigration(trx: Transaction): void;
|
|
@@ -27,5 +27,6 @@ export declare class MigrationStorage implements UmzugStorage {
|
|
|
27
27
|
getTableName(): {
|
|
28
28
|
tableName: string;
|
|
29
29
|
schemaName: string;
|
|
30
|
+
entity: EntitySchema;
|
|
30
31
|
};
|
|
31
32
|
}
|
package/MigrationStorage.js
CHANGED
|
@@ -1,98 +1,94 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { defineEntity, p } from '@mikro-orm/core';
|
|
2
|
+
import { DatabaseTable, } from '@mikro-orm/sql';
|
|
3
3
|
export class MigrationStorage {
|
|
4
4
|
driver;
|
|
5
5
|
options;
|
|
6
|
-
connection;
|
|
7
|
-
helper;
|
|
8
|
-
masterTransaction;
|
|
9
|
-
platform;
|
|
6
|
+
#connection;
|
|
7
|
+
#helper;
|
|
8
|
+
#masterTransaction;
|
|
9
|
+
#platform;
|
|
10
10
|
constructor(driver, options) {
|
|
11
11
|
this.driver = driver;
|
|
12
12
|
this.options = options;
|
|
13
|
-
this
|
|
14
|
-
this
|
|
15
|
-
this
|
|
13
|
+
this.#connection = this.driver.getConnection();
|
|
14
|
+
this.#platform = this.driver.getPlatform();
|
|
15
|
+
this.#helper = this.#platform.getSchemaHelper();
|
|
16
16
|
}
|
|
17
17
|
async executed() {
|
|
18
18
|
const migrations = await this.getExecutedMigrations();
|
|
19
|
-
return migrations.map(({ name }) =>
|
|
19
|
+
return migrations.map(({ name }) => this.getMigrationName(name));
|
|
20
20
|
}
|
|
21
21
|
async logMigration(params) {
|
|
22
|
-
const {
|
|
22
|
+
const { entity } = this.getTableName();
|
|
23
23
|
const name = this.getMigrationName(params.name);
|
|
24
|
-
await this.driver.nativeInsert(
|
|
24
|
+
await this.driver.nativeInsert(entity, { name }, { ctx: this.#masterTransaction });
|
|
25
25
|
}
|
|
26
26
|
async unlogMigration(params) {
|
|
27
|
-
const {
|
|
27
|
+
const { entity } = this.getTableName();
|
|
28
28
|
const withoutExt = this.getMigrationName(params.name);
|
|
29
29
|
const names = [withoutExt, withoutExt + '.js', withoutExt + '.ts'];
|
|
30
|
-
await this.driver.nativeDelete(
|
|
30
|
+
await this.driver.nativeDelete(entity, { name: { $in: [params.name, ...names] } }, { ctx: this.#masterTransaction });
|
|
31
31
|
}
|
|
32
32
|
async getExecutedMigrations() {
|
|
33
|
-
const {
|
|
34
|
-
const res = await this.driver
|
|
33
|
+
const { entity, schemaName } = this.getTableName();
|
|
34
|
+
const res = await this.driver
|
|
35
|
+
.createQueryBuilder(entity, this.#masterTransaction)
|
|
35
36
|
.withSchema(schemaName)
|
|
36
37
|
.orderBy({ id: 'asc' })
|
|
37
|
-
.execute();
|
|
38
|
+
.execute('all', false);
|
|
38
39
|
return res.map(row => {
|
|
39
|
-
if (typeof row.executed_at === 'string') {
|
|
40
|
+
if (typeof row.executed_at === 'string' || typeof row.executed_at === 'number') {
|
|
40
41
|
row.executed_at = new Date(row.executed_at);
|
|
41
42
|
}
|
|
42
43
|
return row;
|
|
43
44
|
});
|
|
44
45
|
}
|
|
45
46
|
async ensureTable() {
|
|
46
|
-
const tables = await this
|
|
47
|
+
const tables = await this.#connection.execute(this.#helper.getListTablesSQL(), [], 'all', this.#masterTransaction);
|
|
47
48
|
const { tableName, schemaName } = this.getTableName();
|
|
48
49
|
if (tables.find(t => t.table_name === tableName && (!t.schema_name || t.schema_name === schemaName))) {
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
51
|
-
const schemas = await this
|
|
52
|
+
const schemas = await this.#helper.getNamespaces(this.#connection);
|
|
52
53
|
if (schemaName && !schemas.includes(schemaName)) {
|
|
53
|
-
const sql = this
|
|
54
|
-
await this
|
|
54
|
+
const sql = this.#helper.getCreateNamespaceSQL(schemaName);
|
|
55
|
+
await this.#connection.execute(sql);
|
|
55
56
|
}
|
|
56
|
-
const table = new DatabaseTable(this
|
|
57
|
+
const table = new DatabaseTable(this.#platform, tableName, schemaName);
|
|
57
58
|
table.addColumn({
|
|
58
59
|
name: 'id',
|
|
59
|
-
type: this
|
|
60
|
-
mappedType: this
|
|
60
|
+
type: this.#platform.getIntegerTypeDeclarationSQL({ autoincrement: true, unsigned: true }),
|
|
61
|
+
mappedType: this.#platform.getMappedType('number'),
|
|
61
62
|
primary: true,
|
|
62
63
|
autoincrement: true,
|
|
63
64
|
});
|
|
64
65
|
table.addColumn({
|
|
65
66
|
name: 'name',
|
|
66
|
-
type: this
|
|
67
|
-
mappedType: this
|
|
67
|
+
type: this.#platform.getVarcharTypeDeclarationSQL({}),
|
|
68
|
+
mappedType: this.#platform.getMappedType('string'),
|
|
68
69
|
});
|
|
69
|
-
const length = this
|
|
70
|
+
const length = this.#platform.getDefaultDateTimeLength();
|
|
70
71
|
table.addColumn({
|
|
71
72
|
name: 'executed_at',
|
|
72
|
-
type: this
|
|
73
|
-
mappedType: this
|
|
74
|
-
default: this
|
|
73
|
+
type: this.#platform.getDateTimeTypeDeclarationSQL({ length }),
|
|
74
|
+
mappedType: this.#platform.getMappedType('datetime'),
|
|
75
|
+
default: this.#platform.getCurrentTimestampSQL(length),
|
|
75
76
|
length,
|
|
76
77
|
});
|
|
77
|
-
const sql = this
|
|
78
|
-
await this
|
|
78
|
+
const sql = this.#helper.createTable(table);
|
|
79
|
+
await this.#connection.execute(sql.join(';\n'), [], 'run', this.#masterTransaction);
|
|
79
80
|
}
|
|
80
81
|
setMasterMigration(trx) {
|
|
81
|
-
this
|
|
82
|
+
this.#masterTransaction = trx;
|
|
82
83
|
}
|
|
83
84
|
unsetMasterMigration() {
|
|
84
|
-
|
|
85
|
+
this.#masterTransaction = undefined;
|
|
85
86
|
}
|
|
86
87
|
/**
|
|
87
88
|
* @internal
|
|
88
89
|
*/
|
|
89
90
|
getMigrationName(name) {
|
|
90
|
-
|
|
91
|
-
if (['.js', '.ts'].includes(parsedName.ext)) {
|
|
92
|
-
// strip extension
|
|
93
|
-
return parsedName.name;
|
|
94
|
-
}
|
|
95
|
-
return name;
|
|
91
|
+
return name.replace(/\.[jt]s$/, '');
|
|
96
92
|
}
|
|
97
93
|
/**
|
|
98
94
|
* @internal
|
|
@@ -101,6 +97,17 @@ export class MigrationStorage {
|
|
|
101
97
|
const parts = this.options.tableName.split('.');
|
|
102
98
|
const tableName = parts.length > 1 ? parts[1] : parts[0];
|
|
103
99
|
const schemaName = parts.length > 1 ? parts[0] : this.driver.config.get('schema', this.driver.getPlatform().getDefaultSchemaName());
|
|
104
|
-
|
|
100
|
+
const entity = defineEntity({
|
|
101
|
+
name: 'Migration',
|
|
102
|
+
tableName,
|
|
103
|
+
schema: schemaName,
|
|
104
|
+
properties: {
|
|
105
|
+
id: p.integer().primary().fieldNames('id'),
|
|
106
|
+
name: p.string().fieldNames('name'),
|
|
107
|
+
executedAt: p.datetime().defaultRaw('current_timestamp').fieldNames('executed_at'),
|
|
108
|
+
},
|
|
109
|
+
}).init();
|
|
110
|
+
entity.meta.sync();
|
|
111
|
+
return { tableName, schemaName, entity };
|
|
105
112
|
}
|
|
106
113
|
}
|
package/Migrator.d.ts
CHANGED
|
@@ -1,41 +1,28 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import {
|
|
3
|
-
import { DatabaseSchema, type EntityManager } from '@mikro-orm/
|
|
4
|
-
import type { Migration } from './Migration.js';
|
|
1
|
+
import { type IMigrationGenerator, type IMigrationRunner, type IMigratorStorage, type MigrateOptions, type MigrationInfo, type MikroORM } from '@mikro-orm/core';
|
|
2
|
+
import { AbstractMigrator } from '@mikro-orm/core/migrations';
|
|
3
|
+
import { type AbstractSqlDriver, DatabaseSchema, type EntityManager } from '@mikro-orm/sql';
|
|
5
4
|
import { MigrationStorage } from './MigrationStorage.js';
|
|
6
|
-
import type {
|
|
7
|
-
export declare class Migrator
|
|
8
|
-
private
|
|
9
|
-
private umzug;
|
|
10
|
-
private runner;
|
|
11
|
-
private storage;
|
|
12
|
-
private generator;
|
|
13
|
-
private readonly driver;
|
|
14
|
-
private readonly schemaGenerator;
|
|
15
|
-
private readonly config;
|
|
16
|
-
private readonly options;
|
|
17
|
-
private readonly absolutePath;
|
|
18
|
-
private readonly snapshotPath;
|
|
5
|
+
import type { MigrationResult } from './typings.js';
|
|
6
|
+
export declare class Migrator extends AbstractMigrator<AbstractSqlDriver> {
|
|
7
|
+
#private;
|
|
19
8
|
constructor(em: EntityManager);
|
|
20
9
|
static register(orm: MikroORM): void;
|
|
10
|
+
protected createRunner(): IMigrationRunner;
|
|
11
|
+
protected createStorage(): IMigratorStorage;
|
|
12
|
+
protected getDefaultGenerator(): IMigrationGenerator;
|
|
13
|
+
private getSnapshotPath;
|
|
14
|
+
protected init(): Promise<void>;
|
|
21
15
|
/**
|
|
22
16
|
* @inheritDoc
|
|
23
17
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
create(path?: string, blank?: boolean, initial?: boolean, name?: string): Promise<MigrationResult>;
|
|
19
|
+
checkSchema(): Promise<boolean>;
|
|
26
20
|
/**
|
|
27
21
|
* @inheritDoc
|
|
28
22
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
*/
|
|
33
|
-
on(eventName: MigratorEvent, listener: (event: UmzugMigration) => MaybePromise<void>): this;
|
|
34
|
-
/**
|
|
35
|
-
* @inheritDoc
|
|
36
|
-
*/
|
|
37
|
-
off(eventName: MigratorEvent, listener: (event: UmzugMigration) => MaybePromise<void>): this;
|
|
38
|
-
private createUmzug;
|
|
23
|
+
createInitial(path?: string, name?: string, blank?: boolean): Promise<MigrationResult>;
|
|
24
|
+
protected runMigrations(method: 'up' | 'down', options?: string | string[] | MigrateOptions): Promise<MigrationInfo[]>;
|
|
25
|
+
getStorage(): MigrationStorage;
|
|
39
26
|
/**
|
|
40
27
|
* Initial migration can be created only if:
|
|
41
28
|
* 1. no previous migrations were generated or executed
|
|
@@ -45,32 +32,7 @@ export declare class Migrator implements IMigrator {
|
|
|
45
32
|
* If only some of the tables are present, exception is thrown.
|
|
46
33
|
*/
|
|
47
34
|
private validateInitialMigration;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
*/
|
|
51
|
-
getExecutedMigrations(): Promise<MigrationRow[]>;
|
|
52
|
-
private ensureDatabase;
|
|
53
|
-
/**
|
|
54
|
-
* @inheritDoc
|
|
55
|
-
*/
|
|
56
|
-
getPendingMigrations(): Promise<UmzugMigration[]>;
|
|
57
|
-
/**
|
|
58
|
-
* @inheritDoc
|
|
59
|
-
*/
|
|
60
|
-
up(options?: string | string[] | MigrateOptions): Promise<UmzugMigration[]>;
|
|
61
|
-
/**
|
|
62
|
-
* @inheritDoc
|
|
63
|
-
*/
|
|
64
|
-
down(options?: string | string[] | MigrateOptions): Promise<UmzugMigration[]>;
|
|
65
|
-
getStorage(): MigrationStorage;
|
|
66
|
-
protected resolve(params: MigrationParams<any>): RunnableMigration<any>;
|
|
67
|
-
protected getSchemaFromSnapshot(): DatabaseSchema | undefined;
|
|
68
|
-
protected storeCurrentSchema(): Promise<void>;
|
|
69
|
-
protected initialize(MigrationClass: Constructor<Migration>, name: string): RunnableMigration<any>;
|
|
35
|
+
protected getSchemaFromSnapshot(): Promise<DatabaseSchema | undefined>;
|
|
36
|
+
protected storeCurrentSchema(schema?: DatabaseSchema): Promise<void>;
|
|
70
37
|
private getSchemaDiff;
|
|
71
|
-
private getMigrationFilename;
|
|
72
|
-
private prefix;
|
|
73
|
-
private runMigrations;
|
|
74
|
-
private runInTransaction;
|
|
75
|
-
private ensureMigrationsDirExists;
|
|
76
38
|
}
|
package/Migrator.js
CHANGED
|
@@ -1,53 +1,65 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t, Type, UnknownType, Utils, } from '@mikro-orm/core';
|
|
5
|
-
import { DatabaseSchema, DatabaseTable, SqlSchemaGenerator, } from '@mikro-orm/knex';
|
|
1
|
+
import { t, Type, UnknownType, } from '@mikro-orm/core';
|
|
2
|
+
import { AbstractMigrator } from '@mikro-orm/core/migrations';
|
|
3
|
+
import { DatabaseSchema, DatabaseTable, } from '@mikro-orm/sql';
|
|
6
4
|
import { MigrationRunner } from './MigrationRunner.js';
|
|
7
5
|
import { MigrationStorage } from './MigrationStorage.js';
|
|
8
6
|
import { TSMigrationGenerator } from './TSMigrationGenerator.js';
|
|
9
7
|
import { JSMigrationGenerator } from './JSMigrationGenerator.js';
|
|
10
|
-
export class Migrator {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
runner;
|
|
14
|
-
storage;
|
|
15
|
-
generator;
|
|
16
|
-
driver;
|
|
17
|
-
schemaGenerator;
|
|
18
|
-
config;
|
|
19
|
-
options;
|
|
20
|
-
absolutePath;
|
|
21
|
-
snapshotPath;
|
|
8
|
+
export class Migrator extends AbstractMigrator {
|
|
9
|
+
#schemaGenerator;
|
|
10
|
+
#snapshotPath;
|
|
22
11
|
constructor(em) {
|
|
23
|
-
|
|
24
|
-
this
|
|
25
|
-
this.schemaGenerator = new SqlSchemaGenerator(this.em);
|
|
26
|
-
this.config = this.em.config;
|
|
27
|
-
this.options = this.config.get('migrations');
|
|
28
|
-
/* v8 ignore next */
|
|
29
|
-
const key = (this.config.get('preferTs', Utils.detectTypeScriptSupport()) && this.options.pathTs) ? 'pathTs' : 'path';
|
|
30
|
-
this.absolutePath = Utils.absolutePath(this.options[key], this.config.get('baseDir'));
|
|
31
|
-
// for snapshots, we always want to use the path based on `emit` option, regardless of whether we run in TS context
|
|
32
|
-
/* v8 ignore next */
|
|
33
|
-
const snapshotPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path;
|
|
34
|
-
const absoluteSnapshotPath = Utils.absolutePath(snapshotPath, this.config.get('baseDir'));
|
|
35
|
-
const dbName = basename(this.config.get('dbName'));
|
|
36
|
-
const snapshotName = this.options.snapshotName ?? `.snapshot-${dbName}`;
|
|
37
|
-
this.snapshotPath = Utils.normalizePath(absoluteSnapshotPath, `${snapshotName}.json`);
|
|
38
|
-
this.createUmzug();
|
|
12
|
+
super(em);
|
|
13
|
+
this.#schemaGenerator = this.config.getExtension('@mikro-orm/schema-generator');
|
|
39
14
|
}
|
|
40
15
|
static register(orm) {
|
|
41
16
|
orm.config.registerExtension('@mikro-orm/migrator', () => new Migrator(orm.em));
|
|
42
17
|
}
|
|
18
|
+
createRunner() {
|
|
19
|
+
return new MigrationRunner(this.driver, this.options, this.config);
|
|
20
|
+
}
|
|
21
|
+
createStorage() {
|
|
22
|
+
return new MigrationStorage(this.driver, this.options);
|
|
23
|
+
}
|
|
24
|
+
getDefaultGenerator() {
|
|
25
|
+
if (this.options.emit === 'js' || this.options.emit === 'cjs') {
|
|
26
|
+
return new JSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
27
|
+
}
|
|
28
|
+
return new TSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
29
|
+
}
|
|
30
|
+
async getSnapshotPath() {
|
|
31
|
+
if (!this.#snapshotPath) {
|
|
32
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
33
|
+
// for snapshots, we always want to use the path based on `emit` option, regardless of whether we run in TS context
|
|
34
|
+
/* v8 ignore next */
|
|
35
|
+
const snapshotPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path;
|
|
36
|
+
const absoluteSnapshotPath = fs.absolutePath(snapshotPath, this.config.get('baseDir'));
|
|
37
|
+
const dbName = this.config.get('dbName').replace(/\\/g, '/').split('/').pop().replace(/:/g, '');
|
|
38
|
+
const snapshotName = this.options.snapshotName ?? `.snapshot-${dbName}`;
|
|
39
|
+
this.#snapshotPath = fs.normalizePath(absoluteSnapshotPath, `${snapshotName}.json`);
|
|
40
|
+
}
|
|
41
|
+
return this.#snapshotPath;
|
|
42
|
+
}
|
|
43
|
+
async init() {
|
|
44
|
+
if (this.initialized) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await super.init();
|
|
48
|
+
const created = await this.#schemaGenerator.ensureDatabase();
|
|
49
|
+
/* v8 ignore next */
|
|
50
|
+
if (created) {
|
|
51
|
+
this.initServices();
|
|
52
|
+
}
|
|
53
|
+
await this.storage.ensureTable();
|
|
54
|
+
}
|
|
43
55
|
/**
|
|
44
56
|
* @inheritDoc
|
|
45
57
|
*/
|
|
46
|
-
async
|
|
58
|
+
async create(path, blank = false, initial = false, name) {
|
|
59
|
+
await this.init();
|
|
47
60
|
if (initial) {
|
|
48
|
-
return this.
|
|
61
|
+
return this.createInitial(path, name, blank);
|
|
49
62
|
}
|
|
50
|
-
this.ensureMigrationsDirExists();
|
|
51
63
|
const diff = await this.getSchemaDiff(blank, initial);
|
|
52
64
|
if (diff.up.length === 0) {
|
|
53
65
|
return { fileName: '', code: '', diff };
|
|
@@ -60,22 +72,22 @@ export class Migrator {
|
|
|
60
72
|
diff,
|
|
61
73
|
};
|
|
62
74
|
}
|
|
63
|
-
async
|
|
64
|
-
this.
|
|
75
|
+
async checkSchema() {
|
|
76
|
+
await this.init();
|
|
65
77
|
const diff = await this.getSchemaDiff(false, false);
|
|
66
78
|
return diff.up.length > 0;
|
|
67
79
|
}
|
|
68
80
|
/**
|
|
69
81
|
* @inheritDoc
|
|
70
82
|
*/
|
|
71
|
-
async
|
|
72
|
-
this.
|
|
83
|
+
async createInitial(path, name, blank = false) {
|
|
84
|
+
await this.init();
|
|
73
85
|
const schemaExists = await this.validateInitialMigration(blank);
|
|
74
86
|
const diff = await this.getSchemaDiff(blank, true);
|
|
75
87
|
const migration = await this.generator.generate(diff, path, name);
|
|
76
88
|
await this.storeCurrentSchema();
|
|
77
89
|
if (schemaExists && !blank) {
|
|
78
|
-
await this.storage.logMigration({ name: migration[1]
|
|
90
|
+
await this.storage.logMigration({ name: migration[1] });
|
|
79
91
|
}
|
|
80
92
|
return {
|
|
81
93
|
fileName: migration[1],
|
|
@@ -83,56 +95,21 @@ export class Migrator {
|
|
|
83
95
|
diff,
|
|
84
96
|
};
|
|
85
97
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
off(eventName, listener) {
|
|
97
|
-
this.umzug.off(eventName, listener);
|
|
98
|
-
return this;
|
|
99
|
-
}
|
|
100
|
-
createUmzug() {
|
|
101
|
-
this.runner = new MigrationRunner(this.driver, this.options, this.config);
|
|
102
|
-
this.storage = new MigrationStorage(this.driver, this.options);
|
|
103
|
-
let migrations = {
|
|
104
|
-
glob: join(this.absolutePath, this.options.glob).replace(/\\/g, '/'),
|
|
105
|
-
resolve: (params) => this.resolve(params),
|
|
106
|
-
};
|
|
107
|
-
if (this.options.migrationsList) {
|
|
108
|
-
migrations = this.options.migrationsList.map(migration => {
|
|
109
|
-
if (typeof migration === 'function') {
|
|
110
|
-
return this.initialize(migration, migration.name);
|
|
111
|
-
}
|
|
112
|
-
return this.initialize(migration.class, migration.name);
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
this.umzug = new Umzug({
|
|
116
|
-
storage: this.storage,
|
|
117
|
-
logger: undefined,
|
|
118
|
-
migrations,
|
|
119
|
-
});
|
|
120
|
-
if (!this.options.silent) {
|
|
121
|
-
const logger = this.config.getLogger();
|
|
122
|
-
this.umzug.on('migrating', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
|
|
123
|
-
this.umzug.on('migrated', event => logger.log('migrator', `Applied '${event.name}'`, { enabled: true }));
|
|
124
|
-
this.umzug.on('reverting', event => logger.log('migrator', `Processing '${event.name}'`, { enabled: true }));
|
|
125
|
-
this.umzug.on('reverted', event => logger.log('migrator', `Reverted '${event.name}'`, { enabled: true }));
|
|
126
|
-
}
|
|
127
|
-
if (this.options.generator) {
|
|
128
|
-
this.generator = new this.options.generator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
129
|
-
}
|
|
130
|
-
else if (this.options.emit === 'js' || this.options.emit === 'cjs') {
|
|
131
|
-
this.generator = new JSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
this.generator = new TSMigrationGenerator(this.driver, this.config.getNamingStrategy(), this.options);
|
|
98
|
+
async runMigrations(method, options) {
|
|
99
|
+
const result = await super.runMigrations(method, options);
|
|
100
|
+
if (result.length > 0 && this.options.snapshot) {
|
|
101
|
+
const schema = await DatabaseSchema.create(this.em.getConnection(), this.em.getPlatform(), this.config);
|
|
102
|
+
try {
|
|
103
|
+
await this.storeCurrentSchema(schema);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Silently ignore for read-only filesystems (production).
|
|
107
|
+
}
|
|
135
108
|
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
getStorage() {
|
|
112
|
+
return this.storage;
|
|
136
113
|
}
|
|
137
114
|
/**
|
|
138
115
|
* Initial migration can be created only if:
|
|
@@ -143,15 +120,15 @@ export class Migrator {
|
|
|
143
120
|
* If only some of the tables are present, exception is thrown.
|
|
144
121
|
*/
|
|
145
122
|
async validateInitialMigration(blank) {
|
|
146
|
-
const executed = await this.
|
|
147
|
-
const pending = await this.
|
|
123
|
+
const executed = await this.getExecuted();
|
|
124
|
+
const pending = await this.getPending();
|
|
148
125
|
if (executed.length > 0 || pending.length > 0) {
|
|
149
126
|
throw new Error('Initial migration cannot be created, as some migrations already exist');
|
|
150
127
|
}
|
|
151
128
|
const schema = await DatabaseSchema.create(this.em.getConnection(), this.em.getPlatform(), this.config);
|
|
152
129
|
const exists = new Set();
|
|
153
130
|
const expected = new Set();
|
|
154
|
-
|
|
131
|
+
[...this.em.getMetadata().getAll().values()]
|
|
155
132
|
.filter(meta => meta.tableName && !meta.embeddable && !meta.virtual)
|
|
156
133
|
.forEach(meta => {
|
|
157
134
|
const schema = meta.schema ?? this.config.get('schema', this.em.getPlatform().getDefaultSchemaName());
|
|
@@ -172,120 +149,111 @@ export class Migrator {
|
|
|
172
149
|
}
|
|
173
150
|
return expected.size === exists.size;
|
|
174
151
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
async getExecutedMigrations() {
|
|
179
|
-
await this.ensureDatabase();
|
|
180
|
-
return this.storage.getExecutedMigrations();
|
|
181
|
-
}
|
|
182
|
-
async ensureDatabase() {
|
|
183
|
-
this.ensureMigrationsDirExists();
|
|
184
|
-
const created = await this.schemaGenerator.ensureDatabase();
|
|
185
|
-
/* v8 ignore next 3 */
|
|
186
|
-
if (created) {
|
|
187
|
-
this.createUmzug();
|
|
152
|
+
async getSchemaFromSnapshot() {
|
|
153
|
+
if (!this.options.snapshot) {
|
|
154
|
+
return undefined;
|
|
188
155
|
}
|
|
189
|
-
await this.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
* @inheritDoc
|
|
193
|
-
*/
|
|
194
|
-
async getPendingMigrations() {
|
|
195
|
-
await this.ensureDatabase();
|
|
196
|
-
return this.umzug.pending();
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* @inheritDoc
|
|
200
|
-
*/
|
|
201
|
-
async up(options) {
|
|
202
|
-
return this.runMigrations('up', options);
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* @inheritDoc
|
|
206
|
-
*/
|
|
207
|
-
async down(options) {
|
|
208
|
-
return this.runMigrations('down', options);
|
|
209
|
-
}
|
|
210
|
-
getStorage() {
|
|
211
|
-
return this.storage;
|
|
212
|
-
}
|
|
213
|
-
resolve(params) {
|
|
214
|
-
const createMigrationHandler = async (method) => {
|
|
215
|
-
const migration = await Utils.dynamicImport(params.path);
|
|
216
|
-
const MigrationClass = Object.values(migration).find(cls => typeof cls === 'function' && typeof cls.constructor === 'function');
|
|
217
|
-
const instance = new MigrationClass(this.driver, this.config);
|
|
218
|
-
await this.runner.run(instance, method);
|
|
219
|
-
};
|
|
220
|
-
return {
|
|
221
|
-
name: this.storage.getMigrationName(params.name),
|
|
222
|
-
up: () => createMigrationHandler('up'),
|
|
223
|
-
down: () => createMigrationHandler('down'),
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
getSchemaFromSnapshot() {
|
|
227
|
-
if (!this.options.snapshot || !existsSync(this.snapshotPath)) {
|
|
156
|
+
const snapshotPath = await this.getSnapshotPath();
|
|
157
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
158
|
+
if (!fs.pathExists(snapshotPath)) {
|
|
228
159
|
return undefined;
|
|
229
160
|
}
|
|
230
|
-
const data =
|
|
161
|
+
const data = fs.readJSONSync(snapshotPath);
|
|
231
162
|
const schema = new DatabaseSchema(this.driver.getPlatform(), this.config.get('schema'));
|
|
232
163
|
const { tables, namespaces, ...rest } = data;
|
|
233
164
|
const tableInstances = tables.map((tbl) => {
|
|
234
|
-
const table = new DatabaseTable(this.driver.getPlatform(), tbl.name);
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
165
|
+
const table = new DatabaseTable(this.driver.getPlatform(), tbl.name, tbl.schema);
|
|
166
|
+
table.nativeEnums = tbl.nativeEnums ?? {};
|
|
167
|
+
table.comment = tbl.comment;
|
|
168
|
+
if (tbl.indexes) {
|
|
169
|
+
table.setIndexes(tbl.indexes);
|
|
170
|
+
}
|
|
171
|
+
if (tbl.checks) {
|
|
172
|
+
table.setChecks(tbl.checks);
|
|
173
|
+
}
|
|
174
|
+
if (tbl.foreignKeys) {
|
|
175
|
+
table.setForeignKeys(tbl.foreignKeys);
|
|
176
|
+
}
|
|
177
|
+
const cols = tbl.columns;
|
|
178
|
+
Object.keys(cols).forEach(col => {
|
|
179
|
+
const column = { ...cols[col] };
|
|
239
180
|
/* v8 ignore next */
|
|
240
|
-
column.mappedType = Type.getType(t[
|
|
181
|
+
column.mappedType = Type.getType(t[cols[col].mappedType] ?? UnknownType);
|
|
241
182
|
table.addColumn(column);
|
|
242
183
|
});
|
|
243
184
|
return table;
|
|
244
185
|
});
|
|
245
|
-
|
|
186
|
+
schema.setTables(tableInstances);
|
|
187
|
+
schema.setNamespaces(new Set(namespaces));
|
|
188
|
+
if (rest.nativeEnums) {
|
|
189
|
+
schema.setNativeEnums(rest.nativeEnums);
|
|
190
|
+
}
|
|
191
|
+
if (rest.views) {
|
|
192
|
+
schema.setViews(rest.views);
|
|
193
|
+
}
|
|
246
194
|
return schema;
|
|
247
195
|
}
|
|
248
|
-
async storeCurrentSchema() {
|
|
196
|
+
async storeCurrentSchema(schema) {
|
|
249
197
|
if (!this.options.snapshot) {
|
|
250
198
|
return;
|
|
251
199
|
}
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const instance = new MigrationClass(this.driver, this.config);
|
|
257
|
-
return {
|
|
258
|
-
name: this.storage.getMigrationName(name),
|
|
259
|
-
up: () => this.runner.run(instance, 'up'),
|
|
260
|
-
down: () => this.runner.run(instance, 'down'),
|
|
261
|
-
};
|
|
200
|
+
const snapshotPath = await this.getSnapshotPath();
|
|
201
|
+
schema ??= this.#schemaGenerator.getTargetSchema();
|
|
202
|
+
const { fs } = await import('@mikro-orm/core/fs-utils');
|
|
203
|
+
await fs.writeFile(snapshotPath, JSON.stringify(schema, null, 2));
|
|
262
204
|
}
|
|
263
205
|
async getSchemaDiff(blank, initial) {
|
|
264
206
|
const up = [];
|
|
265
207
|
const down = [];
|
|
208
|
+
// Split SQL by statement boundaries (semicolons followed by newline) rather than
|
|
209
|
+
// just newlines, to preserve multiline statements like view definitions.
|
|
210
|
+
// Blank lines (from double newlines) are preserved as empty strings for grouping.
|
|
211
|
+
// Splits inside single-quoted string literals are re-merged (GH #7185).
|
|
212
|
+
const splitStatements = (sql) => {
|
|
213
|
+
const result = [];
|
|
214
|
+
let buf = '';
|
|
215
|
+
for (const chunk of sql.split(/;\n/)) {
|
|
216
|
+
buf += (buf ? ';\n' : '') + chunk;
|
|
217
|
+
// odd number of single quotes means we're inside a string literal
|
|
218
|
+
if (buf.split(`'`).length % 2 === 0) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
// A chunk starting with \n indicates there was a blank line (grouping separator)
|
|
222
|
+
if (buf.startsWith('\n')) {
|
|
223
|
+
result.push('');
|
|
224
|
+
}
|
|
225
|
+
const trimmed = buf.trim();
|
|
226
|
+
if (trimmed) {
|
|
227
|
+
result.push(trimmed.endsWith(';') ? trimmed : trimmed + ';');
|
|
228
|
+
}
|
|
229
|
+
buf = '';
|
|
230
|
+
}
|
|
231
|
+
return result;
|
|
232
|
+
};
|
|
266
233
|
if (blank) {
|
|
267
234
|
up.push('select 1');
|
|
268
235
|
down.push('select 1');
|
|
269
236
|
}
|
|
270
237
|
else if (initial) {
|
|
271
|
-
const dump = await this
|
|
272
|
-
up.push(...dump
|
|
238
|
+
const dump = await this.#schemaGenerator.getCreateSchemaSQL({ wrap: false });
|
|
239
|
+
up.push(...splitStatements(dump));
|
|
273
240
|
}
|
|
274
241
|
else {
|
|
275
|
-
const diff = await this
|
|
242
|
+
const diff = await this.#schemaGenerator.getUpdateSchemaMigrationSQL({
|
|
276
243
|
wrap: false,
|
|
277
244
|
safe: this.options.safe,
|
|
278
245
|
dropTables: this.options.dropTables,
|
|
279
|
-
fromSchema: this.getSchemaFromSnapshot(),
|
|
246
|
+
fromSchema: await this.getSchemaFromSnapshot(),
|
|
280
247
|
});
|
|
281
|
-
up.push(...diff.up
|
|
282
|
-
down.push(...diff.down
|
|
248
|
+
up.push(...splitStatements(diff.up));
|
|
249
|
+
down.push(...splitStatements(diff.down));
|
|
283
250
|
}
|
|
284
251
|
const cleanUp = (diff) => {
|
|
285
252
|
for (let i = diff.length - 1; i >= 0; i--) {
|
|
286
253
|
if (diff[i]) {
|
|
287
254
|
break;
|
|
288
255
|
}
|
|
256
|
+
/* v8 ignore next */
|
|
289
257
|
diff.splice(i, 1);
|
|
290
258
|
}
|
|
291
259
|
};
|
|
@@ -293,47 +261,4 @@ export class Migrator {
|
|
|
293
261
|
cleanUp(down);
|
|
294
262
|
return { up, down };
|
|
295
263
|
}
|
|
296
|
-
getMigrationFilename(name) {
|
|
297
|
-
name = name.replace(/\.[jt]s$/, '');
|
|
298
|
-
return name.match(/^\d{14}$/) ? this.options.fileName(name) : name;
|
|
299
|
-
}
|
|
300
|
-
prefix(options) {
|
|
301
|
-
if (Utils.isString(options) || Array.isArray(options)) {
|
|
302
|
-
return { migrations: Utils.asArray(options).map(name => this.getMigrationFilename(name)) };
|
|
303
|
-
}
|
|
304
|
-
if (!options) {
|
|
305
|
-
return {};
|
|
306
|
-
}
|
|
307
|
-
if (options.migrations) {
|
|
308
|
-
options.migrations = options.migrations.map(name => this.getMigrationFilename(name));
|
|
309
|
-
}
|
|
310
|
-
if (options.transaction) {
|
|
311
|
-
delete options.transaction;
|
|
312
|
-
}
|
|
313
|
-
['from', 'to'].filter(k => options[k]).forEach(k => options[k] = this.getMigrationFilename(options[k]));
|
|
314
|
-
return options;
|
|
315
|
-
}
|
|
316
|
-
async runMigrations(method, options) {
|
|
317
|
-
await this.ensureDatabase();
|
|
318
|
-
if (!this.options.transactional || !this.options.allOrNothing) {
|
|
319
|
-
return this.umzug[method](this.prefix(options));
|
|
320
|
-
}
|
|
321
|
-
if (Utils.isObject(options) && options.transaction) {
|
|
322
|
-
return this.runInTransaction(options.transaction, method, options);
|
|
323
|
-
}
|
|
324
|
-
return this.driver.getConnection().transactional(trx => this.runInTransaction(trx, method, options));
|
|
325
|
-
}
|
|
326
|
-
async runInTransaction(trx, method, options) {
|
|
327
|
-
this.runner.setMasterMigration(trx);
|
|
328
|
-
this.storage.setMasterMigration(trx);
|
|
329
|
-
const ret = await this.umzug[method](this.prefix(options));
|
|
330
|
-
this.runner.unsetMasterMigration();
|
|
331
|
-
this.storage.unsetMasterMigration();
|
|
332
|
-
return ret;
|
|
333
|
-
}
|
|
334
|
-
ensureMigrationsDirExists() {
|
|
335
|
-
if (!this.options.migrationsList) {
|
|
336
|
-
Utils.ensureDir(this.absolutePath);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
264
|
}
|
package/README.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
<a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
|
|
3
3
|
</h1>
|
|
4
4
|
|
|
5
|
-
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL
|
|
5
|
+
TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
|
|
6
6
|
|
|
7
7
|
> Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
|
|
8
8
|
|
|
9
|
-
[](https://
|
|
10
|
-
[](https://
|
|
9
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
10
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
11
11
|
[](https://discord.gg/w8bjxFHS7X)
|
|
12
|
-
[](https://
|
|
12
|
+
[](https://npmx.dev/package/@mikro-orm/core)
|
|
13
13
|
[](https://coveralls.io/r/mikro-orm/mikro-orm?branch=master)
|
|
14
14
|
[](https://github.com/mikro-orm/mikro-orm/actions?workflow=tests)
|
|
15
15
|
|
|
@@ -181,6 +181,7 @@ yarn add @mikro-orm/core @mikro-orm/mysql # for mysql/mariadb
|
|
|
181
181
|
yarn add @mikro-orm/core @mikro-orm/mariadb # for mysql/mariadb
|
|
182
182
|
yarn add @mikro-orm/core @mikro-orm/postgresql # for postgresql
|
|
183
183
|
yarn add @mikro-orm/core @mikro-orm/mssql # for mssql
|
|
184
|
+
yarn add @mikro-orm/core @mikro-orm/oracledb # for oracle
|
|
184
185
|
yarn add @mikro-orm/core @mikro-orm/sqlite # for sqlite
|
|
185
186
|
yarn add @mikro-orm/core @mikro-orm/libsql # for libsql
|
|
186
187
|
```
|
|
@@ -381,6 +382,8 @@ See also the list of contributors who [participated](https://github.com/mikro-or
|
|
|
381
382
|
|
|
382
383
|
Please ⭐️ this repository if this project helped you!
|
|
383
384
|
|
|
385
|
+
> If you'd like to support my open-source work, consider sponsoring me directly at [github.com/sponsors/b4nan](https://github.com/sponsors/b4nan).
|
|
386
|
+
|
|
384
387
|
## 📝 License
|
|
385
388
|
|
|
386
389
|
Copyright © 2018 [Martin Adámek](https://github.com/b4nan).
|
package/TSMigrationGenerator.js
CHANGED
|
@@ -7,11 +7,11 @@ export class TSMigrationGenerator extends MigrationGenerator {
|
|
|
7
7
|
let ret = `import { Migration } from '@mikro-orm/migrations';\n\n`;
|
|
8
8
|
ret += `export class ${className} extends Migration {\n\n`;
|
|
9
9
|
ret += ` override async up(): Promise<void> {\n`;
|
|
10
|
-
diff.up.forEach(sql => ret += this.createStatement(sql, 4));
|
|
10
|
+
diff.up.forEach(sql => (ret += this.createStatement(sql, 4)));
|
|
11
11
|
ret += ` }\n\n`;
|
|
12
12
|
if (diff.down.length > 0) {
|
|
13
13
|
ret += ` override async down(): Promise<void> {\n`;
|
|
14
|
-
diff.down.forEach(sql => ret += this.createStatement(sql, 4));
|
|
14
|
+
diff.down.forEach(sql => (ret += this.createStatement(sql, 4)));
|
|
15
15
|
ret += ` }\n\n`;
|
|
16
16
|
}
|
|
17
17
|
ret += `}\n`;
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,62 +1,61 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/migrations",
|
|
3
|
-
"
|
|
4
|
-
"version": "7.0.0-dev.33",
|
|
3
|
+
"version": "7.0.0-dev.331",
|
|
5
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.",
|
|
6
|
-
"exports": {
|
|
7
|
-
"./package.json": "./package.json",
|
|
8
|
-
".": "./index.js"
|
|
9
|
-
},
|
|
10
|
-
"repository": {
|
|
11
|
-
"type": "git",
|
|
12
|
-
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
|
|
13
|
-
},
|
|
14
5
|
"keywords": [
|
|
15
|
-
"
|
|
6
|
+
"data-mapper",
|
|
7
|
+
"ddd",
|
|
8
|
+
"entity",
|
|
9
|
+
"identity-map",
|
|
10
|
+
"javascript",
|
|
11
|
+
"js",
|
|
12
|
+
"mariadb",
|
|
13
|
+
"mikro-orm",
|
|
16
14
|
"mongo",
|
|
17
15
|
"mongodb",
|
|
18
16
|
"mysql",
|
|
19
|
-
"
|
|
17
|
+
"orm",
|
|
20
18
|
"postgresql",
|
|
21
19
|
"sqlite",
|
|
22
20
|
"sqlite3",
|
|
23
21
|
"ts",
|
|
24
22
|
"typescript",
|
|
25
|
-
"
|
|
26
|
-
"javascript",
|
|
27
|
-
"entity",
|
|
28
|
-
"ddd",
|
|
29
|
-
"mikro-orm",
|
|
30
|
-
"unit-of-work",
|
|
31
|
-
"data-mapper",
|
|
32
|
-
"identity-map"
|
|
23
|
+
"unit-of-work"
|
|
33
24
|
],
|
|
34
|
-
"
|
|
35
|
-
"license": "MIT",
|
|
25
|
+
"homepage": "https://mikro-orm.io",
|
|
36
26
|
"bugs": {
|
|
37
27
|
"url": "https://github.com/mikro-orm/mikro-orm/issues"
|
|
38
28
|
},
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"author": "Martin Adámek",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git"
|
|
34
|
+
},
|
|
35
|
+
"type": "module",
|
|
36
|
+
"exports": {
|
|
37
|
+
"./package.json": "./package.json",
|
|
38
|
+
".": "./index.js"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
|
-
"build": "yarn
|
|
44
|
+
"build": "yarn compile && yarn copy",
|
|
45
45
|
"clean": "yarn run -T rimraf ./dist",
|
|
46
46
|
"compile": "yarn run -T tsc -p tsconfig.build.json",
|
|
47
47
|
"copy": "node ../../scripts/copy.mjs"
|
|
48
48
|
},
|
|
49
|
-
"publishConfig": {
|
|
50
|
-
"access": "public"
|
|
51
|
-
},
|
|
52
49
|
"dependencies": {
|
|
53
|
-
"@mikro-orm/
|
|
54
|
-
"umzug": "3.8.2"
|
|
50
|
+
"@mikro-orm/sql": "7.0.0-dev.331"
|
|
55
51
|
},
|
|
56
52
|
"devDependencies": {
|
|
57
|
-
"@mikro-orm/core": "^6.
|
|
53
|
+
"@mikro-orm/core": "^6.6.9"
|
|
58
54
|
},
|
|
59
55
|
"peerDependencies": {
|
|
60
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
56
|
+
"@mikro-orm/core": "7.0.0-dev.331"
|
|
57
|
+
},
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">= 22.17.0"
|
|
61
60
|
}
|
|
62
61
|
}
|
package/typings.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { MigrationInfo, MigrateOptions, MigrationResult, MigrationRow } from '@mikro-orm/core';
|