Skip to content

Commit

Permalink
fix: update foreign keys when table name changes (#5482)
Browse files Browse the repository at this point in the history
* Add repro test for github 5119

* update foreign key matching algo to include table name

* fix naming for test 5119

* lint error

* fix test for 5119

* Drop unnecessary logging, fix lint errors
  • Loading branch information
osdiab committed Feb 14, 2020
1 parent e3c78c1 commit 7157cb3
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/schema-builder/RdbmsSchemaBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {TableCheck} from "./table/TableCheck";
import {TableExclusion} from "./table/TableExclusion";
import {View} from "./view/View";
import {AuroraDataApiDriver} from "../driver/aurora-data-api/AuroraDataApiDriver";
import { ForeignKeyMetadata } from "../metadata/ForeignKeyMetadata";

/**
* Creates complete tables schemas in the database based on the entity metadatas.
Expand Down Expand Up @@ -186,7 +187,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {

// find foreign keys that exist in the schemas but does not exist in the entity metadata
const tableForeignKeysToDrop = table.foreignKeys.filter(tableForeignKey => {
const metadataFK = metadata.foreignKeys.find(metadataForeignKey => metadataForeignKey.name === tableForeignKey.name);
const metadataFK = metadata.foreignKeys.find(metadataForeignKey => foreignKeysMatch(tableForeignKey, metadataForeignKey));
return !metadataFK
|| (metadataFK.onDelete && metadataFK.onDelete !== tableForeignKey.onDelete)
|| (metadataFK.onUpdate && metadataFK.onUpdate !== tableForeignKey.onUpdate);
Expand Down Expand Up @@ -647,7 +648,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
return;

const newKeys = metadata.foreignKeys.filter(foreignKey => {
return !table.foreignKeys.find(dbForeignKey => dbForeignKey.name === foreignKey.name);
return !table.foreignKeys.find(dbForeignKey => foreignKeysMatch(dbForeignKey, foreignKey));
});
if (newKeys.length === 0)
return;
Expand Down Expand Up @@ -782,3 +783,10 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
}

}

function foreignKeysMatch(
tableForeignKey: TableForeignKey, metadataForeignKey: ForeignKeyMetadata
): boolean {
return (tableForeignKey.name === metadataForeignKey.name)
&& (tableForeignKey.referencedTableName === metadataForeignKey.referencedTablePath);
}
22 changes: 22 additions & 0 deletions test/github-issues/5119/entity/v1/Post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
Column,
Entity,
ManyToOne,
PrimaryGeneratedColumn
} from "../../../../../src/index";
import { User } from "./User";

@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;

@Column()
title: string;

@Column()
text: string;

@ManyToOne(type => User)
owner: User;
}
14 changes: 14 additions & 0 deletions test/github-issues/5119/entity/v1/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
Column,
Entity,
PrimaryGeneratedColumn
} from "../../../../../src/index";

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;
}
15 changes: 15 additions & 0 deletions test/github-issues/5119/entity/v2/Account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
Entity,
PrimaryGeneratedColumn,
ManyToOne
} from "../../../../../src/index";
import { User } from "./User";

@Entity()
export class Account {
@PrimaryGeneratedColumn()
id: number;

@ManyToOne(type => User)
user: User;
}
22 changes: 22 additions & 0 deletions test/github-issues/5119/entity/v2/Post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
Column,
Entity,
ManyToOne,
PrimaryGeneratedColumn
} from "../../../../../src/index";
import { Account } from "./Account";

@Entity()
export class Post {
@PrimaryGeneratedColumn()
id: number;

@Column()
title: string;

@Column()
text: string;

@ManyToOne(type => Account)
owner: Account;
}
14 changes: 14 additions & 0 deletions test/github-issues/5119/entity/v2/User.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
Column,
Entity,
PrimaryGeneratedColumn
} from "../../../../../src/index";

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;

@Column()
name: string;
}
69 changes: 69 additions & 0 deletions test/github-issues/5119/issue-5119.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import "reflect-metadata";
import {
closeTestingConnections,
createTestingConnections,
reloadTestingDatabases,
setupSingleTestingConnection
} from "../../utils/test-utils";
import { Connection, createConnection } from "../../../src";
import { fail } from "assert";

describe("github issues > #5119 migration with foreign key that changes target", () => {
let connections: Connection[];
before(
async () =>
(connections = await createTestingConnections({
entities: [__dirname + "/entity/v1/*{.js,.ts}"],
enabledDrivers: ["postgres"],
}))
);
beforeEach(() => reloadTestingDatabases(connections));
after(() => closeTestingConnections([...connections]));

it("should generate a drop and create step", async () => {
return Promise.all(
connections.map(async function(_connection) {
const options = setupSingleTestingConnection(
_connection.options.type,
{
name: `${_connection.name}-v2`,
entities: [__dirname + "/entity/v2/*{.js,.ts}"],
dropSchema: false,
schemaCreate: false
}
);
if (!options) {
fail();
return;
}
const connection = await createConnection(options);
try {
const sqlInMemory = await connection.driver
.createSchemaBuilder()
.log();

const upQueries = sqlInMemory.upQueries.map(
query => query.query
);
const downQueries = sqlInMemory.downQueries.map(
query => query.query
);
upQueries.should.eql([
`ALTER TABLE "post" DROP CONSTRAINT "FK_4490d00e1925ca046a1f52ddf04"`,
`CREATE TABLE "account" ("id" SERIAL NOT NULL, "userId" integer, CONSTRAINT "PK_54115ee388cdb6d86bb4bf5b2ea" PRIMARY KEY ("id"))`,
`ALTER TABLE "account" ADD CONSTRAINT "FK_60328bf27019ff5498c4b977421" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
`ALTER TABLE "post" ADD CONSTRAINT "FK_4490d00e1925ca046a1f52ddf04" FOREIGN KEY ("ownerId") REFERENCES "account"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`
]);
downQueries.should.eql([
`ALTER TABLE "post" ADD CONSTRAINT "FK_4490d00e1925ca046a1f52ddf04" FOREIGN KEY ("ownerId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`,
`DROP TABLE "account"`,
`ALTER TABLE "account" DROP CONSTRAINT "FK_60328bf27019ff5498c4b977421"`,
`ALTER TABLE "post" DROP CONSTRAINT "FK_4490d00e1925ca046a1f52ddf04"`
]);
} finally {
connection.close();
}
})
);
});
});

0 comments on commit 7157cb3

Please sign in to comment.