@dbos-inc/typeorm-datasource 3.4.8-preview → 3.4.9-preview
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/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -24
- package/dist/index.js.map +1 -1
- package/index.ts +55 -25
- package/package.json +1 -1
- package/tests/demoentities/Photo.ts +14 -0
- package/tests/demoentities/User.ts +14 -0
- package/tests/usersuppliedds.test.ts +75 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PoolConfig } from 'pg';
|
|
2
2
|
import { FunctionName } from '@dbos-inc/dbos-sdk';
|
|
3
3
|
import { DBOSDataSource, PGTransactionConfig } from '@dbos-inc/dbos-sdk/datasource';
|
|
4
|
-
import { EntityManager } from 'typeorm';
|
|
4
|
+
import { DataSource, EntityManager } from 'typeorm';
|
|
5
5
|
export interface TypeORMTransactionConfig extends PGTransactionConfig {
|
|
6
6
|
name?: string;
|
|
7
7
|
}
|
|
@@ -11,7 +11,12 @@ export declare class TypeOrmDataSource implements DBOSDataSource<TypeORMTransact
|
|
|
11
11
|
static get entityManager(): EntityManager;
|
|
12
12
|
get entityManager(): EntityManager;
|
|
13
13
|
static initializeDBOSSchema(config: PoolConfig): Promise<void>;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated - For readability, use `createFromConfig` or `createFromDataSource`
|
|
16
|
+
*/
|
|
17
|
+
constructor(name: string, config?: PoolConfig, entities?: Function[], dataSource?: DataSource);
|
|
18
|
+
static createFromConfig(name: string, config: PoolConfig, entities: Function[]): TypeOrmDataSource;
|
|
19
|
+
static createFromDataSource(name: string, ds: DataSource): TypeOrmDataSource;
|
|
15
20
|
/**
|
|
16
21
|
* Run `func` as a transaction against this DataSource
|
|
17
22
|
* @param func Function to run within a transactional context
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAmC,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAQL,cAAc,EAEd,mBAAmB,EAGpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAmC,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAQL,cAAc,EAEd,mBAAmB,EAGpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIpD,MAAM,WAAW,wBAAyB,SAAQ,mBAAmB;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAyOD,qBAAa,iBAAkB,YAAW,cAAc,CAAC,wBAAwB,CAAC;;IAyC9E,QAAQ,CAAC,IAAI,EAAE,MAAM;IAxBvB,MAAM,KAAK,aAAa,kBAEvB;IAED,IAAI,aAAa,kBAEhB;WAEY,oBAAoB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpE;;OAEG;gBAEQ,IAAI,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,UAAU,EAEnB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EACrB,UAAU,CAAC,EAAE,UAAU;IAezB,MAAM,CAAC,gBAAgB,CACrB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,UAAU,EAElB,QAAQ,EAAE,QAAQ,EAAE;IAKtB,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU;IAIxD;;;;;;OAMG;IACG,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,wBAAwB;IAIjF;;;;;;;;OAQG;IACH,mBAAmB,CAAC,IAAI,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,MAAM,EACtD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EACpD,MAAM,CAAC,EAAE,wBAAwB,GAAG,YAAY,GAC/C,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;IAIjD;;OAEG;IACH,WAAW,CAAC,MAAM,CAAC,EAAE,wBAAwB,kDAIjC,MAAM,eACD,WAAW,cACZ,wBAAwB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,oCAAxC,IAAI,WAAW,IAAI,KAAK,QAAQ,MAAM,CAAC;CAevF"}
|
package/dist/index.js
CHANGED
|
@@ -11,16 +11,18 @@ class TypeOrmTransactionHandler {
|
|
|
11
11
|
name;
|
|
12
12
|
config;
|
|
13
13
|
entities;
|
|
14
|
+
providedDataSource;
|
|
14
15
|
dsType = 'TypeOrm';
|
|
15
|
-
#
|
|
16
|
+
#createdDataSource;
|
|
16
17
|
constructor(name, config,
|
|
17
18
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
18
|
-
entities) {
|
|
19
|
+
entities, providedDataSource) {
|
|
19
20
|
this.name = name;
|
|
20
21
|
this.config = config;
|
|
21
22
|
this.entities = entities;
|
|
23
|
+
this.providedDataSource = providedDataSource;
|
|
22
24
|
}
|
|
23
|
-
static async
|
|
25
|
+
static async createDataSource(config,
|
|
24
26
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
25
27
|
entities) {
|
|
26
28
|
const ds = new typeorm_1.DataSource({
|
|
@@ -39,13 +41,22 @@ class TypeOrmTransactionHandler {
|
|
|
39
41
|
await ds.initialize();
|
|
40
42
|
return ds;
|
|
41
43
|
}
|
|
44
|
+
get dataSource() {
|
|
45
|
+
const ds = this.providedDataSource ?? this.#createdDataSource;
|
|
46
|
+
if (!ds) {
|
|
47
|
+
throw new Error(`DataSource ${this.name} is not initialized.`);
|
|
48
|
+
}
|
|
49
|
+
return ds;
|
|
50
|
+
}
|
|
42
51
|
async initialize() {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
52
|
+
if (!this.providedDataSource) {
|
|
53
|
+
const ds = this.#createdDataSource;
|
|
54
|
+
this.#createdDataSource = await TypeOrmTransactionHandler.createDataSource(this.config, this.entities);
|
|
55
|
+
await ds?.destroy();
|
|
56
|
+
}
|
|
46
57
|
let installed = false;
|
|
47
58
|
try {
|
|
48
|
-
const res = await this
|
|
59
|
+
const res = await this.dataSource.query(datasource_1.checkSchemaInstallationPG);
|
|
49
60
|
installed = !!res[0]?.schema_exists && !!res[0]?.table_exists;
|
|
50
61
|
}
|
|
51
62
|
catch (e) {
|
|
@@ -54,8 +65,8 @@ class TypeOrmTransactionHandler {
|
|
|
54
65
|
// Install
|
|
55
66
|
if (!installed) {
|
|
56
67
|
try {
|
|
57
|
-
await this
|
|
58
|
-
await this
|
|
68
|
+
await this.dataSource.query(datasource_1.createTransactionCompletionSchemaPG);
|
|
69
|
+
await this.dataSource.query(datasource_1.createTransactionCompletionTablePG);
|
|
59
70
|
}
|
|
60
71
|
catch (err) {
|
|
61
72
|
throw new Error(`In initialization of 'TypeOrmDataSource' ${this.name}: The 'dbos.transaction_completion' table does not exist, and could not be created. This should be added to your database migrations.
|
|
@@ -64,18 +75,12 @@ class TypeOrmTransactionHandler {
|
|
|
64
75
|
}
|
|
65
76
|
}
|
|
66
77
|
async destroy() {
|
|
67
|
-
const ds = this.#
|
|
68
|
-
this.#
|
|
78
|
+
const ds = this.#createdDataSource;
|
|
79
|
+
this.#createdDataSource = undefined;
|
|
69
80
|
await ds?.destroy();
|
|
70
81
|
}
|
|
71
|
-
get #dataSource() {
|
|
72
|
-
if (!this.#dataSourceField) {
|
|
73
|
-
throw new Error(`DataSource ${this.name} is not initialized.`);
|
|
74
|
-
}
|
|
75
|
-
return this.#dataSourceField;
|
|
76
|
-
}
|
|
77
82
|
async #checkExecution(workflowID, stepID) {
|
|
78
|
-
const rows = await this
|
|
83
|
+
const rows = await this.dataSource.query(`SELECT output, error FROM dbos.transaction_completion
|
|
79
84
|
WHERE workflow_id=$1 AND function_num=$2;`, [workflowID, stepID]);
|
|
80
85
|
if (rows.length !== 1) {
|
|
81
86
|
return undefined;
|
|
@@ -102,7 +107,7 @@ class TypeOrmTransactionHandler {
|
|
|
102
107
|
}
|
|
103
108
|
async #recordError(workflowID, stepID, error) {
|
|
104
109
|
try {
|
|
105
|
-
await this
|
|
110
|
+
await this.dataSource.query(`INSERT INTO dbos.transaction_completion (workflow_id, function_num, error)
|
|
106
111
|
VALUES ($1, $2, $3)`, [workflowID, stepID, error]);
|
|
107
112
|
}
|
|
108
113
|
catch (error) {
|
|
@@ -139,7 +144,7 @@ class TypeOrmTransactionHandler {
|
|
|
139
144
|
return (previousResult.output ? superjson_1.SuperJSON.parse(previousResult.output) : null);
|
|
140
145
|
}
|
|
141
146
|
try {
|
|
142
|
-
const result = await this
|
|
147
|
+
const result = await this.dataSource.transaction(isolationLevel, async (entityManager) => {
|
|
143
148
|
if (readOnly) {
|
|
144
149
|
await entityManager.query('SET TRANSACTION READ ONLY');
|
|
145
150
|
}
|
|
@@ -196,7 +201,7 @@ class TypeOrmDataSource {
|
|
|
196
201
|
return TypeOrmDataSource.#getEntityManager(this.#provider);
|
|
197
202
|
}
|
|
198
203
|
static async initializeDBOSSchema(config) {
|
|
199
|
-
const ds = await TypeOrmTransactionHandler.
|
|
204
|
+
const ds = await TypeOrmTransactionHandler.createDataSource(config, []);
|
|
200
205
|
try {
|
|
201
206
|
await ds.query(datasource_1.createTransactionCompletionSchemaPG);
|
|
202
207
|
await ds.query(datasource_1.createTransactionCompletionTablePG);
|
|
@@ -206,12 +211,32 @@ class TypeOrmDataSource {
|
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
213
|
#provider;
|
|
214
|
+
/**
|
|
215
|
+
* @deprecated - For readability, use `createFromConfig` or `createFromDataSource`
|
|
216
|
+
*/
|
|
209
217
|
constructor(name, config,
|
|
210
218
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
211
|
-
entities) {
|
|
219
|
+
entities, dataSource) {
|
|
212
220
|
this.name = name;
|
|
213
|
-
|
|
214
|
-
|
|
221
|
+
if (config && entities) {
|
|
222
|
+
this.#provider = new TypeOrmTransactionHandler(name, config, entities, undefined);
|
|
223
|
+
(0, datasource_1.registerDataSource)(this.#provider);
|
|
224
|
+
}
|
|
225
|
+
else if (dataSource) {
|
|
226
|
+
this.#provider = new TypeOrmTransactionHandler(name, undefined, undefined, dataSource);
|
|
227
|
+
(0, datasource_1.registerDataSource)(this.#provider);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
throw new TypeError('TypeOrmDataSource must be provided with the underlying `DataSource` or with a configuration and entity list');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
static createFromConfig(name, config,
|
|
234
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
235
|
+
entities) {
|
|
236
|
+
return new TypeOrmDataSource(name, config, entities);
|
|
237
|
+
}
|
|
238
|
+
static createFromDataSource(name, ds) {
|
|
239
|
+
return new TypeOrmDataSource(name, undefined, undefined, ds);
|
|
215
240
|
}
|
|
216
241
|
/**
|
|
217
242
|
* Run `func` as a transaction against this DataSource
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AACA,iDAAmF;AACnF,8DAauC;AACvC,qCAAoD;AACpD,6CAAgD;AAChD,yCAAsC;AAWtC,MAAM,aAAa,GAAG,IAAI,+BAAiB,EAAuB,CAAC;AASnE,MAAM,yBAAyB;IAKlB;IACQ;IAEA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/index.ts
CHANGED
|
@@ -38,16 +38,17 @@ interface transaction_completion {
|
|
|
38
38
|
|
|
39
39
|
class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
40
40
|
readonly dsType = 'TypeOrm';
|
|
41
|
-
#
|
|
41
|
+
#createdDataSource: DataSource | undefined;
|
|
42
42
|
|
|
43
43
|
constructor(
|
|
44
44
|
readonly name: string,
|
|
45
|
-
private readonly config
|
|
45
|
+
private readonly config?: PoolConfig,
|
|
46
46
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
47
|
-
private readonly entities
|
|
47
|
+
private readonly entities?: Function[],
|
|
48
|
+
private readonly providedDataSource?: DataSource,
|
|
48
49
|
) {}
|
|
49
50
|
|
|
50
|
-
static async
|
|
51
|
+
static async createDataSource(
|
|
51
52
|
config: PoolConfig,
|
|
52
53
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
53
54
|
entities: Function[],
|
|
@@ -69,14 +70,24 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
69
70
|
return ds;
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
get dataSource(): DataSource {
|
|
74
|
+
const ds = this.providedDataSource ?? this.#createdDataSource;
|
|
75
|
+
if (!ds) {
|
|
76
|
+
throw new Error(`DataSource ${this.name} is not initialized.`);
|
|
77
|
+
}
|
|
78
|
+
return ds;
|
|
79
|
+
}
|
|
80
|
+
|
|
72
81
|
async initialize(): Promise<void> {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
if (!this.providedDataSource) {
|
|
83
|
+
const ds = this.#createdDataSource;
|
|
84
|
+
this.#createdDataSource = await TypeOrmTransactionHandler.createDataSource(this.config!, this.entities!);
|
|
85
|
+
await ds?.destroy();
|
|
86
|
+
}
|
|
76
87
|
|
|
77
88
|
let installed = false;
|
|
78
89
|
try {
|
|
79
|
-
const res = await this
|
|
90
|
+
const res = await this.dataSource.query<CheckSchemaInstallationReturn[]>(checkSchemaInstallationPG);
|
|
80
91
|
installed = !!res[0]?.schema_exists && !!res[0]?.table_exists;
|
|
81
92
|
} catch (e) {
|
|
82
93
|
throw new Error(
|
|
@@ -87,8 +98,8 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
87
98
|
// Install
|
|
88
99
|
if (!installed) {
|
|
89
100
|
try {
|
|
90
|
-
await this
|
|
91
|
-
await this
|
|
101
|
+
await this.dataSource.query(createTransactionCompletionSchemaPG);
|
|
102
|
+
await this.dataSource.query(createTransactionCompletionTablePG);
|
|
92
103
|
} catch (err) {
|
|
93
104
|
throw new Error(
|
|
94
105
|
`In initialization of 'TypeOrmDataSource' ${this.name}: The 'dbos.transaction_completion' table does not exist, and could not be created. This should be added to your database migrations.
|
|
@@ -99,24 +110,17 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
async destroy(): Promise<void> {
|
|
102
|
-
const ds = this.#
|
|
103
|
-
this.#
|
|
113
|
+
const ds = this.#createdDataSource;
|
|
114
|
+
this.#createdDataSource = undefined;
|
|
104
115
|
await ds?.destroy();
|
|
105
116
|
}
|
|
106
117
|
|
|
107
|
-
get #dataSource() {
|
|
108
|
-
if (!this.#dataSourceField) {
|
|
109
|
-
throw new Error(`DataSource ${this.name} is not initialized.`);
|
|
110
|
-
}
|
|
111
|
-
return this.#dataSourceField;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
118
|
async #checkExecution(
|
|
115
119
|
workflowID: string,
|
|
116
120
|
stepID: number,
|
|
117
121
|
): Promise<{ output: string | null } | { error: string } | undefined> {
|
|
118
122
|
type TxOutputRow = Pick<transaction_completion, 'output' | 'error'>;
|
|
119
|
-
const rows = await this
|
|
123
|
+
const rows = await this.dataSource.query<TxOutputRow[]>(
|
|
120
124
|
`SELECT output, error FROM dbos.transaction_completion
|
|
121
125
|
WHERE workflow_id=$1 AND function_num=$2;`,
|
|
122
126
|
[workflowID, stepID],
|
|
@@ -157,7 +161,7 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
157
161
|
|
|
158
162
|
async #recordError(workflowID: string, stepID: number, error: string): Promise<void> {
|
|
159
163
|
try {
|
|
160
|
-
await this
|
|
164
|
+
await this.dataSource.query(
|
|
161
165
|
`INSERT INTO dbos.transaction_completion (workflow_id, function_num, error)
|
|
162
166
|
VALUES ($1, $2, $3)`,
|
|
163
167
|
[workflowID, stepID, error],
|
|
@@ -206,7 +210,7 @@ class TypeOrmTransactionHandler implements DataSourceTransactionHandler {
|
|
|
206
210
|
}
|
|
207
211
|
|
|
208
212
|
try {
|
|
209
|
-
const result = await this
|
|
213
|
+
const result = await this.dataSource.transaction(isolationLevel, async (entityManager: EntityManager) => {
|
|
210
214
|
if (readOnly) {
|
|
211
215
|
await entityManager.query('SET TRANSACTION READ ONLY');
|
|
212
216
|
}
|
|
@@ -275,7 +279,7 @@ export class TypeOrmDataSource implements DBOSDataSource<TypeORMTransactionConfi
|
|
|
275
279
|
}
|
|
276
280
|
|
|
277
281
|
static async initializeDBOSSchema(config: PoolConfig): Promise<void> {
|
|
278
|
-
const ds = await TypeOrmTransactionHandler.
|
|
282
|
+
const ds = await TypeOrmTransactionHandler.createDataSource(config, []);
|
|
279
283
|
try {
|
|
280
284
|
await ds.query(createTransactionCompletionSchemaPG);
|
|
281
285
|
await ds.query(createTransactionCompletionTablePG);
|
|
@@ -286,14 +290,40 @@ export class TypeOrmDataSource implements DBOSDataSource<TypeORMTransactionConfi
|
|
|
286
290
|
|
|
287
291
|
#provider: TypeOrmTransactionHandler;
|
|
288
292
|
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated - For readability, use `createFromConfig` or `createFromDataSource`
|
|
295
|
+
*/
|
|
289
296
|
constructor(
|
|
290
297
|
readonly name: string,
|
|
298
|
+
config?: PoolConfig,
|
|
299
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
300
|
+
entities?: Function[],
|
|
301
|
+
dataSource?: DataSource,
|
|
302
|
+
) {
|
|
303
|
+
if (config && entities) {
|
|
304
|
+
this.#provider = new TypeOrmTransactionHandler(name, config, entities, undefined);
|
|
305
|
+
registerDataSource(this.#provider);
|
|
306
|
+
} else if (dataSource) {
|
|
307
|
+
this.#provider = new TypeOrmTransactionHandler(name, undefined, undefined, dataSource);
|
|
308
|
+
registerDataSource(this.#provider);
|
|
309
|
+
} else {
|
|
310
|
+
throw new TypeError(
|
|
311
|
+
'TypeOrmDataSource must be provided with the underlying `DataSource` or with a configuration and entity list',
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
static createFromConfig(
|
|
317
|
+
name: string,
|
|
291
318
|
config: PoolConfig,
|
|
292
319
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
293
320
|
entities: Function[],
|
|
294
321
|
) {
|
|
295
|
-
|
|
296
|
-
|
|
322
|
+
return new TypeOrmDataSource(name, config, entities);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
static createFromDataSource(name: string, ds: DataSource) {
|
|
326
|
+
return new TypeOrmDataSource(name, undefined, undefined, ds);
|
|
297
327
|
}
|
|
298
328
|
|
|
299
329
|
/**
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
|
|
2
|
+
import { User } from './User';
|
|
3
|
+
|
|
4
|
+
@Entity()
|
|
5
|
+
export class Photo {
|
|
6
|
+
@PrimaryGeneratedColumn()
|
|
7
|
+
id!: number;
|
|
8
|
+
|
|
9
|
+
@Column()
|
|
10
|
+
url!: string;
|
|
11
|
+
|
|
12
|
+
@ManyToOne(() => User, (user) => user.photos)
|
|
13
|
+
user!: User;
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
|
|
2
|
+
import { Photo } from './Photo';
|
|
3
|
+
|
|
4
|
+
@Entity()
|
|
5
|
+
export class User {
|
|
6
|
+
@PrimaryGeneratedColumn()
|
|
7
|
+
id!: number;
|
|
8
|
+
|
|
9
|
+
@Column()
|
|
10
|
+
name!: string;
|
|
11
|
+
|
|
12
|
+
@OneToMany(() => Photo, (photo) => photo.user)
|
|
13
|
+
photos!: Photo[];
|
|
14
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
|
|
3
|
+
import { User } from './demoentities/User';
|
|
4
|
+
import { Photo } from './demoentities/Photo';
|
|
5
|
+
import { DataSource } from 'typeorm';
|
|
6
|
+
|
|
7
|
+
import { TypeOrmDataSource } from '..';
|
|
8
|
+
|
|
9
|
+
import { DBOS } from '@dbos-inc/dbos-sdk';
|
|
10
|
+
import { ensurePGDatabase } from '../../../dist/src/database_utils';
|
|
11
|
+
|
|
12
|
+
const config = { user: process.env.PGUSER || 'postgres', database: 'typeorm_ds_test_datasource' };
|
|
13
|
+
|
|
14
|
+
export const AppDataSource = new DataSource({
|
|
15
|
+
type: 'postgres',
|
|
16
|
+
database: config.database,
|
|
17
|
+
username: config.user,
|
|
18
|
+
synchronize: true, // auto-create schema in dev
|
|
19
|
+
logging: false,
|
|
20
|
+
entities: ['./tests/demoentities/**/*.{ts,js}'], // glob pattern
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const dataSource: TypeOrmDataSource = TypeOrmDataSource.createFromDataSource('appdb', AppDataSource);
|
|
24
|
+
|
|
25
|
+
const workflow = DBOS.registerWorkflow(
|
|
26
|
+
async () => {
|
|
27
|
+
await dataSource.runTransaction(
|
|
28
|
+
async () => {
|
|
29
|
+
const user = dataSource.entityManager.create(User, { name: 'Alice' });
|
|
30
|
+
await dataSource.entityManager.save(user);
|
|
31
|
+
|
|
32
|
+
// attach a photo
|
|
33
|
+
const photo = dataSource.entityManager.create(Photo, { url: 'https://example.com/me.jpg', user });
|
|
34
|
+
await dataSource.entityManager.save(photo);
|
|
35
|
+
},
|
|
36
|
+
{ name: 'insert' },
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const nusers = await dataSource.runTransaction(
|
|
40
|
+
async () => {
|
|
41
|
+
const users = await AppDataSource.getRepository(User).find({
|
|
42
|
+
relations: ['photos'],
|
|
43
|
+
});
|
|
44
|
+
return users.length;
|
|
45
|
+
},
|
|
46
|
+
{ name: 'select' },
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return nusers;
|
|
50
|
+
},
|
|
51
|
+
{ name: 'testTypeOrm' },
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
describe('TypeOrmDataSourceDemo', () => {
|
|
55
|
+
beforeEach(async () => {
|
|
56
|
+
await ensurePGDatabase({
|
|
57
|
+
dbToEnsure: 'typeorm_demo_ds',
|
|
58
|
+
adminUrl: `postgresql://${config.user}:${process.env['PGPASSWORD'] || 'dbos'}@${process.env['PGHOST'] || 'localhost'}:${process.env['PGPORT'] || '5432'}/postgres`,
|
|
59
|
+
});
|
|
60
|
+
await TypeOrmDataSource.initializeDBOSSchema(config);
|
|
61
|
+
await AppDataSource.initialize();
|
|
62
|
+
|
|
63
|
+
DBOS.setConfig({ name: 'typeorm-demo-ds' });
|
|
64
|
+
await DBOS.launch();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(async () => {
|
|
68
|
+
await DBOS.shutdown();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('insert dataSource.register function', async () => {
|
|
72
|
+
const nusers = await workflow();
|
|
73
|
+
expect(nusers).toBe(1);
|
|
74
|
+
});
|
|
75
|
+
});
|