@reldens/storage 0.88.0 → 0.89.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/.claude/driver-methods-complete-analysis.md +1978 -0
- package/.claude/test-architecture.md +973 -0
- package/CLAUDE.md +121 -1
- package/bin/reldens-storage.js +1 -1
- package/lib/base-driver.js +8 -0
- package/lib/entities-generator.js +1 -3
- package/lib/entity-templates/mikro-orm-model.template +2 -1
- package/lib/generators/models-generation.js +126 -5
- package/lib/mikro-orm/mikro-orm-data-server.js +24 -10
- package/lib/mikro-orm/mikro-orm-driver.js +184 -116
- package/lib/objection-js/objection-js-driver.js +111 -19
- package/lib/prisma/prisma-data-server.js +3 -2
- package/lib/prisma/prisma-driver.js +12 -10
- package/lib/prisma/prisma-filter-processor.js +193 -146
- package/lib/prisma/prisma-metadata-loader.js +0 -4
- package/lib/prisma/prisma-relation-resolver.js +292 -267
- package/lib/prisma/prisma-type-caster.js +280 -260
- package/package.json +15 -6
- package/tests/.env.test.example +7 -0
- package/tests/fixtures/categories-fixtures.js +164 -0
- package/tests/fixtures/expected-entities-mikro-orm/entities/test-categories-entity.js +70 -0
- package/tests/fixtures/expected-entities-mikro-orm/entities/test-products-entity.js +95 -0
- package/tests/fixtures/expected-entities-mikro-orm/entities/test-reviews-entity.js +84 -0
- package/tests/fixtures/expected-entities-mikro-orm/entities-config.js +17 -0
- package/tests/fixtures/expected-entities-mikro-orm/entities-translations.js +13 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/registered-models-mikro-orm.js +23 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-categories-model.js +57 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-products-model.js +79 -0
- package/tests/fixtures/expected-entities-mikro-orm/models/mikro-orm/test-reviews-model.js +70 -0
- package/tests/fixtures/expected-entities-objection-js/entities/test-categories-entity.js +70 -0
- package/tests/fixtures/expected-entities-objection-js/entities/test-products-entity.js +95 -0
- package/tests/fixtures/expected-entities-objection-js/entities/test-reviews-entity.js +84 -0
- package/tests/fixtures/expected-entities-objection-js/entities-config.js +17 -0
- package/tests/fixtures/expected-entities-objection-js/entities-translations.js +13 -0
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/registered-models-objection-js.js +23 -0
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-categories-model.js +33 -0
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-products-model.js +42 -0
- package/tests/fixtures/expected-entities-objection-js/models/objection-js/test-reviews-model.js +33 -0
- package/tests/fixtures/expected-entities-prisma/entities/test-categories-entity.js +70 -0
- package/tests/fixtures/expected-entities-prisma/entities/test-products-entity.js +95 -0
- package/tests/fixtures/expected-entities-prisma/entities/test-reviews-entity.js +84 -0
- package/tests/fixtures/expected-entities-prisma/entities-config.js +17 -0
- package/tests/fixtures/expected-entities-prisma/entities-translations.js +13 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/registered-models-prisma.js +23 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/test-categories-model.js +43 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/test-products-model.js +50 -0
- package/tests/fixtures/expected-entities-prisma/models/prisma/test-reviews-model.js +46 -0
- package/tests/fixtures/products-fixtures.js +119 -0
- package/tests/fixtures/reviews-fixtures.js +42 -0
- package/tests/fixtures/sql/test-schema.sql +59 -0
- package/tests/integration/test-drivers.js +257 -0
- package/tests/integration/test-nested-filters.js +408 -0
- package/tests/integration/test-relations.js +349 -0
- package/tests/run-tests.js +213 -0
- package/tests/unit/test-drivers.js +89 -0
- package/tests/unit/test-entities-generator.js +533 -0
- package/tests/unit/test-entity-manager.js +128 -0
- package/tests/unit/test-type-mapper.js +232 -0
- package/tests/utils/custom-reporter.js +73 -0
- package/tests/utils/driver-registry.js +144 -0
- package/tests/utils/prisma-subprocess-worker.js +150 -0
- package/tests/utils/test-helpers.js +726 -0
- package/tests/utils/test-runner.js +63 -0
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
const { BaseDriver } = require('../base-driver');
|
|
8
8
|
const { Logger, sc } = require('@reldens/utils');
|
|
9
|
+
const { Collection } = require('@mikro-orm/core');
|
|
9
10
|
|
|
10
11
|
class MikroOrmDriver extends BaseDriver
|
|
11
12
|
{
|
|
@@ -27,7 +28,19 @@ class MikroOrmDriver extends BaseDriver
|
|
|
27
28
|
}
|
|
28
29
|
this.orm = props.orm;
|
|
29
30
|
this.server = props.server;
|
|
30
|
-
this.
|
|
31
|
+
this.entitySchema = (sc.isObject(this.rawModel) && sc.hasOwn(this.rawModel, 'schema')) ? this.rawModel.schema : this.rawModel;
|
|
32
|
+
this.repository = this.orm.em.getRepository(this.entitySchema);
|
|
33
|
+
this.mikroOrmOperators = {
|
|
34
|
+
'GT': '$gt',
|
|
35
|
+
'GTE': '$gte',
|
|
36
|
+
'LT': '$lt',
|
|
37
|
+
'LTE': '$lte',
|
|
38
|
+
'NE': '$ne',
|
|
39
|
+
'NOT': '$ne',
|
|
40
|
+
'IN': '$in',
|
|
41
|
+
'NOT IN': '$nin'
|
|
42
|
+
};
|
|
43
|
+
this.fkMappings = this.rawModel._fkMappings || this.entitySchema._fkMappings || {};
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
databaseName()
|
|
@@ -37,17 +50,17 @@ class MikroOrmDriver extends BaseDriver
|
|
|
37
50
|
|
|
38
51
|
id()
|
|
39
52
|
{
|
|
40
|
-
return this.rawModel.entity.name || this.name();
|
|
53
|
+
return (this.rawModel.entity || this.rawModel).name || this.name();
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
name()
|
|
44
57
|
{
|
|
45
|
-
return this.rawModel.entity.name || this.config.dbName;
|
|
58
|
+
return (this.rawModel.entity || this.rawModel).name || this.config.dbName;
|
|
46
59
|
}
|
|
47
60
|
|
|
48
61
|
tableName()
|
|
49
62
|
{
|
|
50
|
-
return this.rawModel.entity.name;
|
|
63
|
+
return (this.rawModel.entity || this.rawModel).name;
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
property(propertyName)
|
|
@@ -57,16 +70,25 @@ class MikroOrmDriver extends BaseDriver
|
|
|
57
70
|
|
|
58
71
|
getAllRelations()
|
|
59
72
|
{
|
|
60
|
-
if(
|
|
73
|
+
if(!this.entitySchema.meta || !this.entitySchema.meta.properties){
|
|
61
74
|
return [];
|
|
62
75
|
}
|
|
63
|
-
|
|
76
|
+
let relations = [];
|
|
77
|
+
for(let propName of Object.keys(this.entitySchema.meta.properties)){
|
|
78
|
+
let prop = this.entitySchema.meta.properties[propName];
|
|
79
|
+
if(prop.kind === 'm:1' || prop.kind === '1:m' || prop.kind === 'm:n'){
|
|
80
|
+
relations.push(propName);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return relations;
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
async create(params)
|
|
67
87
|
{
|
|
68
|
-
let
|
|
88
|
+
let transformed = this.transformFkToRelations(params);
|
|
89
|
+
let newInstance = await this.orm.em.create(this.entitySchema, transformed);
|
|
69
90
|
await this.orm.em.upsert(newInstance);
|
|
91
|
+
await this.orm.em.flush();
|
|
70
92
|
return newInstance;
|
|
71
93
|
}
|
|
72
94
|
|
|
@@ -80,53 +102,61 @@ class MikroOrmDriver extends BaseDriver
|
|
|
80
102
|
return await this.appendRelationsToCollection(newInstance, relations);
|
|
81
103
|
}
|
|
82
104
|
|
|
83
|
-
async
|
|
105
|
+
async applyUpdateToEntities(processedFilters, updatePatch)
|
|
84
106
|
{
|
|
85
|
-
let processedFilters = this.processFilters(filters);
|
|
86
107
|
let entities = await this.repository.find(processedFilters, this.queryBuilder(true, true, true));
|
|
87
108
|
if(0 === entities.length){
|
|
88
109
|
return false;
|
|
89
110
|
}
|
|
111
|
+
let transformed = this.transformFkToRelations(updatePatch);
|
|
90
112
|
for(let entity of entities){
|
|
91
|
-
Object.assign(entity,
|
|
113
|
+
Object.assign(entity, transformed);
|
|
92
114
|
await this.orm.em.upsert(entity);
|
|
93
115
|
await this.orm.em.flush();
|
|
94
116
|
}
|
|
95
117
|
return entities;
|
|
96
118
|
}
|
|
97
119
|
|
|
120
|
+
async update(filters, updatePatch)
|
|
121
|
+
{
|
|
122
|
+
let processedFilters = this.processFilters(filters);
|
|
123
|
+
return this.applyUpdateToEntities(processedFilters, updatePatch);
|
|
124
|
+
}
|
|
125
|
+
|
|
98
126
|
async updateBy(field, fieldValue, updatePatch, operator = null)
|
|
99
127
|
{
|
|
100
128
|
let filter = this.createSingleFilter(field, fieldValue, operator);
|
|
101
129
|
let processedFilters = this.processFilters(filter);
|
|
102
|
-
|
|
103
|
-
if(0 === entities.length){
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
for(let entity of entities){
|
|
107
|
-
Object.assign(entity, updatePatch);
|
|
108
|
-
await this.orm.em.upsert(entity);
|
|
109
|
-
await this.orm.em.flush();
|
|
110
|
-
}
|
|
111
|
-
return entities;
|
|
130
|
+
return this.applyUpdateToEntities(processedFilters, updatePatch);
|
|
112
131
|
}
|
|
113
132
|
|
|
114
|
-
updateById(id, params)
|
|
133
|
+
async updateById(id, params)
|
|
115
134
|
{
|
|
116
|
-
|
|
135
|
+
let entities = await this.update({id}, params);
|
|
136
|
+
if(!entities){
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
if(1 < entities.length){
|
|
140
|
+
Logger.warning('Multiple entities updated by ID: '+entities.map(e => e.id).join(', '));
|
|
141
|
+
}
|
|
142
|
+
return entities.shift();
|
|
117
143
|
}
|
|
118
144
|
|
|
119
145
|
async upsert(params, filters)
|
|
120
146
|
{
|
|
121
147
|
if(params.id){
|
|
122
|
-
let
|
|
123
|
-
|
|
124
|
-
|
|
148
|
+
let existent = await this.loadById(params.id);
|
|
149
|
+
if(existent){
|
|
150
|
+
let patch = Object.assign({}, params);
|
|
151
|
+
delete patch.id;
|
|
152
|
+
return this.updateById(params.id, patch);
|
|
153
|
+
}
|
|
125
154
|
}
|
|
126
155
|
if(filters){
|
|
127
156
|
let existent = await this.loadOne(filters);
|
|
128
157
|
if(existent){
|
|
129
|
-
|
|
158
|
+
let transformed = this.transformFkToRelations(params);
|
|
159
|
+
return this.updateById(existent.id, transformed);
|
|
130
160
|
}
|
|
131
161
|
}
|
|
132
162
|
return this.create(params);
|
|
@@ -136,17 +166,25 @@ class MikroOrmDriver extends BaseDriver
|
|
|
136
166
|
{
|
|
137
167
|
let processedFilters = this.processFilters(filters);
|
|
138
168
|
let entries = await this.repository.find(processedFilters);
|
|
139
|
-
if(!entries){
|
|
169
|
+
if(!entries || 0 === entries.length){
|
|
140
170
|
return false;
|
|
141
171
|
}
|
|
142
172
|
for(let entry of entries){
|
|
143
|
-
await this.
|
|
173
|
+
await this.orm.em.remove(entry);
|
|
144
174
|
}
|
|
175
|
+
await this.orm.em.flush();
|
|
176
|
+
return true;
|
|
145
177
|
}
|
|
146
178
|
|
|
147
|
-
deleteById(id)
|
|
179
|
+
async deleteById(id)
|
|
148
180
|
{
|
|
149
|
-
|
|
181
|
+
let entity = await this.loadById(id);
|
|
182
|
+
if(!entity){
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
await this.orm.em.remove(entity);
|
|
186
|
+
await this.orm.em.flush();
|
|
187
|
+
return true;
|
|
150
188
|
}
|
|
151
189
|
|
|
152
190
|
async count(filters)
|
|
@@ -161,31 +199,30 @@ class MikroOrmDriver extends BaseDriver
|
|
|
161
199
|
relations = this.getAllRelations();
|
|
162
200
|
}
|
|
163
201
|
let processedFilters = this.processFilters(filters);
|
|
164
|
-
if(0 === relations.length ||
|
|
202
|
+
if(0 === relations.length || !this.entitySchema.meta || !this.entitySchema.meta.properties){
|
|
165
203
|
return this.repository.count(processedFilters);
|
|
166
204
|
}
|
|
167
|
-
let queryBuilder = this.orm.em.createQueryBuilder(this.
|
|
168
|
-
let
|
|
205
|
+
let queryBuilder = this.orm.em.createQueryBuilder(this.entitySchema);
|
|
206
|
+
let properties = this.entitySchema.meta.properties;
|
|
169
207
|
let aliasCounter = 0;
|
|
170
208
|
for(let relationName of relations){
|
|
171
|
-
let
|
|
172
|
-
if(!
|
|
209
|
+
let prop = properties[relationName];
|
|
210
|
+
if(!prop || !prop.kind || (prop.kind !== 'm:1' && prop.kind !== '1:m')){
|
|
173
211
|
continue;
|
|
174
212
|
}
|
|
175
|
-
let
|
|
176
|
-
if(!
|
|
213
|
+
let relationDriver = this.server.entityManager.get(prop.entity);
|
|
214
|
+
if(!relationDriver || !relationDriver.entitySchema){
|
|
177
215
|
continue;
|
|
178
216
|
}
|
|
179
217
|
let alias = 'rel_'+aliasCounter;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
let isManyToOne = 'm:1' === relation.reference;
|
|
183
|
-
let isOneToMany = '1:m' === relation.reference;
|
|
184
|
-
if(isManyToOne){
|
|
185
|
-
queryBuilder.leftJoin(relationEntity.rawModel, alias, 'e.'+joinField+' = '+alias+'.'+targetField);
|
|
218
|
+
if('m:1' === prop.kind && prop.joinColumn){
|
|
219
|
+
queryBuilder.leftJoin(relationName, alias, 'e.'+prop.joinColumn+' = '+alias+'.id');
|
|
186
220
|
}
|
|
187
|
-
if(
|
|
188
|
-
|
|
221
|
+
if('1:m' === prop.kind && prop.mappedBy){
|
|
222
|
+
let mappedProp = relationDriver.entitySchema.meta.properties[prop.mappedBy];
|
|
223
|
+
if(mappedProp && mappedProp.joinColumn){
|
|
224
|
+
queryBuilder.leftJoin(relationName, alias, 'e.id = '+alias+'.'+mappedProp.joinColumn);
|
|
225
|
+
}
|
|
189
226
|
}
|
|
190
227
|
aliasCounter++;
|
|
191
228
|
}
|
|
@@ -245,7 +282,7 @@ class MikroOrmDriver extends BaseDriver
|
|
|
245
282
|
|
|
246
283
|
loadById(id)
|
|
247
284
|
{
|
|
248
|
-
return this.
|
|
285
|
+
return this.loadOneBy('id', id);
|
|
249
286
|
}
|
|
250
287
|
|
|
251
288
|
async loadByIdWithRelations(id, relations)
|
|
@@ -253,7 +290,7 @@ class MikroOrmDriver extends BaseDriver
|
|
|
253
290
|
if(!sc.isArray(relations) || 0 === relations.length){
|
|
254
291
|
relations = this.getAllRelations();
|
|
255
292
|
}
|
|
256
|
-
let entity = await this.
|
|
293
|
+
let entity = await this.loadOneBy('id', id);
|
|
257
294
|
return await this.appendRelationsToCollection(entity, relations);
|
|
258
295
|
}
|
|
259
296
|
|
|
@@ -305,6 +342,10 @@ class MikroOrmDriver extends BaseDriver
|
|
|
305
342
|
let processedFilters = {};
|
|
306
343
|
for(let key of Object.keys(filters)){
|
|
307
344
|
let value = filters[key];
|
|
345
|
+
if('AND' === key && sc.isArray(value)){
|
|
346
|
+
processedFilters.$and = value.map(condition => this.processFilters(condition));
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
308
349
|
if('OR' === key && sc.isArray(value)){
|
|
309
350
|
processedFilters.$or = value.map(condition => this.processFilters(condition));
|
|
310
351
|
continue;
|
|
@@ -328,26 +369,22 @@ class MikroOrmDriver extends BaseDriver
|
|
|
328
369
|
if('LIKE' === upperOperator){
|
|
329
370
|
return this.handleLikeOperator(value, fieldName);
|
|
330
371
|
}
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
'IN': {$in: value},
|
|
339
|
-
'NOT IN': {$nin: value}
|
|
340
|
-
};
|
|
341
|
-
return operatorsMap[upperOperator] || value;
|
|
372
|
+
if('EQ' === upperOperator){
|
|
373
|
+
return value;
|
|
374
|
+
}
|
|
375
|
+
if(sc.hasOwn(this.mikroOrmOperators, upperOperator)){
|
|
376
|
+
return {[this.mikroOrmOperators[upperOperator]]: value};
|
|
377
|
+
}
|
|
378
|
+
return value;
|
|
342
379
|
}
|
|
343
380
|
|
|
344
381
|
handleLikeOperator(value, fieldName)
|
|
345
382
|
{
|
|
346
383
|
let cleanValue = String(value).replace(/%/g, '');
|
|
347
384
|
if(this.isJsonField(fieldName)){
|
|
348
|
-
return {$like: '%'
|
|
385
|
+
return {$like: '%'+cleanValue+'%'};
|
|
349
386
|
}
|
|
350
|
-
return {$like: '%'
|
|
387
|
+
return {$like: '%'+cleanValue+'%'};
|
|
351
388
|
}
|
|
352
389
|
|
|
353
390
|
queryBuilder(useLimit = false, useOffset = false, useSort = false)
|
|
@@ -362,7 +399,7 @@ class MikroOrmDriver extends BaseDriver
|
|
|
362
399
|
if(useOffset && 0 !== this.offset){
|
|
363
400
|
queryBuilder.offset = this.offset;
|
|
364
401
|
}
|
|
365
|
-
if(useSort &&
|
|
402
|
+
if(useSort && this.sortBy && this.sortDirection){
|
|
366
403
|
queryBuilder.orderBy = {
|
|
367
404
|
[this.sortBy]: this.sortDirection,
|
|
368
405
|
};
|
|
@@ -381,99 +418,130 @@ class MikroOrmDriver extends BaseDriver
|
|
|
381
418
|
return filter;
|
|
382
419
|
}
|
|
383
420
|
|
|
384
|
-
|
|
421
|
+
convertCollectionsToArrays(entity)
|
|
385
422
|
{
|
|
386
|
-
if(
|
|
387
|
-
return
|
|
388
|
-
}
|
|
389
|
-
if(!sc.isArray(relations) || 0 === relations.length){
|
|
390
|
-
relations = this.getAllRelations();
|
|
391
|
-
}
|
|
392
|
-
if(0 === relations.length){
|
|
393
|
-
return entitiesCollection;
|
|
423
|
+
if(!entity){
|
|
424
|
+
return entity;
|
|
394
425
|
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
426
|
+
for(let key of Object.keys(entity)){
|
|
427
|
+
if(entity[key] && entity[key] instanceof Collection){
|
|
428
|
+
entity[key] = entity[key].getItems();
|
|
398
429
|
}
|
|
399
430
|
}
|
|
400
|
-
|
|
401
|
-
await this.appendRelatedEntities(entitiesCollection, relations);
|
|
402
|
-
}
|
|
403
|
-
return entitiesCollection;
|
|
431
|
+
return entity;
|
|
404
432
|
}
|
|
405
433
|
|
|
406
|
-
|
|
434
|
+
addFkFieldsFromRelations(entity)
|
|
407
435
|
{
|
|
408
|
-
if(
|
|
436
|
+
if(!entity){
|
|
409
437
|
return entity;
|
|
410
438
|
}
|
|
411
|
-
let
|
|
412
|
-
|
|
413
|
-
let relation =
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if(
|
|
418
|
-
entity[
|
|
439
|
+
for(let fkColumn of Object.keys(this.fkMappings)){
|
|
440
|
+
let mapping = this.fkMappings[fkColumn];
|
|
441
|
+
let relation = entity[mapping.relationKey];
|
|
442
|
+
if(!relation){
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if(sc.hasOwn(relation, mapping.referencedColumn)){
|
|
446
|
+
entity[fkColumn] = relation[mapping.referencedColumn];
|
|
447
|
+
continue;
|
|
419
448
|
}
|
|
420
|
-
if(
|
|
421
|
-
entity[
|
|
449
|
+
if(sc.hasOwn(relation, 'id')){
|
|
450
|
+
entity[fkColumn] = relation.id;
|
|
422
451
|
}
|
|
423
452
|
}
|
|
424
453
|
return entity;
|
|
425
454
|
}
|
|
426
455
|
|
|
456
|
+
async appendRelationsToCollection(entitiesCollection, relations)
|
|
457
|
+
{
|
|
458
|
+
if(!relations || 0 === relations.length){
|
|
459
|
+
return entitiesCollection;
|
|
460
|
+
}
|
|
461
|
+
if(!entitiesCollection){
|
|
462
|
+
return entitiesCollection;
|
|
463
|
+
}
|
|
464
|
+
await this.orm.em.populate(entitiesCollection, relations);
|
|
465
|
+
if(sc.isArray(entitiesCollection)){
|
|
466
|
+
for(let entity of entitiesCollection){
|
|
467
|
+
this.convertCollectionsToArrays(entity);
|
|
468
|
+
}
|
|
469
|
+
return entitiesCollection;
|
|
470
|
+
}
|
|
471
|
+
return this.convertCollectionsToArrays(entitiesCollection);
|
|
472
|
+
}
|
|
473
|
+
|
|
427
474
|
async createNested(newInstance, params, relations)
|
|
428
475
|
{
|
|
429
|
-
if(
|
|
476
|
+
if(!this.entitySchema.meta || !this.entitySchema.meta.properties){
|
|
430
477
|
return false;
|
|
431
478
|
}
|
|
432
|
-
let
|
|
433
|
-
for(let
|
|
434
|
-
|
|
479
|
+
let properties = this.entitySchema.meta.properties;
|
|
480
|
+
for(let relationName of Object.keys(properties)){
|
|
481
|
+
let prop = properties[relationName];
|
|
482
|
+
if(!prop.kind || (prop.kind !== 'm:1' && prop.kind !== '1:m')){
|
|
435
483
|
continue;
|
|
436
484
|
}
|
|
437
|
-
|
|
438
|
-
let relationEntity = this.server.entityManager.get(relation.entityName).rawModel.entity;
|
|
439
|
-
if(!relationEntity){
|
|
440
|
-
Logger.warning('Factory not found for relation definition:', relation);
|
|
485
|
+
if(sc.isArray(relations) && 0 < relations.length && -1 === relations.indexOf(relationName)){
|
|
441
486
|
continue;
|
|
442
487
|
}
|
|
443
|
-
let
|
|
444
|
-
if(!
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
488
|
+
let relationDriver = this.server.entityManager.get(prop.entity);
|
|
489
|
+
if(!relationDriver){
|
|
490
|
+
Logger.warning('Entity not found for relation:', prop.entity);
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
let isOneToMany = '1:m' === prop.kind;
|
|
494
|
+
let isManyToOne = 'm:1' === prop.kind;
|
|
495
|
+
if(isManyToOne && sc.hasOwn(params, relationName)){
|
|
496
|
+
await this.createOne(params, relationName, relationDriver, newInstance, prop);
|
|
449
497
|
continue;
|
|
450
498
|
}
|
|
451
|
-
if(isArray){
|
|
452
|
-
await this.createMany(params,
|
|
499
|
+
if(isOneToMany && sc.hasOwn(params, relationName) && sc.isArray(params[relationName])){
|
|
500
|
+
await this.createMany(params, relationName, relationDriver, newInstance, prop);
|
|
453
501
|
}
|
|
454
502
|
}
|
|
455
503
|
}
|
|
456
504
|
|
|
457
|
-
async createOne(params,
|
|
505
|
+
async createOne(params, relationName, relationDriver, newInstance, prop)
|
|
458
506
|
{
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
507
|
+
let nestedData = params[relationName];
|
|
508
|
+
if(prop.joinColumn){
|
|
509
|
+
nestedData[prop.joinColumn] = newInstance.id;
|
|
510
|
+
}
|
|
511
|
+
let nestedObject = await relationDriver.create(nestedData);
|
|
462
512
|
await this.orm.em.flush();
|
|
463
|
-
newInstance[
|
|
513
|
+
newInstance[relationName] = nestedObject;
|
|
464
514
|
}
|
|
465
515
|
|
|
466
|
-
async createMany(params,
|
|
516
|
+
async createMany(params, relationName, relationDriver, newInstance, prop)
|
|
467
517
|
{
|
|
468
518
|
let nestedArray = [];
|
|
469
|
-
for(let objectData of params[
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
519
|
+
for(let objectData of params[relationName]){
|
|
520
|
+
if(prop.joinColumn){
|
|
521
|
+
objectData[prop.joinColumn] = newInstance.id;
|
|
522
|
+
}
|
|
523
|
+
let nestedObject = await relationDriver.create(objectData);
|
|
473
524
|
await this.orm.em.flush();
|
|
474
525
|
nestedArray.push(nestedObject);
|
|
475
526
|
}
|
|
476
|
-
newInstance[
|
|
527
|
+
newInstance[relationName] = nestedArray;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
transformFkToRelations(params)
|
|
531
|
+
{
|
|
532
|
+
if(!params || 'object' !== typeof params){
|
|
533
|
+
return params;
|
|
534
|
+
}
|
|
535
|
+
let transformed = {...params};
|
|
536
|
+
for(let fkColumn of Object.keys(this.fkMappings)){
|
|
537
|
+
if(!sc.hasOwn(params, fkColumn) || null === params[fkColumn]){
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
let mapping = this.fkMappings[fkColumn];
|
|
541
|
+
transformed[mapping.relationKey] = this.orm.em.getReference(mapping.entityName, params[fkColumn]);
|
|
542
|
+
delete transformed[fkColumn];
|
|
543
|
+
}
|
|
544
|
+
return transformed;
|
|
477
545
|
}
|
|
478
546
|
|
|
479
547
|
}
|