tachybase_todo/packages/core/database/src/migration.ts

97 lines
1.9 KiB
TypeScript

import { importModule } from '@tachybase/utils';
import _ from 'lodash';
import { QueryInterface, Sequelize } from 'sequelize';
import Database from './database';
export interface MigrationContext {
db: Database;
queryInterface: QueryInterface;
sequelize: Sequelize;
}
export class Migration {
public name: string;
public context: { db: Database; [key: string]: any };
constructor(context: MigrationContext) {
this.context = context;
}
get db() {
return this.context.db;
}
get sequelize() {
return this.context.db.sequelize;
}
get queryInterface() {
return this.context.db.sequelize.getQueryInterface();
}
async up() {
// todo
}
async down() {
// todo
}
}
export interface MigrationItem {
name: string;
migration?: typeof Migration | string;
context?: any;
up?: any;
down?: any;
}
export class Migrations {
items = [];
context: any;
constructor(context: any) {
this.context = context;
}
clear() {
this.items = [];
}
add(item: MigrationItem) {
const Migration = item.migration;
if (Migration && typeof Migration === 'function') {
const migration = new Migration({ ...this.context, ...item.context });
migration.name = item.name;
this.items.push(migration);
} else {
this.items.push(item);
}
}
callback() {
return async (ctx) => {
return await Promise.all(
_.sortBy(this.items, (item) => {
const keys = item.name.split('/');
return keys.pop() || item.name;
}).map(async (item) => {
if (typeof item.migration === 'string') {
// use es module to import migration
const Migration = await importModule(item.migration);
const migration = new Migration({ ...this.context, ...item.context });
migration.name = item.name;
return migration;
}
return item;
}),
);
};
}
}