From 0191343d104c3a02527107f6509551e744a84814 Mon Sep 17 00:00:00 2001 From: liuyi Date: Sat, 21 Jun 2025 08:21:21 +0800 Subject: [PATCH] add db migration --- .../commands/migration.generate.handler.ts | 1 + .../commands/typeorm.migration.create.ts | 5 +- .../commands/typeorm.migration.generate.ts | 2 +- src/modules/database/config.ts | 1 + .../tree.unique.exist.constraint.ts | 4 +- src/modules/database/database.module.ts | 7 ++- src/modules/database/resolver/auto.migrate.ts | 52 +++++++++++++++++++ src/modules/database/types.ts | 5 ++ 8 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 src/modules/database/resolver/auto.migrate.ts diff --git a/src/modules/database/commands/migration.generate.handler.ts b/src/modules/database/commands/migration.generate.handler.ts index bfd8d06..19b9e10 100644 --- a/src/modules/database/commands/migration.generate.handler.ts +++ b/src/modules/database/commands/migration.generate.handler.ts @@ -30,6 +30,7 @@ export async function MigrationGenerateHandler( } console.log(); const runner = new TypeormMigrationGenerate(); + console.log('dbConfig', dbConfig); const dataSource = new DataSource({ ...dbConfig } as DataSourceOptions); console.log(); await runner.handler({ diff --git a/src/modules/database/commands/typeorm.migration.create.ts b/src/modules/database/commands/typeorm.migration.create.ts index 92b54e4..ab91eb4 100644 --- a/src/modules/database/commands/typeorm.migration.create.ts +++ b/src/modules/database/commands/typeorm.migration.create.ts @@ -22,9 +22,8 @@ export class TypeormMigrationCreate { 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.`, - ); + console.log(); + console.log(`Migration ${chalk.blue(`${filePath}.ts`)} has been created successfully.`); } catch (e) { PlatformTools.logCmdErr('Error during migration creation:', e); process.exit(1); diff --git a/src/modules/database/commands/typeorm.migration.generate.ts b/src/modules/database/commands/typeorm.migration.generate.ts index fa7cb35..03a2c23 100644 --- a/src/modules/database/commands/typeorm.migration.generate.ts +++ b/src/modules/database/commands/typeorm.migration.generate.ts @@ -96,7 +96,7 @@ export class TypeormMigrationGenerate { ); } else { await CommandUtils.createFile(filePath, fileContent); - + console.log(); console.log( chalk.green( `Migration ${chalk.blue(filePath)} has been generated successfully.`, diff --git a/src/modules/database/config.ts b/src/modules/database/config.ts index 8d8d341..16cebcc 100644 --- a/src/modules/database/config.ts +++ b/src/modules/database/config.ts @@ -23,6 +23,7 @@ export const createDBOptions = (options: DBConfig) => { { charset: 'utf8mb4', logging: ['error'], + autoMigrate: true, paths: { migration: resolve(__dirname, '../../database/migrations') }, }, options.common ?? {}, diff --git a/src/modules/database/constraints/tree.unique.exist.constraint.ts b/src/modules/database/constraints/tree.unique.exist.constraint.ts index 63c07c7..55beb8b 100644 --- a/src/modules/database/constraints/tree.unique.exist.constraint.ts +++ b/src/modules/database/constraints/tree.unique.exist.constraint.ts @@ -21,7 +21,7 @@ type Condition = { @ValidatorConstraint({ name: 'treeDataUniqueExist', async: true }) @Injectable() -export class TreeUniqueExistContraint implements ValidatorConstraintInterface { +export class TreeUniqueExistConstraint implements ValidatorConstraintInterface { constructor(private dataSource: DataSource) {} async validate(value: any, args: ValidationArguments) { @@ -93,7 +93,7 @@ export function IsTreeUniqueExist( propertyName, options: validationOptions, constraints: [params], - validator: TreeUniqueExistContraint, + validator: TreeUniqueExistConstraint, }); }; } diff --git a/src/modules/database/database.module.ts b/src/modules/database/database.module.ts index 2c29f72..b88b3b4 100644 --- a/src/modules/database/database.module.ts +++ b/src/modules/database/database.module.ts @@ -5,6 +5,8 @@ import { DataSource, ObjectType } from 'typeorm'; import { CUSTOM_REPOSITORY_METADATA } from '@/modules/database/constants'; +import { AutoMigrateResolver } from '@/modules/database/resolver/auto.migrate'; + import { Configure } from '../config/configure'; import { panic } from '../core/helpers'; @@ -12,7 +14,7 @@ import { panic } from '../core/helpers'; import { DataExistConstraint, TreeUniqueConstraint, - TreeUniqueExistContraint, + TreeUniqueExistConstraint, UniqueConstraint, UniqueExistConstraint, } from './constraints'; @@ -34,7 +36,8 @@ export class DatabaseModule { UniqueConstraint, UniqueExistConstraint, TreeUniqueConstraint, - TreeUniqueExistContraint, + TreeUniqueExistConstraint, + AutoMigrateResolver, ]; return { global: true, diff --git a/src/modules/database/resolver/auto.migrate.ts b/src/modules/database/resolver/auto.migrate.ts new file mode 100644 index 0000000..bae285b --- /dev/null +++ b/src/modules/database/resolver/auto.migrate.ts @@ -0,0 +1,52 @@ +import { join } from 'path'; + +import { Injectable } from '@nestjs/common'; +import { ModuleRef } from '@nestjs/core'; + +import { DataSource, DataSourceOptions } from 'typeorm'; + +import { Configure } from '@/modules/config/configure'; +import { panic } from '@/modules/core/helpers'; +import { TypeormMigrationRun } from '@/modules/database/commands/typeorm.migration.run'; +import { DBOptions } from '@/modules/database/types'; + +@Injectable() +export class AutoMigrateResolver { + constructor(private ref: ModuleRef) {} + + async onModuleInit() { + const configure = this.ref.get(Configure, { strict: false }); + const { connections = [] }: DBOptions = await configure.get('database'); + for (const conn of connections) { + let dataSource: DataSource | undefined; + if (conn.autoMigrate) { + try { + dataSource = new DataSource(conn as DataSourceOptions); + const runner = new TypeormMigrationRun(); + if (dataSource && dataSource.isInitialized) { + await dataSource.destroy(); + } + dataSource.setOptions({ + subscribers: [], + synchronize: false, + migrationsRun: false, + logging: ['error'], + migrations: [ + join(conn.paths.migration, '**/*.ts'), + join(conn.paths.migration, '**/*.js'), + ], + dropSchema: false, + }); + await dataSource.initialize(); + await runner.handler({ dataSource }); + } catch (error) { + await panic({ message: 'Run migrations failed!', error }); + } finally { + if (dataSource && dataSource.isInitialized) { + await dataSource.destroy(); + } + } + } + } + } +} diff --git a/src/modules/database/types.ts b/src/modules/database/types.ts index 9a04193..0e1f8f7 100644 --- a/src/modules/database/types.ts +++ b/src/modules/database/types.ts @@ -87,4 +87,9 @@ type DBAdditionalOption = { paths?: { migration?: string; }; + + /** + * 是否在启动应用后自动运行迁移 + */ + autoMigrate?: boolean; };