@entity-access/entity-access 1.0.95 → 1.0.96
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/.vscode/launch.json +3 -0
- package/dist/compiler/QueryCompiler.d.ts +2 -0
- package/dist/compiler/QueryCompiler.d.ts.map +1 -1
- package/dist/compiler/QueryCompiler.js +6 -0
- package/dist/compiler/QueryCompiler.js.map +1 -1
- package/dist/compiler/RawQuery.d.ts +10 -0
- package/dist/compiler/RawQuery.d.ts.map +1 -0
- package/dist/compiler/RawQuery.js +26 -0
- package/dist/compiler/RawQuery.js.map +1 -0
- package/dist/compiler/postgres/PostgreSqlMethodTransformer.d.ts.map +1 -1
- package/dist/compiler/postgres/PostgreSqlMethodTransformer.js +3 -0
- package/dist/compiler/postgres/PostgreSqlMethodTransformer.js.map +1 -1
- package/dist/compiler/sql-server/SqlServerSqlMethodTransformer.d.ts.map +1 -1
- package/dist/compiler/sql-server/SqlServerSqlMethodTransformer.js +9 -6
- package/dist/compiler/sql-server/SqlServerSqlMethodTransformer.js.map +1 -1
- package/dist/drivers/base/BaseDriver.d.ts +15 -8
- package/dist/drivers/base/BaseDriver.d.ts.map +1 -1
- package/dist/drivers/base/BaseDriver.js +13 -3
- package/dist/drivers/base/BaseDriver.js.map +1 -1
- package/dist/drivers/postgres/PostgreSqlDriver.d.ts +2 -12
- package/dist/drivers/postgres/PostgreSqlDriver.d.ts.map +1 -1
- package/dist/drivers/postgres/PostgreSqlDriver.js +11 -2
- package/dist/drivers/postgres/PostgreSqlDriver.js.map +1 -1
- package/dist/drivers/sql-server/SqlServerDriver.d.ts +8 -2
- package/dist/drivers/sql-server/SqlServerDriver.d.ts.map +1 -1
- package/dist/drivers/sql-server/SqlServerDriver.js +18 -10
- package/dist/drivers/sql-server/SqlServerDriver.js.map +1 -1
- package/dist/eternity/ActivitySuspendedError.d.ts +3 -0
- package/dist/eternity/ActivitySuspendedError.d.ts.map +1 -1
- package/dist/eternity/ActivitySuspendedError.js +6 -0
- package/dist/eternity/ActivitySuspendedError.js.map +1 -1
- package/dist/eternity/EternityContext.d.ts +3 -1
- package/dist/eternity/EternityContext.d.ts.map +1 -1
- package/dist/eternity/EternityContext.js +54 -6
- package/dist/eternity/EternityContext.js.map +1 -1
- package/dist/eternity/EternityStorage.d.ts +6 -0
- package/dist/eternity/EternityStorage.d.ts.map +1 -1
- package/dist/eternity/EternityStorage.js +60 -19
- package/dist/eternity/EternityStorage.js.map +1 -1
- package/dist/eternity/Workflow.d.ts +15 -4
- package/dist/eternity/Workflow.d.ts.map +1 -1
- package/dist/eternity/Workflow.js +35 -22
- package/dist/eternity/Workflow.js.map +1 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts +3 -3
- package/dist/migrations/postgres/PostgresAutomaticMigrations.d.ts.map +1 -1
- package/dist/migrations/postgres/PostgresAutomaticMigrations.js +2 -2
- package/dist/migrations/postgres/PostgresAutomaticMigrations.js.map +1 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts +3 -3
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.d.ts.map +1 -1
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js +2 -2
- package/dist/migrations/sql-server/SqlServerAutomaticMigrations.js.map +1 -1
- package/dist/model/EntityContext.d.ts +3 -1
- package/dist/model/EntityContext.d.ts.map +1 -1
- package/dist/model/EntityContext.js +6 -2
- package/dist/model/EntityContext.js.map +1 -1
- package/dist/model/EntityQuery.js +3 -3
- package/dist/model/EntityQuery.js.map +1 -1
- package/dist/model/verification/VerificationSession.js +1 -1
- package/dist/model/verification/VerificationSession.js.map +1 -1
- package/dist/query/ast/ExpressionToSql.d.ts.map +1 -1
- package/dist/query/ast/ExpressionToSql.js +21 -19
- package/dist/query/ast/ExpressionToSql.js.map +1 -1
- package/dist/query/ast/Expressions.d.ts +1 -0
- package/dist/query/ast/Expressions.d.ts.map +1 -1
- package/dist/query/ast/Expressions.js +3 -0
- package/dist/query/ast/Expressions.js.map +1 -1
- package/dist/sql/ISql.d.ts +2 -0
- package/dist/sql/ISql.d.ts.map +1 -1
- package/dist/tests/drivers/postgres/connection-test.js +1 -1
- package/dist/tests/drivers/postgres/connection-test.js.map +1 -1
- package/dist/tests/eternity/child-tests.d.ts +3 -0
- package/dist/tests/eternity/child-tests.d.ts.map +1 -0
- package/dist/tests/eternity/child-tests.js +103 -0
- package/dist/tests/eternity/child-tests.js.map +1 -0
- package/dist/tests/eternity/eternity-tests.d.ts.map +1 -1
- package/dist/tests/eternity/eternity-tests.js.map +1 -1
- package/dist/tests/model/createContext.js +2 -2
- package/dist/tests/model/createContext.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/compiler/QueryCompiler.ts +7 -0
- package/src/compiler/RawQuery.ts +29 -0
- package/src/compiler/postgres/PostgreSqlMethodTransformer.ts +3 -0
- package/src/compiler/sql-server/SqlServerSqlMethodTransformer.ts +9 -6
- package/src/drivers/base/BaseDriver.ts +28 -10
- package/src/drivers/postgres/PostgreSqlDriver.ts +15 -2
- package/src/drivers/sql-server/SqlServerDriver.ts +21 -11
- package/src/eternity/ActivitySuspendedError.ts +8 -1
- package/src/eternity/EternityContext.ts +69 -6
- package/src/eternity/EternityStorage.ts +79 -19
- package/src/eternity/Workflow.ts +51 -11
- package/src/migrations/postgres/PostgresAutomaticMigrations.ts +5 -5
- package/src/migrations/sql-server/SqlServerAutomaticMigrations.ts +5 -5
- package/src/model/EntityContext.ts +9 -3
- package/src/model/EntityQuery.ts +3 -3
- package/src/model/verification/VerificationSession.ts +1 -1
- package/src/query/ast/ExpressionToSql.ts +22 -20
- package/src/query/ast/Expressions.ts +4 -0
- package/src/sql/ISql.ts +3 -0
- package/src/tests/drivers/postgres/connection-test.ts +1 -1
- package/src/tests/eternity/child-tests.ts +119 -0
- package/src/tests/eternity/eternity-tests.ts +1 -0
- package/src/tests/model/createContext.ts +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IColumn } from "../../decorators/IColumn.js";
|
|
2
2
|
import { IIndex } from "../../decorators/IIndex.js";
|
|
3
|
-
import { BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
3
|
+
import { BaseConnection, BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
4
4
|
import { SqlServerLiteral } from "../../drivers/sql-server/SqlServerLiteral.js";
|
|
5
5
|
import EntityType from "../../entity-query/EntityType.js";
|
|
6
6
|
import EntityContext from "../../model/EntityContext.js";
|
|
@@ -16,7 +16,7 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
16
16
|
const nonKeyColumns = type.nonKeys;
|
|
17
17
|
const keys = type.keys;
|
|
18
18
|
|
|
19
|
-
const driver = context.
|
|
19
|
+
const driver = context.connection;
|
|
20
20
|
|
|
21
21
|
await this.createTable(driver, type, keys);
|
|
22
22
|
|
|
@@ -43,7 +43,7 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
async createColumns(driver:
|
|
46
|
+
async createColumns(driver: BaseConnection, type: EntityType, nonKeyColumns: IColumn[]) {
|
|
47
47
|
|
|
48
48
|
const name = type.schema
|
|
49
49
|
? type.schema + "." + type.name
|
|
@@ -70,7 +70,7 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
70
70
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
async createTable(driver:
|
|
73
|
+
async createTable(driver: BaseConnection, type: EntityType, keys: IColumn[]) {
|
|
74
74
|
|
|
75
75
|
const name = type.schema
|
|
76
76
|
? type.schema + "." + type.name
|
|
@@ -102,7 +102,7 @@ export default class SqlServerAutomaticMigrations extends SqlServerMigrations {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
async migrateIndex(context: EntityContext, index: IIndex, type: EntityType) {
|
|
105
|
-
const driver = context.
|
|
105
|
+
const driver = context.connection;
|
|
106
106
|
const name = type.schema
|
|
107
107
|
? type.schema + "." + type.name
|
|
108
108
|
: type.name;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseDriver } from "../drivers/base/BaseDriver.js";
|
|
1
|
+
import { BaseConnection, BaseDriver } from "../drivers/base/BaseDriver.js";
|
|
2
2
|
import ChangeSet from "./changes/ChangeSet.js";
|
|
3
3
|
import EntityModel from "./EntityModel.js";
|
|
4
4
|
import { Expression } from "../query/ast/Expressions.js";
|
|
@@ -28,8 +28,14 @@ export default class EntityContext {
|
|
|
28
28
|
return this[isChanging];
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
public get connection() {
|
|
32
|
+
return this._connection ??= this.driver.newConnection();
|
|
33
|
+
}
|
|
34
|
+
|
|
31
35
|
private postSaveChangesQueue: { task: () => any, order: number }[];
|
|
32
36
|
|
|
37
|
+
private _connection: BaseConnection;
|
|
38
|
+
|
|
33
39
|
constructor(
|
|
34
40
|
@Inject
|
|
35
41
|
public driver: BaseDriver,
|
|
@@ -180,7 +186,7 @@ export default class EntityContext {
|
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
protected async saveChangesWithoutEvents(signal: AbortSignal) {
|
|
183
|
-
return this.
|
|
189
|
+
return this.connection.runInTransaction(async () => {
|
|
184
190
|
const copy = Array.from(this.changeSet.getChanges()) as ChangeEntry[];
|
|
185
191
|
for (const iterator of copy) {
|
|
186
192
|
switch (iterator.status) {
|
|
@@ -212,7 +218,7 @@ export default class EntityContext {
|
|
|
212
218
|
|
|
213
219
|
private async executeExpression(expression: Expression, signal: AbortSignal) {
|
|
214
220
|
const { text, values } = this.driver.compiler.compileExpression(null, expression);
|
|
215
|
-
const r = await this.
|
|
221
|
+
const r = await this.connection.executeQuery({ text, values }, signal);
|
|
216
222
|
return r.rows?.[0];
|
|
217
223
|
}
|
|
218
224
|
|
package/src/model/EntityQuery.ts
CHANGED
|
@@ -93,7 +93,7 @@ export default class EntityQuery<T = any>
|
|
|
93
93
|
signal?.throwIfAborted();
|
|
94
94
|
|
|
95
95
|
query = this.context.driver.compiler.compileExpression(this, this.selectStatement);
|
|
96
|
-
const reader = await this.context.
|
|
96
|
+
const reader = await this.context.connection.executeReader(query, signal);
|
|
97
97
|
scope.register(reader);
|
|
98
98
|
for await (const iterator of reader.next(10, signal)) {
|
|
99
99
|
if (type) {
|
|
@@ -120,7 +120,7 @@ export default class EntityQuery<T = any>
|
|
|
120
120
|
let reader: IDbReader;
|
|
121
121
|
try {
|
|
122
122
|
query = this.context.driver.compiler.compileExpression(this, select);
|
|
123
|
-
reader = await this.context.
|
|
123
|
+
reader = await this.context.connection.executeReader(query, signal);
|
|
124
124
|
for await (const iterator of reader.next(10, signal)) {
|
|
125
125
|
const item = select.model?.map(iterator) ?? iterator;
|
|
126
126
|
const entry = this.context.changeSet.getEntry(item, item);
|
|
@@ -200,7 +200,7 @@ export default class EntityQuery<T = any>
|
|
|
200
200
|
let query;
|
|
201
201
|
try {
|
|
202
202
|
query = this.context.driver.compiler.compileExpression(nq, select);
|
|
203
|
-
const reader = await this.context.
|
|
203
|
+
const reader = await this.context.connection.executeReader(query);
|
|
204
204
|
scope.register(reader);
|
|
205
205
|
for await (const iterator of reader.next()) {
|
|
206
206
|
return iterator.c1 as number;
|
|
@@ -152,7 +152,7 @@ export default class VerificationSession {
|
|
|
152
152
|
const logger = ServiceProvider.resolve(this.context, Logger);
|
|
153
153
|
const session = logger.newSession();
|
|
154
154
|
try {
|
|
155
|
-
const { rows: [ { error }]} = await this.context.
|
|
155
|
+
const { rows: [ { error }]} = await this.context.connection.executeQuery(query);
|
|
156
156
|
if (error) {
|
|
157
157
|
session.error(`Failed executing ${query.text}\n[${query.values.join(",")}]\n${error?.stack ?? error}`);
|
|
158
158
|
EntityAccessError.throw(error);
|
|
@@ -239,7 +239,7 @@ export default class ExpressionToSql extends Visitor<ITextQuery> {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
if (identifier?.value === "Sql") {
|
|
242
|
-
const argList = e.arguments
|
|
242
|
+
const argList = e.arguments?.map((x) => this.visit(x)) ?? [];
|
|
243
243
|
const transformedCallee = this.compiler.sqlMethodTransformer(this.compiler, chain, argList as any[]);
|
|
244
244
|
if (transformedCallee) {
|
|
245
245
|
return prepare `${transformedCallee}`;
|
|
@@ -269,27 +269,29 @@ export default class ExpressionToSql extends Visitor<ITextQuery> {
|
|
|
269
269
|
const propertyChain = this.getPropertyChain(me);
|
|
270
270
|
if (propertyChain) {
|
|
271
271
|
const { parameter, identifier, chain } = propertyChain;
|
|
272
|
-
if (parameter
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
272
|
+
if (parameter) {
|
|
273
|
+
if (parameter === this.root) {
|
|
274
|
+
// we have a parameter...
|
|
275
|
+
return [(p) => p[chain[0]]];
|
|
276
|
+
}
|
|
277
|
+
if (parameter.value) {
|
|
278
|
+
const value = parameter.value;
|
|
279
|
+
return [() => value[chain[0]]];
|
|
280
|
+
}
|
|
281
|
+
const scope = this.scope.get(parameter);
|
|
282
|
+
if (scope.isRuntimeParam) {
|
|
283
|
+
return [(p) => p[chain[0]]];
|
|
284
|
+
}
|
|
285
|
+
const name = this.scope.nameOf(parameter);
|
|
285
286
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
287
|
+
// need to change name as per naming convention here...
|
|
288
|
+
const namingConvention = this.compiler.namingConvention;
|
|
289
|
+
if (scope.model && namingConvention) {
|
|
290
|
+
chain[0] = namingConvention(chain[0]);
|
|
291
|
+
}
|
|
291
292
|
|
|
292
|
-
|
|
293
|
+
return [ QueryParameter.create(() => name) , "." , chain.join(".")];
|
|
294
|
+
}
|
|
293
295
|
}
|
|
294
296
|
|
|
295
297
|
const { target, computed, property } = me;
|
|
@@ -73,6 +73,10 @@ export abstract class Expression {
|
|
|
73
73
|
return BinaryExpression.create({ left, right, operator: "="});
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
static assign(left: Expression, right: Expression) {
|
|
77
|
+
return BinaryExpression.create({ left, right, operator: "="});
|
|
78
|
+
}
|
|
79
|
+
|
|
76
80
|
static create<T extends Expression>(this: IClassOf<T>, p: Partial<Omit<T, "type">>) {
|
|
77
81
|
(p as any).type = (this as any).name;
|
|
78
82
|
Object.setPrototypeOf(p, this.prototype);
|
package/src/sql/ISql.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import DateTime from "../types/DateTime.js";
|
|
2
|
+
|
|
1
3
|
export interface ISql {
|
|
2
4
|
|
|
3
5
|
in<T>(a: T, array: T[]): boolean;
|
|
@@ -55,6 +57,7 @@ export interface ISql {
|
|
|
55
57
|
},
|
|
56
58
|
|
|
57
59
|
date: {
|
|
60
|
+
now(): DateTime,
|
|
58
61
|
yearOf(d: Date): number;
|
|
59
62
|
monthOf(d: Date): number;
|
|
60
63
|
dayOf(d: Date): number;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import Inject, { Register, RegisterSingleton, ServiceProvider } from "../../di/di.js";
|
|
3
|
+
import EternityContext from "../../eternity/EternityContext.js";
|
|
4
|
+
import Workflow, { Activity, UniqueActivity } from "../../eternity/Workflow.js";
|
|
5
|
+
import WorkflowClock from "../../eternity/WorkflowClock.js";
|
|
6
|
+
import DateTime from "../../types/DateTime.js";
|
|
7
|
+
import { TestConfig } from "../TestConfig.js";
|
|
8
|
+
import { BaseDriver } from "../../drivers/base/BaseDriver.js";
|
|
9
|
+
import EternityStorage from "../../eternity/EternityStorage.js";
|
|
10
|
+
import TimeSpan from "../../types/TimeSpan.js";
|
|
11
|
+
import sleep from "../../common/sleep.js";
|
|
12
|
+
|
|
13
|
+
class MockClock extends WorkflowClock {
|
|
14
|
+
|
|
15
|
+
public get utcNow(): DateTime {
|
|
16
|
+
return this.time;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public set utcNow(v: DateTime) {
|
|
20
|
+
this.time = v;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private time: DateTime = DateTime.utcNow;
|
|
24
|
+
|
|
25
|
+
public add(ts: TimeSpan) {
|
|
26
|
+
this.time = this.time.add(ts);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@RegisterSingleton
|
|
32
|
+
class CallTracker {
|
|
33
|
+
track: number = 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class ChildWorkflow extends Workflow<[string, string], string> {
|
|
37
|
+
|
|
38
|
+
async run() {
|
|
39
|
+
await this.delay(TimeSpan.fromSeconds(30));
|
|
40
|
+
return await this.add("Name:", this.input);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@UniqueActivity
|
|
44
|
+
async add(a: string, b: string[], @Inject tracker?: CallTracker) {
|
|
45
|
+
tracker.track++;
|
|
46
|
+
return a + " " + b.join(" ");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class ParentWorkflow extends Workflow<string, string> {
|
|
51
|
+
|
|
52
|
+
public async run(): Promise<any> {
|
|
53
|
+
const all = await this.all([
|
|
54
|
+
this.runChild(ChildWorkflow, [this.input, "1"]),
|
|
55
|
+
this.runChild(ChildWorkflow, [this.input, "2"])
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
return all.join(",");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default async function(this: TestConfig) {
|
|
64
|
+
|
|
65
|
+
const mockClock = new MockClock();
|
|
66
|
+
|
|
67
|
+
const tracker = new CallTracker();
|
|
68
|
+
|
|
69
|
+
const scope = new ServiceProvider();
|
|
70
|
+
scope.add(WorkflowClock, mockClock);
|
|
71
|
+
scope.add(BaseDriver, this.driver);
|
|
72
|
+
scope.add(CallTracker, tracker);
|
|
73
|
+
const storage = new EternityStorage(this.driver, mockClock);
|
|
74
|
+
scope.add(EternityStorage, storage);
|
|
75
|
+
|
|
76
|
+
const c = new EternityContext(storage);
|
|
77
|
+
scope.add(EternityContext, c);
|
|
78
|
+
|
|
79
|
+
// this is an important step
|
|
80
|
+
c.register(ChildWorkflow);
|
|
81
|
+
c.register(ParentWorkflow);
|
|
82
|
+
|
|
83
|
+
await storage.seed();
|
|
84
|
+
|
|
85
|
+
const id = await c.queue(ParentWorkflow, "a");
|
|
86
|
+
|
|
87
|
+
mockClock.add(TimeSpan.fromSeconds(15));
|
|
88
|
+
|
|
89
|
+
await c.processQueueOnce();
|
|
90
|
+
|
|
91
|
+
assert.equal(0, tracker.track);
|
|
92
|
+
|
|
93
|
+
mockClock.add(TimeSpan.fromSeconds(20));
|
|
94
|
+
|
|
95
|
+
await c.processQueueOnce();
|
|
96
|
+
|
|
97
|
+
mockClock.add(TimeSpan.fromSeconds(20));
|
|
98
|
+
|
|
99
|
+
await c.processQueueOnce();
|
|
100
|
+
|
|
101
|
+
mockClock.add(TimeSpan.fromSeconds(20));
|
|
102
|
+
|
|
103
|
+
await c.processQueueOnce();
|
|
104
|
+
|
|
105
|
+
assert.notEqual(0, tracker.track);
|
|
106
|
+
|
|
107
|
+
await c.processQueueOnce();
|
|
108
|
+
|
|
109
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
110
|
+
|
|
111
|
+
await c.processQueueOnce();
|
|
112
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
113
|
+
await c.processQueueOnce();
|
|
114
|
+
mockClock.add(TimeSpan.fromSeconds(5));
|
|
115
|
+
await c.processQueueOnce();
|
|
116
|
+
|
|
117
|
+
const r = await storage.get(id);
|
|
118
|
+
assert.equal("done", r.state);
|
|
119
|
+
}
|
|
@@ -11,9 +11,9 @@ export async function createContext(driver: BaseDriver) {
|
|
|
11
11
|
Object.setPrototypeOf(copy, Object.getPrototypeOf(driver));
|
|
12
12
|
const context = new ShoppingContext(copy);
|
|
13
13
|
|
|
14
|
-
await context.
|
|
14
|
+
await context.connection.ensureDatabase();
|
|
15
15
|
|
|
16
|
-
await context.
|
|
16
|
+
await context.connection.automaticMigrations().migrate(context);
|
|
17
17
|
|
|
18
18
|
await seed(context);
|
|
19
19
|
|