@mikro-orm/migrations 7.0.4-dev.8 → 7.0.4
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.d.ts +10 -7
- package/JSMigrationGenerator.js +20 -20
- package/Migration.d.ts +29 -23
- package/Migration.js +46 -46
- package/MigrationGenerator.d.ts +35 -23
- package/MigrationGenerator.js +33 -33
- package/MigrationRunner.d.ts +9 -9
- package/MigrationRunner.js +43 -41
- package/MigrationStorage.d.ts +23 -27
- package/MigrationStorage.js +113 -108
- package/Migrator.d.ts +42 -32
- package/Migrator.js +237 -238
- package/README.md +1 -1
- package/TSMigrationGenerator.d.ts +10 -7
- package/TSMigrationGenerator.js +16 -16
- package/package.json +4 -4
package/MigrationStorage.js
CHANGED
|
@@ -1,114 +1,119 @@
|
|
|
1
1
|
import { defineEntity, p } from '@mikro-orm/core';
|
|
2
|
-
import { DatabaseTable
|
|
2
|
+
import { DatabaseTable } from '@mikro-orm/sql';
|
|
3
3
|
/** Tracks executed migrations in a database table. */
|
|
4
4
|
export class MigrationStorage {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
driver;
|
|
6
|
+
options;
|
|
7
|
+
#connection;
|
|
8
|
+
#helper;
|
|
9
|
+
#masterTransaction;
|
|
10
|
+
#platform;
|
|
11
|
+
constructor(driver, options) {
|
|
12
|
+
this.driver = driver;
|
|
13
|
+
this.options = options;
|
|
14
|
+
this.#connection = this.driver.getConnection();
|
|
15
|
+
this.#platform = this.driver.getPlatform();
|
|
16
|
+
this.#helper = this.#platform.getSchemaHelper();
|
|
17
|
+
}
|
|
18
|
+
async executed() {
|
|
19
|
+
const migrations = await this.getExecutedMigrations();
|
|
20
|
+
return migrations.map(({ name }) => this.getMigrationName(name));
|
|
21
|
+
}
|
|
22
|
+
async logMigration(params) {
|
|
23
|
+
const { entity } = this.getTableName();
|
|
24
|
+
const name = this.getMigrationName(params.name);
|
|
25
|
+
await this.driver.nativeInsert(entity, { name }, { ctx: this.#masterTransaction });
|
|
26
|
+
}
|
|
27
|
+
async unlogMigration(params) {
|
|
28
|
+
const { entity } = this.getTableName();
|
|
29
|
+
const withoutExt = this.getMigrationName(params.name);
|
|
30
|
+
const names = [withoutExt, withoutExt + '.js', withoutExt + '.ts'];
|
|
31
|
+
await this.driver.nativeDelete(
|
|
32
|
+
entity,
|
|
33
|
+
{ name: { $in: [params.name, ...names] } },
|
|
34
|
+
{ ctx: this.#masterTransaction },
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
async getExecutedMigrations() {
|
|
38
|
+
const { entity, schemaName } = this.getTableName();
|
|
39
|
+
const res = await this.driver
|
|
40
|
+
.createQueryBuilder(entity, this.#masterTransaction)
|
|
41
|
+
.withSchema(schemaName)
|
|
42
|
+
.orderBy({ id: 'asc' })
|
|
43
|
+
.execute('all', false);
|
|
44
|
+
return res.map(row => {
|
|
45
|
+
if (typeof row.executed_at === 'string' || typeof row.executed_at === 'number') {
|
|
46
|
+
row.executed_at = new Date(row.executed_at);
|
|
47
|
+
}
|
|
48
|
+
return row;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async ensureTable() {
|
|
52
|
+
const tables = await this.#connection.execute(this.#helper.getListTablesSQL(), [], 'all', this.#masterTransaction);
|
|
53
|
+
const { tableName, schemaName } = this.getTableName();
|
|
54
|
+
if (tables.find(t => t.table_name === tableName && (!t.schema_name || t.schema_name === schemaName))) {
|
|
55
|
+
return;
|
|
17
56
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
async logMigration(params) {
|
|
23
|
-
const { entity } = this.getTableName();
|
|
24
|
-
const name = this.getMigrationName(params.name);
|
|
25
|
-
await this.driver.nativeInsert(entity, { name }, { ctx: this.#masterTransaction });
|
|
26
|
-
}
|
|
27
|
-
async unlogMigration(params) {
|
|
28
|
-
const { entity } = this.getTableName();
|
|
29
|
-
const withoutExt = this.getMigrationName(params.name);
|
|
30
|
-
const names = [withoutExt, withoutExt + '.js', withoutExt + '.ts'];
|
|
31
|
-
await this.driver.nativeDelete(entity, { name: { $in: [params.name, ...names] } }, { ctx: this.#masterTransaction });
|
|
32
|
-
}
|
|
33
|
-
async getExecutedMigrations() {
|
|
34
|
-
const { entity, schemaName } = this.getTableName();
|
|
35
|
-
const res = await this.driver
|
|
36
|
-
.createQueryBuilder(entity, this.#masterTransaction)
|
|
37
|
-
.withSchema(schemaName)
|
|
38
|
-
.orderBy({ id: 'asc' })
|
|
39
|
-
.execute('all', false);
|
|
40
|
-
return res.map(row => {
|
|
41
|
-
if (typeof row.executed_at === 'string' || typeof row.executed_at === 'number') {
|
|
42
|
-
row.executed_at = new Date(row.executed_at);
|
|
43
|
-
}
|
|
44
|
-
return row;
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
async ensureTable() {
|
|
48
|
-
const tables = await this.#connection.execute(this.#helper.getListTablesSQL(), [], 'all', this.#masterTransaction);
|
|
49
|
-
const { tableName, schemaName } = this.getTableName();
|
|
50
|
-
if (tables.find(t => t.table_name === tableName && (!t.schema_name || t.schema_name === schemaName))) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const schemas = await this.#helper.getNamespaces(this.#connection);
|
|
54
|
-
if (schemaName && !schemas.includes(schemaName)) {
|
|
55
|
-
const sql = this.#helper.getCreateNamespaceSQL(schemaName);
|
|
56
|
-
await this.#connection.execute(sql);
|
|
57
|
-
}
|
|
58
|
-
const table = new DatabaseTable(this.#platform, tableName, schemaName);
|
|
59
|
-
table.addColumn({
|
|
60
|
-
name: 'id',
|
|
61
|
-
type: this.#platform.getIntegerTypeDeclarationSQL({ autoincrement: true, unsigned: true }),
|
|
62
|
-
mappedType: this.#platform.getMappedType('number'),
|
|
63
|
-
primary: true,
|
|
64
|
-
autoincrement: true,
|
|
65
|
-
});
|
|
66
|
-
table.addColumn({
|
|
67
|
-
name: 'name',
|
|
68
|
-
type: this.#platform.getVarcharTypeDeclarationSQL({}),
|
|
69
|
-
mappedType: this.#platform.getMappedType('string'),
|
|
70
|
-
});
|
|
71
|
-
const length = this.#platform.getDefaultDateTimeLength();
|
|
72
|
-
table.addColumn({
|
|
73
|
-
name: 'executed_at',
|
|
74
|
-
type: this.#platform.getDateTimeTypeDeclarationSQL({ length }),
|
|
75
|
-
mappedType: this.#platform.getMappedType('datetime'),
|
|
76
|
-
default: this.#platform.getCurrentTimestampSQL(length),
|
|
77
|
-
length,
|
|
78
|
-
});
|
|
79
|
-
const sql = this.#helper.createTable(table);
|
|
80
|
-
await this.#connection.execute(sql.join(';\n'), [], 'run', this.#masterTransaction);
|
|
81
|
-
}
|
|
82
|
-
setMasterMigration(trx) {
|
|
83
|
-
this.#masterTransaction = trx;
|
|
84
|
-
}
|
|
85
|
-
unsetMasterMigration() {
|
|
86
|
-
this.#masterTransaction = undefined;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* @internal
|
|
90
|
-
*/
|
|
91
|
-
getMigrationName(name) {
|
|
92
|
-
return name.replace(/\.[jt]s$/, '');
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* @internal
|
|
96
|
-
*/
|
|
97
|
-
getTableName() {
|
|
98
|
-
const parts = this.options.tableName.split('.');
|
|
99
|
-
const tableName = parts.length > 1 ? parts[1] : parts[0];
|
|
100
|
-
const schemaName = parts.length > 1 ? parts[0] : this.driver.config.get('schema', this.driver.getPlatform().getDefaultSchemaName());
|
|
101
|
-
const entity = defineEntity({
|
|
102
|
-
name: 'Migration',
|
|
103
|
-
tableName,
|
|
104
|
-
schema: schemaName,
|
|
105
|
-
properties: {
|
|
106
|
-
id: p.integer().primary().fieldNames('id'),
|
|
107
|
-
name: p.string().fieldNames('name'),
|
|
108
|
-
executedAt: p.datetime().defaultRaw('current_timestamp').fieldNames('executed_at'),
|
|
109
|
-
},
|
|
110
|
-
}).init();
|
|
111
|
-
entity.meta.sync();
|
|
112
|
-
return { tableName, schemaName, entity };
|
|
57
|
+
const schemas = await this.#helper.getNamespaces(this.#connection);
|
|
58
|
+
if (schemaName && !schemas.includes(schemaName)) {
|
|
59
|
+
const sql = this.#helper.getCreateNamespaceSQL(schemaName);
|
|
60
|
+
await this.#connection.execute(sql);
|
|
113
61
|
}
|
|
62
|
+
const table = new DatabaseTable(this.#platform, tableName, schemaName);
|
|
63
|
+
table.addColumn({
|
|
64
|
+
name: 'id',
|
|
65
|
+
type: this.#platform.getIntegerTypeDeclarationSQL({ autoincrement: true, unsigned: true }),
|
|
66
|
+
mappedType: this.#platform.getMappedType('number'),
|
|
67
|
+
primary: true,
|
|
68
|
+
autoincrement: true,
|
|
69
|
+
});
|
|
70
|
+
table.addColumn({
|
|
71
|
+
name: 'name',
|
|
72
|
+
type: this.#platform.getVarcharTypeDeclarationSQL({}),
|
|
73
|
+
mappedType: this.#platform.getMappedType('string'),
|
|
74
|
+
});
|
|
75
|
+
const length = this.#platform.getDefaultDateTimeLength();
|
|
76
|
+
table.addColumn({
|
|
77
|
+
name: 'executed_at',
|
|
78
|
+
type: this.#platform.getDateTimeTypeDeclarationSQL({ length }),
|
|
79
|
+
mappedType: this.#platform.getMappedType('datetime'),
|
|
80
|
+
default: this.#platform.getCurrentTimestampSQL(length),
|
|
81
|
+
length,
|
|
82
|
+
});
|
|
83
|
+
const sql = this.#helper.createTable(table);
|
|
84
|
+
await this.#connection.execute(sql.join(';\n'), [], 'run', this.#masterTransaction);
|
|
85
|
+
}
|
|
86
|
+
setMasterMigration(trx) {
|
|
87
|
+
this.#masterTransaction = trx;
|
|
88
|
+
}
|
|
89
|
+
unsetMasterMigration() {
|
|
90
|
+
this.#masterTransaction = undefined;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
getMigrationName(name) {
|
|
96
|
+
return name.replace(/\.[jt]s$/, '');
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* @internal
|
|
100
|
+
*/
|
|
101
|
+
getTableName() {
|
|
102
|
+
const parts = this.options.tableName.split('.');
|
|
103
|
+
const tableName = parts.length > 1 ? parts[1] : parts[0];
|
|
104
|
+
const schemaName =
|
|
105
|
+
parts.length > 1 ? parts[0] : this.driver.config.get('schema', this.driver.getPlatform().getDefaultSchemaName());
|
|
106
|
+
const entity = defineEntity({
|
|
107
|
+
name: 'Migration',
|
|
108
|
+
tableName,
|
|
109
|
+
schema: schemaName,
|
|
110
|
+
properties: {
|
|
111
|
+
id: p.integer().primary().fieldNames('id'),
|
|
112
|
+
name: p.string().fieldNames('name'),
|
|
113
|
+
executedAt: p.datetime().defaultRaw('current_timestamp').fieldNames('executed_at'),
|
|
114
|
+
},
|
|
115
|
+
}).init();
|
|
116
|
+
entity.meta.sync();
|
|
117
|
+
return { tableName, schemaName, entity };
|
|
118
|
+
}
|
|
114
119
|
}
|
package/Migrator.d.ts
CHANGED
|
@@ -1,39 +1,49 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type IMigrationGenerator,
|
|
3
|
+
type IMigrationRunner,
|
|
4
|
+
type IMigratorStorage,
|
|
5
|
+
type MigrateOptions,
|
|
6
|
+
type MigrationInfo,
|
|
7
|
+
type MikroORM,
|
|
8
|
+
} from '@mikro-orm/core';
|
|
2
9
|
import { AbstractMigrator } from '@mikro-orm/core/migrations';
|
|
3
10
|
import { type AbstractSqlDriver, DatabaseSchema, type EntityManager } from '@mikro-orm/sql';
|
|
4
11
|
import { MigrationStorage } from './MigrationStorage.js';
|
|
5
12
|
import type { MigrationResult } from './typings.js';
|
|
6
13
|
/** Manages SQL database migrations: creation, execution, and rollback of schema changes. */
|
|
7
14
|
export declare class Migrator extends AbstractMigrator<AbstractSqlDriver> {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
15
|
+
#private;
|
|
16
|
+
constructor(em: EntityManager);
|
|
17
|
+
static register(orm: MikroORM): void;
|
|
18
|
+
protected createRunner(): IMigrationRunner;
|
|
19
|
+
protected createStorage(): IMigratorStorage;
|
|
20
|
+
protected getDefaultGenerator(): IMigrationGenerator;
|
|
21
|
+
private getSnapshotPath;
|
|
22
|
+
protected init(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* @inheritDoc
|
|
25
|
+
*/
|
|
26
|
+
create(path?: string, blank?: boolean, initial?: boolean, name?: string): Promise<MigrationResult>;
|
|
27
|
+
checkSchema(): Promise<boolean>;
|
|
28
|
+
/**
|
|
29
|
+
* @inheritDoc
|
|
30
|
+
*/
|
|
31
|
+
createInitial(path?: string, name?: string, blank?: boolean): Promise<MigrationResult>;
|
|
32
|
+
protected runMigrations(
|
|
33
|
+
method: 'up' | 'down',
|
|
34
|
+
options?: string | string[] | MigrateOptions,
|
|
35
|
+
): Promise<MigrationInfo[]>;
|
|
36
|
+
getStorage(): MigrationStorage;
|
|
37
|
+
/**
|
|
38
|
+
* Initial migration can be created only if:
|
|
39
|
+
* 1. no previous migrations were generated or executed
|
|
40
|
+
* 2. existing schema do not contain any of the tables defined by metadata
|
|
41
|
+
*
|
|
42
|
+
* If existing schema contains all of the tables already, we return true, based on that we mark the migration as already executed.
|
|
43
|
+
* If only some of the tables are present, exception is thrown.
|
|
44
|
+
*/
|
|
45
|
+
private validateInitialMigration;
|
|
46
|
+
protected getSchemaFromSnapshot(): Promise<DatabaseSchema | undefined>;
|
|
47
|
+
protected storeCurrentSchema(schema?: DatabaseSchema): Promise<void>;
|
|
48
|
+
private getSchemaDiff;
|
|
39
49
|
}
|