Skip to content

Commit

Permalink
fix: throwing error on duplicate migration names #4701 (#4704)
Browse files Browse the repository at this point in the history
* fix: skip duplicated pending migrations

Make the behavior the same whether duplicated migrations applied in one step or not.

Closes: #4701

* style: revert unnecessary formatting

* fix: throw exception when duplicate migrations
  • Loading branch information
jurasan authored and pleerock committed Oct 19, 2019
1 parent d205574 commit 3e4dc9f
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/migration/MigrationExecutor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,20 @@ export class MigrationExecutor {
return new Migration(undefined, migrationTimestamp, migrationClassName, migration);
});

this.checkForDuplicateMigrations(migrations);

// sort them by timestamp
return migrations.sort((a, b) => a.timestamp - b.timestamp);
}

protected checkForDuplicateMigrations(migrations: Migration[]) {
const migrationNames = migrations.map(migration => migration.name);
const duplicates = Array.from(new Set(migrationNames.filter((migrationName, index) => migrationNames.indexOf(migrationName) < index)));
if (duplicates.length > 0) {
throw Error(`Duplicate migrations: ${duplicates.join(", ")}`);
}
}

/**
* Finds the latest migration (sorts by timestamp) in the given array of migrations.
*/
Expand Down
24 changes: 24 additions & 0 deletions test/github-issues/4701/issue-4701.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import "reflect-metadata";
import {expect} from "chai";
import {
createTestingConnections,
closeTestingConnections,
reloadTestingDatabases
} from "../../utils/test-utils";
import { Connection } from "../../../src/connection/Connection";

describe("github issues > #4701 Duplicate migrations are executed.", () => {
let connections: Connection[];
before(async () => connections = await createTestingConnections({
migrations: [__dirname + "/migration/*.js"],
enabledDrivers: ["postgres"],
schemaCreate: true,
dropSchema: true
}));
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections(connections));

it("should throw error if there're duplicate migrations", () => Promise.all(connections.map(async connection => {
await expect(connection.runMigrations()).to.be.rejectedWith(Error, "Duplicate migrations: ExampleMigrationOne1567759789051");
})));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { MigrationInterface } from "../../../../src/migration/MigrationInterface";
import { QueryRunner } from "../../../../src/query-runner/QueryRunner";

export class ExampleMigrationOne1567759789051 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {}
public async down(queryRunner: QueryRunner): Promise<any> {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { MigrationInterface } from "../../../../src/migration/MigrationInterface";
import { QueryRunner } from "../../../../src/query-runner/QueryRunner";

export class ExampleMigrationOne1567759789051 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {}
public async down(queryRunner: QueryRunner): Promise<any> {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { MigrationInterface } from "../../../../src/migration/MigrationInterface";
import { QueryRunner } from "../../../../src/query-runner/QueryRunner";

export class ExampleMigrationThree1571426391120 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<any> {}
public async down(queryRunner: QueryRunner): Promise<any> {}
}

0 comments on commit 3e4dc9f

Please sign in to comment.