@spinajs/orm 2.0.175 → 2.0.177
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/lib/cjs/builders.d.ts.map +1 -1
- package/lib/cjs/builders.js +9 -14
- package/lib/cjs/builders.js.map +1 -1
- package/lib/cjs/decorators.d.ts +1 -1
- package/lib/cjs/decorators.d.ts.map +1 -1
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/cjs/hydrators.d.ts.map +1 -1
- package/lib/cjs/hydrators.js +3 -3
- package/lib/cjs/hydrators.js.map +1 -1
- package/lib/cjs/index.d.ts +2 -0
- package/lib/cjs/index.d.ts.map +1 -1
- package/lib/cjs/index.js +2 -0
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/interfaces.d.ts +10 -2
- package/lib/cjs/interfaces.d.ts.map +1 -1
- package/lib/cjs/interfaces.js.map +1 -1
- package/lib/cjs/middlewares.d.ts +63 -0
- package/lib/cjs/middlewares.d.ts.map +1 -0
- package/lib/cjs/middlewares.js +259 -0
- package/lib/cjs/middlewares.js.map +1 -0
- package/lib/cjs/model.d.ts.map +1 -1
- package/lib/cjs/model.js +6 -5
- package/lib/cjs/model.js.map +1 -1
- package/lib/cjs/orm.d.ts.map +1 -1
- package/lib/cjs/orm.js +14 -8
- package/lib/cjs/orm.js.map +1 -1
- package/lib/cjs/relation-objects.d.ts +109 -0
- package/lib/cjs/relation-objects.d.ts.map +1 -0
- package/lib/cjs/relation-objects.js +222 -0
- package/lib/cjs/relation-objects.js.map +1 -0
- package/lib/cjs/relations.d.ts +24 -158
- package/lib/cjs/relations.d.ts.map +1 -1
- package/lib/cjs/relations.js +50 -500
- package/lib/cjs/relations.js.map +1 -1
- package/lib/cjs/types.d.ts +1 -1
- package/lib/cjs/types.d.ts.map +1 -1
- package/lib/mjs/builders.d.ts.map +1 -1
- package/lib/mjs/builders.js +10 -15
- package/lib/mjs/builders.js.map +1 -1
- package/lib/mjs/decorators.d.ts +1 -1
- package/lib/mjs/decorators.d.ts.map +1 -1
- package/lib/mjs/decorators.js.map +1 -1
- package/lib/mjs/hydrators.d.ts.map +1 -1
- package/lib/mjs/hydrators.js +1 -1
- package/lib/mjs/hydrators.js.map +1 -1
- package/lib/mjs/index.d.ts +2 -0
- package/lib/mjs/index.d.ts.map +1 -1
- package/lib/mjs/index.js +2 -0
- package/lib/mjs/index.js.map +1 -1
- package/lib/mjs/interfaces.d.ts +10 -2
- package/lib/mjs/interfaces.d.ts.map +1 -1
- package/lib/mjs/interfaces.js.map +1 -1
- package/lib/mjs/middlewares.d.ts +63 -0
- package/lib/mjs/middlewares.d.ts.map +1 -0
- package/lib/mjs/middlewares.js +250 -0
- package/lib/mjs/middlewares.js.map +1 -0
- package/lib/mjs/model.d.ts.map +1 -1
- package/lib/mjs/model.js +2 -1
- package/lib/mjs/model.js.map +1 -1
- package/lib/mjs/orm.d.ts.map +1 -1
- package/lib/mjs/orm.js +14 -8
- package/lib/mjs/orm.js.map +1 -1
- package/lib/mjs/relation-objects.d.ts +109 -0
- package/lib/mjs/relation-objects.d.ts.map +1 -0
- package/lib/mjs/relation-objects.js +212 -0
- package/lib/mjs/relation-objects.js.map +1 -0
- package/lib/mjs/relations.d.ts +24 -158
- package/lib/mjs/relations.d.ts.map +1 -1
- package/lib/mjs/relations.js +48 -487
- package/lib/mjs/relations.js.map +1 -1
- package/lib/mjs/types.d.ts +1 -1
- package/lib/mjs/types.d.ts.map +1 -1
- package/lib/tsconfig.cjs.tsbuildinfo +1 -1
- package/lib/tsconfig.mjs.tsbuildinfo +1 -1
- package/package.json +5 -5
package/lib/cjs/relations.js
CHANGED
|
@@ -8,302 +8,53 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
8
8
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
11
|
var BelongsToRelation_1;
|
|
15
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
-
exports.
|
|
13
|
+
exports.ManyToManyRelation = exports.OneToManyRelation = exports.BelongsToRecursiveRelation = exports.BelongsToRelation = exports.OrmRelation = void 0;
|
|
17
14
|
/* eslint-disable prettier/prettier */
|
|
18
15
|
const exceptions_1 = require("@spinajs/exceptions");
|
|
19
16
|
const interfaces_js_1 = require("./interfaces.js");
|
|
20
17
|
const di_1 = require("@spinajs/di");
|
|
21
|
-
const
|
|
18
|
+
const middlewares_js_1 = require("./middlewares.js");
|
|
22
19
|
const model_js_1 = require("./model.js");
|
|
23
20
|
const orm_js_1 = require("./orm.js");
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
function _paramCheck(callback, err) {
|
|
22
|
+
const val = callback();
|
|
23
|
+
if (!callback()) {
|
|
24
|
+
throw new Error(err);
|
|
25
|
+
}
|
|
26
|
+
return val;
|
|
27
|
+
}
|
|
28
|
+
let OrmRelation = class OrmRelation {
|
|
26
29
|
get Alias() {
|
|
27
30
|
return this.parentRelation ? `${this.parentRelation.Alias}.${this._separator}${this._description.Name}${this._separator}` : `${this._separator}${this._description.Name}${this._separator}`;
|
|
28
31
|
}
|
|
29
|
-
constructor(
|
|
30
|
-
this.
|
|
32
|
+
constructor(_container, _query, _description, parentRelation) {
|
|
33
|
+
this._container = _container;
|
|
31
34
|
this._query = _query;
|
|
32
35
|
this._description = _description;
|
|
33
36
|
this.parentRelation = parentRelation;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this._separator = driver.Options.AliasSeparator;
|
|
42
|
-
if (driver.Options.Database) {
|
|
43
|
-
this._relationQuery.database(driver.Options.Database);
|
|
37
|
+
this._targetModel = this._description.TargetModel;
|
|
38
|
+
this._targetModelDescriptor = _paramCheck(() => (0, model_js_1.extractModelDescriptor)(this._targetModel), `Model ${this._targetModel?.name} does not have model descriptor set`);
|
|
39
|
+
this._driver = _paramCheck(() => di_1.DI.resolve("OrmConnection", [this._targetModelDescriptor.Connection]), `Connection ${this._targetModelDescriptor.Connection} is not set in configuration file`);
|
|
40
|
+
this._relationQuery = this._container.resolve("SelectQueryBuilder", [this._driver, this._targetModel, this]);
|
|
41
|
+
this._separator = this._driver.Options.AliasSeparator;
|
|
42
|
+
if (this._driver.Options.Database) {
|
|
43
|
+
this._relationQuery.database(this._driver.Options.Database);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
executeOnQuery(callback) {
|
|
47
47
|
callback.call(this._relationQuery, [this]);
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
};
|
|
50
|
+
OrmRelation = __decorate([
|
|
51
|
+
(0, di_1.Inject)(di_1.Container),
|
|
52
|
+
__metadata("design:paramtypes", [di_1.Container, Object, Object, OrmRelation])
|
|
53
|
+
], OrmRelation);
|
|
50
54
|
exports.OrmRelation = OrmRelation;
|
|
51
|
-
class HasManyRelationMiddleware {
|
|
52
|
-
constructor(_relationQuery, _description, _path) {
|
|
53
|
-
this._relationQuery = _relationQuery;
|
|
54
|
-
this._description = _description;
|
|
55
|
-
this._path = _path;
|
|
56
|
-
}
|
|
57
|
-
afterQuery(data) {
|
|
58
|
-
return data;
|
|
59
|
-
}
|
|
60
|
-
modelCreation(_) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
async afterHydration(data) {
|
|
64
|
-
const self = this;
|
|
65
|
-
const pks = data.map((d) => {
|
|
66
|
-
return d[this._description.PrimaryKey];
|
|
67
|
-
});
|
|
68
|
-
const hydrateMiddleware = {
|
|
69
|
-
afterQuery(data) {
|
|
70
|
-
return data;
|
|
71
|
-
},
|
|
72
|
-
modelCreation() {
|
|
73
|
-
return null;
|
|
74
|
-
},
|
|
75
|
-
async afterHydration(relationData) {
|
|
76
|
-
relationData.forEach((d) => (d.__relationKey__ = self._description.Name));
|
|
77
|
-
data.forEach((d) => {
|
|
78
|
-
const relData = relationData.filter((rd) => {
|
|
79
|
-
return d[self._description.PrimaryKey] === rd[self._description.ForeignKey];
|
|
80
|
-
});
|
|
81
|
-
d[self._description.Name] = new OneToManyRelationList(d, self._description.TargetModel, self._description, relData);
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
if (pks.length !== 0) {
|
|
86
|
-
this._relationQuery.whereIn(this._description.ForeignKey, pks);
|
|
87
|
-
this._relationQuery.middleware(hydrateMiddleware);
|
|
88
|
-
return await this._relationQuery;
|
|
89
|
-
}
|
|
90
|
-
return [];
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
exports.HasManyRelationMiddleware = HasManyRelationMiddleware;
|
|
94
|
-
class BelongsToRelationRecursiveMiddleware {
|
|
95
|
-
constructor(_relationQuery, _description, _targetModelDescriptor) {
|
|
96
|
-
this._relationQuery = _relationQuery;
|
|
97
|
-
this._description = _description;
|
|
98
|
-
this._targetModelDescriptor = _targetModelDescriptor;
|
|
99
|
-
}
|
|
100
|
-
afterQuery(data) {
|
|
101
|
-
return data;
|
|
102
|
-
}
|
|
103
|
-
modelCreation(_) {
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
async afterHydration(data) {
|
|
107
|
-
const self = this;
|
|
108
|
-
const pks = data.map((d) => d[this._description.PrimaryKey]);
|
|
109
|
-
const fKey = this._description.ForeignKey;
|
|
110
|
-
const key = this._description.PrimaryKey;
|
|
111
|
-
const name = this._description.Name;
|
|
112
|
-
const hydrateMiddleware = {
|
|
113
|
-
afterQuery(data) {
|
|
114
|
-
return data;
|
|
115
|
-
},
|
|
116
|
-
modelCreation(_) {
|
|
117
|
-
return null;
|
|
118
|
-
},
|
|
119
|
-
async afterHydration(relationData) {
|
|
120
|
-
relationData.forEach((d) => (d.__relationKey__ = self._description.Name));
|
|
121
|
-
function buildRelationTree(_d, parent) {
|
|
122
|
-
const branch = [];
|
|
123
|
-
_d.forEach((d) => {
|
|
124
|
-
if (d[fKey] === parent) {
|
|
125
|
-
const children = buildRelationTree(_d, d[key]);
|
|
126
|
-
if (children) {
|
|
127
|
-
// TODO:
|
|
128
|
-
// implement RecursiveRelation list to allow for
|
|
129
|
-
// manipulation of the recursive data
|
|
130
|
-
d[name] = new OneToManyRelationList(d, d.Model, {
|
|
131
|
-
Name: name,
|
|
132
|
-
Type: interfaces_js_1.RelationType.Many,
|
|
133
|
-
TargetModelType: d.Model,
|
|
134
|
-
TargetModel: d.Model,
|
|
135
|
-
SourceModel: d.Model,
|
|
136
|
-
ForeignKey: fKey,
|
|
137
|
-
PrimaryKey: key,
|
|
138
|
-
Recursive: false,
|
|
139
|
-
}, children);
|
|
140
|
-
}
|
|
141
|
-
branch.push(d);
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
return branch;
|
|
145
|
-
}
|
|
146
|
-
const result = buildRelationTree(relationData, null);
|
|
147
|
-
data.forEach((d) => {
|
|
148
|
-
d[name] = result.find((r) => r[key] === d[key])[name];
|
|
149
|
-
});
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
this._relationQuery.whereIn(this._description.PrimaryKey, pks);
|
|
153
|
-
this._relationQuery.middleware(new DiscriminationMapMiddleware(this._targetModelDescriptor));
|
|
154
|
-
this._relationQuery.middleware(hydrateMiddleware);
|
|
155
|
-
return await this._relationQuery;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
class HasManyToManyRelationMiddleware {
|
|
159
|
-
constructor(_relationQuery, _description, _targetModelDescriptor) {
|
|
160
|
-
this._relationQuery = _relationQuery;
|
|
161
|
-
this._description = _description;
|
|
162
|
-
this._targetModelDescriptor = _targetModelDescriptor;
|
|
163
|
-
}
|
|
164
|
-
afterQuery(data) {
|
|
165
|
-
return data;
|
|
166
|
-
}
|
|
167
|
-
modelCreation(_) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
async afterHydration(data) {
|
|
171
|
-
const self = this;
|
|
172
|
-
const pks = data.map((d) => d[this._description.PrimaryKey]);
|
|
173
|
-
const hydrateMiddleware = {
|
|
174
|
-
afterQuery(data) {
|
|
175
|
-
return data.map((d) => Object.assign({}, d[self._description.Name], { JunctionModel: self.pickProps(d, [self._description.Name]) }));
|
|
176
|
-
},
|
|
177
|
-
modelCreation(_) {
|
|
178
|
-
return null;
|
|
179
|
-
},
|
|
180
|
-
async afterHydration(relationData) {
|
|
181
|
-
relationData.forEach((d) => (d.__relationKey__ = self._description.Name));
|
|
182
|
-
data.forEach((d) => {
|
|
183
|
-
const relData = relationData.filter((rd) => rd.JunctionModel[self._description.ForeignKey] === d[self._description.PrimaryKey]);
|
|
184
|
-
d[self._description.Name] = new ManyToManyRelationList(d, self._description.TargetModel, self._description, relData);
|
|
185
|
-
});
|
|
186
|
-
relationData.forEach((d) => delete d.JunctionModel);
|
|
187
|
-
},
|
|
188
|
-
};
|
|
189
|
-
if (pks.length !== 0) {
|
|
190
|
-
this._relationQuery.whereIn(this._description.ForeignKey, pks);
|
|
191
|
-
this._relationQuery.middleware(new BelongsToRelationResultTransformMiddleware(this._description, null));
|
|
192
|
-
this._relationQuery.middleware(new DiscriminationMapMiddleware(this._targetModelDescriptor));
|
|
193
|
-
this._relationQuery.middleware(hydrateMiddleware);
|
|
194
|
-
return await this._relationQuery;
|
|
195
|
-
}
|
|
196
|
-
return [];
|
|
197
|
-
}
|
|
198
|
-
pickProps(source, except) {
|
|
199
|
-
const obj = {};
|
|
200
|
-
for (const p in source) {
|
|
201
|
-
if (except.indexOf(p) === -1) {
|
|
202
|
-
obj[p] = source[p];
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
return obj;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
exports.HasManyToManyRelationMiddleware = HasManyToManyRelationMiddleware;
|
|
209
|
-
class BelongsToPopulateDataMiddleware {
|
|
210
|
-
constructor(_description, relation) {
|
|
211
|
-
this._description = _description;
|
|
212
|
-
this.relation = relation;
|
|
213
|
-
}
|
|
214
|
-
afterQuery(data) {
|
|
215
|
-
return data;
|
|
216
|
-
}
|
|
217
|
-
modelCreation(_) {
|
|
218
|
-
return null;
|
|
219
|
-
}
|
|
220
|
-
afterHydration(data) {
|
|
221
|
-
const relData = data.map((d) => d[this._description.Name].Value).filter((x) => x !== null && x !== undefined);
|
|
222
|
-
const middlewares = this.relation._relationQuery.Relations
|
|
223
|
-
.map((x) => {
|
|
224
|
-
return x._query._middlewares;
|
|
225
|
-
})
|
|
226
|
-
.reduce((prev, current) => {
|
|
227
|
-
return prev.concat(current);
|
|
228
|
-
}, []);
|
|
229
|
-
return Promise.all(middlewares.map((x) => {
|
|
230
|
-
return x.afterHydration(relData);
|
|
231
|
-
}));
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
class BelongsToRelationResultTransformMiddleware {
|
|
235
|
-
constructor(_description, relation) {
|
|
236
|
-
this._description = _description;
|
|
237
|
-
this.relation = relation;
|
|
238
|
-
}
|
|
239
|
-
afterQuery(data) {
|
|
240
|
-
return data.map((d) => {
|
|
241
|
-
const transformedData = Object.assign(d);
|
|
242
|
-
for (const key in transformedData) {
|
|
243
|
-
if (key.startsWith('$')) {
|
|
244
|
-
this.setDeep(transformedData, this.keyTransform(key), d[key]);
|
|
245
|
-
delete transformedData[key];
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return transformedData;
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
modelCreation(_) {
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
// tslint:disable-next-line: no-empty
|
|
255
|
-
async afterHydration(_data) { }
|
|
256
|
-
/**
|
|
257
|
-
* Dynamically sets a deeply nested value in an object.
|
|
258
|
-
* Optionally "bores" a path to it if its undefined.
|
|
259
|
-
*
|
|
260
|
-
* @param obj - The object which contains the value you want to change/set.
|
|
261
|
-
* @param path - The array representation of path to the value you want to change/set.
|
|
262
|
-
* @param value - The value you want to set it to.
|
|
263
|
-
* @param setrecursively - If true, will set value of non-existing path as well.
|
|
264
|
-
*/
|
|
265
|
-
setDeep(obj, path, value, setrecursively = true) {
|
|
266
|
-
path.reduce((a, b, level) => {
|
|
267
|
-
if (setrecursively && typeof a[b] === 'undefined' && level !== path.length - 1) {
|
|
268
|
-
a[b] = {};
|
|
269
|
-
return a[b];
|
|
270
|
-
}
|
|
271
|
-
if (level === path.length - 1) {
|
|
272
|
-
a[b] = value;
|
|
273
|
-
return value;
|
|
274
|
-
}
|
|
275
|
-
return a[b];
|
|
276
|
-
}, obj);
|
|
277
|
-
}
|
|
278
|
-
keyTransform(key) {
|
|
279
|
-
return key.replace(/\$+/g, '').split('.');
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
class DiscriminationMapMiddleware {
|
|
283
|
-
constructor(_description) {
|
|
284
|
-
this._description = _description;
|
|
285
|
-
}
|
|
286
|
-
afterQuery(data) {
|
|
287
|
-
return data;
|
|
288
|
-
}
|
|
289
|
-
modelCreation(data) {
|
|
290
|
-
if (this._description.DiscriminationMap && this._description.DiscriminationMap.Field) {
|
|
291
|
-
const distValue = data[this._description.DiscriminationMap.Field];
|
|
292
|
-
if (distValue && this._description.DiscriminationMap.Models.has(distValue)) {
|
|
293
|
-
const result = new (this._description.DiscriminationMap.Models.get(distValue))();
|
|
294
|
-
result.hydrate(data);
|
|
295
|
-
return result;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
// tslint:disable-next-line: no-empty
|
|
301
|
-
async afterHydration(_data) { }
|
|
302
|
-
}
|
|
303
|
-
exports.DiscriminationMapMiddleware = DiscriminationMapMiddleware;
|
|
304
55
|
let BelongsToRelation = BelongsToRelation_1 = class BelongsToRelation extends OrmRelation {
|
|
305
|
-
constructor(
|
|
306
|
-
super(
|
|
56
|
+
constructor(_container, _query, _description, _parentRelation) {
|
|
57
|
+
super(_container, _query, _description, _parentRelation);
|
|
307
58
|
this._relationQuery.from(this._targetModelDescriptor.TableName, this.Alias);
|
|
308
59
|
this._targetModelDescriptor.Columns.forEach((c) => {
|
|
309
60
|
this._relationQuery.select(c.Name, `${this.Alias}.${c.Name}`);
|
|
@@ -317,25 +68,27 @@ let BelongsToRelation = BelongsToRelation_1 = class BelongsToRelation extends Or
|
|
|
317
68
|
if (callback) {
|
|
318
69
|
callback.call(this._relationQuery, [this]);
|
|
319
70
|
}
|
|
71
|
+
// todo: fix this cast
|
|
320
72
|
this._query.mergeBuilder(this._relationQuery);
|
|
321
|
-
this._query.middleware(new BelongsToPopulateDataMiddleware(this._description, this));
|
|
73
|
+
this._query.middleware(new middlewares_js_1.BelongsToPopulateDataMiddleware(this._description, this));
|
|
322
74
|
if (!this.parentRelation || !(this.parentRelation instanceof BelongsToRelation_1)) {
|
|
323
75
|
// if we are on top of the belongsTo relation stack
|
|
324
76
|
// add transform middleware
|
|
325
77
|
// we do this becouse belongsTo modifies query (not creating new like oneToMany and manyToMany)
|
|
326
78
|
// and we only need to run transform once
|
|
327
|
-
this._query.middleware(new BelongsToRelationResultTransformMiddleware(
|
|
79
|
+
this._query.middleware(new middlewares_js_1.BelongsToRelationResultTransformMiddleware());
|
|
328
80
|
}
|
|
329
81
|
}
|
|
330
82
|
};
|
|
331
83
|
BelongsToRelation = BelongsToRelation_1 = __decorate([
|
|
332
84
|
(0, di_1.NewInstance)(),
|
|
333
|
-
|
|
85
|
+
(0, di_1.Inject)(di_1.Container),
|
|
86
|
+
__metadata("design:paramtypes", [di_1.Container, Object, Object, OrmRelation])
|
|
334
87
|
], BelongsToRelation);
|
|
335
88
|
exports.BelongsToRelation = BelongsToRelation;
|
|
336
89
|
let BelongsToRecursiveRelation = class BelongsToRecursiveRelation extends OrmRelation {
|
|
337
|
-
constructor(
|
|
338
|
-
super(
|
|
90
|
+
constructor(_container, _query, _description, _parentRelation) {
|
|
91
|
+
super(_container, _query, _description, _parentRelation);
|
|
339
92
|
this._relationQuery.withRecursive(this._description.ForeignKey, this._description.PrimaryKey).from(this._targetModelDescriptor.TableName, this.Alias);
|
|
340
93
|
this._targetModelDescriptor.Columns.forEach((c) => {
|
|
341
94
|
this._relationQuery.select(c.Name, `${this.Alias}.${c.Name}`);
|
|
@@ -345,17 +98,18 @@ let BelongsToRecursiveRelation = class BelongsToRecursiveRelation extends OrmRel
|
|
|
345
98
|
if (callback) {
|
|
346
99
|
callback.call(this._relationQuery, [this]);
|
|
347
100
|
}
|
|
348
|
-
this._query.middleware(new BelongsToRelationRecursiveMiddleware(this._relationQuery, this._description, this._targetModelDescriptor));
|
|
101
|
+
this._query.middleware(new middlewares_js_1.BelongsToRelationRecursiveMiddleware(this._relationQuery, this._description, this._targetModelDescriptor));
|
|
349
102
|
}
|
|
350
103
|
};
|
|
351
104
|
BelongsToRecursiveRelation = __decorate([
|
|
352
105
|
(0, di_1.NewInstance)(),
|
|
353
|
-
|
|
106
|
+
(0, di_1.Inject)(di_1.Container),
|
|
107
|
+
__metadata("design:paramtypes", [di_1.Container, Object, Object, OrmRelation])
|
|
354
108
|
], BelongsToRecursiveRelation);
|
|
355
109
|
exports.BelongsToRecursiveRelation = BelongsToRecursiveRelation;
|
|
356
110
|
let OneToManyRelation = class OneToManyRelation extends OrmRelation {
|
|
357
|
-
constructor(
|
|
358
|
-
super(
|
|
111
|
+
constructor(_container, _query, _description, _parentRelation) {
|
|
112
|
+
super(_container, _query, _description, _parentRelation);
|
|
359
113
|
this._relationQuery.from(this._targetModelDescriptor.TableName, this.Alias);
|
|
360
114
|
this._relationQuery.columns(this._targetModelDescriptor.Columns.map((c) => {
|
|
361
115
|
return c.Name;
|
|
@@ -368,13 +122,14 @@ let OneToManyRelation = class OneToManyRelation extends OrmRelation {
|
|
|
368
122
|
if (callback) {
|
|
369
123
|
callback.call(this._relationQuery, [this]);
|
|
370
124
|
}
|
|
371
|
-
this._query.middleware(new DiscriminationMapMiddleware(this._targetModelDescriptor));
|
|
372
|
-
this._query.middleware(new HasManyRelationMiddleware(this._relationQuery, this._description, null));
|
|
125
|
+
this._query.middleware(new middlewares_js_1.DiscriminationMapMiddleware(this._targetModelDescriptor));
|
|
126
|
+
this._query.middleware(new middlewares_js_1.HasManyRelationMiddleware(this._relationQuery, this._description, null));
|
|
373
127
|
}
|
|
374
128
|
};
|
|
375
129
|
OneToManyRelation = __decorate([
|
|
376
130
|
(0, di_1.NewInstance)(),
|
|
377
|
-
|
|
131
|
+
(0, di_1.Inject)(di_1.Container),
|
|
132
|
+
__metadata("design:paramtypes", [di_1.Container, Object, Object, OrmRelation])
|
|
378
133
|
], OneToManyRelation);
|
|
379
134
|
exports.OneToManyRelation = OneToManyRelation;
|
|
380
135
|
let ManyToManyRelation = class ManyToManyRelation extends OrmRelation {
|
|
@@ -384,8 +139,9 @@ let ManyToManyRelation = class ManyToManyRelation extends OrmRelation {
|
|
|
384
139
|
get RelationQuery() {
|
|
385
140
|
return this._relationQuery;
|
|
386
141
|
}
|
|
387
|
-
constructor(_orm, _query, _description, _parentRelation) {
|
|
388
|
-
super(
|
|
142
|
+
constructor(_container, _orm, _query, _description, _parentRelation) {
|
|
143
|
+
super(_container, _query, _description, _parentRelation);
|
|
144
|
+
this._orm = _orm;
|
|
389
145
|
this._joinModel = this._orm.Models.find((m) => m.name === this._description.JunctionModel?.name)?.type ?? undefined;
|
|
390
146
|
if (this._joinModel === undefined) {
|
|
391
147
|
throw new exceptions_1.InvalidOperation(`model ${this._description.JunctionModel} not exists in orm module`);
|
|
@@ -394,7 +150,7 @@ let ManyToManyRelation = class ManyToManyRelation extends OrmRelation {
|
|
|
394
150
|
const orm = di_1.DI.get(orm_js_1.Orm);
|
|
395
151
|
const driver = orm.Connections.get(this._joinModelDescriptor.Connection);
|
|
396
152
|
const cnt = driver.Container;
|
|
397
|
-
this._joinQuery = cnt.resolve(
|
|
153
|
+
this._joinQuery = cnt.resolve("SelectQueryBuilder", [driver, this._targetModel, this]);
|
|
398
154
|
if (driver.Options.Database) {
|
|
399
155
|
this._joinQuery.database(driver.Options.Database);
|
|
400
156
|
}
|
|
@@ -424,222 +180,16 @@ let ManyToManyRelation = class ManyToManyRelation extends OrmRelation {
|
|
|
424
180
|
PrimaryKey: this._description.PrimaryKey,
|
|
425
181
|
Recursive: false,
|
|
426
182
|
};
|
|
183
|
+
// todo fix this cast
|
|
427
184
|
this._joinQuery.mergeBuilder(this._relationQuery);
|
|
428
185
|
this._joinQuery.mergeRelations(this._relationQuery);
|
|
429
|
-
this._query.middleware(new HasManyToManyRelationMiddleware(this._joinQuery, joinRelationDescriptor, this._targetModelDescriptor));
|
|
186
|
+
this._query.middleware(new middlewares_js_1.HasManyToManyRelationMiddleware(this._joinQuery, joinRelationDescriptor, this._targetModelDescriptor));
|
|
430
187
|
}
|
|
431
188
|
};
|
|
432
189
|
ManyToManyRelation = __decorate([
|
|
433
190
|
(0, di_1.NewInstance)(),
|
|
434
|
-
|
|
191
|
+
(0, di_1.Inject)(di_1.Container, orm_js_1.Orm),
|
|
192
|
+
__metadata("design:paramtypes", [di_1.Container, orm_js_1.Orm, Object, Object, OrmRelation])
|
|
435
193
|
], ManyToManyRelation);
|
|
436
194
|
exports.ManyToManyRelation = ManyToManyRelation;
|
|
437
|
-
class SingleRelation {
|
|
438
|
-
constructor(_owner, model, Relation, object) {
|
|
439
|
-
this._owner = _owner;
|
|
440
|
-
this.model = model;
|
|
441
|
-
this.Relation = Relation;
|
|
442
|
-
this.Populated = false;
|
|
443
|
-
this.TargetModelDescriptor = (0, model_js_1.extractModelDescriptor)(model);
|
|
444
|
-
this.Orm = di_1.DI.get(orm_js_1.Orm);
|
|
445
|
-
this.Value = object;
|
|
446
|
-
}
|
|
447
|
-
async set(obj) {
|
|
448
|
-
this.Value = obj;
|
|
449
|
-
await this._owner.update();
|
|
450
|
-
}
|
|
451
|
-
attach(obj) {
|
|
452
|
-
this.Value = obj;
|
|
453
|
-
}
|
|
454
|
-
detach() {
|
|
455
|
-
this.Value = null;
|
|
456
|
-
}
|
|
457
|
-
async remove() {
|
|
458
|
-
this.Value = null;
|
|
459
|
-
await this.Value.destroy();
|
|
460
|
-
await this._owner.update();
|
|
461
|
-
}
|
|
462
|
-
async populate(callback) {
|
|
463
|
-
/**
|
|
464
|
-
* Do little cheat - we construct query that loads initial model with given relation.
|
|
465
|
-
* Then we only assign relation property.
|
|
466
|
-
*
|
|
467
|
-
* TODO: create only relation query without loading its owner.
|
|
468
|
-
*/
|
|
469
|
-
const query = (0, model_js_1.createQuery)(this.Relation.TargetModel, (builders_js_1.SelectQueryBuilder)).query;
|
|
470
|
-
const desc = (0, model_js_1.extractModelDescriptor)(this.Relation.TargetModel);
|
|
471
|
-
query.where({ [desc.PrimaryKey]: this._owner[this.Relation.ForeignKey] });
|
|
472
|
-
if (callback) {
|
|
473
|
-
callback.apply(query);
|
|
474
|
-
}
|
|
475
|
-
const result = await query.firstOrFail();
|
|
476
|
-
if (result) {
|
|
477
|
-
this.Value = result;
|
|
478
|
-
}
|
|
479
|
-
this.Populated = true;
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
exports.SingleRelation = SingleRelation;
|
|
483
|
-
/**
|
|
484
|
-
* Iterable list of populated relation entities
|
|
485
|
-
*
|
|
486
|
-
* It allows to add / remove objects to relation
|
|
487
|
-
*/
|
|
488
|
-
class Relation extends Array {
|
|
489
|
-
constructor(owner, Model, Relation, objects) {
|
|
490
|
-
super();
|
|
491
|
-
this.owner = owner;
|
|
492
|
-
this.Model = Model;
|
|
493
|
-
this.Relation = Relation;
|
|
494
|
-
this.Populated = false;
|
|
495
|
-
if (objects) {
|
|
496
|
-
this.push(...objects);
|
|
497
|
-
}
|
|
498
|
-
this.TargetModelDescriptor = (0, model_js_1.extractModelDescriptor)(Model);
|
|
499
|
-
this.Orm = di_1.DI.get(orm_js_1.Orm);
|
|
500
|
-
if (this.TargetModelDescriptor) {
|
|
501
|
-
this.Driver = this.Orm.Connections.get(this.TargetModelDescriptor.Connection);
|
|
502
|
-
}
|
|
503
|
-
this.IsModelAForwardRef = !(0, di_1.isConstructor)(this.Model);
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Delete all objects from relation
|
|
507
|
-
*/
|
|
508
|
-
async clear() {
|
|
509
|
-
await this.remove(this);
|
|
510
|
-
}
|
|
511
|
-
empty() {
|
|
512
|
-
this.length = 0;
|
|
513
|
-
}
|
|
514
|
-
/**
|
|
515
|
-
* Populates this relation ( loads all data related to owner of this relation)
|
|
516
|
-
*/
|
|
517
|
-
async populate(callback) {
|
|
518
|
-
const query = this.Relation.TargetModel.where(this.Relation.ForeignKey, this.owner.PrimaryKeyValue);
|
|
519
|
-
if (callback) {
|
|
520
|
-
callback.apply(query);
|
|
521
|
-
}
|
|
522
|
-
const result = await query;
|
|
523
|
-
if (result) {
|
|
524
|
-
this.length = 0;
|
|
525
|
-
this.push(...result);
|
|
526
|
-
}
|
|
527
|
-
this.Populated = true;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
exports.Relation = Relation;
|
|
531
|
-
class ManyToManyRelationList extends Relation {
|
|
532
|
-
intersection(_obj, _callback) {
|
|
533
|
-
throw new Error('Method not implemented.');
|
|
534
|
-
}
|
|
535
|
-
union(_obj, _mode) {
|
|
536
|
-
throw new Error('Method not implemented.');
|
|
537
|
-
}
|
|
538
|
-
diff(_obj, _callback) {
|
|
539
|
-
throw new Error('Method not implemented.');
|
|
540
|
-
}
|
|
541
|
-
set(_obj, _callback) {
|
|
542
|
-
throw new Error('Method not implemented.');
|
|
543
|
-
}
|
|
544
|
-
async remove(obj) {
|
|
545
|
-
const self = this;
|
|
546
|
-
const data = (Array.isArray(obj) ? obj : [obj]).map((d) => d.PrimaryKeyValue);
|
|
547
|
-
const jmodelDescriptor = (0, model_js_1.extractModelDescriptor)(this.Relation.JunctionModel);
|
|
548
|
-
const query = this.Driver.del()
|
|
549
|
-
.from(jmodelDescriptor.TableName)
|
|
550
|
-
.where(function () {
|
|
551
|
-
this.whereIn(self.Relation.JunctionModelTargetModelFKey_Name, data);
|
|
552
|
-
this.andWhere(self.Relation.JunctionModelSourceModelFKey_Name, self.owner.PrimaryKeyValue);
|
|
553
|
-
});
|
|
554
|
-
if (this.Driver.Options.Database) {
|
|
555
|
-
query.database(this.Driver.Options.Database);
|
|
556
|
-
}
|
|
557
|
-
await query;
|
|
558
|
-
lodash_1.default.remove(this, (o) => data.indexOf(o.PrimaryKeyValue) !== -1);
|
|
559
|
-
}
|
|
560
|
-
async add(obj, mode) {
|
|
561
|
-
const data = Array.isArray(obj) ? obj : [obj];
|
|
562
|
-
const relEntities = data.map((d) => {
|
|
563
|
-
const relEntity = new this.Relation.JunctionModel();
|
|
564
|
-
relEntity[this.Relation.JunctionModelSourceModelFKey_Name] = this.owner.PrimaryKeyValue;
|
|
565
|
-
relEntity[this.Relation.JunctionModelTargetModelFKey_Name] = d.PrimaryKeyValue;
|
|
566
|
-
return relEntity;
|
|
567
|
-
});
|
|
568
|
-
for (const m of relEntities) {
|
|
569
|
-
await m.insert(mode);
|
|
570
|
-
}
|
|
571
|
-
this.push(...data);
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
exports.ManyToManyRelationList = ManyToManyRelationList;
|
|
575
|
-
class OneToManyRelationList extends Relation {
|
|
576
|
-
async deleteRelationData(data) {
|
|
577
|
-
if (data.length === 0) {
|
|
578
|
-
return;
|
|
579
|
-
}
|
|
580
|
-
const self = this;
|
|
581
|
-
const query = this.Driver.del()
|
|
582
|
-
.from(this.TargetModelDescriptor.TableName)
|
|
583
|
-
.andWhere(function () {
|
|
584
|
-
this.whereNotIn(self.Relation.PrimaryKey, data.filter((x) => x.PrimaryKeyValue).map((x) => x.PrimaryKeyValue));
|
|
585
|
-
this.where(self.Relation.ForeignKey, self.owner.PrimaryKeyValue);
|
|
586
|
-
});
|
|
587
|
-
if (this.Driver.Options.Database) {
|
|
588
|
-
query.database(this.Driver.Options.Database);
|
|
589
|
-
}
|
|
590
|
-
await query;
|
|
591
|
-
this.empty();
|
|
592
|
-
}
|
|
593
|
-
async diff(dataset, callback) {
|
|
594
|
-
// calculate difference between this data in relation and dataset ( objects from this relation)
|
|
595
|
-
const result = callback ? lodash_1.default.differenceWith(dataset, [...this], callback) : lodash_1.default.differenceBy(dataset, [...this], this.TargetModelDescriptor.PrimaryKey);
|
|
596
|
-
// calculate difference between dataset and data in this relation ( objects from dataset )
|
|
597
|
-
const result2 = callback ? lodash_1.default.differenceWith([...this], dataset, callback) : lodash_1.default.differenceBy([...this], dataset, this.TargetModelDescriptor.PrimaryKey);
|
|
598
|
-
// combine difference from two sets
|
|
599
|
-
const finalDiff = [...result, ...result2];
|
|
600
|
-
await this.deleteRelationData(finalDiff);
|
|
601
|
-
await this.add(finalDiff, interfaces_js_1.InsertBehaviour.InsertOrUpdate);
|
|
602
|
-
}
|
|
603
|
-
async set(obj) {
|
|
604
|
-
await this.deleteRelationData(obj);
|
|
605
|
-
await this.add(obj, interfaces_js_1.InsertBehaviour.InsertOrUpdate);
|
|
606
|
-
}
|
|
607
|
-
async intersection(obj, callback) {
|
|
608
|
-
const result = callback ? lodash_1.default.intersectionWith(obj, [...this], callback) : lodash_1.default.intersectionBy(obj, [...this], this.TargetModelDescriptor.PrimaryKey);
|
|
609
|
-
await this.deleteRelationData(result);
|
|
610
|
-
await this.add(result, interfaces_js_1.InsertBehaviour.InsertOrUpdate);
|
|
611
|
-
}
|
|
612
|
-
async union(obj, mode) {
|
|
613
|
-
await this.add(obj, mode ?? interfaces_js_1.InsertBehaviour.InsertOrIgnore);
|
|
614
|
-
}
|
|
615
|
-
async remove(obj) {
|
|
616
|
-
const data = (Array.isArray(obj) ? obj : [obj]).map((d) => d.PrimaryKeyValue);
|
|
617
|
-
const query = this.Driver.del().whereIn(this.Relation.ForeignKey, data).setTable(this.TargetModelDescriptor.TableName);
|
|
618
|
-
if (this.Driver.Options.Database) {
|
|
619
|
-
query.database(this.Driver.Options.Database);
|
|
620
|
-
}
|
|
621
|
-
await query;
|
|
622
|
-
lodash_1.default.remove(this, (o) => data.indexOf(o.PrimaryKeyValue) !== -1);
|
|
623
|
-
}
|
|
624
|
-
async add(obj, mode) {
|
|
625
|
-
const data = Array.isArray(obj) ? obj : [obj];
|
|
626
|
-
const tInsert = data.map((x) => {
|
|
627
|
-
if (x instanceof model_js_1.ModelBase) {
|
|
628
|
-
return x;
|
|
629
|
-
}
|
|
630
|
-
if (this.IsModelAForwardRef) {
|
|
631
|
-
new (this.Model())(x);
|
|
632
|
-
}
|
|
633
|
-
return new this.Model(x);
|
|
634
|
-
});
|
|
635
|
-
data.forEach((d) => {
|
|
636
|
-
d[this.Relation.ForeignKey] = this.owner.PrimaryKeyValue;
|
|
637
|
-
});
|
|
638
|
-
for (const m of tInsert) {
|
|
639
|
-
await m.insertOrUpdate(mode);
|
|
640
|
-
}
|
|
641
|
-
this.push(...tInsert);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
exports.OneToManyRelationList = OneToManyRelationList;
|
|
645
195
|
//# sourceMappingURL=relations.js.map
|