-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add dependency configuraiton for views #8240
Add dependsOn option to @view decorator, where dependencies can be listed. Also use these dependencies to order draop/create view correctly when generating migrations
- Loading branch information
Svetlozar
committed
Oct 10, 2021
1 parent
8615733
commit d3e88cf
Showing
12 changed files
with
243 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { EntityMetadata } from "../../metadata/EntityMetadata"; | ||
|
||
export class ViewUtils { | ||
|
||
/** | ||
* Comparator for .sort() that will order views bases on dependencies in creation order | ||
*/ | ||
static viewMetadataCmp(metadataA: EntityMetadata | undefined, metadataB: EntityMetadata| undefined): number { | ||
if(!metadataA || !metadataB){ | ||
return 0; | ||
} | ||
if(metadataA.dependsOn && ( | ||
metadataA.dependsOn.has(metadataB.target) || | ||
metadataA.dependsOn.has(metadataB.name) | ||
)) { | ||
return 1; | ||
} | ||
if(metadataB.dependsOn && ( | ||
metadataB.dependsOn.has(metadataA.target) || | ||
metadataB.dependsOn.has(metadataA.name) | ||
)){ | ||
return -1; | ||
} | ||
return 0; | ||
} | ||
|
||
} |
30 changes: 30 additions & 0 deletions
30
test/functional/view-entity/view-dependencies/entity/Test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import {Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn} from "../../../../../src"; | ||
import { ViewC } from "./ViewC"; | ||
import { ViewB } from "./ViewB"; | ||
import { ViewA } from "./ViewA"; | ||
|
||
|
||
@Entity() | ||
export class TestEntity { | ||
@PrimaryGeneratedColumn() | ||
id: number; | ||
|
||
@Column("varchar") | ||
type: string; | ||
|
||
// Bogus relations to mix up import order | ||
@OneToOne(() => ViewC) | ||
@JoinColumn() | ||
somehowMatched: ViewC; | ||
|
||
// Bogus relations to mix up import order | ||
@OneToOne(() => ViewB) | ||
@JoinColumn() | ||
somehowMatched2: ViewB; | ||
|
||
// Bogus relations to mix up import order | ||
@OneToOne(() => ViewA) | ||
@JoinColumn() | ||
somehowMatched3: ViewA; | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
test/functional/view-entity/view-dependencies/entity/ViewA.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import {ViewColumn, ViewEntity} from "../../../../../src"; | ||
|
||
@ViewEntity({ | ||
name: "view_a", | ||
expression: ` | ||
select * from test_entity -- V1 simulate view change with comment | ||
` | ||
}) | ||
export class ViewA { | ||
@ViewColumn() | ||
id: number; | ||
|
||
@ViewColumn() | ||
type: string; | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
test/functional/view-entity/view-dependencies/entity/ViewB.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { ViewColumn, ViewEntity} from "../../../../../src"; | ||
|
||
@ViewEntity({ | ||
name: "view_b", | ||
expression: `select * from view_a -- V1 simulate view change with comment`, | ||
dependsOn: ["ViewA"], | ||
}) | ||
export class ViewB { | ||
@ViewColumn() | ||
id: number; | ||
|
||
@ViewColumn() | ||
type: string; | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
test/functional/view-entity/view-dependencies/entity/ViewC.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import {ViewColumn, ViewEntity} from "../../../../../src"; | ||
|
||
@ViewEntity({ | ||
name: "view_c", | ||
expression: `select * from view_b -- V1 simulate view change with comment`, | ||
dependsOn: ["ViewB"], | ||
}) | ||
export class ViewC { | ||
@ViewColumn() | ||
id: number; | ||
|
||
@ViewColumn() | ||
type: string; | ||
|
||
} |
49 changes: 49 additions & 0 deletions
49
test/functional/view-entity/view-dependencies/view-entity-dependencies.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { expect } from "chai"; | ||
import "reflect-metadata"; | ||
import {Connection} from "../../../../src"; | ||
import {closeTestingConnections, createTestingConnections} from "../../../utils/test-utils"; | ||
import {ViewC} from "./entity/ViewC"; | ||
import {ViewA} from "./entity/ViewA"; | ||
import {ViewB} from "./entity/ViewB"; | ||
import {TestEntity} from "./entity/Test"; | ||
|
||
describe("views dependencies", () => { | ||
let connections: Connection[]; | ||
before(async () => connections = await createTestingConnections({ | ||
enabledDrivers: ["postgres"], | ||
schemaCreate: true, | ||
dropSchema: true, | ||
// entities: [ViewC, ViewB, ViewA, TestEntity], | ||
entities: [TestEntity, ViewA, ViewB, ViewC], | ||
})); | ||
after(() => closeTestingConnections(connections)); | ||
|
||
it("should generate drop and create queries in correct order", () => Promise.all(connections.map(async connection => { | ||
const expectedDrops: RegExp[] = []; | ||
const expectedCreates: RegExp[] = []; | ||
// Views in order in which they should be created | ||
for(const view of [ViewA, ViewB, ViewC]){ | ||
const metadata = connection.getMetadata(view); | ||
// Modify ViewA, this should trigger updates on all views that depend on it | ||
if(view === ViewA){ | ||
metadata.expression = (metadata.expression as string)?.replace("V1", "V2"); | ||
} | ||
expectedDrops.push(new RegExp(`^DROP\\s+VIEW.*"${metadata.tableName}"`)); | ||
expectedCreates.push(new RegExp(`^CREATE\\s+VIEW.*"${metadata.tableName}"`)); | ||
} | ||
// Drop order should be reverse of create order | ||
expectedDrops.reverse(); | ||
const sqlInMemory = await connection.driver.createSchemaBuilder().log(); | ||
// console.log(sqlInMemory.upQueries.map(q => q.query)); | ||
const dropPositions = expectedDrops.map(expected => sqlInMemory.upQueries.findIndex(q => q.query.match(expected))); | ||
// console.log("dropPositions", dropPositions); | ||
expect(dropPositions).to.have.length(3); | ||
const dropPositionsSorted = dropPositions.slice().sort((a,b) => a-b); | ||
expect(dropPositions).eql(dropPositionsSorted); | ||
const createPositions = expectedCreates.map(expected => sqlInMemory.upQueries.findIndex(q => q.query.match(expected))); | ||
// console.log("createPositions", createPositions); | ||
expect(createPositions).to.have.length(3); | ||
const createPositionsSorted = createPositions.slice().sort((a,b) => a-b); | ||
expect(createPositions).eql(createPositionsSorted); | ||
}))); | ||
}); |