@nest-batch/typeorm 0.2.0
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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/src/adapters/index.d.ts +18 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/src/adapters/index.js +35 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/adapters/typeorm.adapter.d.ts +42 -0
- package/dist/src/adapters/typeorm.adapter.d.ts.map +1 -0
- package/dist/src/adapters/typeorm.adapter.js +85 -0
- package/dist/src/adapters/typeorm.adapter.js.map +1 -0
- package/dist/src/entities/index.d.ts +2 -0
- package/dist/src/entities/index.d.ts.map +1 -0
- package/dist/src/entities/index.js +20 -0
- package/dist/src/entities/index.js.map +1 -0
- package/dist/src/entities/job-meta.entities.d.ts +96 -0
- package/dist/src/entities/job-meta.entities.d.ts.map +1 -0
- package/dist/src/entities/job-meta.entities.js +357 -0
- package/dist/src/entities/job-meta.entities.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +74 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/migrations/1700000000000-CreateBatchMeta.d.ts +28 -0
- package/dist/src/migrations/1700000000000-CreateBatchMeta.d.ts.map +1 -0
- package/dist/src/migrations/1700000000000-CreateBatchMeta.js +83 -0
- package/dist/src/migrations/1700000000000-CreateBatchMeta.js.map +1 -0
- package/dist/src/repository/typeorm-job-repository.d.ts +57 -0
- package/dist/src/repository/typeorm-job-repository.d.ts.map +1 -0
- package/dist/src/repository/typeorm-job-repository.js +489 -0
- package/dist/src/repository/typeorm-job-repository.js.map +1 -0
- package/dist/src/transaction/typeorm-transaction-manager.d.ts +24 -0
- package/dist/src/transaction/typeorm-transaction-manager.d.ts.map +1 -0
- package/dist/src/transaction/typeorm-transaction-manager.js +55 -0
- package/dist/src/transaction/typeorm-transaction-manager.js.map +1 -0
- package/dist/src/typeorm.driver-provider.d.ts +22 -0
- package/dist/src/typeorm.driver-provider.d.ts.map +1 -0
- package/dist/src/typeorm.driver-provider.js +32 -0
- package/dist/src/typeorm.driver-provider.js.map +1 -0
- package/package.json +69 -0
- package/src/adapters/index.ts +17 -0
- package/src/adapters/typeorm.adapter.ts +82 -0
- package/src/entities/index.ts +1 -0
- package/src/entities/job-meta.entities.ts +184 -0
- package/src/index.ts +42 -0
- package/src/migrations/1700000000000-CreateBatchMeta.ts +100 -0
- package/src/repository/typeorm-job-repository.ts +548 -0
- package/src/transaction/typeorm-transaction-manager.ts +47 -0
- package/src/typeorm.driver-provider.ts +23 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get BATCH_META_ENTITIES () {
|
|
13
|
+
return BATCH_META_ENTITIES;
|
|
14
|
+
},
|
|
15
|
+
get JobExecutionContextEntity () {
|
|
16
|
+
return JobExecutionContextEntity;
|
|
17
|
+
},
|
|
18
|
+
get JobExecutionEntity () {
|
|
19
|
+
return JobExecutionEntity;
|
|
20
|
+
},
|
|
21
|
+
get JobInstanceEntity () {
|
|
22
|
+
return JobInstanceEntity;
|
|
23
|
+
},
|
|
24
|
+
get StepExecutionContextEntity () {
|
|
25
|
+
return StepExecutionContextEntity;
|
|
26
|
+
},
|
|
27
|
+
get StepExecutionEntity () {
|
|
28
|
+
return StepExecutionEntity;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const _typeorm = require("typeorm");
|
|
32
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
33
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
34
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
35
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
36
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
37
|
+
}
|
|
38
|
+
function _ts_metadata(k, v) {
|
|
39
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
40
|
+
}
|
|
41
|
+
let JobInstanceEntity = class JobInstanceEntity {
|
|
42
|
+
id;
|
|
43
|
+
jobName;
|
|
44
|
+
jobKey;
|
|
45
|
+
createdAt = new Date();
|
|
46
|
+
};
|
|
47
|
+
_ts_decorate([
|
|
48
|
+
(0, _typeorm.PrimaryColumn)({
|
|
49
|
+
type: 'varchar',
|
|
50
|
+
length: 255
|
|
51
|
+
}),
|
|
52
|
+
_ts_metadata("design:type", String)
|
|
53
|
+
], JobInstanceEntity.prototype, "id", void 0);
|
|
54
|
+
_ts_decorate([
|
|
55
|
+
(0, _typeorm.Column)({
|
|
56
|
+
name: 'job_name',
|
|
57
|
+
type: 'varchar',
|
|
58
|
+
length: 255
|
|
59
|
+
}),
|
|
60
|
+
_ts_metadata("design:type", String)
|
|
61
|
+
], JobInstanceEntity.prototype, "jobName", void 0);
|
|
62
|
+
_ts_decorate([
|
|
63
|
+
(0, _typeorm.Column)({
|
|
64
|
+
name: 'job_key',
|
|
65
|
+
type: 'varchar',
|
|
66
|
+
length: 255
|
|
67
|
+
}),
|
|
68
|
+
_ts_metadata("design:type", String)
|
|
69
|
+
], JobInstanceEntity.prototype, "jobKey", void 0);
|
|
70
|
+
_ts_decorate([
|
|
71
|
+
(0, _typeorm.Column)({
|
|
72
|
+
name: 'created_at',
|
|
73
|
+
// `datetime` is portable across PostgreSQL and SQLite (the test
|
|
74
|
+
// driver). The bundled migration uses timestamptz on
|
|
75
|
+
// PostgreSQL by hand; SQLite loses the timezone qualifier,
|
|
76
|
+
// which is acceptable for a creation-time stamp that is never
|
|
77
|
+
// compared with sub-second precision in queries.
|
|
78
|
+
type: 'datetime',
|
|
79
|
+
default: ()=>'CURRENT_TIMESTAMP'
|
|
80
|
+
}),
|
|
81
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
82
|
+
], JobInstanceEntity.prototype, "createdAt", void 0);
|
|
83
|
+
JobInstanceEntity = _ts_decorate([
|
|
84
|
+
(0, _typeorm.Entity)('batch_job_instance'),
|
|
85
|
+
(0, _typeorm.Index)('batch_job_instance_job_name_job_key_unique', [
|
|
86
|
+
'jobName',
|
|
87
|
+
'jobKey'
|
|
88
|
+
], {
|
|
89
|
+
unique: true
|
|
90
|
+
})
|
|
91
|
+
], JobInstanceEntity);
|
|
92
|
+
let JobExecutionEntity = class JobExecutionEntity {
|
|
93
|
+
id;
|
|
94
|
+
jobInstanceId;
|
|
95
|
+
status;
|
|
96
|
+
startTime = null;
|
|
97
|
+
endTime = null;
|
|
98
|
+
exitCode;
|
|
99
|
+
exitMessage;
|
|
100
|
+
/**
|
|
101
|
+
* JSON-serialized `JobParameters` snapshot. Stored as `text` (not
|
|
102
|
+
* native `jsonb`) so the adapter works uniformly across SQLite (used
|
|
103
|
+
* in unit tests) and PostgreSQL/MySQL — the column is always a
|
|
104
|
+
* serialized payload, never queried by the ORM.
|
|
105
|
+
*/ params;
|
|
106
|
+
};
|
|
107
|
+
_ts_decorate([
|
|
108
|
+
(0, _typeorm.PrimaryColumn)({
|
|
109
|
+
type: 'varchar',
|
|
110
|
+
length: 255
|
|
111
|
+
}),
|
|
112
|
+
_ts_metadata("design:type", String)
|
|
113
|
+
], JobExecutionEntity.prototype, "id", void 0);
|
|
114
|
+
_ts_decorate([
|
|
115
|
+
(0, _typeorm.Column)({
|
|
116
|
+
name: 'job_instance_id',
|
|
117
|
+
type: 'varchar',
|
|
118
|
+
length: 255
|
|
119
|
+
}),
|
|
120
|
+
_ts_metadata("design:type", String)
|
|
121
|
+
], JobExecutionEntity.prototype, "jobInstanceId", void 0);
|
|
122
|
+
_ts_decorate([
|
|
123
|
+
(0, _typeorm.Column)({
|
|
124
|
+
type: 'varchar',
|
|
125
|
+
length: 20
|
|
126
|
+
}),
|
|
127
|
+
_ts_metadata("design:type", String)
|
|
128
|
+
], JobExecutionEntity.prototype, "status", void 0);
|
|
129
|
+
_ts_decorate([
|
|
130
|
+
(0, _typeorm.Column)({
|
|
131
|
+
name: 'start_time',
|
|
132
|
+
type: 'datetime',
|
|
133
|
+
nullable: true
|
|
134
|
+
}),
|
|
135
|
+
_ts_metadata("design:type", Object)
|
|
136
|
+
], JobExecutionEntity.prototype, "startTime", void 0);
|
|
137
|
+
_ts_decorate([
|
|
138
|
+
(0, _typeorm.Column)({
|
|
139
|
+
name: 'end_time',
|
|
140
|
+
type: 'datetime',
|
|
141
|
+
nullable: true
|
|
142
|
+
}),
|
|
143
|
+
_ts_metadata("design:type", Object)
|
|
144
|
+
], JobExecutionEntity.prototype, "endTime", void 0);
|
|
145
|
+
_ts_decorate([
|
|
146
|
+
(0, _typeorm.Column)({
|
|
147
|
+
name: 'exit_code',
|
|
148
|
+
type: 'varchar',
|
|
149
|
+
length: 255,
|
|
150
|
+
default: ''
|
|
151
|
+
}),
|
|
152
|
+
_ts_metadata("design:type", String)
|
|
153
|
+
], JobExecutionEntity.prototype, "exitCode", void 0);
|
|
154
|
+
_ts_decorate([
|
|
155
|
+
(0, _typeorm.Column)({
|
|
156
|
+
name: 'exit_message',
|
|
157
|
+
type: 'text',
|
|
158
|
+
default: ''
|
|
159
|
+
}),
|
|
160
|
+
_ts_metadata("design:type", String)
|
|
161
|
+
], JobExecutionEntity.prototype, "exitMessage", void 0);
|
|
162
|
+
_ts_decorate([
|
|
163
|
+
(0, _typeorm.Column)({
|
|
164
|
+
name: 'params',
|
|
165
|
+
type: 'text',
|
|
166
|
+
default: '{}'
|
|
167
|
+
}),
|
|
168
|
+
_ts_metadata("design:type", String)
|
|
169
|
+
], JobExecutionEntity.prototype, "params", void 0);
|
|
170
|
+
JobExecutionEntity = _ts_decorate([
|
|
171
|
+
(0, _typeorm.Entity)('batch_job_execution'),
|
|
172
|
+
(0, _typeorm.Index)('batch_job_execution_job_instance_id_index', [
|
|
173
|
+
'jobInstanceId'
|
|
174
|
+
])
|
|
175
|
+
], JobExecutionEntity);
|
|
176
|
+
let StepExecutionEntity = class StepExecutionEntity {
|
|
177
|
+
id;
|
|
178
|
+
jobExecutionId;
|
|
179
|
+
stepName;
|
|
180
|
+
status;
|
|
181
|
+
readCount;
|
|
182
|
+
writeCount;
|
|
183
|
+
skipCount;
|
|
184
|
+
rollbackCount;
|
|
185
|
+
commitCount;
|
|
186
|
+
exitCode;
|
|
187
|
+
exitMessage;
|
|
188
|
+
createdAt = new Date();
|
|
189
|
+
};
|
|
190
|
+
_ts_decorate([
|
|
191
|
+
(0, _typeorm.PrimaryColumn)({
|
|
192
|
+
type: 'varchar',
|
|
193
|
+
length: 255
|
|
194
|
+
}),
|
|
195
|
+
_ts_metadata("design:type", String)
|
|
196
|
+
], StepExecutionEntity.prototype, "id", void 0);
|
|
197
|
+
_ts_decorate([
|
|
198
|
+
(0, _typeorm.Column)({
|
|
199
|
+
name: 'job_execution_id',
|
|
200
|
+
type: 'varchar',
|
|
201
|
+
length: 255
|
|
202
|
+
}),
|
|
203
|
+
_ts_metadata("design:type", String)
|
|
204
|
+
], StepExecutionEntity.prototype, "jobExecutionId", void 0);
|
|
205
|
+
_ts_decorate([
|
|
206
|
+
(0, _typeorm.Column)({
|
|
207
|
+
name: 'step_name',
|
|
208
|
+
type: 'varchar',
|
|
209
|
+
length: 255
|
|
210
|
+
}),
|
|
211
|
+
_ts_metadata("design:type", String)
|
|
212
|
+
], StepExecutionEntity.prototype, "stepName", void 0);
|
|
213
|
+
_ts_decorate([
|
|
214
|
+
(0, _typeorm.Column)({
|
|
215
|
+
type: 'varchar',
|
|
216
|
+
length: 20
|
|
217
|
+
}),
|
|
218
|
+
_ts_metadata("design:type", String)
|
|
219
|
+
], StepExecutionEntity.prototype, "status", void 0);
|
|
220
|
+
_ts_decorate([
|
|
221
|
+
(0, _typeorm.Column)({
|
|
222
|
+
name: 'read_count',
|
|
223
|
+
type: 'int',
|
|
224
|
+
default: 0
|
|
225
|
+
}),
|
|
226
|
+
_ts_metadata("design:type", Number)
|
|
227
|
+
], StepExecutionEntity.prototype, "readCount", void 0);
|
|
228
|
+
_ts_decorate([
|
|
229
|
+
(0, _typeorm.Column)({
|
|
230
|
+
name: 'write_count',
|
|
231
|
+
type: 'int',
|
|
232
|
+
default: 0
|
|
233
|
+
}),
|
|
234
|
+
_ts_metadata("design:type", Number)
|
|
235
|
+
], StepExecutionEntity.prototype, "writeCount", void 0);
|
|
236
|
+
_ts_decorate([
|
|
237
|
+
(0, _typeorm.Column)({
|
|
238
|
+
name: 'skip_count',
|
|
239
|
+
type: 'int',
|
|
240
|
+
default: 0
|
|
241
|
+
}),
|
|
242
|
+
_ts_metadata("design:type", Number)
|
|
243
|
+
], StepExecutionEntity.prototype, "skipCount", void 0);
|
|
244
|
+
_ts_decorate([
|
|
245
|
+
(0, _typeorm.Column)({
|
|
246
|
+
name: 'rollback_count',
|
|
247
|
+
type: 'int',
|
|
248
|
+
default: 0
|
|
249
|
+
}),
|
|
250
|
+
_ts_metadata("design:type", Number)
|
|
251
|
+
], StepExecutionEntity.prototype, "rollbackCount", void 0);
|
|
252
|
+
_ts_decorate([
|
|
253
|
+
(0, _typeorm.Column)({
|
|
254
|
+
name: 'commit_count',
|
|
255
|
+
type: 'int',
|
|
256
|
+
default: 0
|
|
257
|
+
}),
|
|
258
|
+
_ts_metadata("design:type", Number)
|
|
259
|
+
], StepExecutionEntity.prototype, "commitCount", void 0);
|
|
260
|
+
_ts_decorate([
|
|
261
|
+
(0, _typeorm.Column)({
|
|
262
|
+
name: 'exit_code',
|
|
263
|
+
type: 'varchar',
|
|
264
|
+
length: 255,
|
|
265
|
+
default: ''
|
|
266
|
+
}),
|
|
267
|
+
_ts_metadata("design:type", String)
|
|
268
|
+
], StepExecutionEntity.prototype, "exitCode", void 0);
|
|
269
|
+
_ts_decorate([
|
|
270
|
+
(0, _typeorm.Column)({
|
|
271
|
+
name: 'exit_message',
|
|
272
|
+
type: 'text',
|
|
273
|
+
default: ''
|
|
274
|
+
}),
|
|
275
|
+
_ts_metadata("design:type", String)
|
|
276
|
+
], StepExecutionEntity.prototype, "exitMessage", void 0);
|
|
277
|
+
_ts_decorate([
|
|
278
|
+
(0, _typeorm.Column)({
|
|
279
|
+
name: 'created_at',
|
|
280
|
+
type: 'datetime',
|
|
281
|
+
default: ()=>'CURRENT_TIMESTAMP'
|
|
282
|
+
}),
|
|
283
|
+
_ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
|
|
284
|
+
], StepExecutionEntity.prototype, "createdAt", void 0);
|
|
285
|
+
StepExecutionEntity = _ts_decorate([
|
|
286
|
+
(0, _typeorm.Entity)('batch_step_execution'),
|
|
287
|
+
(0, _typeorm.Index)('batch_step_execution_job_execution_id_index', [
|
|
288
|
+
'jobExecutionId'
|
|
289
|
+
])
|
|
290
|
+
], StepExecutionEntity);
|
|
291
|
+
let JobExecutionContextEntity = class JobExecutionContextEntity {
|
|
292
|
+
jobExecutionId;
|
|
293
|
+
data;
|
|
294
|
+
version;
|
|
295
|
+
};
|
|
296
|
+
_ts_decorate([
|
|
297
|
+
(0, _typeorm.PrimaryColumn)({
|
|
298
|
+
name: 'job_execution_id',
|
|
299
|
+
type: 'varchar',
|
|
300
|
+
length: 255
|
|
301
|
+
}),
|
|
302
|
+
_ts_metadata("design:type", String)
|
|
303
|
+
], JobExecutionContextEntity.prototype, "jobExecutionId", void 0);
|
|
304
|
+
_ts_decorate([
|
|
305
|
+
(0, _typeorm.Column)({
|
|
306
|
+
type: 'text'
|
|
307
|
+
}),
|
|
308
|
+
_ts_metadata("design:type", String)
|
|
309
|
+
], JobExecutionContextEntity.prototype, "data", void 0);
|
|
310
|
+
_ts_decorate([
|
|
311
|
+
(0, _typeorm.Column)({
|
|
312
|
+
type: 'int',
|
|
313
|
+
default: 0
|
|
314
|
+
}),
|
|
315
|
+
_ts_metadata("design:type", Number)
|
|
316
|
+
], JobExecutionContextEntity.prototype, "version", void 0);
|
|
317
|
+
JobExecutionContextEntity = _ts_decorate([
|
|
318
|
+
(0, _typeorm.Entity)('batch_job_execution_context')
|
|
319
|
+
], JobExecutionContextEntity);
|
|
320
|
+
let StepExecutionContextEntity = class StepExecutionContextEntity {
|
|
321
|
+
stepExecutionId;
|
|
322
|
+
data;
|
|
323
|
+
version;
|
|
324
|
+
};
|
|
325
|
+
_ts_decorate([
|
|
326
|
+
(0, _typeorm.PrimaryColumn)({
|
|
327
|
+
name: 'step_execution_id',
|
|
328
|
+
type: 'varchar',
|
|
329
|
+
length: 255
|
|
330
|
+
}),
|
|
331
|
+
_ts_metadata("design:type", String)
|
|
332
|
+
], StepExecutionContextEntity.prototype, "stepExecutionId", void 0);
|
|
333
|
+
_ts_decorate([
|
|
334
|
+
(0, _typeorm.Column)({
|
|
335
|
+
type: 'text'
|
|
336
|
+
}),
|
|
337
|
+
_ts_metadata("design:type", String)
|
|
338
|
+
], StepExecutionContextEntity.prototype, "data", void 0);
|
|
339
|
+
_ts_decorate([
|
|
340
|
+
(0, _typeorm.Column)({
|
|
341
|
+
type: 'int',
|
|
342
|
+
default: 0
|
|
343
|
+
}),
|
|
344
|
+
_ts_metadata("design:type", Number)
|
|
345
|
+
], StepExecutionContextEntity.prototype, "version", void 0);
|
|
346
|
+
StepExecutionContextEntity = _ts_decorate([
|
|
347
|
+
(0, _typeorm.Entity)('batch_step_execution_context')
|
|
348
|
+
], StepExecutionContextEntity);
|
|
349
|
+
const BATCH_META_ENTITIES = [
|
|
350
|
+
JobInstanceEntity,
|
|
351
|
+
JobExecutionEntity,
|
|
352
|
+
StepExecutionEntity,
|
|
353
|
+
JobExecutionContextEntity,
|
|
354
|
+
StepExecutionContextEntity
|
|
355
|
+
];
|
|
356
|
+
|
|
357
|
+
//# sourceMappingURL=job-meta.entities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/entities/job-meta.entities.ts"],"sourcesContent":["import { Entity, PrimaryColumn, Column, Index } from 'typeorm';\n\n/**\n * `batch_job_instance` metadata row.\n *\n * One row per logical job instance. Uniqueness is enforced on\n * (jobName, jobKey) so that the same canonical key resolves to the\n * same instance across restarts. The composite unique index is\n * declared on the entity and is also reified in the bundled\n * migration under the same name.\n */\n@Entity('batch_job_instance')\n@Index('batch_job_instance_job_name_job_key_unique', ['jobName', 'jobKey'], { unique: true })\nexport class JobInstanceEntity {\n @PrimaryColumn({ type: 'varchar', length: 255 })\n id!: string;\n\n @Column({ name: 'job_name', type: 'varchar', length: 255 })\n jobName!: string;\n\n @Column({ name: 'job_key', type: 'varchar', length: 255 })\n jobKey!: string;\n\n @Column({\n name: 'created_at',\n // `datetime` is portable across PostgreSQL and SQLite (the test\n // driver). The bundled migration uses timestamptz on\n // PostgreSQL by hand; SQLite loses the timezone qualifier,\n // which is acceptable for a creation-time stamp that is never\n // compared with sub-second precision in queries.\n type: 'datetime',\n default: () => 'CURRENT_TIMESTAMP',\n })\n createdAt: Date = new Date();\n}\n\n/**\n * `batch_job_execution` metadata row.\n *\n * One row per job run. `status` is the stringified JobStatus enum\n * (kept as a plain varchar — TypeORM enum support varies across\n * drivers and v1.0.0 dropped a few columns we don't need). The\n * `jobInstanceId` column is indexed because every contract lookup\n * (\"is this instance running?\") scans by it.\n */\n@Entity('batch_job_execution')\n@Index('batch_job_execution_job_instance_id_index', ['jobInstanceId'])\nexport class JobExecutionEntity {\n @PrimaryColumn({ type: 'varchar', length: 255 })\n id!: string;\n\n @Column({ name: 'job_instance_id', type: 'varchar', length: 255 })\n jobInstanceId!: string;\n\n @Column({ type: 'varchar', length: 20 })\n status!: string;\n\n @Column({ name: 'start_time', type: 'datetime', nullable: true })\n startTime: Date | null = null;\n\n @Column({ name: 'end_time', type: 'datetime', nullable: true })\n endTime: Date | null = null;\n\n @Column({ name: 'exit_code', type: 'varchar', length: 255, default: '' })\n exitCode!: string;\n\n @Column({ name: 'exit_message', type: 'text', default: '' })\n exitMessage!: string;\n\n /**\n * JSON-serialized `JobParameters` snapshot. Stored as `text` (not\n * native `jsonb`) so the adapter works uniformly across SQLite (used\n * in unit tests) and PostgreSQL/MySQL — the column is always a\n * serialized payload, never queried by the ORM.\n */\n @Column({ name: 'params', type: 'text', default: '{}' })\n params!: string;\n}\n\n/**\n * `batch_step_execution` metadata row.\n *\n * One row per step run. Counters default to 0 so the entity can\n * be persisted immediately upon creation, before any items are\n * processed. `createdAt` is stamped on insert and used by\n * `findLatestStepExecution` to resolve the most recently created\n * step for a given `(jobExecutionId, stepName)` pair — a v4 UUID\n * primary key does not preserve insertion order, so an explicit\n * monotonic column is required.\n */\n@Entity('batch_step_execution')\n@Index('batch_step_execution_job_execution_id_index', ['jobExecutionId'])\nexport class StepExecutionEntity {\n @PrimaryColumn({ type: 'varchar', length: 255 })\n id!: string;\n\n @Column({ name: 'job_execution_id', type: 'varchar', length: 255 })\n jobExecutionId!: string;\n\n @Column({ name: 'step_name', type: 'varchar', length: 255 })\n stepName!: string;\n\n @Column({ type: 'varchar', length: 20 })\n status!: string;\n\n @Column({ name: 'read_count', type: 'int', default: 0 })\n readCount!: number;\n\n @Column({ name: 'write_count', type: 'int', default: 0 })\n writeCount!: number;\n\n @Column({ name: 'skip_count', type: 'int', default: 0 })\n skipCount!: number;\n\n @Column({ name: 'rollback_count', type: 'int', default: 0 })\n rollbackCount!: number;\n\n @Column({ name: 'commit_count', type: 'int', default: 0 })\n commitCount!: number;\n\n @Column({ name: 'exit_code', type: 'varchar', length: 255, default: '' })\n exitCode!: string;\n\n @Column({ name: 'exit_message', type: 'text', default: '' })\n exitMessage!: string;\n\n @Column({\n name: 'created_at',\n type: 'datetime',\n default: () => 'CURRENT_TIMESTAMP',\n })\n createdAt: Date = new Date();\n}\n\n/**\n * `batch_job_execution_context` metadata row.\n *\n * `data` is a JSON-serialized ExecutionContext payload. `version`\n * guards against lost updates during concurrent writers.\n */\n@Entity('batch_job_execution_context')\nexport class JobExecutionContextEntity {\n @PrimaryColumn({ name: 'job_execution_id', type: 'varchar', length: 255 })\n jobExecutionId!: string;\n\n @Column({ type: 'text' })\n data!: string;\n\n @Column({ type: 'int', default: 0 })\n version!: number;\n}\n\n/**\n * `batch_step_execution_context` metadata row.\n *\n * Mirrors the job-level context table but scoped to a single\n * step execution. There is intentionally no params sibling table\n * for steps — step parameters are derivable from the parent job\n * execution params + the step execution context.\n */\n@Entity('batch_step_execution_context')\nexport class StepExecutionContextEntity {\n @PrimaryColumn({ name: 'step_execution_id', type: 'varchar', length: 255 })\n stepExecutionId!: string;\n\n @Column({ type: 'text' })\n data!: string;\n\n @Column({ type: 'int', default: 0 })\n version!: number;\n}\n\n/**\n * All batch meta entities owned by this package. Hand to\n * `DataSource#entityMetadatas` (or `entities:`) so TypeORM\n * discovers them through the standard decorator scan.\n */\nexport const BATCH_META_ENTITIES = [\n JobInstanceEntity,\n JobExecutionEntity,\n StepExecutionEntity,\n JobExecutionContextEntity,\n StepExecutionContextEntity,\n] as const;\n"],"names":["BATCH_META_ENTITIES","JobExecutionContextEntity","JobExecutionEntity","JobInstanceEntity","StepExecutionContextEntity","StepExecutionEntity","id","jobName","jobKey","createdAt","Date","type","length","name","default","unique","jobInstanceId","status","startTime","endTime","exitCode","exitMessage","params","nullable","jobExecutionId","stepName","readCount","writeCount","skipCount","rollbackCount","commitCount","data","version","stepExecutionId"],"mappings":";;;;;;;;;;;QAiLaA;eAAAA;;QApCAC;eAAAA;;QA9FAC;eAAAA;;QAlCAC;eAAAA;;QAoJAC;eAAAA;;QArEAC;eAAAA;;;yBA5FwC;;;;;;;;;;AAa9C,IAAA,AAAMF,oBAAN,MAAMA;IAEXG,GAAY;IAGZC,QAAiB;IAGjBC,OAAgB;IAYhBC,YAAkB,IAAIC,OAAO;AAC/B;;;QApBmBC,MAAM;QAAWC,QAAQ;;;;;;QAGhCC,MAAM;QAAYF,MAAM;QAAWC,QAAQ;;;;;;QAG3CC,MAAM;QAAWF,MAAM;QAAWC,QAAQ;;;;;;QAIlDC,MAAM;QACN,gEAAgE;QAChE,qDAAqD;QACrD,2DAA2D;QAC3D,8DAA8D;QAC9D,iDAAiD;QACjDF,MAAM;QACNG,SAAS,IAAM;;;;;;;QAnBmC;QAAW;;QAAaC,QAAQ;;;AAmC/E,IAAA,AAAMb,qBAAN,MAAMA;IAEXI,GAAY;IAGZU,cAAuB;IAGvBC,OAAgB;IAGhBC,YAAyB,KAAK;IAG9BC,UAAuB,KAAK;IAG5BC,SAAkB;IAGlBC,YAAqB;IAErB;;;;;GAKC,GACD,AACAC,OAAgB;AAClB;;;QA7BmBX,MAAM;QAAWC,QAAQ;;;;;;QAGhCC,MAAM;QAAmBF,MAAM;QAAWC,QAAQ;;;;;;QAGlDD,MAAM;QAAWC,QAAQ;;;;;;QAGzBC,MAAM;QAAcF,MAAM;QAAYY,UAAU;;;;;;QAGhDV,MAAM;QAAYF,MAAM;QAAYY,UAAU;;;;;;QAG9CV,MAAM;QAAaF,MAAM;QAAWC,QAAQ;QAAKE,SAAS;;;;;;QAG1DD,MAAM;QAAgBF,MAAM;QAAQG,SAAS;;;;;;QAS7CD,MAAM;QAAUF,MAAM;QAAQG,SAAS;;;;;;;QA7BE;;;AA8C9C,IAAA,AAAMT,sBAAN,MAAMA;IAEXC,GAAY;IAGZkB,eAAwB;IAGxBC,SAAkB;IAGlBR,OAAgB;IAGhBS,UAAmB;IAGnBC,WAAoB;IAGpBC,UAAmB;IAGnBC,cAAuB;IAGvBC,YAAqB;IAGrBV,SAAkB;IAGlBC,YAAqB;IAOrBZ,YAAkB,IAAIC,OAAO;AAC/B;;;QAvCmBC,MAAM;QAAWC,QAAQ;;;;;;QAGhCC,MAAM;QAAoBF,MAAM;QAAWC,QAAQ;;;;;;QAGnDC,MAAM;QAAaF,MAAM;QAAWC,QAAQ;;;;;;QAG5CD,MAAM;QAAWC,QAAQ;;;;;;QAGzBC,MAAM;QAAcF,MAAM;QAAOG,SAAS;;;;;;QAG1CD,MAAM;QAAeF,MAAM;QAAOG,SAAS;;;;;;QAG3CD,MAAM;QAAcF,MAAM;QAAOG,SAAS;;;;;;QAG1CD,MAAM;QAAkBF,MAAM;QAAOG,SAAS;;;;;;QAG9CD,MAAM;QAAgBF,MAAM;QAAOG,SAAS;;;;;;QAG5CD,MAAM;QAAaF,MAAM;QAAWC,QAAQ;QAAKE,SAAS;;;;;;QAG1DD,MAAM;QAAgBF,MAAM;QAAQG,SAAS;;;;;;QAIrDD,MAAM;QACNF,MAAM;QACNG,SAAS,IAAM;;;;;;;QAtCoC;;;AAkDhD,IAAA,AAAMb,4BAAN,MAAMA;IAEXuB,eAAwB;IAGxBO,KAAc;IAGdC,QAAiB;AACnB;;;QARmBnB,MAAM;QAAoBF,MAAM;QAAWC,QAAQ;;;;;;QAG1DD,MAAM;;;;;;QAGNA,MAAM;QAAOG,SAAS;;;;;;;AAa3B,IAAA,AAAMV,6BAAN,MAAMA;IAEX6B,gBAAyB;IAGzBF,KAAc;IAGdC,QAAiB;AACnB;;;QARmBnB,MAAM;QAAqBF,MAAM;QAAWC,QAAQ;;;;;;QAG3DD,MAAM;;;;;;QAGNA,MAAM;QAAOG,SAAS;;;;;;;AAS3B,MAAMd,sBAAsB;IACjCG;IACAD;IACAG;IACAJ;IACAG;CACD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { TypeOrmJobRepository } from './repository/typeorm-job-repository';
|
|
2
|
+
export type { TypeOrmTransactionContext } from './transaction/typeorm-transaction-manager';
|
|
3
|
+
export { TypeOrmTransactionManager } from './transaction/typeorm-transaction-manager';
|
|
4
|
+
export * from './adapters';
|
|
5
|
+
export * from './typeorm.driver-provider';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,YAAY,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AAC3F,OAAO,EAAE,yBAAyB,EAAE,MAAM,2CAA2C,CAAC;AACtF,cAAc,YAAY,CAAC;AAC3B,cAAc,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Public API barrel for @nest-batch/typeorm.
|
|
2
|
+
//
|
|
3
|
+
// The package is a **driver-agnostic adapter SLOT**. It owns the
|
|
4
|
+
// `TypeOrmAdapter` factory, the `TypeOrmJobRepository` /
|
|
5
|
+
// `TypeOrmTransactionManager` interface shape, and the
|
|
6
|
+
// `TypeOrmDriverProvider` injection token. It does NOT import
|
|
7
|
+
// `@nestjs/typeorm` (which carries the Postgres driver) — the
|
|
8
|
+
// driver implementation lives in the `@nest-batch/postgresql` (or
|
|
9
|
+
// `@nest-batch/mysql`) sibling package, which binds the
|
|
10
|
+
// `TypeOrmDriverProvider` token to the concrete `DataSource`
|
|
11
|
+
// in its own `forRoot()` factory.
|
|
12
|
+
//
|
|
13
|
+
// Apps wire the persistence concern into `NestBatchModule.forRoot()`
|
|
14
|
+
// via the new `BatchAdapter` factory pattern:
|
|
15
|
+
//
|
|
16
|
+
// import { NestBatchModule, InProcessAdapter } from '@nest-batch/core';
|
|
17
|
+
// import { TypeOrmAdapter } from '@nest-batch/typeorm';
|
|
18
|
+
// import { PostgresAdapter } from '@nest-batch/postgresql';
|
|
19
|
+
//
|
|
20
|
+
// // The host must also call
|
|
21
|
+
// // `TypeOrmModule.forRoot({ ... })` in their `AppModule.imports`.
|
|
22
|
+
// // The PostgresAdapter.forRoot() factory binds the
|
|
23
|
+
// // TypeOrmDriverProvider token to the host's DataSource.
|
|
24
|
+
//
|
|
25
|
+
// NestBatchModule.forRoot({
|
|
26
|
+
// adapters: {
|
|
27
|
+
// persistence: PostgresAdapter.forRoot(),
|
|
28
|
+
// transport: InProcessAdapter.forRoot(),
|
|
29
|
+
// },
|
|
30
|
+
// });
|
|
31
|
+
//
|
|
32
|
+
// The original `batchMetaEntities()` factory and the bundled
|
|
33
|
+
// `CreateBatchMeta1700000000000` migration moved to
|
|
34
|
+
// `@nest-batch/postgresql/src/migrations/`. The driver sibling owns
|
|
35
|
+
// the TypeORM-specific entity classes and the migration scripts;
|
|
36
|
+
// this package owns only the repository / transaction manager
|
|
37
|
+
// shape and the driver-provider token.
|
|
38
|
+
"use strict";
|
|
39
|
+
Object.defineProperty(exports, "__esModule", {
|
|
40
|
+
value: true
|
|
41
|
+
});
|
|
42
|
+
function _export(target, all) {
|
|
43
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
_export(exports, {
|
|
49
|
+
get TypeOrmJobRepository () {
|
|
50
|
+
return _typeormjobrepository.TypeOrmJobRepository;
|
|
51
|
+
},
|
|
52
|
+
get TypeOrmTransactionManager () {
|
|
53
|
+
return _typeormtransactionmanager.TypeOrmTransactionManager;
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const _typeormjobrepository = require("./repository/typeorm-job-repository");
|
|
57
|
+
const _typeormtransactionmanager = require("./transaction/typeorm-transaction-manager");
|
|
58
|
+
_export_star(require("./adapters"), exports);
|
|
59
|
+
_export_star(require("./typeorm.driver-provider"), exports);
|
|
60
|
+
function _export_star(from, to) {
|
|
61
|
+
Object.keys(from).forEach(function(k) {
|
|
62
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
63
|
+
Object.defineProperty(to, k, {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
get: function() {
|
|
66
|
+
return from[k];
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return from;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts"],"sourcesContent":["// Public API barrel for @nest-batch/typeorm.\n//\n// The package is a **driver-agnostic adapter SLOT**. It owns the\n// `TypeOrmAdapter` factory, the `TypeOrmJobRepository` /\n// `TypeOrmTransactionManager` interface shape, and the\n// `TypeOrmDriverProvider` injection token. It does NOT import\n// `@nestjs/typeorm` (which carries the Postgres driver) — the\n// driver implementation lives in the `@nest-batch/postgresql` (or\n// `@nest-batch/mysql`) sibling package, which binds the\n// `TypeOrmDriverProvider` token to the concrete `DataSource`\n// in its own `forRoot()` factory.\n//\n// Apps wire the persistence concern into `NestBatchModule.forRoot()`\n// via the new `BatchAdapter` factory pattern:\n//\n// import { NestBatchModule, InProcessAdapter } from '@nest-batch/core';\n// import { TypeOrmAdapter } from '@nest-batch/typeorm';\n// import { PostgresAdapter } from '@nest-batch/postgresql';\n//\n// // The host must also call\n// // `TypeOrmModule.forRoot({ ... })` in their `AppModule.imports`.\n// // The PostgresAdapter.forRoot() factory binds the\n// // TypeOrmDriverProvider token to the host's DataSource.\n//\n// NestBatchModule.forRoot({\n// adapters: {\n// persistence: PostgresAdapter.forRoot(),\n// transport: InProcessAdapter.forRoot(),\n// },\n// });\n//\n// The original `batchMetaEntities()` factory and the bundled\n// `CreateBatchMeta1700000000000` migration moved to\n// `@nest-batch/postgresql/src/migrations/`. The driver sibling owns\n// the TypeORM-specific entity classes and the migration scripts;\n// this package owns only the repository / transaction manager\n// shape and the driver-provider token.\nexport { TypeOrmJobRepository } from './repository/typeorm-job-repository';\nexport type { TypeOrmTransactionContext } from './transaction/typeorm-transaction-manager';\nexport { TypeOrmTransactionManager } from './transaction/typeorm-transaction-manager';\nexport * from './adapters';\nexport * from './typeorm.driver-provider';\n"],"names":["TypeOrmJobRepository","TypeOrmTransactionManager"],"mappings":"AAAA,6CAA6C;AAC7C,EAAE;AACF,iEAAiE;AACjE,yDAAyD;AACzD,uDAAuD;AACvD,8DAA8D;AAC9D,8DAA8D;AAC9D,kEAAkE;AAClE,wDAAwD;AACxD,6DAA6D;AAC7D,kCAAkC;AAClC,EAAE;AACF,qEAAqE;AACrE,8CAA8C;AAC9C,EAAE;AACF,0EAA0E;AAC1E,0DAA0D;AAC1D,8DAA8D;AAC9D,EAAE;AACF,+BAA+B;AAC/B,sEAAsE;AACtE,uDAAuD;AACvD,6DAA6D;AAC7D,EAAE;AACF,8BAA8B;AAC9B,kBAAkB;AAClB,gDAAgD;AAChD,+CAA+C;AAC/C,SAAS;AACT,QAAQ;AACR,EAAE;AACF,6DAA6D;AAC7D,oDAAoD;AACpD,oEAAoE;AACpE,iEAAiE;AACjE,8DAA8D;AAC9D,uCAAuC;;;;;;;;;;;;QAC9BA;eAAAA,0CAAoB;;QAEpBC;eAAAA,oDAAyB;;;sCAFG;2CAEK;qBAC5B;qBACA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the six batch meta-tables owned by
|
|
4
|
+
* this package:
|
|
5
|
+
*
|
|
6
|
+
* - batch_job_instance (root, unique on (job_name, job_key))
|
|
7
|
+
* - batch_job_execution (one per job run, indexed by instance)
|
|
8
|
+
* - batch_step_execution (one per step run, indexed by exec)
|
|
9
|
+
* - batch_job_execution_context (JSON payload + version, keyed by exec)
|
|
10
|
+
* - batch_step_execution_context (JSON payload + version, keyed by step)
|
|
11
|
+
*
|
|
12
|
+
* This migration intentionally uses generic ANSI/PostgreSQL
|
|
13
|
+
* syntax (varchar + text + timestamptz + int). The adapter
|
|
14
|
+
* package's `typeorm-job-repository` is portable across SQLite
|
|
15
|
+
* (test database) and PostgreSQL (production). Users targeting
|
|
16
|
+
* MySQL or another driver should adjust the `down` (and
|
|
17
|
+
* optionally `up`) to match their column types.
|
|
18
|
+
*
|
|
19
|
+
* The `params` column on `batch_job_execution` is a JSON
|
|
20
|
+
* snapshot — stored as `text` to keep the schema portable and
|
|
21
|
+
* always serialized, never queried structurally.
|
|
22
|
+
*/
|
|
23
|
+
export declare class CreateBatchMeta1700000000000 implements MigrationInterface {
|
|
24
|
+
name: string;
|
|
25
|
+
up(queryRunner: QueryRunner): Promise<void>;
|
|
26
|
+
down(queryRunner: QueryRunner): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=1700000000000-CreateBatchMeta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"1700000000000-CreateBatchMeta.d.ts","sourceRoot":"","sources":["../../../src/migrations/1700000000000-CreateBatchMeta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,4BAA6B,YAAW,kBAAkB;IACrE,IAAI,SAAkC;IAEzB,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAkE3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAO3D"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "CreateBatchMeta1700000000000", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return CreateBatchMeta1700000000000;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
let CreateBatchMeta1700000000000 = class CreateBatchMeta1700000000000 {
|
|
12
|
+
name = 'CreateBatchMeta1700000000000';
|
|
13
|
+
async up(queryRunner) {
|
|
14
|
+
await queryRunner.query(`
|
|
15
|
+
CREATE TABLE IF NOT EXISTS "batch_job_instance" (
|
|
16
|
+
"id" varchar(255) PRIMARY KEY,
|
|
17
|
+
"job_name" varchar(255) NOT NULL,
|
|
18
|
+
"job_key" varchar(255) NOT NULL,
|
|
19
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
20
|
+
CONSTRAINT "batch_job_instance_job_name_job_key_unique" UNIQUE ("job_name", "job_key")
|
|
21
|
+
)
|
|
22
|
+
`);
|
|
23
|
+
await queryRunner.query(`
|
|
24
|
+
CREATE TABLE IF NOT EXISTS "batch_job_execution" (
|
|
25
|
+
"id" varchar(255) PRIMARY KEY,
|
|
26
|
+
"job_instance_id" varchar(255) NOT NULL,
|
|
27
|
+
"status" varchar(20) NOT NULL,
|
|
28
|
+
"start_time" timestamptz NULL,
|
|
29
|
+
"end_time" timestamptz NULL,
|
|
30
|
+
"exit_code" varchar(255) NOT NULL DEFAULT '',
|
|
31
|
+
"exit_message" text NOT NULL DEFAULT '',
|
|
32
|
+
"params" text NOT NULL DEFAULT '{}'
|
|
33
|
+
)
|
|
34
|
+
`);
|
|
35
|
+
await queryRunner.query(`
|
|
36
|
+
CREATE INDEX IF NOT EXISTS "batch_job_execution_job_instance_id_index"
|
|
37
|
+
ON "batch_job_execution" ("job_instance_id")
|
|
38
|
+
`);
|
|
39
|
+
await queryRunner.query(`
|
|
40
|
+
CREATE TABLE IF NOT EXISTS "batch_step_execution" (
|
|
41
|
+
"id" varchar(255) PRIMARY KEY,
|
|
42
|
+
"job_execution_id" varchar(255) NOT NULL,
|
|
43
|
+
"step_name" varchar(255) NOT NULL,
|
|
44
|
+
"status" varchar(20) NOT NULL,
|
|
45
|
+
"read_count" int NOT NULL DEFAULT 0,
|
|
46
|
+
"write_count" int NOT NULL DEFAULT 0,
|
|
47
|
+
"skip_count" int NOT NULL DEFAULT 0,
|
|
48
|
+
"rollback_count" int NOT NULL DEFAULT 0,
|
|
49
|
+
"commit_count" int NOT NULL DEFAULT 0,
|
|
50
|
+
"exit_code" varchar(255) NOT NULL DEFAULT '',
|
|
51
|
+
"exit_message" text NOT NULL DEFAULT '',
|
|
52
|
+
"created_at" timestamptz NOT NULL DEFAULT now()
|
|
53
|
+
)
|
|
54
|
+
`);
|
|
55
|
+
await queryRunner.query(`
|
|
56
|
+
CREATE INDEX IF NOT EXISTS "batch_step_execution_job_execution_id_index"
|
|
57
|
+
ON "batch_step_execution" ("job_execution_id")
|
|
58
|
+
`);
|
|
59
|
+
await queryRunner.query(`
|
|
60
|
+
CREATE TABLE IF NOT EXISTS "batch_job_execution_context" (
|
|
61
|
+
"job_execution_id" varchar(255) PRIMARY KEY,
|
|
62
|
+
"data" text NOT NULL,
|
|
63
|
+
"version" int NOT NULL DEFAULT 0
|
|
64
|
+
)
|
|
65
|
+
`);
|
|
66
|
+
await queryRunner.query(`
|
|
67
|
+
CREATE TABLE IF NOT EXISTS "batch_step_execution_context" (
|
|
68
|
+
"step_execution_id" varchar(255) PRIMARY KEY,
|
|
69
|
+
"data" text NOT NULL,
|
|
70
|
+
"version" int NOT NULL DEFAULT 0
|
|
71
|
+
)
|
|
72
|
+
`);
|
|
73
|
+
}
|
|
74
|
+
async down(queryRunner) {
|
|
75
|
+
await queryRunner.query(`DROP TABLE IF EXISTS "batch_step_execution_context"`);
|
|
76
|
+
await queryRunner.query(`DROP TABLE IF EXISTS "batch_job_execution_context"`);
|
|
77
|
+
await queryRunner.query(`DROP TABLE IF EXISTS "batch_step_execution"`);
|
|
78
|
+
await queryRunner.query(`DROP TABLE IF EXISTS "batch_job_execution"`);
|
|
79
|
+
await queryRunner.query(`DROP TABLE IF EXISTS "batch_job_instance"`);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=1700000000000-CreateBatchMeta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/migrations/1700000000000-CreateBatchMeta.ts"],"sourcesContent":["import { MigrationInterface, QueryRunner } from 'typeorm';\n\n/**\n * Creates the six batch meta-tables owned by\n * this package:\n *\n * - batch_job_instance (root, unique on (job_name, job_key))\n * - batch_job_execution (one per job run, indexed by instance)\n * - batch_step_execution (one per step run, indexed by exec)\n * - batch_job_execution_context (JSON payload + version, keyed by exec)\n * - batch_step_execution_context (JSON payload + version, keyed by step)\n *\n * This migration intentionally uses generic ANSI/PostgreSQL\n * syntax (varchar + text + timestamptz + int). The adapter\n * package's `typeorm-job-repository` is portable across SQLite\n * (test database) and PostgreSQL (production). Users targeting\n * MySQL or another driver should adjust the `down` (and\n * optionally `up`) to match their column types.\n *\n * The `params` column on `batch_job_execution` is a JSON\n * snapshot — stored as `text` to keep the schema portable and\n * always serialized, never queried structurally.\n */\nexport class CreateBatchMeta1700000000000 implements MigrationInterface {\n name = 'CreateBatchMeta1700000000000';\n\n public async up(queryRunner: QueryRunner): Promise<void> {\n await queryRunner.query(`\n CREATE TABLE IF NOT EXISTS \"batch_job_instance\" (\n \"id\" varchar(255) PRIMARY KEY,\n \"job_name\" varchar(255) NOT NULL,\n \"job_key\" varchar(255) NOT NULL,\n \"created_at\" timestamptz NOT NULL DEFAULT now(),\n CONSTRAINT \"batch_job_instance_job_name_job_key_unique\" UNIQUE (\"job_name\", \"job_key\")\n )\n `);\n\n await queryRunner.query(`\n CREATE TABLE IF NOT EXISTS \"batch_job_execution\" (\n \"id\" varchar(255) PRIMARY KEY,\n \"job_instance_id\" varchar(255) NOT NULL,\n \"status\" varchar(20) NOT NULL,\n \"start_time\" timestamptz NULL,\n \"end_time\" timestamptz NULL,\n \"exit_code\" varchar(255) NOT NULL DEFAULT '',\n \"exit_message\" text NOT NULL DEFAULT '',\n \"params\" text NOT NULL DEFAULT '{}'\n )\n `);\n await queryRunner.query(`\n CREATE INDEX IF NOT EXISTS \"batch_job_execution_job_instance_id_index\"\n ON \"batch_job_execution\" (\"job_instance_id\")\n `);\n\n await queryRunner.query(`\n CREATE TABLE IF NOT EXISTS \"batch_step_execution\" (\n \"id\" varchar(255) PRIMARY KEY,\n \"job_execution_id\" varchar(255) NOT NULL,\n \"step_name\" varchar(255) NOT NULL,\n \"status\" varchar(20) NOT NULL,\n \"read_count\" int NOT NULL DEFAULT 0,\n \"write_count\" int NOT NULL DEFAULT 0,\n \"skip_count\" int NOT NULL DEFAULT 0,\n \"rollback_count\" int NOT NULL DEFAULT 0,\n \"commit_count\" int NOT NULL DEFAULT 0,\n \"exit_code\" varchar(255) NOT NULL DEFAULT '',\n \"exit_message\" text NOT NULL DEFAULT '',\n \"created_at\" timestamptz NOT NULL DEFAULT now()\n )\n `);\n await queryRunner.query(`\n CREATE INDEX IF NOT EXISTS \"batch_step_execution_job_execution_id_index\"\n ON \"batch_step_execution\" (\"job_execution_id\")\n `);\n\n await queryRunner.query(`\n CREATE TABLE IF NOT EXISTS \"batch_job_execution_context\" (\n \"job_execution_id\" varchar(255) PRIMARY KEY,\n \"data\" text NOT NULL,\n \"version\" int NOT NULL DEFAULT 0\n )\n `);\n\n await queryRunner.query(`\n CREATE TABLE IF NOT EXISTS \"batch_step_execution_context\" (\n \"step_execution_id\" varchar(255) PRIMARY KEY,\n \"data\" text NOT NULL,\n \"version\" int NOT NULL DEFAULT 0\n )\n `);\n }\n\n public async down(queryRunner: QueryRunner): Promise<void> {\n await queryRunner.query(`DROP TABLE IF EXISTS \"batch_step_execution_context\"`);\n await queryRunner.query(`DROP TABLE IF EXISTS \"batch_job_execution_context\"`);\n await queryRunner.query(`DROP TABLE IF EXISTS \"batch_step_execution\"`);\n await queryRunner.query(`DROP TABLE IF EXISTS \"batch_job_execution\"`);\n await queryRunner.query(`DROP TABLE IF EXISTS \"batch_job_instance\"`);\n }\n}\n"],"names":["CreateBatchMeta1700000000000","name","up","queryRunner","query","down"],"mappings":";;;;+BAuBaA;;;eAAAA;;;AAAN,IAAA,AAAMA,+BAAN,MAAMA;IACXC,OAAO,+BAA+B;IAEtC,MAAaC,GAAGC,WAAwB,EAAiB;QACvD,MAAMA,YAAYC,KAAK,CAAC,CAAC;;;;;;;;IAQzB,CAAC;QAED,MAAMD,YAAYC,KAAK,CAAC,CAAC;;;;;;;;;;;IAWzB,CAAC;QACD,MAAMD,YAAYC,KAAK,CAAC,CAAC;;;IAGzB,CAAC;QAED,MAAMD,YAAYC,KAAK,CAAC,CAAC;;;;;;;;;;;;;;;IAezB,CAAC;QACD,MAAMD,YAAYC,KAAK,CAAC,CAAC;;;IAGzB,CAAC;QAED,MAAMD,YAAYC,KAAK,CAAC,CAAC;;;;;;IAMzB,CAAC;QAED,MAAMD,YAAYC,KAAK,CAAC,CAAC;;;;;;IAMzB,CAAC;IACH;IAEA,MAAaC,KAAKF,WAAwB,EAAiB;QACzD,MAAMA,YAAYC,KAAK,CAAC,CAAC,mDAAmD,CAAC;QAC7E,MAAMD,YAAYC,KAAK,CAAC,CAAC,kDAAkD,CAAC;QAC5E,MAAMD,YAAYC,KAAK,CAAC,CAAC,2CAA2C,CAAC;QACrE,MAAMD,YAAYC,KAAK,CAAC,CAAC,0CAA0C,CAAC;QACpE,MAAMD,YAAYC,KAAK,CAAC,CAAC,yCAAyC,CAAC;IACrE;AACF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { DataSource } from 'typeorm';
|
|
2
|
+
import { JobRepository } from '@nest-batch/core';
|
|
3
|
+
import type { JobInstance, JobExecution, JobExecutionPatch, JobParameters, StepExecution, StepExecutionPatch, ExecutionContext, ExecutionScope, JobInstanceFilter, JobExecutionFilter } from '@nest-batch/core';
|
|
4
|
+
/**
|
|
5
|
+
* TypeORM 1.0.0-backed `JobRepository`.
|
|
6
|
+
*
|
|
7
|
+
* The package is driver-agnostic: the actual `DataSource` is
|
|
8
|
+
* provided by the `@nest-batch/postgresql` (or future
|
|
9
|
+
* `@nest-batch/mysql`) driver sibling via the `TypeOrmDriverProvider`
|
|
10
|
+
* token. The repository itself uses raw SQL via `EntityManager.query`
|
|
11
|
+
* so the column-shape contract is owned by the driver sibling
|
|
12
|
+
* (the bundled 6-table migration).
|
|
13
|
+
*
|
|
14
|
+
* The contract guarantees:
|
|
15
|
+
* - `getOrCreateJobInstance` is race-safe via the (jobName, jobKey)
|
|
16
|
+
* unique index.
|
|
17
|
+
* - `createExecutionAtomic` runs inside a single transaction that
|
|
18
|
+
* (a) idempotently upserts the instance row, (b) acquires a row
|
|
19
|
+
* lock with `SELECT ... FOR UPDATE SKIP LOCKED` (PostgreSQL) or
|
|
20
|
+
* a plain select (SQLite test driver), and (c) rejects with
|
|
21
|
+
* `JobExecutionAlreadyRunningError` if a STARTING/STARTED
|
|
22
|
+
* execution already exists.
|
|
23
|
+
* - `saveExecutionContext` deep-clones the data and auto-increments
|
|
24
|
+
* the version counter when `version` is omitted.
|
|
25
|
+
* - `findLatestStepExecution` orders by `created_at` descending.
|
|
26
|
+
*/
|
|
27
|
+
export declare class TypeOrmJobRepository extends JobRepository {
|
|
28
|
+
private readonly dataSource;
|
|
29
|
+
constructor(dataSource: DataSource);
|
|
30
|
+
private em;
|
|
31
|
+
getOrCreateJobInstance(name: string, jobKey: string): Promise<JobInstance>;
|
|
32
|
+
createJobExecution(jobInstanceId: string, params: JobParameters): Promise<JobExecution>;
|
|
33
|
+
createExecutionAtomic(name: string, jobKey: string, params: JobParameters): Promise<JobExecution>;
|
|
34
|
+
updateJobExecution(executionId: string, patch: JobExecutionPatch): Promise<void>;
|
|
35
|
+
getJobExecution(executionId: string): Promise<JobExecution | null>;
|
|
36
|
+
getJobInstance(jobInstanceId: string): Promise<JobInstance | null>;
|
|
37
|
+
findJobInstances(filter?: JobInstanceFilter): Promise<JobInstance[]>;
|
|
38
|
+
findJobExecutions(filter?: JobExecutionFilter): Promise<JobExecution[]>;
|
|
39
|
+
getRunningJobExecution(jobInstanceId: string): Promise<JobExecution | null>;
|
|
40
|
+
createStepExecution(jobExecutionId: string, stepName: string): Promise<StepExecution>;
|
|
41
|
+
updateStepExecution(stepExecutionId: string, patch: StepExecutionPatch): Promise<void>;
|
|
42
|
+
getStepExecution(stepExecutionId: string): Promise<StepExecution | null>;
|
|
43
|
+
findStepExecutions(jobExecutionId: string): Promise<StepExecution[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Find the most recently created step execution for the given
|
|
46
|
+
* `(jobExecutionId, stepName)` pair, or `null` when none exists.
|
|
47
|
+
* Insertion order is determined by the `created_at` column; the
|
|
48
|
+
* primary key is a v4 UUID which is random, so a `id DESC` order
|
|
49
|
+
* would not correspond to insertion time. The `created_at DESC,
|
|
50
|
+
* id DESC` secondary order keeps the result stable when two rows
|
|
51
|
+
* share the same `CURRENT_TIMESTAMP` resolution.
|
|
52
|
+
*/
|
|
53
|
+
findLatestStepExecution(jobExecutionId: string, stepName: string): Promise<StepExecution | null>;
|
|
54
|
+
getExecutionContext(scope: ExecutionScope): Promise<ExecutionContext>;
|
|
55
|
+
saveExecutionContext(scope: ExecutionScope, ctx: ExecutionContext, version?: number): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=typeorm-job-repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typeorm-job-repository.d.ts","sourceRoot":"","sources":["../../../src/repository/typeorm-job-repository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAqB,MAAM,SAAS,CAAC;AACxD,OAAO,EACL,aAAa,EAOd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAyG1B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBACa,oBAAqB,SAAQ,aAAa;IAEpB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAKxE,OAAO,CAAC,EAAE;IAIJ,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAsC1E,kBAAkB,CACtB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC;IAoBlB,qBAAqB,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,YAAY,CAAC;IA6DlB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhF,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IASzD,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAWlE,gBAAgB,CAAC,MAAM,GAAE,iBAAsB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAsBxE,iBAAiB,CAAC,MAAM,GAAE,kBAAuB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAgCpF,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAY3E,mBAAmB,CACvB,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC;IAWnB,mBAAmB,CACvB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,IAAI,CAAC;IAoBV,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAS/D,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAWnF;;;;;;;;OAQG;IACG,uBAAuB,CAC3B,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAY1B,mBAAmB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4BrE,oBAAoB,CACxB,KAAK,EAAE,cAAc,EACrB,GAAG,EAAE,gBAAgB,EACrB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;CA0CjB"}
|