Skip to content

Commit

Permalink
feat(schema): allow dropping migrations table via schema:drop cli cmd
Browse files Browse the repository at this point in the history
Now one can force removal of migrations table that is by default ignored in schema generator.

`mikro-orm schema:drop --drop-migrations-table`

Closes #220
  • Loading branch information
B4nan committed Nov 2, 2019
1 parent 78f2f08 commit 36402b9
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 15 deletions.
19 changes: 13 additions & 6 deletions lib/cli/SchemaCommandFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ export class SchemaCommandFactory {
return {
command: `schema:${command}`,
describe: SchemaCommandFactory.DESCRIPTIONS[command],
builder: (args: Argv) => SchemaCommandFactory.configureSchemaCommand(args) as Argv<U>,
builder: (args: Argv) => SchemaCommandFactory.configureSchemaCommand(args, command) as Argv<U>,
handler: (args: Arguments<U>) => SchemaCommandFactory.handleSchemaCommand(args, command, successMessage),
};
}

static configureSchemaCommand(args: Argv) {
static configureSchemaCommand(args: Argv, command: 'create' | 'update' | 'drop') {
args.option('r', {
alias: 'run',
type: 'boolean',
Expand All @@ -43,10 +43,17 @@ export class SchemaCommandFactory {
desc: 'Do not skip foreign key checks',
});

if (command === 'drop') {
args.option('drop-migrations-table', {
type: 'boolean',
desc: 'Drop also migrations table',
});
}

return args;
}

static async handleSchemaCommand(args: Arguments<{ dump: boolean; run: boolean; fkChecks: boolean }>, method: 'create' | 'update' | 'drop', successMessage: string) {
static async handleSchemaCommand(args: Arguments<Options>, method: 'create' | 'update' | 'drop', successMessage: string) {
if (!args.run && !args.dump) {
yargs.showHelp();
return;
Expand All @@ -57,11 +64,11 @@ export class SchemaCommandFactory {

if (args.dump) {
const m = `get${method.substr(0, 1).toUpperCase()}${method.substr(1)}SchemaSQL`;
const dump = await generator[m](!args.fkChecks);
const dump = await generator[m](!args.fkChecks, args.dropMigrationsTable);
CLIHelper.dump(dump, orm.config, 'sql');
} else {
const m = method + 'Schema';
await generator[m](!args.fkChecks);
await generator[m](!args.fkChecks, args.dropMigrationsTable);
CLIHelper.dump(chalk.green(successMessage));
}

Expand All @@ -70,4 +77,4 @@ export class SchemaCommandFactory {

}

export type Options = { dump: boolean; run: boolean; fkChecks: boolean };
export type Options = { dump: boolean; run: boolean; fkChecks: boolean; dropMigrationsTable: boolean };
10 changes: 7 additions & 3 deletions lib/schema/SchemaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,22 @@ export class SchemaGenerator {
return this.wrapSchema(ret, wrap);
}

async dropSchema(wrap = true): Promise<void> {
const sql = await this.getDropSchemaSQL(wrap);
async dropSchema(wrap = true, dropMigrationsTable = false): Promise<void> {
const sql = await this.getDropSchemaSQL(wrap, dropMigrationsTable);
await this.execute(sql);
}

async getDropSchemaSQL(wrap = true): Promise<string> {
async getDropSchemaSQL(wrap = true, dropMigrationsTable = false): Promise<string> {
let ret = '';

for (const meta of Object.values(this.metadata.getAll())) {
ret += this.dump(this.dropTable(meta.collection), '\n');
}

if (dropMigrationsTable) {
ret += this.dump(this.dropTable(this.config.get('migrations').tableName!), '\n');
}

return this.wrapSchema(ret + '\n', wrap);
}

Expand Down
8 changes: 6 additions & 2 deletions tests/SchemaGenerator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,12 @@ describe('SchemaGenerator', () => {
const dump = await generator.generate();
expect(dump).toMatchSnapshot('sqlite-schema-dump');

const dropDump = await generator.getDropSchemaSQL();
expect(dropDump).toMatchSnapshot('sqlite-drop-schema-dump');
const dropDump = await generator.getDropSchemaSQL(false, true);
expect(dropDump).toMatchSnapshot('sqlite-drop-schema-dump-1');
await generator.dropSchema(true, true);

const dropDump2 = await generator.getDropSchemaSQL();
expect(dropDump2).toMatchSnapshot('sqlite-drop-schema-dump-2');
await generator.dropSchema();

const createDump = await generator.getCreateSchemaSQL();
Expand Down
15 changes: 14 additions & 1 deletion tests/__snapshots__/SchemaGenerator.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,20 @@ pragma foreign_keys = on;
"
`;

exports[`SchemaGenerator generate schema from metadata [sqlite]: sqlite-drop-schema-dump 1`] = `
exports[`SchemaGenerator generate schema from metadata [sqlite]: sqlite-drop-schema-dump-1 1`] = `
"drop table if exists \`author3\`;
drop table if exists \`book3\`;
drop table if exists \`book_tag3\`;
drop table if exists \`publisher3\`;
drop table if exists \`test3\`;
drop table if exists \`book3_to_book_tag3\`;
drop table if exists \`publisher3_to_test3\`;
drop table if exists \`mikro_orm_migrations\`;
"
`;

exports[`SchemaGenerator generate schema from metadata [sqlite]: sqlite-drop-schema-dump-2 1`] = `
"pragma foreign_keys = off;
drop table if exists \`author3\`;
Expand Down
6 changes: 4 additions & 2 deletions tests/cli/CLIHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,16 @@ describe('CLIHelper', () => {

test('builder', async () => {
const args = { option: jest.fn() };
SchemaCommandFactory.configureSchemaCommand(args as any);
expect(args.option.mock.calls.length).toBe(3);
SchemaCommandFactory.configureSchemaCommand(args as any, 'drop');
expect(args.option.mock.calls.length).toBe(4);
expect(args.option.mock.calls[0][0]).toBe('r');
expect(args.option.mock.calls[0][1]).toMatchObject({ alias: 'run', type: 'boolean' });
expect(args.option.mock.calls[1][0]).toBe('d');
expect(args.option.mock.calls[1][1]).toMatchObject({ alias: 'dump', type: 'boolean' });
expect(args.option.mock.calls[2][0]).toBe('fk-checks');
expect(args.option.mock.calls[2][1]).toMatchObject({ type: 'boolean' });
expect(args.option.mock.calls[3][0]).toBe('drop-migrations-table');
expect(args.option.mock.calls[3][1]).toMatchObject({ type: 'boolean' });
});

test('dump', async () => {
Expand Down
12 changes: 11 additions & 1 deletion tests/cli/DropSchemaCommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,20 @@ describe('DropSchemaCommand', () => {
expect(schemaGenerator.dropSchema.mock.calls.length).toBe(1);
expect(close.mock.calls.length).toBe(1);

await expect(cmd.handler({ run: true, dropMigrationsTable: true } as any)).resolves.toBeUndefined();
expect(schemaGenerator.dropSchema.mock.calls.length).toBe(2);
expect(schemaGenerator.dropSchema.mock.calls[1]).toEqual([true, true]);
expect(close.mock.calls.length).toBe(2);

expect(schemaGenerator.getDropSchemaSQL.mock.calls.length).toBe(0);
await expect(cmd.handler({ dump: true } as any)).resolves.toBeUndefined();
expect(schemaGenerator.getDropSchemaSQL.mock.calls.length).toBe(1);
expect(close.mock.calls.length).toBe(2);
expect(close.mock.calls.length).toBe(3);

await expect(cmd.handler({ dump: true, dropMigrationsTable: true } as any)).resolves.toBeUndefined();
expect(schemaGenerator.getDropSchemaSQL.mock.calls.length).toBe(2);
expect(schemaGenerator.getDropSchemaSQL.mock.calls[1]).toEqual([true, true]);
expect(close.mock.calls.length).toBe(4);
});

});

0 comments on commit 36402b9

Please sign in to comment.