Skip to content

Commit ad13069

Browse files
committed
feat: export Migration Execution API from main package (fixes typeorm#4880)
1 parent e42091e commit ad13069

File tree

2 files changed

+88
-1
lines changed

2 files changed

+88
-1
lines changed

src/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ export {DeleteResult} from "./query-builder/result/DeleteResult";
139139
export {QueryRunner} from "./query-runner/QueryRunner";
140140
export {EntityManager} from "./entity-manager/EntityManager";
141141
export {MongoEntityManager} from "./entity-manager/MongoEntityManager";
142+
export {Migration} from "./migration/Migration";
143+
export {MigrationExecutor} from "./migration/MigrationExecutor";
142144
export {MigrationInterface} from "./migration/MigrationInterface";
143145
export {DefaultNamingStrategy} from "./naming-strategy/DefaultNamingStrategy";
144146
export {NamingStrategyInterface} from "./naming-strategy/NamingStrategyInterface";

src/migration/MigrationExecutor.ts

+86-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,78 @@ export class MigrationExecutor {
5151
// Public Methods
5252
// -------------------------------------------------------------------------
5353

54+
/**
55+
* Tries to execute a single migration given.
56+
*/
57+
public async executeMigration(migration: Migration): Promise<Migration> {
58+
return this.withQueryRunner(async (queryRunner) => {
59+
await this.createMigrationsTableIfNotExist(queryRunner);
60+
await (migration.instance as any).up(queryRunner);
61+
await this.insertExecutedMigration(queryRunner, migration);
62+
63+
return migration;
64+
});
65+
}
66+
67+
/**
68+
* Returns an array of all migrations.
69+
*/
70+
public async getAllMigrations(): Promise<Migration[]> {
71+
return Promise.resolve(this.getMigrations());
72+
}
73+
74+
/**
75+
* Returns an array of all executed migrations.
76+
*/
77+
public async getExecutedMigrations(): Promise<Migration[]> {
78+
return this.withQueryRunner(async queryRunner => {
79+
await this.createMigrationsTableIfNotExist(queryRunner);
80+
81+
return await this.loadExecutedMigrations(queryRunner);
82+
});
83+
}
84+
85+
/**
86+
* Returns an array of all pending migrations.
87+
*/
88+
public async getPendingMigrations(): Promise<Migration[]> {
89+
const allMigrations = await this.getAllMigrations();
90+
const executedMigrations = await this.getExecutedMigrations();
91+
92+
return allMigrations.filter(migration =>
93+
executedMigrations.find(
94+
executedMigration =>
95+
executedMigration.name === migration.name
96+
)
97+
);
98+
}
99+
100+
/**
101+
* Inserts an executed migration.
102+
*/
103+
public insertMigration(migration: Migration): Promise<void> {
104+
return new Promise((resolve, reject) => {
105+
this.withQueryRunner(queryRunner => {
106+
this.insertExecutedMigration(queryRunner, migration)
107+
.then(resolve)
108+
.catch(reject);
109+
});
110+
});
111+
}
112+
113+
/**
114+
* Deletes an executed migration.
115+
*/
116+
public deleteMigration(migration: Migration): Promise<void> {
117+
return new Promise((resolve, reject) => {
118+
this.withQueryRunner(queryRunner => {
119+
this.deleteExecutedMigration(queryRunner, migration)
120+
.then(resolve)
121+
.catch(reject);
122+
});
123+
});
124+
}
125+
54126
/**
55127
* Lists all migrations and whether they have been executed or not
56128
* returns true if there are unapplied migrations
@@ -333,8 +405,9 @@ export class MigrationExecutor {
333405
const migrations = this.connection.migrations.map(migration => {
334406
const migrationClassName = migration.name || (migration.constructor as any).name;
335407
const migrationTimestamp = parseInt(migrationClassName.substr(-13));
336-
if (!migrationTimestamp)
408+
if (!migrationTimestamp || isNaN(migrationTimestamp)) {
337409
throw new Error(`${migrationClassName} migration name is wrong. Migration class name should have a JavaScript timestamp appended.`);
410+
}
338411

339412
return new Migration(undefined, migrationTimestamp, migrationClassName, migration);
340413
});
@@ -421,4 +494,16 @@ export class MigrationExecutor {
421494
}
422495

423496
}
497+
498+
protected async withQueryRunner<T extends any>(callback: (queryRunner: QueryRunner) => T) {
499+
const queryRunner = this.queryRunner || this.connection.createQueryRunner("master");
500+
501+
try {
502+
return callback(queryRunner);
503+
} finally {
504+
if (!this.queryRunner) {
505+
await queryRunner.release();
506+
}
507+
}
508+
}
424509
}

0 commit comments

Comments
 (0)