Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit 0b103dd

Browse files
zaroSvetlozar
andauthored
fix: Incorrect migration generated when multiple views are updated in a single migration (typeorm#7587)
* test: Add test for github issue 7586 * fix: Oddly indexed views are not dropped in migration (typeorm#7586) Co-authored-by: Svetlozar <[email protected]>
1 parent 7eb0327 commit 0b103dd

File tree

6 files changed

+86
-1
lines changed

6 files changed

+86
-1
lines changed

src/schema-builder/RdbmsSchemaBuilder.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
410410
}
411411

412412
protected async dropOldViews(): Promise<void> {
413+
const droppedViews: Set<View> = new Set();
413414
for (const view of this.queryRunner.loadedViews) {
414415
const existViewMetadata = this.viewEntityToSyncMetadatas.find(metadata => {
415416
const database = metadata.database && metadata.database !== this.connection.driver.database ? metadata.database : undefined;
@@ -427,8 +428,9 @@ export class RdbmsSchemaBuilder implements SchemaBuilder {
427428

428429
// drop an old view
429430
await this.queryRunner.dropView(view);
430-
this.queryRunner.loadedViews.splice(this.queryRunner.loadedViews.indexOf(view), 1);
431+
droppedViews.add(view);
431432
}
433+
this.queryRunner.loadedViews = this.queryRunner.loadedViews.filter(view => !droppedViews.has(view));
432434
}
433435

434436
/**
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {Column, Entity, PrimaryGeneratedColumn} from "../../../../src";
2+
3+
4+
@Entity()
5+
export class TestEntity {
6+
@PrimaryGeneratedColumn()
7+
id: number
8+
9+
@Column("varchar")
10+
type: string;
11+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {ViewColumn, ViewEntity} from "../../../../src";
2+
3+
@ViewEntity({
4+
expression: `
5+
select * from test_entity -- V1 simlate view change with comment
6+
`
7+
})
8+
export class ViewA {
9+
@ViewColumn()
10+
id: number
11+
12+
@ViewColumn()
13+
type: string;
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {ViewColumn, ViewEntity} from "../../../../src";
2+
3+
@ViewEntity({
4+
expression: `
5+
select * from test_entity -- V1 simlate view change with comment
6+
`
7+
})
8+
export class ViewB {
9+
@ViewColumn()
10+
id: number
11+
12+
@ViewColumn()
13+
type: string;
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import {ViewColumn, ViewEntity} from "../../../../src";
2+
3+
@ViewEntity({
4+
expression: `
5+
select * from test_entity -- V1 simlate view change with comment
6+
`
7+
})
8+
export class ViewC {
9+
@ViewColumn()
10+
id: number
11+
12+
@ViewColumn()
13+
type: string;
14+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import "reflect-metadata";
2+
import {Connection} from "../../../src";
3+
import {closeTestingConnections, createTestingConnections} from "../../utils/test-utils";
4+
import {TestEntity} from "./entity/Test";
5+
import {ViewA} from "./entity/ViewA";
6+
import {ViewB} from "./entity/ViewB";
7+
import {ViewC} from "./entity/ViewC";
8+
9+
describe("github issues > #7586 Oddly indexed views are not dropped in migration", () => {
10+
let connections: Connection[];
11+
before(async () => connections = await createTestingConnections({
12+
enabledDrivers: ["postgres"],
13+
schemaCreate: true,
14+
dropSchema: true,
15+
entities: [TestEntity, ViewA, ViewB, ViewC],
16+
}));
17+
after(() => closeTestingConnections(connections));
18+
19+
it("should generate drop queries for all views", () => Promise.all(connections.map(async connection => {
20+
const expectedDrops: RegExp[] = [];
21+
for(const view of [ViewA, ViewB, ViewC]){
22+
const metadata = connection.getMetadata(view);
23+
metadata.expression = (metadata.expression as string)?.replace('V1', 'V2')
24+
expectedDrops.push(new RegExp(`^DROP\\s+VIEW.*"${metadata.tableName}"`))
25+
}
26+
const sqlInMemory = await connection.driver.createSchemaBuilder().log();
27+
sqlInMemory.downQueries.filter(q => expectedDrops.find(expected => q.query.match(expected))).length.should.be.equal(expectedDrops.length);
28+
sqlInMemory.upQueries.filter(q => expectedDrops.find(expected => q.query.match(expected))).length.should.be.equal(expectedDrops.length);
29+
})));
30+
});

0 commit comments

Comments
 (0)