mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
fix: unhance migration logic
This commit is contained in:
parent
a1765b647b
commit
e0d2388e95
@ -28,6 +28,7 @@ import {
|
||||
MigrationAction,
|
||||
MigrationRunParams,
|
||||
MigrationSuccessCallback,
|
||||
MigrationTrigger,
|
||||
} from './types';
|
||||
|
||||
@Injectable()
|
||||
@ -146,23 +147,18 @@ module.exports = {
|
||||
}: MigrationRunParams) {
|
||||
if (!name) {
|
||||
if (isAutoMigrate) {
|
||||
const newVersion = await this.runFromVersion(action, version);
|
||||
|
||||
await this.metadataService.findOrCreate({
|
||||
name: 'db-version',
|
||||
value: newVersion,
|
||||
});
|
||||
await this.runFromVersion(action, version);
|
||||
} else {
|
||||
await this.runAll(action);
|
||||
this.exit();
|
||||
}
|
||||
} else {
|
||||
await this.runOne({ action, name });
|
||||
await this.runOne({ action, name, trigger: MigrationTrigger.CLI });
|
||||
this.exit();
|
||||
}
|
||||
}
|
||||
|
||||
private async runOne({ name, action }: MigrationRunParams) {
|
||||
private async runOne({ name, action, trigger }: MigrationRunParams) {
|
||||
// verify DB status
|
||||
const { exist, migrationDocument } = await this.verifyStatus({
|
||||
name,
|
||||
@ -179,6 +175,7 @@ module.exports = {
|
||||
name,
|
||||
action,
|
||||
migrationDocument,
|
||||
trigger,
|
||||
});
|
||||
} catch (e) {
|
||||
this.failureCallback({
|
||||
@ -216,37 +213,27 @@ module.exports = {
|
||||
}
|
||||
|
||||
private async runFromVersion(action: MigrationAction, version: string) {
|
||||
const files = await this.getDirFiles();
|
||||
const migrationFiles = files
|
||||
.filter((fileName) => fileName.endsWith('.migration.js'))
|
||||
.map((fileName) => {
|
||||
const [migrationFileName] = fileName.split('.');
|
||||
const [, , ...migrationVersion] = migrationFileName.split('-');
|
||||
return `v${migrationVersion.join('.')}`;
|
||||
})
|
||||
.filter((v) => this.isNewerVersion(v, version));
|
||||
|
||||
const filenames = await this.getDirFiles();
|
||||
const versions = this.getVersionsFromFilenames(filenames);
|
||||
const filteredVersions = versions.filter(
|
||||
(v) => v === version || this.isNewerVersion(v, version),
|
||||
);
|
||||
let lastVersion = version;
|
||||
for (const name of migrationFiles) {
|
||||
await this.runOne({ name, action });
|
||||
lastVersion = name;
|
||||
|
||||
for (const version of filteredVersions) {
|
||||
await this.runOne({ name: version, action });
|
||||
lastVersion = version;
|
||||
}
|
||||
|
||||
return lastVersion;
|
||||
}
|
||||
|
||||
private async runAll(action: MigrationAction) {
|
||||
const files = await this.getDirFiles();
|
||||
const migrationFiles = files
|
||||
.filter((fileName) => fileName.includes('migration'))
|
||||
.map((fileName) => {
|
||||
const [migrationFileName] = fileName.split('.');
|
||||
const [, , ...migrationVersion] = migrationFileName.split('-');
|
||||
return `v${migrationVersion.join('.')}`;
|
||||
});
|
||||
const filenames = await this.getDirFiles();
|
||||
const versions = this.getVersionsFromFilenames(filenames);
|
||||
|
||||
for (const name of migrationFiles) {
|
||||
await this.runOne({ name, action });
|
||||
for (const version of versions) {
|
||||
await this.runOne({ name: version, action });
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,6 +272,16 @@ module.exports = {
|
||||
return migrationName;
|
||||
}
|
||||
|
||||
private getVersionsFromFilenames(filenames: string[]) {
|
||||
return filenames
|
||||
.filter((fileName) => fileName.endsWith('.migration.js'))
|
||||
.map((filename: string) => {
|
||||
const [migrationFileName] = filename.split('.');
|
||||
const [, , ...migrationVersion] = migrationFileName.split('-');
|
||||
return `v${migrationVersion.join('.')}`;
|
||||
});
|
||||
}
|
||||
|
||||
async findMigrationFileByName(name: string): Promise<string | null> {
|
||||
const files = await this.getMigrationFiles();
|
||||
return (
|
||||
@ -342,10 +339,19 @@ module.exports = {
|
||||
name,
|
||||
action,
|
||||
migrationDocument,
|
||||
trigger,
|
||||
}: MigrationSuccessCallback) {
|
||||
await this.updateStatus({ name, action, migrationDocument });
|
||||
const migrationDisplayName = `${name} [${action}]`;
|
||||
this.logger.log(`"${migrationDisplayName}" migration done`);
|
||||
if (trigger === MigrationTrigger.CLI) {
|
||||
const result = await this.metadataService.createOrUpdate({
|
||||
name: 'db-version',
|
||||
value: name,
|
||||
});
|
||||
const operation = result ? 'updated' : 'created';
|
||||
this.logger.log(`db-version metadata ${operation} "${name}"`);
|
||||
}
|
||||
}
|
||||
|
||||
private failureCallback({ name, action }: MigrationRunParams) {
|
||||
|
@ -13,15 +13,26 @@ enum MigrationAction {
|
||||
DOWN = 'down',
|
||||
}
|
||||
|
||||
enum MigrationTrigger {
|
||||
CLI = 'cli',
|
||||
PROGRAM = 'program',
|
||||
}
|
||||
|
||||
interface MigrationRunParams {
|
||||
name?: string;
|
||||
action: MigrationAction;
|
||||
version?: string;
|
||||
isAutoMigrate?: boolean;
|
||||
trigger?: MigrationTrigger;
|
||||
}
|
||||
|
||||
interface MigrationSuccessCallback extends MigrationRunParams {
|
||||
migrationDocument: MigrationDocument;
|
||||
}
|
||||
|
||||
export { MigrationAction, MigrationRunParams, MigrationSuccessCallback };
|
||||
export {
|
||||
MigrationAction,
|
||||
MigrationRunParams,
|
||||
MigrationSuccessCallback,
|
||||
MigrationTrigger,
|
||||
};
|
||||
|
@ -19,18 +19,10 @@ export class MetadataService {
|
||||
private readonly metadataModel: Model<Metadata>,
|
||||
) {}
|
||||
|
||||
async createMetadata(dto: Partial<Metadata>) {
|
||||
return await this.metadataModel.create(dto);
|
||||
}
|
||||
|
||||
async findOrCreate(dto: Partial<Metadata>) {
|
||||
const metadata = await this.metadataModel.findOne({ name: dto.name });
|
||||
|
||||
if (metadata) {
|
||||
await this.setMetadata(dto.name, dto.value);
|
||||
} else {
|
||||
await this.createMetadata(dto);
|
||||
}
|
||||
async createOrUpdate(dto: Metadata) {
|
||||
return await this.metadataModel.findOneAndUpdate({ name: dto.name }, dto, {
|
||||
upsert: true,
|
||||
});
|
||||
}
|
||||
|
||||
async getMetadata(name: string) {
|
||||
|
Loading…
Reference in New Issue
Block a user