Compare commits
3 Commits
77e27a4b93
...
94fc1a6877
Author | SHA1 | Date | |
---|---|---|---|
94fc1a6877 | |||
edff100ef2 | |||
cecc96bbba |
@ -1,7 +1,5 @@
|
|||||||
import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';
|
import { DynamicModule, Module, ModuleMetadata } from '@nestjs/common';
|
||||||
|
|
||||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
|
||||||
|
|
||||||
import * as entities from '@/modules/content/entities';
|
import * as entities from '@/modules/content/entities';
|
||||||
import * as repositories from '@/modules/content/repositories';
|
import * as repositories from '@/modules/content/repositories';
|
||||||
import * as services from '@/modules/content/services';
|
import * as services from '@/modules/content/services';
|
||||||
@ -12,7 +10,7 @@ import { PostService } from '@/modules/content/services/post.service';
|
|||||||
|
|
||||||
import { DatabaseModule } from '@/modules/database/database.module';
|
import { DatabaseModule } from '@/modules/database/database.module';
|
||||||
|
|
||||||
import { addSubscribers } from '@/modules/database/utils';
|
import { addEntities, addSubscribers } from '@/modules/database/utils';
|
||||||
|
|
||||||
import { Configure } from '../config/configure';
|
import { Configure } from '../config/configure';
|
||||||
|
|
||||||
@ -70,7 +68,7 @@ export class ContentModule {
|
|||||||
return {
|
return {
|
||||||
module: ContentModule,
|
module: ContentModule,
|
||||||
imports: [
|
imports: [
|
||||||
TypeOrmModule.forFeature(Object.values(entities)),
|
await addEntities(configure, Object.values(entities)),
|
||||||
DatabaseModule.forRepository(Object.values(repositories)),
|
DatabaseModule.forRepository(Object.values(repositories)),
|
||||||
],
|
],
|
||||||
providers,
|
providers,
|
||||||
|
4
src/modules/database/commands/index.ts
Normal file
4
src/modules/database/commands/index.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export * from './migration.create.command';
|
||||||
|
export * from './migration.revert.command';
|
||||||
|
export * from './migration.generate.command';
|
||||||
|
export * from './migration.run.command';
|
37
src/modules/database/commands/migration.revert.command.ts
Normal file
37
src/modules/database/commands/migration.revert.command.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { Arguments } from 'yargs';
|
||||||
|
|
||||||
|
import { CommandItem } from '@/modules/core/types';
|
||||||
|
import { MigrationRevertHandler } from '@/modules/database/commands/migration.revert.handler';
|
||||||
|
import { MigrationRevertArguments } from '@/modules/database/commands/types';
|
||||||
|
|
||||||
|
export const RevertMigrationCommand: CommandItem<any, MigrationRevertArguments> = async ({
|
||||||
|
configure,
|
||||||
|
}) => ({
|
||||||
|
source: true,
|
||||||
|
command: ['db:migration:revert', 'dbmv'],
|
||||||
|
describe: 'Reverts last executed migration.',
|
||||||
|
builder: {
|
||||||
|
connection: {
|
||||||
|
type: 'string',
|
||||||
|
alias: 'c',
|
||||||
|
describe: 'Connection name of typeorm to connect database.',
|
||||||
|
},
|
||||||
|
transaction: {
|
||||||
|
type: 'string',
|
||||||
|
alias: 't',
|
||||||
|
describe:
|
||||||
|
'Indicates if transaction should be used or not for migration run/revert/reflash. Enabled by default.',
|
||||||
|
default: 'default',
|
||||||
|
},
|
||||||
|
fake: {
|
||||||
|
type: 'boolean',
|
||||||
|
alias: 'f',
|
||||||
|
describe:
|
||||||
|
'Fakes running the migrations if table schema has already been changed manually or externally ' +
|
||||||
|
'(e.g. through another project)',
|
||||||
|
},
|
||||||
|
} as const,
|
||||||
|
|
||||||
|
handler: async (args: Arguments<MigrationRevertArguments>) =>
|
||||||
|
MigrationRevertHandler(configure, args),
|
||||||
|
});
|
62
src/modules/database/commands/migration.revert.handler.ts
Normal file
62
src/modules/database/commands/migration.revert.handler.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import { join } from 'path';
|
||||||
|
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import { isNil } from 'lodash';
|
||||||
|
import ora from 'ora';
|
||||||
|
import { DataSource, DataSourceOptions } from 'typeorm';
|
||||||
|
import { Arguments } from 'yargs';
|
||||||
|
|
||||||
|
import { Configure } from '@/modules/config/configure';
|
||||||
|
import { panic } from '@/modules/core/helpers';
|
||||||
|
import { TypeormMigrationRevert } from '@/modules/database/commands/typeorm.migration.revert';
|
||||||
|
import { MigrationRevertArguments } from '@/modules/database/commands/types';
|
||||||
|
|
||||||
|
import { DBOptions } from '@/modules/database/types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除迁移处理器
|
||||||
|
* @param configure
|
||||||
|
* @param args
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
export async function MigrationRevertHandler(
|
||||||
|
configure: Configure,
|
||||||
|
args: Arguments<MigrationRevertArguments>,
|
||||||
|
) {
|
||||||
|
const spinner = ora('Start to revert migration...');
|
||||||
|
const cname = args.connection ?? 'default';
|
||||||
|
let dataSource: DataSource | undefined;
|
||||||
|
try {
|
||||||
|
spinner.start();
|
||||||
|
const { connections = [] }: DBOptions = await configure.get<DBOptions>('database');
|
||||||
|
const dbConfig = connections.find(({ name }) => name === cname);
|
||||||
|
if (isNil(dbConfig)) {
|
||||||
|
await panic(`Database connection named ${cname} not exists!`);
|
||||||
|
}
|
||||||
|
console.log();
|
||||||
|
const runner = new TypeormMigrationRevert();
|
||||||
|
dataSource = new DataSource({ ...dbConfig } as DataSourceOptions);
|
||||||
|
|
||||||
|
dataSource.setOptions({
|
||||||
|
subscribers: [],
|
||||||
|
synchronize: false,
|
||||||
|
migrationsRun: false,
|
||||||
|
dropSchema: false,
|
||||||
|
logging: ['error'],
|
||||||
|
migrations: [
|
||||||
|
join(dbConfig.paths.migration, '**/*.ts'),
|
||||||
|
join(dbConfig.paths.migration, '**/*.js'),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
await dataSource.initialize();
|
||||||
|
console.log();
|
||||||
|
await runner.handler({ dataSource, transaction: args.transaction, fake: args.fake });
|
||||||
|
spinner.succeed(chalk.greenBright.underline('\n 👍 Finished revert migrations'));
|
||||||
|
} catch (error) {
|
||||||
|
await panic({ spinner, message: 'revert migrations failed!', error });
|
||||||
|
} finally {
|
||||||
|
if (dataSource && dataSource.isInitialized) {
|
||||||
|
await dataSource.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
|
||||||
import chalk from 'chalk';
|
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';
|
import { MigrationCreateOptions } from '@/modules/database/commands/types';
|
||||||
|
|
||||||
|
const { CommandUtils } = require('typeorm/commands/CommandUtils');
|
||||||
|
const { PlatformTools } = require('typeorm/platform/PlatformTools');
|
||||||
|
const { camelCase } = require('typeorm/util/StringUtils');
|
||||||
|
|
||||||
type HandleOptions = MigrationCreateOptions & { dir: string };
|
type HandleOptions = MigrationCreateOptions & { dir: string };
|
||||||
|
|
||||||
export class TypeormMigrationCreate {
|
export class TypeormMigrationCreate {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
@ -5,13 +6,12 @@ import { upperFirst } from 'lodash';
|
|||||||
import { format } from 'mysql2';
|
import { format } from 'mysql2';
|
||||||
import { DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
import { CommandUtils } from 'typeorm/commands/CommandUtils';
|
|
||||||
import { PlatformTools } from 'typeorm/platform/PlatformTools';
|
|
||||||
|
|
||||||
import { camelCase } from 'typeorm/util/StringUtils';
|
|
||||||
|
|
||||||
import { MigrationGenerateOptions } from '@/modules/database/commands/types';
|
import { MigrationGenerateOptions } from '@/modules/database/commands/types';
|
||||||
|
|
||||||
|
const { CommandUtils } = require('typeorm/commands/CommandUtils');
|
||||||
|
const { PlatformTools } = require('typeorm/platform/PlatformTools');
|
||||||
|
const { camelCase } = require('typeorm/util/StringUtils');
|
||||||
|
|
||||||
type HandlerOptions = MigrationGenerateOptions & { dataSource: DataSource } & { dir: string };
|
type HandlerOptions = MigrationGenerateOptions & { dataSource: DataSource } & { dir: string };
|
||||||
|
|
||||||
export class TypeormMigrationGenerate {
|
export class TypeormMigrationGenerate {
|
||||||
@ -44,6 +44,7 @@ export class TypeormMigrationGenerate {
|
|||||||
downSql.query = TypeormMigrationGenerate.prettifyQuery(downSql.query);
|
downSql.query = TypeormMigrationGenerate.prettifyQuery(downSql.query);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
console.log('sqlInMemory', sqlInMemory);
|
||||||
sqlInMemory.upQueries.forEach((upQuery) => {
|
sqlInMemory.upQueries.forEach((upQuery) => {
|
||||||
upSqls.push(
|
upSqls.push(
|
||||||
` await queryRunner.query(\`${upQuery.query.replace(
|
` await queryRunner.query(\`${upQuery.query.replace(
|
||||||
|
28
src/modules/database/commands/typeorm.migration.revert.ts
Normal file
28
src/modules/database/commands/typeorm.migration.revert.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { DataSource } from 'typeorm';
|
||||||
|
|
||||||
|
import { MigrationRevertOptions } from '@/modules/database/commands/types';
|
||||||
|
|
||||||
|
type HandleOptions = MigrationRevertOptions & { dataSource: DataSource };
|
||||||
|
|
||||||
|
export class TypeormMigrationRevert {
|
||||||
|
async handler({ transaction, fake, dataSource }: HandleOptions) {
|
||||||
|
const options = {
|
||||||
|
transaction: dataSource.options.migrationsTransactionMode ?? 'all',
|
||||||
|
fake,
|
||||||
|
};
|
||||||
|
switch (transaction) {
|
||||||
|
case 'all':
|
||||||
|
options.transaction = 'all';
|
||||||
|
break;
|
||||||
|
case 'none':
|
||||||
|
case 'false':
|
||||||
|
options.transaction = 'none';
|
||||||
|
break;
|
||||||
|
case 'each':
|
||||||
|
options.transaction = 'each';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
await dataSource.undoLastMigration(options);
|
||||||
|
}
|
||||||
|
}
|
@ -55,3 +55,8 @@ export interface MigrationRevertOptions {
|
|||||||
|
|
||||||
fake?: boolean;
|
fake?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 恢复迁移的命令参数
|
||||||
|
*/
|
||||||
|
export type MigrationRevertArguments = TypeOrmArguments & MigrationRevertOptions;
|
||||||
|
@ -7,9 +7,9 @@ import { panic } from '../core/helpers';
|
|||||||
|
|
||||||
@Module({})
|
@Module({})
|
||||||
export class MeiliModule {
|
export class MeiliModule {
|
||||||
static forRoot(configure: Configure): DynamicModule {
|
static async forRoot(configure: Configure): Promise<DynamicModule> {
|
||||||
if (!configure.has('meili')) {
|
if (!configure.has('meili')) {
|
||||||
panic({ message: 'MeilliSearch config not exists' });
|
await panic({ message: 'MeiliSearch config not exists' });
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
global: true,
|
global: true,
|
||||||
|
@ -10,6 +10,7 @@ import { isNil } from 'lodash';
|
|||||||
import * as configs from './config';
|
import * as configs from './config';
|
||||||
import { ContentModule } from './modules/content/content.module';
|
import { ContentModule } from './modules/content/content.module';
|
||||||
import { CreateOptions } from './modules/core/types';
|
import { CreateOptions } from './modules/core/types';
|
||||||
|
import * as dbCommands from './modules/database/commands';
|
||||||
import { DatabaseModule } from './modules/database/database.module';
|
import { DatabaseModule } from './modules/database/database.module';
|
||||||
import { MeiliModule } from './modules/meilisearch/meili.module';
|
import { MeiliModule } from './modules/meilisearch/meili.module';
|
||||||
import { Restful } from './modules/restful/restful';
|
import { Restful } from './modules/restful/restful';
|
||||||
@ -17,13 +18,13 @@ import { RestfulModule } from './modules/restful/restful.module';
|
|||||||
import { ApiConfig } from './modules/restful/types';
|
import { ApiConfig } from './modules/restful/types';
|
||||||
|
|
||||||
export const createOptions: CreateOptions = {
|
export const createOptions: CreateOptions = {
|
||||||
commands: () => [],
|
commands: () => [...Object.values(dbCommands)],
|
||||||
config: { factories: configs as any, storage: { enable: true } },
|
config: { factories: configs as any, storage: { enable: true } },
|
||||||
modules: async (configure) => [
|
modules: async (configure) => [
|
||||||
DatabaseModule.forRoot(configure),
|
await DatabaseModule.forRoot(configure),
|
||||||
MeiliModule.forRoot(configure),
|
await MeiliModule.forRoot(configure),
|
||||||
RestfulModule.forRoot(configure),
|
await RestfulModule.forRoot(configure),
|
||||||
ContentModule.forRoot(configure),
|
await ContentModule.forRoot(configure),
|
||||||
],
|
],
|
||||||
globals: {},
|
globals: {},
|
||||||
builder: async ({ configure, BootModule }) => {
|
builder: async ({ configure, BootModule }) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user