@spinajs/orm 2.0.46 → 2.0.48
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/README.md +11 -11
- package/lib/builders.d.ts +9 -8
- package/lib/builders.d.ts.map +1 -0
- package/lib/builders.js +277 -310
- package/lib/builders.js.map +1 -1
- package/lib/converters.d.ts +4 -3
- package/lib/converters.d.ts.map +1 -0
- package/lib/converters.js +11 -19
- package/lib/converters.js.map +1 -1
- package/lib/decorators.d.ts +4 -3
- package/lib/decorators.d.ts.map +1 -0
- package/lib/decorators.js +71 -99
- package/lib/decorators.js.map +1 -1
- package/lib/dehydrators.d.ts +2 -1
- package/lib/dehydrators.d.ts.map +1 -0
- package/lib/dehydrators.js +9 -16
- package/lib/dehydrators.js.map +1 -1
- package/lib/driver.d.ts +6 -5
- package/lib/driver.d.ts.map +1 -0
- package/lib/driver.js +20 -24
- package/lib/driver.js.map +1 -1
- package/lib/enums.d.ts +2 -1
- package/lib/enums.d.ts.map +1 -0
- package/lib/enums.js +14 -17
- package/lib/enums.js.map +1 -1
- package/lib/exceptions.d.ts +2 -1
- package/lib/exceptions.d.ts.map +1 -0
- package/lib/exceptions.js +2 -6
- package/lib/exceptions.js.map +1 -1
- package/lib/hydrators.d.ts +2 -1
- package/lib/hydrators.d.ts.map +1 -0
- package/lib/hydrators.js +23 -28
- package/lib/hydrators.js.map +1 -1
- package/lib/index.d.ts +16 -15
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -31
- package/lib/index.js.map +1 -1
- package/lib/interfaces.d.ts +10 -9
- package/lib/interfaces.d.ts.map +1 -0
- package/lib/interfaces.js +76 -89
- package/lib/interfaces.js.map +1 -1
- package/lib/model.d.ts +8 -7
- package/lib/model.d.ts.map +1 -0
- package/lib/model.js +116 -154
- package/lib/model.js.map +1 -1
- package/lib/orm.d.ts +4 -3
- package/lib/orm.d.ts.map +1 -0
- package/lib/orm.js +45 -74
- package/lib/orm.js.map +1 -1
- package/lib/relations.d.ts +6 -11
- package/lib/relations.d.ts.map +1 -0
- package/lib/relations.js +56 -90
- package/lib/relations.js.map +1 -1
- package/lib/statements.d.ts +6 -7
- package/lib/statements.d.ts.map +1 -0
- package/lib/statements.js +55 -86
- package/lib/statements.js.map +1 -1
- package/lib/types.d.ts +15 -14
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +1 -2
- package/lib/wrappers.d.ts +2 -1
- package/lib/wrappers.d.ts.map +1 -0
- package/lib/wrappers.js +4 -7
- package/lib/wrappers.js.map +1 -1
- package/package.json +63 -61
package/lib/model.js
CHANGED
|
@@ -1,45 +1,19 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.MODEL_STATIC_MIXINS = exports.createQuery = exports.HistoricalModel = exports.ModelBase = exports.extractModelDescriptor = void 0;
|
|
27
1
|
/* eslint-disable prettier/prettier */
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
function extractModelDescriptor(targetOrForward) {
|
|
42
|
-
const target = !
|
|
2
|
+
import { DiscriminationMapMiddleware, OneToManyRelationList, ManyToManyRelationList, SingleRelation } from './relations.js';
|
|
3
|
+
import { SordOrder } from './enums.js';
|
|
4
|
+
import { MODEL_DESCTRIPTION_SYMBOL } from './decorators.js';
|
|
5
|
+
import { RelationType, InsertBehaviour, ModelToSqlConverter, ObjectToSqlConverter } from './interfaces.js';
|
|
6
|
+
import { UpdateQueryBuilder, TruncateTableQueryBuilder, SelectQueryBuilder, DeleteQueryBuilder, InsertQueryBuilder } from './builders.js';
|
|
7
|
+
import { DI, isConstructor } from '@spinajs/di';
|
|
8
|
+
import { Orm } from './orm.js';
|
|
9
|
+
import { ModelHydrator } from './hydrators.js';
|
|
10
|
+
import _ from 'lodash';
|
|
11
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
12
|
+
import { OrmException } from './exceptions.js';
|
|
13
|
+
import { StandardModelDehydrator, StandardModelWithRelationsDehydrator } from './dehydrators.js';
|
|
14
|
+
import { DateTime } from 'luxon';
|
|
15
|
+
export function extractModelDescriptor(targetOrForward) {
|
|
16
|
+
const target = !isConstructor(targetOrForward) && targetOrForward ? targetOrForward() : targetOrForward;
|
|
43
17
|
if (!target) {
|
|
44
18
|
return null;
|
|
45
19
|
}
|
|
@@ -50,9 +24,9 @@ function extractModelDescriptor(targetOrForward) {
|
|
|
50
24
|
if (!t) {
|
|
51
25
|
return;
|
|
52
26
|
}
|
|
53
|
-
if (t[
|
|
54
|
-
descriptor = descriptor
|
|
55
|
-
_.mergeWith(descriptor, t[
|
|
27
|
+
if (t[MODEL_DESCTRIPTION_SYMBOL]) {
|
|
28
|
+
descriptor = descriptor ?? {};
|
|
29
|
+
_.mergeWith(descriptor, t[MODEL_DESCTRIPTION_SYMBOL], (a, b) => {
|
|
56
30
|
if (!a) {
|
|
57
31
|
return b;
|
|
58
32
|
}
|
|
@@ -66,19 +40,7 @@ function extractModelDescriptor(targetOrForward) {
|
|
|
66
40
|
_reduce(t.__proto__);
|
|
67
41
|
}
|
|
68
42
|
}
|
|
69
|
-
|
|
70
|
-
class ModelBase {
|
|
71
|
-
constructor(data) {
|
|
72
|
-
/**
|
|
73
|
-
* List of hidden properties from JSON / dehydrations
|
|
74
|
-
* eg. password field of user
|
|
75
|
-
*/
|
|
76
|
-
this._hidden = [];
|
|
77
|
-
this.setDefaults();
|
|
78
|
-
if (data) {
|
|
79
|
-
this.hydrate(data);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
43
|
+
export class ModelBase {
|
|
82
44
|
/**
|
|
83
45
|
* Gets descriptor for this model. It contains information about relations, orm driver, connection properties,
|
|
84
46
|
* db table attached, column information and others.
|
|
@@ -91,7 +53,7 @@ class ModelBase {
|
|
|
91
53
|
*/
|
|
92
54
|
get Container() {
|
|
93
55
|
if (!this._container) {
|
|
94
|
-
const orm =
|
|
56
|
+
const orm = DI.get(Orm);
|
|
95
57
|
const driver = orm.Connections.get(this.ModelDescriptor.Connection);
|
|
96
58
|
if (!driver) {
|
|
97
59
|
throw new Error(`model ${this.constructor.name} have invalid connection ${this.ModelDescriptor.Connection}, please check your db config file or model connection name`);
|
|
@@ -113,20 +75,20 @@ class ModelBase {
|
|
|
113
75
|
if (!rel)
|
|
114
76
|
return;
|
|
115
77
|
switch (r.Type) {
|
|
116
|
-
case
|
|
78
|
+
case RelationType.One:
|
|
117
79
|
rel[r.ForeignKey] = newVal;
|
|
118
80
|
break;
|
|
119
|
-
case
|
|
81
|
+
case RelationType.Many:
|
|
120
82
|
rel.forEach((rVal) => (rVal[r.ForeignKey] = newVal));
|
|
121
83
|
break;
|
|
122
|
-
case
|
|
84
|
+
case RelationType.ManyToMany:
|
|
123
85
|
// TODO: rethink this
|
|
124
86
|
break;
|
|
125
87
|
}
|
|
126
88
|
});
|
|
127
89
|
}
|
|
128
90
|
driver() {
|
|
129
|
-
const orm =
|
|
91
|
+
const orm = DI.get(Orm);
|
|
130
92
|
const driver = orm.Connections.get(this.ModelDescriptor.Connection);
|
|
131
93
|
return driver;
|
|
132
94
|
}
|
|
@@ -137,7 +99,7 @@ class ModelBase {
|
|
|
137
99
|
const reduceRelations = function (m) {
|
|
138
100
|
const relations = [...m.ModelDescriptor.Relations.values()];
|
|
139
101
|
const models = _.flatMap(relations, (r) => {
|
|
140
|
-
if (r.Type ===
|
|
102
|
+
if (r.Type === RelationType.Many || r.Type === RelationType.ManyToMany) {
|
|
141
103
|
return m[r.Name];
|
|
142
104
|
}
|
|
143
105
|
if (m[r.Name].Value) {
|
|
@@ -168,7 +130,7 @@ class ModelBase {
|
|
|
168
130
|
*
|
|
169
131
|
* @param _data - data to insert
|
|
170
132
|
*/
|
|
171
|
-
static insert(_data, _insertBehaviour =
|
|
133
|
+
static insert(_data, _insertBehaviour = InsertBehaviour.None) {
|
|
172
134
|
throw new Error('Not implemented');
|
|
173
135
|
}
|
|
174
136
|
static where(_column, _operator, _value) {
|
|
@@ -264,13 +226,24 @@ class ModelBase {
|
|
|
264
226
|
static destroy(_pk) {
|
|
265
227
|
throw new Error('Not implemented');
|
|
266
228
|
}
|
|
229
|
+
constructor(data) {
|
|
230
|
+
/**
|
|
231
|
+
* List of hidden properties from JSON / dehydrations
|
|
232
|
+
* eg. password field of user
|
|
233
|
+
*/
|
|
234
|
+
this._hidden = [];
|
|
235
|
+
this.setDefaults();
|
|
236
|
+
if (data) {
|
|
237
|
+
this.hydrate(data);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
267
240
|
/**
|
|
268
241
|
* Fills model with data. It only fills properties that exists in database
|
|
269
242
|
*
|
|
270
243
|
* @param data - data to fill
|
|
271
244
|
*/
|
|
272
245
|
hydrate(data) {
|
|
273
|
-
this.Container.resolve(Array.ofType(
|
|
246
|
+
this.Container.resolve(Array.ofType(ModelHydrator)).forEach((h) => h.hydrate(this, data));
|
|
274
247
|
}
|
|
275
248
|
/**
|
|
276
249
|
*
|
|
@@ -285,11 +258,11 @@ class ModelBase {
|
|
|
285
258
|
if (v.TargetModel.name === data.constructor.name) {
|
|
286
259
|
data[v.ForeignKey] = this.PrimaryKeyValue;
|
|
287
260
|
switch (v.Type) {
|
|
288
|
-
case
|
|
261
|
+
case RelationType.One:
|
|
289
262
|
this[v.Name].attach(data);
|
|
290
263
|
break;
|
|
291
|
-
case
|
|
292
|
-
case
|
|
264
|
+
case RelationType.Many:
|
|
265
|
+
case RelationType.ManyToMany:
|
|
293
266
|
this[v.Name].push(data);
|
|
294
267
|
break;
|
|
295
268
|
}
|
|
@@ -300,7 +273,7 @@ class ModelBase {
|
|
|
300
273
|
* Extracts all data from model. It takes only properties that exists in DB
|
|
301
274
|
*/
|
|
302
275
|
dehydrate(omit) {
|
|
303
|
-
return this.Container.resolve(
|
|
276
|
+
return this.Container.resolve(StandardModelDehydrator).dehydrate(this, [...(omit ?? []), ...this._hidden]);
|
|
304
277
|
}
|
|
305
278
|
/**
|
|
306
279
|
*
|
|
@@ -309,10 +282,10 @@ class ModelBase {
|
|
|
309
282
|
* @param omit - fields to omit
|
|
310
283
|
*/
|
|
311
284
|
dehydrateWithRelations(omit) {
|
|
312
|
-
return this.Container.resolve(
|
|
285
|
+
return this.Container.resolve(StandardModelWithRelationsDehydrator).dehydrate(this, [...(omit ?? []), ...this._hidden]);
|
|
313
286
|
}
|
|
314
287
|
toSql() {
|
|
315
|
-
return this.Container.resolve(
|
|
288
|
+
return this.Container.resolve(ModelToSqlConverter).toSql(this);
|
|
316
289
|
}
|
|
317
290
|
/**
|
|
318
291
|
* deletes enitt from db. If model have SoftDelete decorator, model is marked as deleted
|
|
@@ -328,10 +301,10 @@ class ModelBase {
|
|
|
328
301
|
*/
|
|
329
302
|
async archive() {
|
|
330
303
|
if (this.ModelDescriptor.Archived) {
|
|
331
|
-
this[this.ModelDescriptor.Archived.ArchivedAt] =
|
|
304
|
+
this[this.ModelDescriptor.Archived.ArchivedAt] = DateTime.now();
|
|
332
305
|
}
|
|
333
306
|
else {
|
|
334
|
-
throw new
|
|
307
|
+
throw new OrmException('archived at column not exists in model');
|
|
335
308
|
}
|
|
336
309
|
const { query } = this.createUpdateQuery();
|
|
337
310
|
await query.update(this.toSql()).where(this.PrimaryKeyName, this.PrimaryKeyValue);
|
|
@@ -339,7 +312,7 @@ class ModelBase {
|
|
|
339
312
|
async update() {
|
|
340
313
|
const { query } = this.createUpdateQuery();
|
|
341
314
|
if (this.ModelDescriptor.Timestamps.UpdatedAt) {
|
|
342
|
-
this[this.ModelDescriptor.Timestamps.UpdatedAt] =
|
|
315
|
+
this[this.ModelDescriptor.Timestamps.UpdatedAt] = DateTime.now();
|
|
343
316
|
}
|
|
344
317
|
await query.update(this.toSql()).where(this.PrimaryKeyName, this.PrimaryKeyValue);
|
|
345
318
|
}
|
|
@@ -347,23 +320,22 @@ class ModelBase {
|
|
|
347
320
|
* Save all changes to db. It creates new entry id db or updates existing one if
|
|
348
321
|
* primary key exists
|
|
349
322
|
*/
|
|
350
|
-
async insert(insertBehaviour =
|
|
323
|
+
async insert(insertBehaviour = InsertBehaviour.None) {
|
|
351
324
|
const { query, description } = this.createInsertQuery();
|
|
352
325
|
switch (insertBehaviour) {
|
|
353
|
-
case
|
|
326
|
+
case InsertBehaviour.InsertOrIgnore:
|
|
354
327
|
query.orIgnore();
|
|
355
328
|
break;
|
|
356
|
-
case
|
|
329
|
+
case InsertBehaviour.InsertOrUpdate:
|
|
357
330
|
query.onDuplicate().update(description.Columns.filter((c) => !c.PrimaryKey).map((c) => c.Name));
|
|
358
331
|
break;
|
|
359
|
-
case
|
|
332
|
+
case InsertBehaviour.InsertOrReplace:
|
|
360
333
|
query.orReplace();
|
|
361
334
|
break;
|
|
362
335
|
}
|
|
363
336
|
const iMidleware = {
|
|
364
337
|
afterQuery: (data) => {
|
|
365
|
-
|
|
366
|
-
this.PrimaryKeyValue = (_a = this.PrimaryKeyValue) !== null && _a !== void 0 ? _a : data.LastInsertId;
|
|
338
|
+
this.PrimaryKeyValue = this.PrimaryKeyValue ?? data.LastInsertId;
|
|
367
339
|
return data;
|
|
368
340
|
},
|
|
369
341
|
modelCreation: () => null,
|
|
@@ -379,7 +351,7 @@ class ModelBase {
|
|
|
379
351
|
*
|
|
380
352
|
* @param insertBehaviour - insert mode
|
|
381
353
|
*/
|
|
382
|
-
async insertOrUpdate(insertBehaviour =
|
|
354
|
+
async insertOrUpdate(insertBehaviour = InsertBehaviour.None) {
|
|
383
355
|
if (this.PrimaryKeyValue) {
|
|
384
356
|
await this.update();
|
|
385
357
|
}
|
|
@@ -421,17 +393,16 @@ class ModelBase {
|
|
|
421
393
|
* sets default values for model. values are taken from DB default column prop
|
|
422
394
|
*/
|
|
423
395
|
setDefaults() {
|
|
424
|
-
|
|
425
|
-
(_a = this.ModelDescriptor.Columns) === null || _a === void 0 ? void 0 : _a.forEach((c) => {
|
|
396
|
+
this.ModelDescriptor.Columns?.forEach((c) => {
|
|
426
397
|
if (c.Uuid) {
|
|
427
|
-
this[c.Name] = (
|
|
398
|
+
this[c.Name] = uuidv4();
|
|
428
399
|
}
|
|
429
400
|
else {
|
|
430
401
|
this[c.Name] = c.DefaultValue;
|
|
431
402
|
}
|
|
432
403
|
});
|
|
433
404
|
if (this.ModelDescriptor.Timestamps.CreatedAt) {
|
|
434
|
-
this[this.ModelDescriptor.Timestamps.CreatedAt] =
|
|
405
|
+
this[this.ModelDescriptor.Timestamps.CreatedAt] = DateTime.now();
|
|
435
406
|
}
|
|
436
407
|
for (const [, rel] of this.ModelDescriptor.Relations) {
|
|
437
408
|
if (rel.Factory) {
|
|
@@ -440,30 +411,29 @@ class ModelBase {
|
|
|
440
411
|
else if (rel.RelationClass) {
|
|
441
412
|
this[rel.Name] = this.Container.resolve(rel.RelationClass, [this, rel.TargetModel, rel, []]);
|
|
442
413
|
}
|
|
443
|
-
else if (rel.Type ===
|
|
444
|
-
this[rel.Name] = new
|
|
414
|
+
else if (rel.Type === RelationType.Many) {
|
|
415
|
+
this[rel.Name] = new OneToManyRelationList(this, rel.TargetModel, rel, []);
|
|
445
416
|
}
|
|
446
|
-
else if (rel.Type ===
|
|
447
|
-
this[rel.Name] = new
|
|
417
|
+
else if (rel.Type === RelationType.ManyToMany) {
|
|
418
|
+
this[rel.Name] = new ManyToManyRelationList(this, rel.TargetModel, rel, []);
|
|
448
419
|
}
|
|
449
420
|
else {
|
|
450
|
-
this[rel.Name] = new
|
|
421
|
+
this[rel.Name] = new SingleRelation(this, rel.TargetModel, rel, null);
|
|
451
422
|
}
|
|
452
423
|
}
|
|
453
424
|
}
|
|
454
425
|
createSelectQuery() {
|
|
455
|
-
return createQuery(this.constructor,
|
|
426
|
+
return createQuery(this.constructor, SelectQueryBuilder);
|
|
456
427
|
}
|
|
457
428
|
createUpdateQuery() {
|
|
458
|
-
return createQuery(this.constructor,
|
|
429
|
+
return createQuery(this.constructor, UpdateQueryBuilder);
|
|
459
430
|
}
|
|
460
431
|
createInsertQuery() {
|
|
461
|
-
return createQuery(this.constructor,
|
|
432
|
+
return createQuery(this.constructor, InsertQueryBuilder);
|
|
462
433
|
}
|
|
463
434
|
}
|
|
464
|
-
exports.ModelBase = ModelBase;
|
|
465
435
|
function _descriptor(model) {
|
|
466
|
-
return model[
|
|
436
|
+
return model[MODEL_DESCTRIPTION_SYMBOL];
|
|
467
437
|
}
|
|
468
438
|
function _preparePkWhere(description, query, model) {
|
|
469
439
|
if (description.PrimaryKey) {
|
|
@@ -477,31 +447,29 @@ function _preparePkWhere(description, query, model) {
|
|
|
477
447
|
}
|
|
478
448
|
}
|
|
479
449
|
else {
|
|
480
|
-
throw new
|
|
450
|
+
throw new OrmException('Model dont have primary key set or columns with unique constraint, cannot fetch model from database');
|
|
481
451
|
}
|
|
482
452
|
}
|
|
483
453
|
}
|
|
484
454
|
function _prepareOrderBy(description, query, order) {
|
|
485
|
-
var _a, _b;
|
|
486
455
|
if (description.PrimaryKey) {
|
|
487
|
-
query.order(description.PrimaryKey, order
|
|
456
|
+
query.order(description.PrimaryKey, order ?? SordOrder.DESC);
|
|
488
457
|
}
|
|
489
458
|
else {
|
|
490
459
|
const unique = description.Columns.filter((c) => c.Unique);
|
|
491
460
|
if (unique.length !== 0) {
|
|
492
|
-
unique.forEach((c) => query.order(c.Name, order
|
|
461
|
+
unique.forEach((c) => query.order(c.Name, order ?? SordOrder.DESC));
|
|
493
462
|
}
|
|
494
|
-
else if (
|
|
495
|
-
query.order(description.Timestamps.CreatedAt, order
|
|
463
|
+
else if (description.Timestamps?.CreatedAt) {
|
|
464
|
+
query.order(description.Timestamps.CreatedAt, order ?? SordOrder.DESC);
|
|
496
465
|
}
|
|
497
|
-
else if (
|
|
498
|
-
query.order(description.Timestamps.UpdatedAt, order
|
|
466
|
+
else if (description.Timestamps?.UpdatedAt) {
|
|
467
|
+
query.order(description.Timestamps.UpdatedAt, order ?? SordOrder.DESC);
|
|
499
468
|
}
|
|
500
469
|
}
|
|
501
470
|
}
|
|
502
|
-
class HistoricalModel {
|
|
471
|
+
export class HistoricalModel {
|
|
503
472
|
}
|
|
504
|
-
exports.HistoricalModel = HistoricalModel;
|
|
505
473
|
/**
|
|
506
474
|
* Helper function to create query based on model
|
|
507
475
|
*
|
|
@@ -511,19 +479,19 @@ exports.HistoricalModel = HistoricalModel;
|
|
|
511
479
|
*
|
|
512
480
|
* @returns
|
|
513
481
|
*/
|
|
514
|
-
function createQuery(model, query, injectModel = true) {
|
|
482
|
+
export function createQuery(model, query, injectModel = true) {
|
|
515
483
|
const dsc = _descriptor(model);
|
|
516
484
|
if (!dsc) {
|
|
517
485
|
throw new Error(`model ${model.name} does not have model descriptor. Use @model decorator on class`);
|
|
518
486
|
}
|
|
519
|
-
const orm =
|
|
487
|
+
const orm = DI.get(Orm);
|
|
520
488
|
const driver = orm.Connections.get(dsc.Connection);
|
|
521
489
|
if (!driver) {
|
|
522
490
|
throw new Error(`model ${model.name} have invalid connection ${dsc.Connection}, please check your db config file or model connection name`);
|
|
523
491
|
}
|
|
524
492
|
const cnt = driver.Container;
|
|
525
493
|
const qr = cnt.resolve(query, [driver, injectModel ? orm.Models.find((x) => x.name === model.name).type : null]);
|
|
526
|
-
if (qr instanceof
|
|
494
|
+
if (qr instanceof SelectQueryBuilder) {
|
|
527
495
|
const scope = model._queryScopes;
|
|
528
496
|
if (scope) {
|
|
529
497
|
Object.getOwnPropertyNames(scope.__proto__)
|
|
@@ -535,7 +503,7 @@ function createQuery(model, query, injectModel = true) {
|
|
|
535
503
|
});
|
|
536
504
|
}
|
|
537
505
|
}
|
|
538
|
-
qr.middleware(new
|
|
506
|
+
qr.middleware(new DiscriminationMapMiddleware(dsc));
|
|
539
507
|
qr.setTable(dsc.TableName);
|
|
540
508
|
if (driver.Options.Database) {
|
|
541
509
|
qr.database(driver.Options.Database);
|
|
@@ -547,15 +515,14 @@ function createQuery(model, query, injectModel = true) {
|
|
|
547
515
|
container: driver.Container,
|
|
548
516
|
};
|
|
549
517
|
}
|
|
550
|
-
|
|
551
|
-
exports.MODEL_STATIC_MIXINS = {
|
|
518
|
+
export const MODEL_STATIC_MIXINS = {
|
|
552
519
|
truncate() {
|
|
553
|
-
const { query } = createQuery(this,
|
|
520
|
+
const { query } = createQuery(this, TruncateTableQueryBuilder, false);
|
|
554
521
|
return query;
|
|
555
522
|
},
|
|
556
523
|
driver() {
|
|
557
524
|
const dsc = _descriptor(this);
|
|
558
|
-
const orm =
|
|
525
|
+
const orm = DI.get(Orm);
|
|
559
526
|
const driver = orm.Connections.get(dsc.Connection);
|
|
560
527
|
if (!driver) {
|
|
561
528
|
throw new Error(`model ${this.name} have invalid connection ${dsc.Connection}, please check your db config file or model connection name`);
|
|
@@ -563,20 +530,20 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
563
530
|
return driver;
|
|
564
531
|
},
|
|
565
532
|
query() {
|
|
566
|
-
const { query } = createQuery(this,
|
|
533
|
+
const { query } = createQuery(this, SelectQueryBuilder);
|
|
567
534
|
return query;
|
|
568
535
|
},
|
|
569
536
|
where(column, operator, value) {
|
|
570
|
-
const { query } = createQuery(this,
|
|
537
|
+
const { query } = createQuery(this, SelectQueryBuilder);
|
|
571
538
|
query.select('*');
|
|
572
539
|
return query.where(column, operator, value);
|
|
573
540
|
},
|
|
574
541
|
update(data) {
|
|
575
|
-
const { query } = createQuery(this,
|
|
542
|
+
const { query } = createQuery(this, UpdateQueryBuilder);
|
|
576
543
|
return query.update(data);
|
|
577
544
|
},
|
|
578
545
|
all(page, perPage) {
|
|
579
|
-
const { query } = createQuery(this,
|
|
546
|
+
const { query } = createQuery(this, SelectQueryBuilder);
|
|
580
547
|
query.select('*');
|
|
581
548
|
if (page >= 0 && perPage > 0) {
|
|
582
549
|
query.take(perPage).skip(page * perPage);
|
|
@@ -586,12 +553,12 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
586
553
|
/**
|
|
587
554
|
* Try to insert new value
|
|
588
555
|
*/
|
|
589
|
-
async insert(data, insertBehaviour =
|
|
590
|
-
const { query, description, container } = createQuery(this,
|
|
591
|
-
const converter = container.resolve(
|
|
556
|
+
async insert(data, insertBehaviour = InsertBehaviour.None) {
|
|
557
|
+
const { query, description, container } = createQuery(this, InsertQueryBuilder);
|
|
558
|
+
const converter = container.resolve(ObjectToSqlConverter);
|
|
592
559
|
if (Array.isArray(data)) {
|
|
593
|
-
if (insertBehaviour !==
|
|
594
|
-
throw new
|
|
560
|
+
if (insertBehaviour !== InsertBehaviour.None) {
|
|
561
|
+
throw new OrmException(`insert behaviour is not supported with arrays`);
|
|
595
562
|
}
|
|
596
563
|
query.values(data.map((d) => {
|
|
597
564
|
if (d instanceof ModelBase) {
|
|
@@ -602,13 +569,13 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
602
569
|
}
|
|
603
570
|
else {
|
|
604
571
|
switch (insertBehaviour) {
|
|
605
|
-
case
|
|
572
|
+
case InsertBehaviour.InsertOrIgnore:
|
|
606
573
|
query.orIgnore();
|
|
607
574
|
break;
|
|
608
|
-
case
|
|
575
|
+
case InsertBehaviour.InsertOrUpdate:
|
|
609
576
|
query.onDuplicate().update(description.Columns.filter((c) => !c.PrimaryKey).map((c) => c.Name));
|
|
610
577
|
break;
|
|
611
|
-
case
|
|
578
|
+
case InsertBehaviour.InsertOrReplace:
|
|
612
579
|
query.orReplace();
|
|
613
580
|
break;
|
|
614
581
|
}
|
|
@@ -621,17 +588,15 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
621
588
|
}
|
|
622
589
|
const iMidleware = {
|
|
623
590
|
afterQuery: (result) => {
|
|
624
|
-
var _a;
|
|
625
591
|
if (Array.isArray(data)) {
|
|
626
592
|
data.forEach((v, idx) => {
|
|
627
|
-
var _a;
|
|
628
593
|
if (v instanceof ModelBase) {
|
|
629
|
-
v.PrimaryKeyValue =
|
|
594
|
+
v.PrimaryKeyValue = v.PrimaryKeyValue ?? result.LastInsertId - data.length + idx;
|
|
630
595
|
}
|
|
631
596
|
});
|
|
632
597
|
}
|
|
633
598
|
else if (data instanceof ModelBase) {
|
|
634
|
-
data.PrimaryKeyValue =
|
|
599
|
+
data.PrimaryKeyValue = data.PrimaryKeyValue ?? result.LastInsertId;
|
|
635
600
|
}
|
|
636
601
|
return result;
|
|
637
602
|
},
|
|
@@ -642,14 +607,14 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
642
607
|
return query;
|
|
643
608
|
},
|
|
644
609
|
async find(pks) {
|
|
645
|
-
const { query, description } = createQuery(this,
|
|
610
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
646
611
|
const pkey = description.PrimaryKey;
|
|
647
612
|
query.select('*');
|
|
648
613
|
query.whereIn(pkey, pks);
|
|
649
614
|
return await query;
|
|
650
615
|
},
|
|
651
616
|
async findOrFail(pks) {
|
|
652
|
-
const { query, description, model } = createQuery(this,
|
|
617
|
+
const { query, description, model } = createQuery(this, SelectQueryBuilder);
|
|
653
618
|
const pkey = description.PrimaryKey;
|
|
654
619
|
query.select('*');
|
|
655
620
|
query.whereIn(pkey, pks);
|
|
@@ -660,7 +625,7 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
660
625
|
return result;
|
|
661
626
|
},
|
|
662
627
|
async get(pk) {
|
|
663
|
-
const { query, description } = createQuery(this,
|
|
628
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
664
629
|
const pkey = description.PrimaryKey;
|
|
665
630
|
query.select('*');
|
|
666
631
|
query.where(pkey, pk);
|
|
@@ -668,7 +633,7 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
668
633
|
return (await query.first());
|
|
669
634
|
},
|
|
670
635
|
async getOrFail(pk) {
|
|
671
|
-
const { query, description } = createQuery(this,
|
|
636
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
672
637
|
const pkey = description.PrimaryKey;
|
|
673
638
|
query.select('*');
|
|
674
639
|
query.where(pkey, pk);
|
|
@@ -676,13 +641,12 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
676
641
|
return (await query.firstOrFail());
|
|
677
642
|
},
|
|
678
643
|
destroy(pks) {
|
|
679
|
-
var _a, _b;
|
|
680
644
|
const description = _descriptor(this);
|
|
681
645
|
const data = Array.isArray(pks) ? pks : [pks];
|
|
682
|
-
const { query } =
|
|
683
|
-
if (
|
|
646
|
+
const { query } = description.SoftDelete?.DeletedAt ? createQuery(this, UpdateQueryBuilder) : createQuery(this, DeleteQueryBuilder);
|
|
647
|
+
if (description.SoftDelete?.DeletedAt) {
|
|
684
648
|
query.update({
|
|
685
|
-
[description.SoftDelete.DeletedAt]:
|
|
649
|
+
[description.SoftDelete.DeletedAt]: DateTime.now(),
|
|
686
650
|
});
|
|
687
651
|
}
|
|
688
652
|
if (pks) {
|
|
@@ -696,7 +660,7 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
696
660
|
return entity;
|
|
697
661
|
},
|
|
698
662
|
async getOrCreate(pk, data) {
|
|
699
|
-
const { query, description } = createQuery(this,
|
|
663
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
700
664
|
// pk constrain
|
|
701
665
|
if (description.PrimaryKey && pk !== null) {
|
|
702
666
|
query.where(description.PrimaryKey, pk);
|
|
@@ -715,7 +679,7 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
715
679
|
return entity;
|
|
716
680
|
},
|
|
717
681
|
async getOrNew(pk, data) {
|
|
718
|
-
const { query, description } = createQuery(this,
|
|
682
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
719
683
|
// pk constrain
|
|
720
684
|
if (description.PrimaryKey) {
|
|
721
685
|
query.where(description.PrimaryKey, pk);
|
|
@@ -733,29 +697,28 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
733
697
|
return entity;
|
|
734
698
|
},
|
|
735
699
|
async first(callback) {
|
|
736
|
-
const { query, description } = createQuery(this,
|
|
737
|
-
_prepareOrderBy(description, query,
|
|
700
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
701
|
+
_prepareOrderBy(description, query, SordOrder.ASC);
|
|
738
702
|
if (callback) {
|
|
739
703
|
callback(query);
|
|
740
704
|
}
|
|
741
705
|
return (await query.first());
|
|
742
706
|
},
|
|
743
707
|
async last(callback) {
|
|
744
|
-
const { query, description } = createQuery(this,
|
|
745
|
-
_prepareOrderBy(description, query,
|
|
708
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
709
|
+
_prepareOrderBy(description, query, SordOrder.DESC);
|
|
746
710
|
if (callback) {
|
|
747
711
|
callback(query);
|
|
748
712
|
}
|
|
749
713
|
return (await query.first());
|
|
750
714
|
},
|
|
751
715
|
async newest(callback) {
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
query.order(description.Timestamps.CreatedAt, enums_1.SordOrder.DESC);
|
|
716
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
717
|
+
if (description.Timestamps?.CreatedAt) {
|
|
718
|
+
query.order(description.Timestamps.CreatedAt, SordOrder.DESC);
|
|
756
719
|
}
|
|
757
720
|
else {
|
|
758
|
-
throw new
|
|
721
|
+
throw new OrmException('cannot fetch newest entity - CreateAt column not exists in model/db');
|
|
759
722
|
}
|
|
760
723
|
if (callback) {
|
|
761
724
|
callback(query);
|
|
@@ -763,13 +726,12 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
763
726
|
return (await query.first());
|
|
764
727
|
},
|
|
765
728
|
async oldest(callback) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
query.order(description.Timestamps.CreatedAt, enums_1.SordOrder.ASC);
|
|
729
|
+
const { query, description } = createQuery(this, SelectQueryBuilder);
|
|
730
|
+
if (description.Timestamps?.CreatedAt) {
|
|
731
|
+
query.order(description.Timestamps.CreatedAt, SordOrder.ASC);
|
|
770
732
|
}
|
|
771
733
|
else {
|
|
772
|
-
throw new
|
|
734
|
+
throw new OrmException('cannot fetch oldest entity - CreateAt column not exists in model/db');
|
|
773
735
|
}
|
|
774
736
|
if (callback) {
|
|
775
737
|
callback(query);
|
|
@@ -777,7 +739,7 @@ exports.MODEL_STATIC_MIXINS = {
|
|
|
777
739
|
return (await query.first());
|
|
778
740
|
},
|
|
779
741
|
async count(callback) {
|
|
780
|
-
const { query } = createQuery(this,
|
|
742
|
+
const { query } = createQuery(this, SelectQueryBuilder);
|
|
781
743
|
query.count('*', 'count');
|
|
782
744
|
if (callback) {
|
|
783
745
|
callback(query);
|