Skip to content

Commit d1e3950

Browse files
authored
feat: support virtual columns in entity schema (#11597)
* feat: add entity mode virtual-property * test: virtual columns
1 parent 1698313 commit d1e3950

File tree

5 files changed

+78
-0
lines changed

5 files changed

+78
-0
lines changed

src/decorator/options/ColumnOptions.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,11 @@ export interface ColumnOptions extends ColumnCommonOptions {
187187
* SRID (Spatial Reference ID (EPSG code))
188188
*/
189189
srid?: number
190+
191+
/**
192+
* Query to be used to populate the column data. This query is used when generating the relational db script.
193+
* The query function is called with the current entities alias either defined by the Entity Decorator or automatically
194+
* @See https://typeorm.io/decorator-reference#virtualcolumn for more details.
195+
*/
196+
query?: (alias: string) => string
190197
}

src/entity-schema/EntitySchemaColumnOptions.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ export interface EntitySchemaColumnOptions extends SpatialColumnOptions {
4444
*/
4545
treeLevel?: boolean
4646

47+
/**
48+
* Indicates if this column is a virtualProperty column.
49+
*/
50+
virtualProperty?: boolean
51+
4752
/**
4853
* Column type. Must be one of the value from the ColumnTypes class.
4954
*/
@@ -214,4 +219,11 @@ export interface EntitySchemaColumnOptions extends SpatialColumnOptions {
214219
* Foreign key options of this column.
215220
*/
216221
foreignKey?: EntitySchemaColumnForeignKeyOptions
222+
223+
/**
224+
* Query to be used to populate the column data. This query is used when generating the relational db script.
225+
* The query function is called with the current entities alias either defined by the Entity Decorator or automatically
226+
* @See https://typeorm.io/decorator-reference#virtualcolumn for more details.
227+
*/
228+
query?: (alias: string) => string
217229
}

src/entity-schema/EntitySchemaTransformer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export class EntitySchemaTransformer {
9898
if (regularColumn.treeChildrenCount) mode = "treeChildrenCount"
9999
if (regularColumn.treeLevel) mode = "treeLevel"
100100
if (regularColumn.objectId) mode = "objectId"
101+
if (regularColumn.virtualProperty) mode = "virtual-property"
101102

102103
const columnArgs: ColumnMetadataArgs = {
103104
target: options.target || options.name,
@@ -135,6 +136,7 @@ export class EntitySchemaTransformer {
135136
transformer: regularColumn.transformer,
136137
spatialFeatureType: regularColumn.spatialFeatureType,
137138
srid: regularColumn.srid,
139+
query: regularColumn.query,
138140
},
139141
}
140142
metadataArgsStorage.columns.push(columnArgs)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { EntitySchema } from "../../../../../../src"
2+
3+
export const Activity = new EntitySchema({
4+
name: "activities",
5+
columns: {
6+
id: {
7+
primary: true,
8+
generated: "increment",
9+
type: "int",
10+
unsigned: true,
11+
},
12+
k1: {
13+
type: "int",
14+
},
15+
vK1: {
16+
type: "int",
17+
virtualProperty: true,
18+
query: (alias) =>
19+
`SELECT k1 FROM "activities" WHERE "k1" = ${alias}."k1"`,
20+
},
21+
},
22+
})
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import "reflect-metadata"
2+
3+
import { Activity } from "./entity/Activity"
4+
import {
5+
closeTestingConnections,
6+
createTestingConnections,
7+
reloadTestingDatabases,
8+
} from "../../../../utils/test-utils"
9+
import { DataSource } from "../../../../../src"
10+
import { expect } from "chai"
11+
12+
describe("entity-schema > columns > virtual column", () => {
13+
let connections: DataSource[]
14+
before(
15+
async () =>
16+
(connections = await createTestingConnections({
17+
entities: [<any>Activity],
18+
enabledDrivers: ["better-sqlite3"],
19+
})),
20+
)
21+
beforeEach(() => reloadTestingDatabases(connections))
22+
after(() => closeTestingConnections(connections))
23+
24+
it("should query virtual columns", () => {
25+
return Promise.all(
26+
connections.map(async (connection) => {
27+
const repo = connection.getRepository(Activity)
28+
await repo.save({ id: 0, k1: 1 })
29+
const result = (await repo.findOne({ where: { id: 0 } }))!
30+
expect(result.vK1).eq(result.k1)
31+
expect(result.vK1).eq(1)
32+
}),
33+
)
34+
})
35+
})

0 commit comments

Comments
 (0)