@entity-access/entity-access 1.0.164 → 1.0.166
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/decorators/IColumn.d.ts +2 -0
- package/dist/decorators/IColumn.d.ts.map +1 -1
- package/dist/decorators/IForeignKeyConstraint.d.ts +12 -0
- package/dist/decorators/IForeignKeyConstraint.d.ts.map +1 -0
- package/dist/decorators/IForeignKeyConstraint.js +2 -0
- package/dist/decorators/IForeignKeyConstraint.js.map +1 -0
- package/dist/decorators/Relate.d.ts +5 -0
- package/dist/decorators/Relate.d.ts.map +1 -1
- package/dist/decorators/Relate.js +2 -1
- package/dist/decorators/Relate.js.map +1 -1
- package/dist/drivers/base/BaseDriver.d.ts +2 -1
- package/dist/drivers/base/BaseDriver.d.ts.map +1 -1
- package/dist/drivers/base/BaseDriver.js +60 -1
- package/dist/drivers/base/BaseDriver.js.map +1 -1
- package/dist/drivers/sql-server/ExpressionToSqlServer.d.ts +2 -1
- package/dist/drivers/sql-server/ExpressionToSqlServer.d.ts.map +1 -1
- package/dist/drivers/sql-server/ExpressionToSqlServer.js +35 -2
- package/dist/drivers/sql-server/ExpressionToSqlServer.js.map +1 -1
- package/dist/entity-query/EntityType.d.ts.map +1 -1
- package/dist/entity-query/EntityType.js +8 -0
- package/dist/entity-query/EntityType.js.map +1 -1
- package/dist/migrations/Migrations.d.ts +3 -1
- package/dist/migrations/Migrations.d.ts.map +1 -1
- package/dist/migrations/Migrations.js +17 -0
- package/dist/migrations/Migrations.js.map +1 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts +2 -0
- package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts.map +1 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.js +39 -0
- package/dist/migrations/postgres/PostgresAutomaticMigrations.js.map +1 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts +2 -0
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts.map +1 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js +39 -0
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js.map +1 -1
- package/dist/model/EntitySource.d.ts +2 -0
- package/dist/model/EntitySource.d.ts.map +1 -1
- package/dist/model/EntitySource.js +7 -0
- package/dist/model/EntitySource.js.map +1 -1
- package/dist/query/ast/ExpressionToSql.d.ts +2 -1
- package/dist/query/ast/ExpressionToSql.d.ts.map +1 -1
- package/dist/query/ast/ExpressionToSql.js +28 -1
- package/dist/query/ast/ExpressionToSql.js.map +1 -1
- package/dist/query/ast/Expressions.d.ts +8 -1
- package/dist/query/ast/Expressions.d.ts.map +1 -1
- package/dist/query/ast/Expressions.js +6 -0
- package/dist/query/ast/Expressions.js.map +1 -1
- package/dist/query/ast/Visitor.d.ts +2 -1
- package/dist/query/ast/Visitor.d.ts.map +1 -1
- package/dist/query/ast/Visitor.js +5 -0
- package/dist/query/ast/Visitor.js.map +1 -1
- package/dist/tests/model/ShoppingContext.d.ts.map +1 -1
- package/dist/tests/model/ShoppingContext.js +4 -1
- package/dist/tests/model/ShoppingContext.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/workflows/WorkflowContext.d.ts +15 -12
- package/dist/workflows/WorkflowContext.d.ts.map +1 -1
- package/dist/workflows/WorkflowContext.js +6 -5
- package/dist/workflows/WorkflowContext.js.map +1 -1
- package/dist/workflows/WorkflowStorage.d.ts +7 -2
- package/dist/workflows/WorkflowStorage.d.ts.map +1 -1
- package/dist/workflows/WorkflowStorage.js +33 -20
- package/dist/workflows/WorkflowStorage.js.map +1 -1
- package/package.json +3 -3
- package/src/decorators/IColumn.ts +3 -0
- package/src/decorators/IForeignKeyConstraint.ts +19 -0
- package/src/decorators/Relate.ts +8 -1
- package/src/drivers/base/BaseDriver.ts +70 -1
- package/src/drivers/sql-server/ExpressionToSqlServer.ts +45 -3
- package/src/entity-query/EntityType.ts +9 -0
- package/src/migrations/Migrations.ts +25 -2
- package/src/migrations/postgres/PostgresAutomaticMigrations.ts +50 -0
- package/src/migrations/sql-server/SqlServerAutomaticMigrations.ts +47 -0
- package/src/model/EntitySource.ts +13 -1
- package/src/query/ast/ExpressionToSql.ts +37 -2
- package/src/query/ast/Expressions.ts +10 -1
- package/src/query/ast/Visitor.ts +6 -1
- package/src/tests/model/ShoppingContext.ts +4 -1
- package/src/workflows/WorkflowContext.ts +25 -10
- package/src/workflows/WorkflowStorage.ts +36 -23
- package/tsconfig.json +1 -1
|
@@ -9,6 +9,7 @@ import EntityContext from "../model/EntityContext.js";
|
|
|
9
9
|
import { CallExpression, Expression, NullExpression, NumberLiteral, UpdateStatement } from "../query/ast/Expressions.js";
|
|
10
10
|
import DateTime from "../types/DateTime.js";
|
|
11
11
|
import WorkflowClock from "./WorkflowClock.js";
|
|
12
|
+
const loadedFromDb = Symbol("loadedFromDB");
|
|
12
13
|
let WorkflowItem = class WorkflowItem {
|
|
13
14
|
};
|
|
14
15
|
__decorate([
|
|
@@ -53,7 +54,7 @@ __decorate([
|
|
|
53
54
|
default: () => `default`
|
|
54
55
|
}),
|
|
55
56
|
__metadata("design:type", String)
|
|
56
|
-
], WorkflowItem.prototype, "
|
|
57
|
+
], WorkflowItem.prototype, "taskGroup", void 0);
|
|
57
58
|
__decorate([
|
|
58
59
|
Column({ dataType: "Int", default: () => 0 }),
|
|
59
60
|
__metadata("design:type", Number)
|
|
@@ -94,10 +95,10 @@ WorkflowItem = __decorate([
|
|
|
94
95
|
filter: (x) => x.groupName !== null
|
|
95
96
|
}),
|
|
96
97
|
Index({
|
|
97
|
-
name: "
|
|
98
|
+
name: "IX_Workflows_taskGroup_ETA",
|
|
98
99
|
columns: [
|
|
99
100
|
{ name: (x) => x.eta, descending: false },
|
|
100
|
-
{ name: (x) => x.
|
|
101
|
+
{ name: (x) => x.taskGroup, descending: false }
|
|
101
102
|
],
|
|
102
103
|
filter: (x) => x.isWorkflow === true
|
|
103
104
|
})
|
|
@@ -134,7 +135,9 @@ let WorkflowStorage = class WorkflowStorage {
|
|
|
134
135
|
state: r.state,
|
|
135
136
|
output: r.output,
|
|
136
137
|
error: r.error,
|
|
137
|
-
lastID: r.lastID
|
|
138
|
+
lastID: r.lastID,
|
|
139
|
+
taskGroup: r.taskGroup,
|
|
140
|
+
[loadedFromDb]: true,
|
|
138
141
|
};
|
|
139
142
|
}
|
|
140
143
|
return null;
|
|
@@ -154,7 +157,8 @@ let WorkflowStorage = class WorkflowStorage {
|
|
|
154
157
|
state: r.state,
|
|
155
158
|
output: r.output,
|
|
156
159
|
error: r.error,
|
|
157
|
-
lastID: r.lastID
|
|
160
|
+
lastID: r.lastID,
|
|
161
|
+
[loadedFromDb]: true
|
|
158
162
|
};
|
|
159
163
|
}
|
|
160
164
|
return null;
|
|
@@ -190,23 +194,32 @@ let WorkflowStorage = class WorkflowStorage {
|
|
|
190
194
|
const db = new WorkflowContext(this.driver);
|
|
191
195
|
const connection = db.connection;
|
|
192
196
|
await connection.runInTransaction(async () => {
|
|
193
|
-
let w = await db.workflows.where(state, (p) => (x) => x.id === p.id).first();
|
|
194
|
-
if (!w) {
|
|
195
|
-
|
|
197
|
+
// let w = await db.workflows.where(state, (p) => (x) => x.id === p.id).first();
|
|
198
|
+
// if (!w) {
|
|
199
|
+
// w = db.workflows.add(state);
|
|
200
|
+
// w.taskGroup ||= "default";
|
|
201
|
+
// }
|
|
202
|
+
// for (const key in state) {
|
|
203
|
+
// if (Object.prototype.hasOwnProperty.call(state, key)) {
|
|
204
|
+
// const element = state[key];
|
|
205
|
+
// w[key] = element;
|
|
206
|
+
// }
|
|
207
|
+
// }
|
|
208
|
+
// w.state ||= "queued";
|
|
209
|
+
// w.updated ??= DateTime.utcNow;
|
|
210
|
+
state.state ||= "queued";
|
|
211
|
+
state.updated ??= DateTime.utcNow;
|
|
212
|
+
state.taskGroup ||= "default";
|
|
213
|
+
// await db.saveChanges();
|
|
214
|
+
if (state[loadedFromDb]) {
|
|
215
|
+
await db.workflows.saveDirect(state, "update");
|
|
196
216
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const element = state[key];
|
|
200
|
-
w[key] = element;
|
|
201
|
-
}
|
|
217
|
+
else {
|
|
218
|
+
await db.workflows.saveDirect(state, "upsert");
|
|
202
219
|
}
|
|
203
|
-
w.state ||= "queued";
|
|
204
|
-
w.workerGroup ||= "default";
|
|
205
|
-
w.updated ??= DateTime.utcNow;
|
|
206
|
-
await db.saveChanges();
|
|
207
220
|
});
|
|
208
221
|
}
|
|
209
|
-
async dequeue(
|
|
222
|
+
async dequeue(taskGroup, signal) {
|
|
210
223
|
const db = new WorkflowContext(this.driver);
|
|
211
224
|
const now = this.clock.utcNow;
|
|
212
225
|
if (!this.lockQuery) {
|
|
@@ -233,11 +246,11 @@ let WorkflowStorage = class WorkflowStorage {
|
|
|
233
246
|
}
|
|
234
247
|
const q = this.lockQuery;
|
|
235
248
|
const items = await db.workflows
|
|
236
|
-
.where({ now,
|
|
249
|
+
.where({ now, taskGroup }, (p) => (x) => x.eta <= p.now
|
|
237
250
|
&& (x.lockedTTL === null || x.lockedTTL <= p.now)
|
|
238
251
|
&& x.lockToken === null
|
|
239
252
|
&& x.isWorkflow === true
|
|
240
|
-
&& x.
|
|
253
|
+
&& x.taskGroup === p.taskGroup)
|
|
241
254
|
.orderBy({}, (p) => (x) => x.eta)
|
|
242
255
|
.thenBy({}, (p) => (x) => x.priority)
|
|
243
256
|
.limit(20)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowStorage.js","sourceRoot":"","sources":["../../src/workflows/WorkflowStorage.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,KAAK,MAAM,wBAAwB,CAAC;AAC3C,OAAO,KAAK,MAAM,wBAAwB,CAAC;AAC3C,OAAO,MAAM,EAAE,EAAE,cAAc,EAAE,iBAAiB,EAAmB,MAAM,aAAa,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,aAAa,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAoB,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC3I,OAAO,QAAQ,MAAM,sBAAsB,CAAC;AAC5C,OAAO,aAAa,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkflowStorage.js","sourceRoot":"","sources":["../../src/workflows/WorkflowStorage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@entity-access/entity-access",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.166",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@types/node": "^20.3.2",
|
|
41
41
|
"@types/pg": "^8.10.2",
|
|
42
42
|
"@types/pg-cursor": "^2.7.0",
|
|
43
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
44
|
-
"@typescript-eslint/parser": "^6.
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
|
44
|
+
"@typescript-eslint/parser": "^6.7.3",
|
|
45
45
|
"eslint": "^8.42.0",
|
|
46
46
|
"eslint-config-prettier": "^8.8.0",
|
|
47
47
|
"eslint-config-standard": "^17.1.0",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import EntityType from "../entity-query/EntityType.js";
|
|
2
2
|
import { IClassOf } from "./IClassOf.js";
|
|
3
|
+
import { IForeignKeyConstraint } from "./IForeignKeyConstraint.js";
|
|
3
4
|
import { ISqlType } from "./ISqlType.js";
|
|
4
5
|
|
|
5
6
|
|
|
@@ -106,5 +107,7 @@ export interface IEntityRelation {
|
|
|
106
107
|
|
|
107
108
|
dotNotCreateIndex?: boolean;
|
|
108
109
|
|
|
110
|
+
foreignKeyConstraint?: IForeignKeyConstraint;
|
|
111
|
+
|
|
109
112
|
}
|
|
110
113
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type EntityType from "../entity-query/EntityType.js";
|
|
2
|
+
import { IColumn } from "./IColumn.js";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export interface IForeignKeyConstraint {
|
|
6
|
+
|
|
7
|
+
name?: string;
|
|
8
|
+
|
|
9
|
+
type?: EntityType;
|
|
10
|
+
|
|
11
|
+
validate?: boolean;
|
|
12
|
+
index?: boolean;
|
|
13
|
+
|
|
14
|
+
cascade?: "delete" | "restrict" | "set-null" | "set-default";
|
|
15
|
+
|
|
16
|
+
column?: IColumn;
|
|
17
|
+
|
|
18
|
+
refColumns?: IColumn[];
|
|
19
|
+
}
|
package/src/decorators/Relate.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { IClassOf } from "./IClassOf.js";
|
|
2
|
+
import { IForeignKeyConstraint } from "./IForeignKeyConstraint.js";
|
|
2
3
|
import SchemaRegistry from "./SchemaRegistry.js";
|
|
3
4
|
import NameParser from "./parser/NameParser.js";
|
|
4
5
|
|
|
6
|
+
|
|
5
7
|
export interface IRelatedType<T, TRelated> {
|
|
6
8
|
property: (item: T) => TRelated;
|
|
7
9
|
inverseProperty: (item: TRelated) => T[];
|
|
8
10
|
inverseKey?: (item: TRelated) => any;
|
|
9
11
|
dotNotCreateIndex?: boolean;
|
|
12
|
+
foreignKeyConstraint?: IForeignKeyConstraint;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export interface IRelatedTypeOne<T, TRelated> {
|
|
@@ -14,6 +17,7 @@ export interface IRelatedTypeOne<T, TRelated> {
|
|
|
14
17
|
inverseProperty: (item: TRelated) => T;
|
|
15
18
|
inverseKey?: (item: TRelated) => any;
|
|
16
19
|
dotNotCreateIndex?: boolean;
|
|
20
|
+
foreignKeyConstraint?: IForeignKeyConstraint;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
export interface IRelatedTypeWithType<T, TRelated> {
|
|
@@ -22,6 +26,7 @@ export interface IRelatedTypeWithType<T, TRelated> {
|
|
|
22
26
|
inverseProperty: (item: TRelated) => T[];
|
|
23
27
|
inverseKey?: (item: TRelated) => any;
|
|
24
28
|
dotNotCreateIndex?: boolean;
|
|
29
|
+
foreignKeyConstraint?: IForeignKeyConstraint;
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
export interface IRelatedTypeOneWithType<T, TRelated> {
|
|
@@ -30,6 +35,7 @@ export interface IRelatedTypeOneWithType<T, TRelated> {
|
|
|
30
35
|
inverseProperty: (item: TRelated) => T;
|
|
31
36
|
inverseKey?: (item: TRelated) => any;
|
|
32
37
|
dotNotCreateIndex?: boolean;
|
|
38
|
+
foreignKeyConstraint?: IForeignKeyConstraint;
|
|
33
39
|
}
|
|
34
40
|
export function RelateTo<T, TRelated>(p: IRelatedTypeWithType<T, TRelated>): (target: T, key: string) => any;
|
|
35
41
|
export function RelateTo<T, TRelated>(c: IClassOf<TRelated>, p: IRelatedType<T, TRelated>): (target: T, key: string) => any;
|
|
@@ -43,7 +49,7 @@ export function RelateTo(c, p?): any {
|
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
const { property, inverseKey: invKey, inverseProperty, dotNotCreateIndex } = p;
|
|
52
|
+
const { property, inverseKey: invKey, inverseProperty, dotNotCreateIndex, foreignKeyConstraint } = p;
|
|
47
53
|
|
|
48
54
|
return (target: any, foreignKey: string): any => {
|
|
49
55
|
|
|
@@ -60,6 +66,7 @@ export function RelateTo(c, p?): any {
|
|
|
60
66
|
relatedTypeClassFactory: p.type,
|
|
61
67
|
relatedName: NameParser.parseMember(inverseProperty),
|
|
62
68
|
relatedKey: invKey ? NameParser.parseMember(invKey) : void 0,
|
|
69
|
+
foreignKeyConstraint,
|
|
63
70
|
dotNotCreateIndex
|
|
64
71
|
});
|
|
65
72
|
|
|
@@ -7,7 +7,7 @@ import QueryCompiler from "../../compiler/QueryCompiler.js";
|
|
|
7
7
|
import EntityType from "../../entity-query/EntityType.js";
|
|
8
8
|
import Migrations from "../../migrations/Migrations.js";
|
|
9
9
|
import ChangeEntry from "../../model/changes/ChangeEntry.js";
|
|
10
|
-
import { BinaryExpression, Constant, DeleteStatement, ExistsExpression, Expression, Identifier, InsertStatement, NotExits, ReturnUpdated, SelectStatement, TableLiteral, UnionAllStatement, UpdateStatement, ValuesStatement } from "../../query/ast/Expressions.js";
|
|
10
|
+
import { BinaryExpression, Constant, DeleteStatement, ExistsExpression, Expression, Identifier, InsertStatement, NotExits, ReturnUpdated, SelectStatement, TableLiteral, UnionAllStatement, UpdateStatement, UpsertStatement, ValuesStatement } from "../../query/ast/Expressions.js";
|
|
11
11
|
|
|
12
12
|
export interface IRecord {
|
|
13
13
|
[key: string]: string | boolean | number | Date | Uint8Array | Blob;
|
|
@@ -148,6 +148,75 @@ export abstract class BaseDriver {
|
|
|
148
148
|
/** Must dispose ObjectPools */
|
|
149
149
|
abstract dispose();
|
|
150
150
|
|
|
151
|
+
createUpsertExpression(type: EntityType, entity: any, mode: "update" | "upsert" | "insert"): Expression {
|
|
152
|
+
const table = type.fullyQualifiedName as TableLiteral;
|
|
153
|
+
|
|
154
|
+
if (mode === "insert") {
|
|
155
|
+
const fields = [];
|
|
156
|
+
const values = [];
|
|
157
|
+
for (const iterator of type.columns) {
|
|
158
|
+
const value = entity[iterator.name];
|
|
159
|
+
if (value === void 0) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
fields.push(Expression.identifier(iterator.columnName));
|
|
163
|
+
values.push(Expression.constant(value));
|
|
164
|
+
}
|
|
165
|
+
return InsertStatement.create({
|
|
166
|
+
table,
|
|
167
|
+
values: ValuesStatement.create({
|
|
168
|
+
fields,
|
|
169
|
+
values: [values]
|
|
170
|
+
})
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
const insert = [] as BinaryExpression[];
|
|
176
|
+
const update = [] as BinaryExpression[];
|
|
177
|
+
const keys = [] as BinaryExpression[];
|
|
178
|
+
for (const iterator of type.columns) {
|
|
179
|
+
const value = entity[iterator.name];
|
|
180
|
+
const assign = Expression.assign(
|
|
181
|
+
Expression.identifier(iterator.columnName),
|
|
182
|
+
Expression.constant(value)
|
|
183
|
+
);
|
|
184
|
+
if (iterator.key) {
|
|
185
|
+
keys.push(assign);
|
|
186
|
+
insert.push(assign);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (value === undefined) {
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
insert.push(assign);
|
|
193
|
+
if (value === undefined) {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
update.push(assign);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
if (mode === "update") {
|
|
201
|
+
let where = null;
|
|
202
|
+
for (const iterator of keys) {
|
|
203
|
+
where = where ? Expression.logicalAnd(where, iterator) : iterator;
|
|
204
|
+
}
|
|
205
|
+
return UpdateStatement.create({
|
|
206
|
+
table,
|
|
207
|
+
set: update,
|
|
208
|
+
where
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return UpsertStatement.create({
|
|
213
|
+
table,
|
|
214
|
+
insert,
|
|
215
|
+
update,
|
|
216
|
+
keys
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
151
220
|
createInsertExpression(type: EntityType, entity: any): InsertStatement {
|
|
152
221
|
const returnFields = [] as Identifier[];
|
|
153
222
|
const fields = [] as Identifier[];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ExpressionToSql from "../../query/ast/ExpressionToSql.js";
|
|
2
|
-
import { BooleanLiteral, InsertStatement, NumberLiteral, OrderByExpression, ReturnUpdated, SelectStatement, ValuesStatement } from "../../query/ast/Expressions.js";
|
|
3
|
-
import { ITextQuery, prepare } from "../../query/ast/IStringTransformer.js";
|
|
2
|
+
import { BooleanLiteral, InsertStatement, NumberLiteral, OrderByExpression, ReturnUpdated, SelectStatement, UpsertStatement, ValuesStatement } from "../../query/ast/Expressions.js";
|
|
3
|
+
import { ITextQuery, prepare, prepareJoin } from "../../query/ast/IStringTransformer.js";
|
|
4
4
|
|
|
5
5
|
export default class ExpressionToSqlServer extends ExpressionToSql {
|
|
6
6
|
|
|
@@ -23,7 +23,7 @@ export default class ExpressionToSqlServer extends ExpressionToSql {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
visitInsertStatement(e: InsertStatement): ITextQuery {
|
|
26
|
-
const returnValues = this.visit(e.returnValues);
|
|
26
|
+
const returnValues = e.returnValues ? this.visit(e.returnValues) : [];
|
|
27
27
|
if (e.values instanceof ValuesStatement) {
|
|
28
28
|
|
|
29
29
|
const rows = [];
|
|
@@ -45,6 +45,48 @@ export default class ExpressionToSqlServer extends ExpressionToSql {
|
|
|
45
45
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
visitUpsertStatement(e: UpsertStatement): ITextQuery {
|
|
49
|
+
const table = this.visit(e.table);
|
|
50
|
+
|
|
51
|
+
const insertColumns = [];
|
|
52
|
+
const insertValues = [];
|
|
53
|
+
const updateSet = [];
|
|
54
|
+
|
|
55
|
+
const compare = [];
|
|
56
|
+
|
|
57
|
+
for (const { left, right } of e.insert) {
|
|
58
|
+
const c = this.visit(left);
|
|
59
|
+
const v = this.visit(right);
|
|
60
|
+
insertColumns.push(c);
|
|
61
|
+
insertValues.push(v);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for (const { left, right } of e.update) {
|
|
65
|
+
const c = this.visit(left);
|
|
66
|
+
const v = this.visit(right);
|
|
67
|
+
updateSet.push(prepare `${c} = ${v}`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const { left, right } of e.keys) {
|
|
71
|
+
const c = this.visit(left);
|
|
72
|
+
const v = this.visit(right);
|
|
73
|
+
compare.push(prepare `${c} = ${v}`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
return prepare `INSERT INTO ${table} (${prepareJoin(insertColumns)})
|
|
78
|
+
SELECT * FROM (VALUES (${prepareJoin(insertValues)})) as A(${prepareJoin(insertColumns)})
|
|
79
|
+
WHERE NOT EXISTS (SELECT 1 FROM ${table} WHERE ${prepareJoin(compare, " AND ")});
|
|
80
|
+
IF @@ROWCOUNT=0
|
|
81
|
+
BEGIN
|
|
82
|
+
UPDATE ${table}
|
|
83
|
+
SET
|
|
84
|
+
${prepareJoin(updateSet)}
|
|
85
|
+
WHERE ${prepareJoin(compare, " AND ")}
|
|
86
|
+
END;`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
48
90
|
visitSelectStatement(e: SelectStatement): ITextQuery {
|
|
49
91
|
|
|
50
92
|
this.prepareStatement(e);
|
|
@@ -148,6 +148,15 @@ export default class EntityType {
|
|
|
148
148
|
relatedType.relations.push(inverseRelation);
|
|
149
149
|
inverseRelation.relatedRelation = relation;
|
|
150
150
|
relation.relatedRelation = inverseRelation;
|
|
151
|
+
|
|
152
|
+
let { foreignKeyConstraint } = relation;
|
|
153
|
+
if(foreignKeyConstraint) {
|
|
154
|
+
foreignKeyConstraint = { ... foreignKeyConstraint};
|
|
155
|
+
relation.foreignKeyConstraint = foreignKeyConstraint;
|
|
156
|
+
foreignKeyConstraint.name ||= `FK_${this.name}_${fkColumn.name}_${this.typeClass.name}_${relatedType.keys[0].name}`;
|
|
157
|
+
foreignKeyConstraint.column = fkColumn;
|
|
158
|
+
foreignKeyConstraint.refColumns = relatedType.keys;
|
|
159
|
+
}
|
|
151
160
|
return relation;
|
|
152
161
|
}
|
|
153
162
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { modelSymbol } from "../common/symbols/symbols.js";
|
|
2
2
|
import type QueryCompiler from "../compiler/QueryCompiler.js";
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
3
|
+
import type { IForeignKeyConstraint } from "../decorators/IForeignKeyConstraint.js";
|
|
4
|
+
import type { IIndex } from "../decorators/IIndex.js";
|
|
5
5
|
import type EntityType from "../entity-query/EntityType.js";
|
|
6
6
|
import type EntityContext from "../model/EntityContext.js";
|
|
7
7
|
import type EntityQuery from "../model/EntityQuery.js";
|
|
@@ -37,6 +37,27 @@ export default abstract class Migrations {
|
|
|
37
37
|
for (const index of type.indexes) {
|
|
38
38
|
await this.migrateIndexInternal(context, index, type);
|
|
39
39
|
}
|
|
40
|
+
|
|
41
|
+
for (const { isInverseRelation , foreignKeyConstraint, relatedTypeClass } of type.relations) {
|
|
42
|
+
if (isInverseRelation) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (!foreignKeyConstraint) {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const relatedEntity = model.register(relatedTypeClass)[modelSymbol] as EntityType;
|
|
50
|
+
|
|
51
|
+
foreignKeyConstraint.type = type;
|
|
52
|
+
foreignKeyConstraint.column = type.getProperty(foreignKeyConstraint.column.name).field;
|
|
53
|
+
const refColumns = foreignKeyConstraint.refColumns;
|
|
54
|
+
foreignKeyConstraint.refColumns = [];
|
|
55
|
+
for (const iterator of refColumns) {
|
|
56
|
+
foreignKeyConstraint.refColumns.push(relatedEntity.getProperty(iterator.name).field);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
await this.migrateForeignKey(context, foreignKeyConstraint);
|
|
60
|
+
}
|
|
40
61
|
}
|
|
41
62
|
|
|
42
63
|
}
|
|
@@ -69,5 +90,7 @@ export default abstract class Migrations {
|
|
|
69
90
|
|
|
70
91
|
abstract migrateTable(context: EntityContext, type: EntityType): Promise<any>;
|
|
71
92
|
|
|
93
|
+
abstract migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint);
|
|
94
|
+
|
|
72
95
|
|
|
73
96
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IColumn } from "../../decorators/IColumn.js";
|
|
2
|
+
import { IForeignKeyConstraint } from "../../decorators/IForeignKeyConstraint.js";
|
|
2
3
|
import { IIndex } from "../../decorators/IIndex.js";
|
|
3
4
|
import { BaseConnection, BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
4
5
|
import EntityType from "../../entity-query/EntityType.js";
|
|
@@ -129,5 +130,54 @@ export default class PostgresAutomaticMigrations extends PostgresMigrations {
|
|
|
129
130
|
await driver.executeQuery(query);
|
|
130
131
|
}
|
|
131
132
|
|
|
133
|
+
async migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint) {
|
|
134
|
+
const { type } = constraint;
|
|
135
|
+
const name = type.schema
|
|
136
|
+
? type.schema + "." + type.name
|
|
137
|
+
: type.name;
|
|
138
|
+
|
|
139
|
+
let text = `select constraint_name
|
|
140
|
+
from information_schema.constraint_column_usage
|
|
141
|
+
where table_name = $1 and constraint_name = $2 `;
|
|
142
|
+
|
|
143
|
+
const values = [type.name, constraint.name];
|
|
144
|
+
|
|
145
|
+
if(type.schema) {
|
|
146
|
+
text += " and schema_name = $3";
|
|
147
|
+
values.push(type.schema);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const driver = context.connection;
|
|
151
|
+
|
|
152
|
+
const r = await driver.executeQuery({ text, values });
|
|
153
|
+
if (r.rows?.length) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name}
|
|
158
|
+
foreign key (${constraint.column.columnName})
|
|
159
|
+
references ${constraint.refColumns[0].entityType.name}(
|
|
160
|
+
${constraint.refColumns.map((x) => x.columnName).join(",")}
|
|
161
|
+
) `;
|
|
162
|
+
|
|
163
|
+
switch(constraint.cascade) {
|
|
164
|
+
case "delete":
|
|
165
|
+
text += " ON DELETE CASCADE";
|
|
166
|
+
break;
|
|
167
|
+
case "set-null":
|
|
168
|
+
text += " ON DELETE SET NULL";
|
|
169
|
+
break;
|
|
170
|
+
case "set-default":
|
|
171
|
+
text += " ON DELETE SET DEFAULT";
|
|
172
|
+
break;
|
|
173
|
+
case "restrict":
|
|
174
|
+
text += " ON DELETE RESTRICT";
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
await driver.executeQuery(text);
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
132
182
|
|
|
133
183
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IColumn } from "../../decorators/IColumn.js";
|
|
2
|
+
import { IForeignKeyConstraint } from "../../decorators/IForeignKeyConstraint.js";
|
|
2
3
|
import { IIndex } from "../../decorators/IIndex.js";
|
|
3
4
|
import { BaseConnection, BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
4
5
|
import { SqlServerLiteral } from "../../drivers/sql-server/SqlServerLiteral.js";
|
|
@@ -136,5 +137,51 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
136
137
|
await driver.executeQuery(query);
|
|
137
138
|
}
|
|
138
139
|
|
|
140
|
+
async migrateForeignKey(context: EntityContext, constraint: IForeignKeyConstraint) {
|
|
141
|
+
const { type } = constraint;
|
|
142
|
+
const name = type.schema
|
|
143
|
+
? type.schema + "." + type.name
|
|
144
|
+
: type.name;
|
|
145
|
+
|
|
146
|
+
let text = `SELECT COUNT(*)
|
|
147
|
+
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
|
|
148
|
+
WHERE TABLE_NAME='${type.name}'
|
|
149
|
+
AND CONSTRAINT_NAME='${constraint.name}'
|
|
150
|
+
AND CONSTRAINT_TYPE='FOREIGN KEY'`;
|
|
151
|
+
|
|
152
|
+
if(type.schema) {
|
|
153
|
+
text += ` and schema_name = ${type.schema}`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const driver = context.connection;
|
|
157
|
+
|
|
158
|
+
const r = await driver.executeQuery(text);
|
|
159
|
+
if (r.rows?.length) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
text = `ALTER TABLE ${name} ADD CONSTRAINT ${constraint.name}
|
|
164
|
+
foreign key (${constraint.column.columnName})
|
|
165
|
+
references ${constraint.refColumns[0].entityType.name}(
|
|
166
|
+
${constraint.refColumns.map((x) => x.columnName).join(",")}
|
|
167
|
+
) `;
|
|
168
|
+
|
|
169
|
+
switch(constraint.cascade) {
|
|
170
|
+
case "delete":
|
|
171
|
+
text += " ON DELETE CASCADE";
|
|
172
|
+
break;
|
|
173
|
+
case "set-null":
|
|
174
|
+
text += " ON DELETE SET NULL";
|
|
175
|
+
break;
|
|
176
|
+
case "set-default":
|
|
177
|
+
text += " ON DELETE SET DEFAULT";
|
|
178
|
+
break;
|
|
179
|
+
case "restrict":
|
|
180
|
+
text += " ON DELETE RESTRICT";
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
await driver.executeQuery(text);
|
|
185
|
+
}
|
|
139
186
|
|
|
140
187
|
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import type EntityContext from "./EntityContext.js";
|
|
2
2
|
import type EntityType from "../entity-query/EntityType.js";
|
|
3
3
|
import type { IEntityQuery, IFilterExpression } from "./IFilterWithParameter.js";
|
|
4
|
-
import { Expression } from "../query/ast/Expressions.js";
|
|
5
4
|
import EntityQuery from "./EntityQuery.js";
|
|
6
5
|
import { contextSymbol, modelSymbol } from "../common/symbols/symbols.js";
|
|
6
|
+
import { Expression } from "../query/ast/Expressions.js";
|
|
7
7
|
|
|
8
8
|
export class EntitySource<T = any> {
|
|
9
9
|
|
|
10
|
+
public statements = {
|
|
11
|
+
|
|
12
|
+
};
|
|
13
|
+
|
|
10
14
|
get [modelSymbol]() {
|
|
11
15
|
return this.model;
|
|
12
16
|
}
|
|
@@ -17,6 +21,7 @@ export class EntitySource<T = any> {
|
|
|
17
21
|
|
|
18
22
|
private filter: Expression;
|
|
19
23
|
|
|
24
|
+
|
|
20
25
|
constructor(
|
|
21
26
|
private readonly model: EntityType,
|
|
22
27
|
private readonly context: EntityContext
|
|
@@ -24,6 +29,13 @@ export class EntitySource<T = any> {
|
|
|
24
29
|
|
|
25
30
|
}
|
|
26
31
|
|
|
32
|
+
public async saveDirect(item: Partial<T>, mode: "update" | "upsert" | "insert") {
|
|
33
|
+
const { driver } = this.context;
|
|
34
|
+
const expression = driver.createUpsertExpression(this.model, item, mode);
|
|
35
|
+
const { text, values } = driver.compiler.compileExpression(null, expression);
|
|
36
|
+
await this.context.connection.executeQuery({ text, values });
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
public add(item: Partial<T>): T {
|
|
28
40
|
const p = Object.getPrototypeOf(item).constructor;
|
|
29
41
|
if (!p || p === Object) {
|