From 64fcacdb3dafaa39daef867ba2718d2c065cf6e4 Mon Sep 17 00:00:00 2001 From: liuyi Date: Fri, 20 Jun 2025 14:38:22 +0800 Subject: [PATCH] add db migration --- .../commands/migration.create.command.ts | 34 ++++++++++++++ .../commands/migration.create.handler.ts | 38 ++++++++++++++++ .../commands/typeorm.migration.create.ts | 45 +++++++++++++++++++ .../commands/typeorm.migration.generate.ts | 8 ++++ src/modules/database/commands/types.ts | 34 ++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 src/modules/database/commands/migration.create.command.ts create mode 100644 src/modules/database/commands/migration.create.handler.ts create mode 100644 src/modules/database/commands/typeorm.migration.create.ts create mode 100644 src/modules/database/commands/typeorm.migration.generate.ts create mode 100644 src/modules/database/commands/types.ts diff --git a/src/modules/database/commands/migration.create.command.ts b/src/modules/database/commands/migration.create.command.ts new file mode 100644 index 0000000..f5876ad --- /dev/null +++ b/src/modules/database/commands/migration.create.command.ts @@ -0,0 +1,34 @@ +import { Arguments } from 'yargs'; + +import { CommandItem } from '@/modules/core/types'; +import { MigrationCreateHandler } from '@/modules/database/commands/migration.create.handler'; +import { MigrationCreateArguments } from '@/modules/database/commands/types'; + +/** + * 创建迁移 + * + * @param configure + * @constructor + */ +export const CreateMigrationCommand: CommandItem = async ({ + configure, +}) => ({ + source: true, + command: [], + describe: 'Creates a new migration file', + builder: { + connection: { + type: 'string', + alias: 'c', + describe: 'Connection name of typeorm to connect database.', + }, + name: { + type: 'string', + alias: 'n', + describe: 'Name of the migration class.', + demandOption: true, + }, + }, + handler: async (args: Arguments) => + MigrationCreateHandler(configure, args), +}); diff --git a/src/modules/database/commands/migration.create.handler.ts b/src/modules/database/commands/migration.create.handler.ts new file mode 100644 index 0000000..be68e58 --- /dev/null +++ b/src/modules/database/commands/migration.create.handler.ts @@ -0,0 +1,38 @@ +import chalk from 'chalk'; +import { isNil } from 'lodash'; +import ora from 'ora'; +import { Arguments } from 'yargs'; + +import { Configure } from '@/modules/config/configure'; +import { panic } from '@/modules/core/helpers'; +import { TypeormMigrationCreate } from '@/modules/database/commands/typeorm.migration.create'; +import { MigrationCreateArguments } from '@/modules/database/commands/types'; +import { DBOptions, TypeormOption } from '@/modules/database/types'; + +/** + * 创建迁移处理器 + * + * @param configure + * @param args + * @constructor + */ +export async function MigrationCreateHandler( + configure: Configure, + args: Arguments, +) { + const spinner = ora('start to create migration').start(); + const cname = args.connection ?? 'default'; + try { + const { connections = [] } = await configure.get('database'); + const dbConfig: TypeormOption = connections.find(({ name }) => name === cname); + if (isNil(dbConfig)) { + await panic(`database connection ${cname} not found`); + } + const runner = new TypeormMigrationCreate(); + console.log(); + await runner.handler({ name: cname, dir: dbConfig.path.migration }); + spinner.start(chalk.greenBright.underline('\n 👍 Finished create migration')); + } catch (e) { + await panic({ spinner, message: 'Create migration failed!', error: e }); + } +} diff --git a/src/modules/database/commands/typeorm.migration.create.ts b/src/modules/database/commands/typeorm.migration.create.ts new file mode 100644 index 0000000..56624e6 --- /dev/null +++ b/src/modules/database/commands/typeorm.migration.create.ts @@ -0,0 +1,45 @@ +import { resolve } from 'path'; + +import chalk from 'chalk'; +import { CommandUtils } from 'typeorm/commands/CommandUtils'; +import { PlatformTools } from 'typeorm/platform/PlatformTools'; +import { camelCase } from 'typeorm/util/StringUtils'; + +import { MigrationCreateOptions } from '@/modules/database/commands/types'; + +type HandleOptions = MigrationCreateOptions & { dir: string }; + +export class TypeormMigrationCreate { + async handler(args: HandleOptions) { + try { + const timestamp = new Date().getTime(); + const directory = args.dir.startsWith('/') + ? args.dir + : resolve(process.cwd(), args.dir); + const fileContent = TypeormMigrationCreate.getTemplate(args.name, timestamp); + const fileName = `${timestamp}-${args.name}`; + const filePath = `${directory}/${fileName}`; + await CommandUtils.createFile(`${filePath}.ts`, fileContent); + console.log( + `Migration ${chalk.blue(`${filePath}.ts`)} has been generated successfully.`, + ); + } catch (e) { + PlatformTools.logCmdErr('Error during migration creation:', e); + process.exit(1); + } + } + + protected static getTemplate(name: string, timestamp: number): string { + return `import typeorm = require('typeorm'); + class ${camelCase(name, true)}${timestamp} implements typeorm.MigrationInterface { + + public async up(queryRunner: typeorm.QueryRunner): Promise { + } + + public async down(queryRunner: typeorm.QueryRunner): Promise { + } + +} +`; + } +} diff --git a/src/modules/database/commands/typeorm.migration.generate.ts b/src/modules/database/commands/typeorm.migration.generate.ts new file mode 100644 index 0000000..41d1782 --- /dev/null +++ b/src/modules/database/commands/typeorm.migration.generate.ts @@ -0,0 +1,8 @@ +import { DataSource } from 'typeorm'; + +import { MigrationGenerateOptions } from '@/modules/database/commands/types'; + +type HandlerOptions = MigrationGenerateOptions & { dataSource: DataSource }; +export class TypeormMigrationGenerate { + async handler(args: HandlerOptions) {} +} diff --git a/src/modules/database/commands/types.ts b/src/modules/database/commands/types.ts new file mode 100644 index 0000000..187ccf5 --- /dev/null +++ b/src/modules/database/commands/types.ts @@ -0,0 +1,34 @@ +import { Arguments } from 'yargs'; + +/** + * 基础数据库命令参数类型 + */ +export type TypeOrmArguments = Arguments<{ connection?: string }>; + +/** + * 创建迁移命令参数 + */ +export type MigrationCreateArguments = TypeOrmArguments & MigrationCreateOptions; + +/** + * 创建迁移处理器选项 + */ +export interface MigrationCreateOptions { + name?: string; +} + +/** + * 生成迁移命令参数 + */ +export type MigrationGenerateArguments = TypeOrmArguments & MigrationCreateOptions; + +/** + * 生成迁移处理器选项 + */ +export interface MigrationGenerateOptions { + name?: string; + run?: boolean; + pretty?: boolean; + dryrun?: boolean; + check?: boolean; +}