@cheetah.js/orm 0.1.45 → 0.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SqlBuilder.d.ts +18 -33
- package/dist/SqlBuilder.js +102 -584
- package/dist/driver/bun-driver.base.d.ts +35 -1
- package/dist/driver/bun-driver.base.js +132 -0
- package/dist/driver/bun-mysql.driver.d.ts +13 -6
- package/dist/driver/bun-mysql.driver.js +47 -72
- package/dist/driver/bun-pg.driver.d.ts +12 -6
- package/dist/driver/bun-pg.driver.js +27 -59
- package/dist/driver/driver.interface.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/query/model-transformer.d.ts +21 -0
- package/dist/query/model-transformer.js +118 -0
- package/dist/query/sql-column-manager.d.ts +25 -0
- package/dist/query/sql-column-manager.js +124 -0
- package/dist/query/sql-condition-builder.d.ts +36 -0
- package/dist/query/sql-condition-builder.js +160 -0
- package/dist/query/sql-join-manager.d.ts +39 -0
- package/dist/query/sql-join-manager.js +224 -0
- package/dist/repository/Repository.d.ts +125 -0
- package/dist/repository/Repository.js +150 -0
- package/dist/utils/value-processor.d.ts +14 -0
- package/dist/utils/value-processor.js +84 -0
- package/package.json +3 -3
- package/build.ts +0 -14
- package/cheetah.config.ts +0 -14
- package/dist/SqlBuilder.js.map +0 -1
- package/dist/bun/index.js +0 -233434
- package/dist/bun/index.js.map +0 -336
- package/dist/common/email.vo.js.map +0 -1
- package/dist/common/uuid.js.map +0 -1
- package/dist/common/value-object.js.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/decorators/entity.decorator.js.map +0 -1
- package/dist/decorators/enum.decorator.js.map +0 -1
- package/dist/decorators/event-hook.decorator.js.map +0 -1
- package/dist/decorators/index.decorator.js.map +0 -1
- package/dist/decorators/one-many.decorator.js.map +0 -1
- package/dist/decorators/primary-key.decorator.js.map +0 -1
- package/dist/decorators/property.decorator.js.map +0 -1
- package/dist/domain/base-entity.js.map +0 -1
- package/dist/domain/collection.js.map +0 -1
- package/dist/domain/entities.js.map +0 -1
- package/dist/domain/reference.js.map +0 -1
- package/dist/driver/bun-driver.base.js.map +0 -1
- package/dist/driver/bun-mysql.driver.js.map +0 -1
- package/dist/driver/bun-pg.driver.js.map +0 -1
- package/dist/driver/driver.interface.js.map +0 -1
- package/dist/driver/pg-driver.d.ts +0 -63
- package/dist/driver/pg-driver.js +0 -335
- package/dist/driver/pg-driver.js.map +0 -1
- package/dist/entry.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/orm.js.map +0 -1
- package/dist/orm.service.js.map +0 -1
- package/dist/utils.js.map +0 -1
package/dist/SqlBuilder.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { EntityStorage } from './domain/entities';
|
|
2
2
|
import { Orm } from './orm';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { ValueProcessor } from './utils/value-processor';
|
|
4
|
+
import { SqlConditionBuilder } from './query/sql-condition-builder';
|
|
5
|
+
import { ModelTransformer } from './query/model-transformer';
|
|
6
|
+
import { SqlColumnManager } from './query/sql-column-manager';
|
|
7
|
+
import { SqlJoinManager } from './query/sql-join-manager';
|
|
6
8
|
export class SqlBuilder {
|
|
7
9
|
constructor(model) {
|
|
8
10
|
this.statements = {};
|
|
9
11
|
this.aliases = new Set();
|
|
10
|
-
this.lastKeyNotOperator = '';
|
|
11
12
|
this.updatedColumns = [];
|
|
12
13
|
this.originalColumns = [];
|
|
13
14
|
const orm = Orm.getInstance();
|
|
@@ -16,6 +17,13 @@ export class SqlBuilder {
|
|
|
16
17
|
this.entityStorage = EntityStorage.getInstance();
|
|
17
18
|
this.getEntity(model);
|
|
18
19
|
this.statements.hooks = this.entity.hooks;
|
|
20
|
+
this.modelTransformer = new ModelTransformer(this.entityStorage);
|
|
21
|
+
this.columnManager = new SqlColumnManager(this.entityStorage, this.statements, this.entity);
|
|
22
|
+
const applyJoinWrapper = (relationship, value, alias) => {
|
|
23
|
+
return this.joinManager.applyJoin(relationship, value, alias);
|
|
24
|
+
};
|
|
25
|
+
this.conditionBuilder = new SqlConditionBuilder(this.entityStorage, applyJoinWrapper, this.statements);
|
|
26
|
+
this.joinManager = new SqlJoinManager(this.entityStorage, this.statements, this.entity, this.model, this.driver, this.logger, this.conditionBuilder, this.columnManager, this.modelTransformer, () => this.originalColumns, this.getAlias.bind(this));
|
|
19
27
|
}
|
|
20
28
|
select(columns) {
|
|
21
29
|
const tableName = this.entity.tableName || this.model.name.toLowerCase();
|
|
@@ -37,25 +45,23 @@ export class SqlBuilder {
|
|
|
37
45
|
}
|
|
38
46
|
insert(values) {
|
|
39
47
|
const { tableName, schema } = this.getTableName();
|
|
40
|
-
|
|
41
|
-
values = processValuesForInsert(values, this.entity);
|
|
48
|
+
const processedValues = ValueProcessor.processForInsert(values, this.entity);
|
|
42
49
|
this.statements.statement = 'insert';
|
|
43
|
-
this.statements.instance =
|
|
50
|
+
this.statements.instance = ValueProcessor.createInstance(processedValues, this.model, 'insert');
|
|
44
51
|
this.statements.alias = this.getAlias(tableName);
|
|
45
52
|
this.statements.table = `"${schema}"."${tableName}"`;
|
|
46
|
-
this.statements.values = this.withUpdatedValues(this.withDefaultValues(
|
|
53
|
+
this.statements.values = this.withUpdatedValues(this.withDefaultValues(processedValues, this.entity), this.entity);
|
|
47
54
|
this.reflectToValues();
|
|
48
55
|
return this;
|
|
49
56
|
}
|
|
50
57
|
update(values) {
|
|
51
58
|
const { tableName, schema } = this.getTableName();
|
|
52
|
-
|
|
53
|
-
values = processValuesForUpdate(values, this.entity);
|
|
59
|
+
const processedValues = ValueProcessor.processForUpdate(values, this.entity);
|
|
54
60
|
this.statements.statement = 'update';
|
|
55
61
|
this.statements.alias = this.getAlias(tableName);
|
|
56
62
|
this.statements.table = `${schema}.${tableName}`;
|
|
57
|
-
this.statements.values = this.withUpdatedValues(
|
|
58
|
-
this.statements.instance =
|
|
63
|
+
this.statements.values = this.withUpdatedValues(processedValues, this.entity);
|
|
64
|
+
this.statements.instance = ValueProcessor.createInstance(processedValues, this.model, 'update');
|
|
59
65
|
return this;
|
|
60
66
|
}
|
|
61
67
|
where(where) {
|
|
@@ -68,10 +74,10 @@ export class SqlBuilder {
|
|
|
68
74
|
newWhere[key] = where[key];
|
|
69
75
|
continue;
|
|
70
76
|
}
|
|
71
|
-
newWhere[getColumnName(key, this.entity)] = where[key];
|
|
77
|
+
newWhere[ValueProcessor.getColumnName(key, this.entity)] = where[key];
|
|
72
78
|
}
|
|
73
79
|
where = newWhere;
|
|
74
|
-
this.statements.where = this.
|
|
80
|
+
this.statements.where = this.conditionBuilder.build(where, this.statements.alias, this.model);
|
|
75
81
|
return this;
|
|
76
82
|
}
|
|
77
83
|
orderBy(orderBy) {
|
|
@@ -91,7 +97,7 @@ export class SqlBuilder {
|
|
|
91
97
|
}
|
|
92
98
|
load(load) {
|
|
93
99
|
load?.forEach(relationshipPath => {
|
|
94
|
-
this.addJoinForRelationshipPath(
|
|
100
|
+
this.joinManager.addJoinForRelationshipPath(relationshipPath);
|
|
95
101
|
});
|
|
96
102
|
if (this.statements.join) {
|
|
97
103
|
this.statements.join = this.statements.join?.reverse();
|
|
@@ -101,34 +107,6 @@ export class SqlBuilder {
|
|
|
101
107
|
}
|
|
102
108
|
return this;
|
|
103
109
|
}
|
|
104
|
-
addJoinForRelationshipPath(entity, relationshipPath) {
|
|
105
|
-
const relationshipNames = relationshipPath.split('.');
|
|
106
|
-
let currentEntity = entity;
|
|
107
|
-
let currentAlias = this.statements.alias;
|
|
108
|
-
let statement = this.statements.strategy === 'joined' ? this.statements.join : this.statements.selectJoin;
|
|
109
|
-
let nameAliasProperty = this.statements.strategy === 'joined' ? 'joinAlias' : 'alias';
|
|
110
|
-
relationshipNames.forEach((relationshipName, index) => {
|
|
111
|
-
const relationship = currentEntity.relations.find(rel => rel.propertyKey === relationshipName);
|
|
112
|
-
if (!relationship) {
|
|
113
|
-
// @ts-ignore
|
|
114
|
-
throw new Error(`Relationship "${relationshipName}" not found in entity "${currentEntity.name}"`);
|
|
115
|
-
}
|
|
116
|
-
const isLastRelationship = index === relationshipNames.length - 1;
|
|
117
|
-
if (index === (relationshipNames.length - 2 >= 0 ? relationshipNames.length - 2 : 0)) {
|
|
118
|
-
const join = statement?.find(j => j.joinProperty === relationshipName);
|
|
119
|
-
if (join) {
|
|
120
|
-
// @ts-ignore
|
|
121
|
-
currentAlias = join[nameAliasProperty];
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (relationship.relation === 'many-to-one' && isLastRelationship) {
|
|
125
|
-
this.applyJoin(relationship, {}, currentAlias);
|
|
126
|
-
statement = this.statements.strategy === 'joined' ? this.statements.join : this.statements.selectJoin;
|
|
127
|
-
currentAlias = statement[statement.length - 1][nameAliasProperty];
|
|
128
|
-
}
|
|
129
|
-
currentEntity = this.entityStorage.get(relationship.entity());
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
110
|
getPrimaryKeyColumnName(entity) {
|
|
133
111
|
// Lógica para obter o nome da coluna de chave primária da entidade
|
|
134
112
|
// Aqui você pode substituir por sua própria lógica, dependendo da estrutura do seu projeto
|
|
@@ -138,14 +116,12 @@ export class SqlBuilder {
|
|
|
138
116
|
}
|
|
139
117
|
async execute() {
|
|
140
118
|
if (!this.statements.columns) {
|
|
141
|
-
this.statements.columns = this.generateColumns();
|
|
119
|
+
this.statements.columns = this.columnManager.generateColumns(this.model, this.updatedColumns);
|
|
142
120
|
}
|
|
143
121
|
else {
|
|
144
|
-
this.
|
|
145
|
-
this.filterInvalidColumns();
|
|
122
|
+
this.statements.columns = [...this.columnManager.processUserColumns(this.statements.columns), ...this.updatedColumns];
|
|
146
123
|
}
|
|
147
124
|
this.statements.join = this.statements.join?.reverse();
|
|
148
|
-
this.includeUpdatedColumns();
|
|
149
125
|
this.beforeHooks();
|
|
150
126
|
const result = await this.driver.executeStatement(this.statements);
|
|
151
127
|
this.logExecution(result);
|
|
@@ -178,9 +154,9 @@ export class SqlBuilder {
|
|
|
178
154
|
return undefined;
|
|
179
155
|
}
|
|
180
156
|
const entities = result.query.rows[0];
|
|
181
|
-
const model = await this.
|
|
157
|
+
const model = await this.modelTransformer.transform(this.model, this.statements, entities);
|
|
182
158
|
this.afterHooks(model);
|
|
183
|
-
await this.handleSelectJoin(entities, model);
|
|
159
|
+
await this.joinManager.handleSelectJoin(entities, model);
|
|
184
160
|
return model;
|
|
185
161
|
}
|
|
186
162
|
async executeAndReturnFirstOrFail() {
|
|
@@ -190,9 +166,9 @@ export class SqlBuilder {
|
|
|
190
166
|
throw new Error('Result not found');
|
|
191
167
|
}
|
|
192
168
|
const entities = result.query.rows[0];
|
|
193
|
-
const model = await this.
|
|
169
|
+
const model = await this.modelTransformer.transform(this.model, this.statements, entities);
|
|
194
170
|
this.afterHooks(model);
|
|
195
|
-
await this.handleSelectJoin(entities, model);
|
|
171
|
+
await this.joinManager.handleSelectJoin(entities, model);
|
|
196
172
|
return model;
|
|
197
173
|
}
|
|
198
174
|
async executeAndReturnAll() {
|
|
@@ -203,133 +179,16 @@ export class SqlBuilder {
|
|
|
203
179
|
const rows = result.query.rows;
|
|
204
180
|
const results = [];
|
|
205
181
|
for (const row of rows) {
|
|
206
|
-
const models = this.
|
|
182
|
+
const models = this.modelTransformer.transform(this.model, this.statements, row);
|
|
207
183
|
this.afterHooks(models);
|
|
208
|
-
await this.handleSelectJoin(row, models);
|
|
184
|
+
await this.joinManager.handleSelectJoin(row, models);
|
|
209
185
|
results.push(models);
|
|
210
186
|
}
|
|
211
187
|
return results;
|
|
212
188
|
}
|
|
213
|
-
async handleSelectJoin(entities, models) {
|
|
214
|
-
if (!this.statements.selectJoin || this.statements.selectJoin.length === 0) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
for (const join of this.statements.selectJoin.reverse()) {
|
|
218
|
-
let ids = entities[`${join.originAlias}_${join.primaryKey}`];
|
|
219
|
-
if (typeof ids === 'undefined') {
|
|
220
|
-
// get of models
|
|
221
|
-
const selectJoined = this.statements.selectJoin.find(j => j.joinEntity === join.originEntity);
|
|
222
|
-
if (!selectJoined) {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
ids = this.findIdRecursively(models, selectJoined, join);
|
|
226
|
-
}
|
|
227
|
-
if (Array.isArray(ids)) {
|
|
228
|
-
ids = ids.map((id) => this.t(id)).join(', ');
|
|
229
|
-
}
|
|
230
|
-
if (join.where) {
|
|
231
|
-
join.where = `${join.where} AND ${join.alias}."${join.fkKey}" IN (${ids})`;
|
|
232
|
-
}
|
|
233
|
-
else {
|
|
234
|
-
join.where = `${join.alias}."${join.fkKey}" IN (${ids})`;
|
|
235
|
-
}
|
|
236
|
-
if (join.columns && join.columns.length > 0) {
|
|
237
|
-
join.columns = join.columns.map(
|
|
238
|
-
// @ts-ignore
|
|
239
|
-
(column) => `${join.alias}."${column}" as "${join.alias}_${column}"`);
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
join.columns = this.getColumnsEntity(join.joinEntity, join.alias);
|
|
243
|
-
}
|
|
244
|
-
const child = await this.driver.executeStatement(join);
|
|
245
|
-
this.logger.debug(`SQL: ${child.sql} [${Date.now() - child.startTime}ms]`);
|
|
246
|
-
const property = this.entityStorage.get(this.model).relations.find((rel) => rel.propertyKey === join.joinProperty);
|
|
247
|
-
const values = child.query.rows.map((row) => this.transformToModel(join.joinEntity, join, row));
|
|
248
|
-
const path = this.getPathForSelectJoin(join);
|
|
249
|
-
this.setValueByPath(models, path, property?.type === Array ? [...values] : values[0]);
|
|
250
|
-
}
|
|
251
|
-
return models;
|
|
252
|
-
}
|
|
253
|
-
getPathForSelectJoin(selectJoin) {
|
|
254
|
-
const path = this.getPathForSelectJoinRecursive(this.statements, selectJoin);
|
|
255
|
-
return path.reverse();
|
|
256
|
-
}
|
|
257
|
-
setValueByPath(obj, path, value) {
|
|
258
|
-
let currentObj = obj;
|
|
259
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
260
|
-
const key = path[i];
|
|
261
|
-
currentObj[key] = currentObj[key] || {};
|
|
262
|
-
currentObj = currentObj[key];
|
|
263
|
-
}
|
|
264
|
-
currentObj[path[path.length - 1]] = value;
|
|
265
|
-
}
|
|
266
|
-
getPathForSelectJoinRecursive(statements, selectJoin) {
|
|
267
|
-
const originJoin = this.statements.selectJoin.find(j => j.joinEntity === selectJoin.originEntity);
|
|
268
|
-
let pathInJoin = [];
|
|
269
|
-
if (!originJoin) {
|
|
270
|
-
return [selectJoin.joinProperty];
|
|
271
|
-
}
|
|
272
|
-
if (originJoin.originEntity !== statements.originEntity) {
|
|
273
|
-
pathInJoin = this.getPathForSelectJoinRecursive(statements, originJoin);
|
|
274
|
-
}
|
|
275
|
-
return [selectJoin.joinProperty, ...pathInJoin];
|
|
276
|
-
}
|
|
277
|
-
findIdRecursively(models, selectJoined, join) {
|
|
278
|
-
let ids = models[selectJoined.originProperty][join.primaryKey];
|
|
279
|
-
if (typeof ids === 'undefined') {
|
|
280
|
-
const nextSelectJoined = this.statements.selectJoin.find(j => j.joinEntity === selectJoined.originEntity);
|
|
281
|
-
if (nextSelectJoined) {
|
|
282
|
-
// Chamada recursiva para a próxima camada
|
|
283
|
-
ids = this.findIdRecursively(models, nextSelectJoined, join);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
return ids;
|
|
287
|
-
}
|
|
288
|
-
generateColumns() {
|
|
289
|
-
let columns = [
|
|
290
|
-
...this.getColumnsEntity(this.model, this.statements.alias),
|
|
291
|
-
];
|
|
292
|
-
if (this.statements.join) {
|
|
293
|
-
columns = [
|
|
294
|
-
...columns,
|
|
295
|
-
...this.statements.join.flatMap(join => this.getColumnsEntity(join.joinEntity, join.joinAlias)),
|
|
296
|
-
];
|
|
297
|
-
}
|
|
298
|
-
return columns;
|
|
299
|
-
}
|
|
300
|
-
extractAliasForColumns() {
|
|
301
|
-
// @ts-ignore
|
|
302
|
-
this.statements.columns = this.statements.columns.map((column) => {
|
|
303
|
-
return this.discoverColumnAlias(column);
|
|
304
|
-
}).flat();
|
|
305
|
-
}
|
|
306
|
-
filterInvalidColumns() {
|
|
307
|
-
this.statements.columns = this.statements.columns.filter(Boolean);
|
|
308
|
-
}
|
|
309
|
-
includeUpdatedColumns() {
|
|
310
|
-
this.statements.columns.push(...this.updatedColumns);
|
|
311
|
-
}
|
|
312
189
|
logExecution(result) {
|
|
313
190
|
this.logger.debug(`SQL: ${result.sql} [${Date.now() - result.startTime}ms]`);
|
|
314
191
|
}
|
|
315
|
-
/**
|
|
316
|
-
* @deprecated Use inTransaction() instead
|
|
317
|
-
*/
|
|
318
|
-
startTransaction() {
|
|
319
|
-
throw new Error('startTransaction() is deprecated. Use inTransaction() instead.');
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* @deprecated Use inTransaction() instead
|
|
323
|
-
*/
|
|
324
|
-
commit() {
|
|
325
|
-
throw new Error('commit() is deprecated. Use inTransaction() instead.');
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* @deprecated Use inTransaction() instead
|
|
329
|
-
*/
|
|
330
|
-
rollback() {
|
|
331
|
-
throw new Error('rollback() is deprecated. Use inTransaction() instead.');
|
|
332
|
-
}
|
|
333
192
|
async inTransaction(callback) {
|
|
334
193
|
return await this.driver.transaction(async (tx) => {
|
|
335
194
|
// @ts-ignore
|
|
@@ -337,243 +196,32 @@ export class SqlBuilder {
|
|
|
337
196
|
});
|
|
338
197
|
}
|
|
339
198
|
objectToStringMap(obj, parentKey = '') {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
let fullKey = parentKey ? `${parentKey}.${key}` : key;
|
|
344
|
-
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
345
|
-
result = result.concat(this.objectToStringMap(obj[key], fullKey));
|
|
346
|
-
}
|
|
347
|
-
else {
|
|
348
|
-
result.push(`${this.discoverColumnAlias(fullKey, true)} ${obj[key]}`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return result;
|
|
199
|
+
return Object.keys(obj)
|
|
200
|
+
.filter(key => obj.hasOwnProperty(key))
|
|
201
|
+
.flatMap(key => this.mapObjectKey(obj, key, parentKey));
|
|
353
202
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}
|
|
359
|
-
return `${this.statements.alias}."${column}" as ${this.statements.alias}_${column}`;
|
|
203
|
+
mapObjectKey(obj, key, parentKey) {
|
|
204
|
+
const fullKey = parentKey ? `${parentKey}.${key}` : key;
|
|
205
|
+
if (this.isNestedObject(obj[key])) {
|
|
206
|
+
return this.objectToStringMap(obj[key], fullKey);
|
|
360
207
|
}
|
|
361
|
-
if (
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
const entities = column.split('.');
|
|
365
|
-
let lastEntity = this.model;
|
|
366
|
-
let lastAlias = this.statements.alias;
|
|
367
|
-
const relationsMap = new Map(this.entity.relations.map(rel => [rel.propertyKey, rel]));
|
|
368
|
-
const joinMap = new Map();
|
|
369
|
-
const joinSelectMap = new Map();
|
|
370
|
-
this.statements.join?.forEach(join => joinMap.set(join.joinProperty, join));
|
|
371
|
-
this.statements.selectJoin?.forEach(join => joinSelectMap.set(join.joinProperty, join));
|
|
372
|
-
for (let i = 0; i < entities.length; i++) {
|
|
373
|
-
if (i === 0) {
|
|
374
|
-
const relation = relationsMap.get(entities[i]);
|
|
375
|
-
lastEntity = relation?.entity();
|
|
376
|
-
// @ts-ignore
|
|
377
|
-
if (joinMap.has(entities[i])) {
|
|
378
|
-
lastAlias = joinMap.get(entities[i]).joinAlias;
|
|
379
|
-
}
|
|
380
|
-
else {
|
|
381
|
-
lastAlias = joinSelectMap.get(entities[i])?.alias;
|
|
382
|
-
return undefined;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
if ((i + 1) === entities.length) {
|
|
387
|
-
if (onlyAlias) {
|
|
388
|
-
return `${lastAlias}."${entities[i]}"`;
|
|
389
|
-
}
|
|
390
|
-
return `${lastAlias}."${entities[i]}" as ${lastAlias}_${entities[i]}`;
|
|
391
|
-
}
|
|
392
|
-
const lastStatement = joinMap.get(entities[i]);
|
|
393
|
-
lastEntity = lastStatement?.joinEntity;
|
|
394
|
-
// @ts-ignore
|
|
395
|
-
lastAlias = lastStatement?.joinAlias;
|
|
396
|
-
}
|
|
208
|
+
if (parentKey) {
|
|
209
|
+
return [`${this.columnManager.discoverAlias(fullKey, true)} ${obj[key]}`];
|
|
397
210
|
}
|
|
398
|
-
|
|
211
|
+
const columnName = ValueProcessor.getColumnName(key, this.entity);
|
|
212
|
+
return [`${this.columnManager.discoverAlias(columnName, true)} ${obj[key]}`];
|
|
213
|
+
}
|
|
214
|
+
isNestedObject(value) {
|
|
215
|
+
return typeof value === 'object' && value !== null;
|
|
399
216
|
}
|
|
400
217
|
getTableName() {
|
|
401
218
|
const tableName = this.entity.tableName || this.model.name.toLowerCase();
|
|
402
219
|
const schema = this.entity.schema || 'public';
|
|
403
220
|
return { tableName, schema };
|
|
404
221
|
}
|
|
405
|
-
addSimpleConditionToSql(key, value, alias = null, operator = '=') {
|
|
406
|
-
const aliasToUse = alias || this.statements.alias;
|
|
407
|
-
const valueByType = (typeof value === 'string') ? `'${value}'` : value;
|
|
408
|
-
return `${aliasToUse}.${key} ${operator} ${valueByType}`;
|
|
409
|
-
}
|
|
410
|
-
addInConditionToSql(key, values, alias = null) {
|
|
411
|
-
const aliasToUse = alias || this.statements.alias;
|
|
412
|
-
return `${aliasToUse}.${key} IN (${values.map(val => (typeof val === 'string') ? `'${val}'` : val).join(", ")})`;
|
|
413
|
-
}
|
|
414
|
-
addLogicalOperatorToSql(conditions, operator) {
|
|
415
|
-
return `(${conditions.join(` ${operator} `)})`;
|
|
416
|
-
}
|
|
417
|
-
conditionToSql(condition, alias, model) {
|
|
418
|
-
const sqlParts = [];
|
|
419
|
-
const operators = ['$eq', '$ne', '$in', '$nin', '$like', '$gt', '$gte', '$lt', '$lte', '$and', '$or'];
|
|
420
|
-
for (let [key, value] of Object.entries(condition)) {
|
|
421
|
-
if (extendsFrom(ValueObject, value.constructor.prototype)) {
|
|
422
|
-
value = value.getValue();
|
|
423
|
-
}
|
|
424
|
-
if (!operators.includes(key)) {
|
|
425
|
-
this.lastKeyNotOperator = key;
|
|
426
|
-
}
|
|
427
|
-
const entity = this.entityStorage.get(model);
|
|
428
|
-
const relationShip = entity.relations?.find(rel => rel.propertyKey === key);
|
|
429
|
-
if (relationShip) {
|
|
430
|
-
const sql = this.applyJoin(relationShip, value, alias);
|
|
431
|
-
if (this.statements.strategy === 'joined') {
|
|
432
|
-
sqlParts.push(sql);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
else if (typeof value !== 'object' || value === null) {
|
|
436
|
-
if (key === '$eq') {
|
|
437
|
-
sqlParts.push(this.addSimpleConditionToSql(this.lastKeyNotOperator, value, alias, '='));
|
|
438
|
-
continue;
|
|
439
|
-
}
|
|
440
|
-
sqlParts.push(this.addSimpleConditionToSql(key, value, alias));
|
|
441
|
-
}
|
|
442
|
-
else if (!(operators.includes(key)) && Array.isArray(value)) {
|
|
443
|
-
sqlParts.push(this.addInConditionToSql(key, value, alias));
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
if (['$or', '$and'].includes(key)) {
|
|
447
|
-
sqlParts.push(this.addLogicalOperatorToSql(value.map((cond) => this.conditionToSql(cond, alias, model)), key.toUpperCase().replace('$', '')));
|
|
448
|
-
}
|
|
449
|
-
for (const operator of operators) {
|
|
450
|
-
if (operator in value) {
|
|
451
|
-
switch (operator) {
|
|
452
|
-
case '$eq':
|
|
453
|
-
sqlParts.push(this.addSimpleConditionToSql(key, value['$eq'], alias, '='));
|
|
454
|
-
break;
|
|
455
|
-
case '$ne':
|
|
456
|
-
sqlParts.push(this.addSimpleConditionToSql(key, value['$ne'], alias, '!='));
|
|
457
|
-
break;
|
|
458
|
-
case '$in':
|
|
459
|
-
sqlParts.push(this.addInConditionToSql(key, value['$in'], alias));
|
|
460
|
-
break;
|
|
461
|
-
case '$nin':
|
|
462
|
-
sqlParts.push(`${alias}.${key} NOT IN (${value['$nin'].map((val) => this.t(val)).join(", ")})`);
|
|
463
|
-
break;
|
|
464
|
-
case '$like':
|
|
465
|
-
sqlParts.push(`${alias}.${key} LIKE '${value['$like']}'`);
|
|
466
|
-
break;
|
|
467
|
-
case '$gt':
|
|
468
|
-
sqlParts.push(`${alias}.${key} > ${value['$gt']}`);
|
|
469
|
-
break;
|
|
470
|
-
case '$gte':
|
|
471
|
-
sqlParts.push(`${alias}.${key} >= ${value['$gte']}`);
|
|
472
|
-
break;
|
|
473
|
-
case '$lt':
|
|
474
|
-
sqlParts.push(`${alias}.${key} < ${value['$lt']}`);
|
|
475
|
-
break;
|
|
476
|
-
case '$lte':
|
|
477
|
-
sqlParts.push(`${alias}.${key} <= ${value['$lte']}`);
|
|
478
|
-
break;
|
|
479
|
-
case '$and':
|
|
480
|
-
case '$or':
|
|
481
|
-
const parts = value[operator].map((cond) => this.conditionToSql(cond, alias, model));
|
|
482
|
-
sqlParts.push(this.addLogicalOperatorToSql(parts, operator.toUpperCase().replace('$', '')));
|
|
483
|
-
break;
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
if (sqlParts.length === 0) {
|
|
490
|
-
return '';
|
|
491
|
-
}
|
|
492
|
-
return this.addLogicalOperatorToSql(sqlParts, 'AND');
|
|
493
|
-
}
|
|
494
222
|
t(value) {
|
|
495
223
|
return (typeof value === 'string') ? `'${value}'` : value;
|
|
496
224
|
}
|
|
497
|
-
applyJoin(relationShip, value, alias) {
|
|
498
|
-
const { tableName, schema } = this.getTableName();
|
|
499
|
-
const { tableName: joinTableName, schema: joinSchema, hooks: joinHooks, } = this.entityStorage.get(relationShip.entity()) || {
|
|
500
|
-
tableName: relationShip.entity().name.toLowerCase(),
|
|
501
|
-
schema: 'public',
|
|
502
|
-
};
|
|
503
|
-
let originPrimaryKey = 'id';
|
|
504
|
-
for (const prop in this.entity.properties) {
|
|
505
|
-
if (this.entity.properties[prop].options.isPrimary) {
|
|
506
|
-
originPrimaryKey = prop;
|
|
507
|
-
break;
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
const joinAlias = `${this.getAlias(joinTableName)}`;
|
|
511
|
-
const joinWhere = this.conditionToSql(value, joinAlias, relationShip.entity());
|
|
512
|
-
let on = '';
|
|
513
|
-
switch (relationShip.relation) {
|
|
514
|
-
case "one-to-many":
|
|
515
|
-
on = `${joinAlias}."${this.getFkKey(relationShip)}" = ${alias}."${originPrimaryKey}"`;
|
|
516
|
-
break;
|
|
517
|
-
case "many-to-one":
|
|
518
|
-
on = `${alias}."${relationShip.columnName}" = ${joinAlias}."${this.getFkKey(relationShip)}"`;
|
|
519
|
-
break;
|
|
520
|
-
}
|
|
521
|
-
if (this.statements.strategy === 'joined') {
|
|
522
|
-
this.statements.join = this.statements.join || [];
|
|
523
|
-
this.statements.join.push({
|
|
524
|
-
joinAlias: joinAlias,
|
|
525
|
-
joinTable: joinTableName,
|
|
526
|
-
joinSchema: joinSchema || 'public',
|
|
527
|
-
joinWhere: joinWhere,
|
|
528
|
-
joinProperty: relationShip.propertyKey,
|
|
529
|
-
originAlias: alias,
|
|
530
|
-
originSchema: schema,
|
|
531
|
-
originTable: tableName,
|
|
532
|
-
propertyKey: relationShip.propertyKey,
|
|
533
|
-
joinEntity: relationShip.entity(),
|
|
534
|
-
type: 'LEFT',
|
|
535
|
-
// @ts-ignore
|
|
536
|
-
on,
|
|
537
|
-
originalEntity: relationShip.originalEntity,
|
|
538
|
-
hooks: joinHooks,
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
else {
|
|
542
|
-
this.statements.selectJoin = this.statements.selectJoin || [];
|
|
543
|
-
this.statements.selectJoin.push({
|
|
544
|
-
statement: 'select',
|
|
545
|
-
columns: this.originalColumns.filter(column => column.startsWith(`${relationShip.propertyKey}`)).map(column => column.split('.')[1]) || [],
|
|
546
|
-
table: `"${joinSchema || 'public'}"."${joinTableName}"`,
|
|
547
|
-
alias: joinAlias,
|
|
548
|
-
where: joinWhere,
|
|
549
|
-
joinProperty: relationShip.propertyKey,
|
|
550
|
-
fkKey: this.getFkKey(relationShip),
|
|
551
|
-
primaryKey: originPrimaryKey,
|
|
552
|
-
originAlias: alias,
|
|
553
|
-
originProperty: relationShip.propertyKey,
|
|
554
|
-
joinEntity: relationShip.entity(),
|
|
555
|
-
originEntity: relationShip.originalEntity,
|
|
556
|
-
hooks: joinHooks,
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
return joinWhere;
|
|
560
|
-
}
|
|
561
|
-
getFkKey(relationShip) {
|
|
562
|
-
// se for nullable, deverá retornar o primary key da entidade target
|
|
563
|
-
if (typeof relationShip.fkKey === 'undefined') {
|
|
564
|
-
return 'id'; // TODO: Pegar dinamicamente o primary key da entidade target
|
|
565
|
-
}
|
|
566
|
-
// se o fkKey é uma função, ele retornará a propriedade da entidade que é a chave estrangeira
|
|
567
|
-
// precisamos pegar o nome dessa propriedade
|
|
568
|
-
if (typeof relationShip.fkKey === 'string') {
|
|
569
|
-
return relationShip.fkKey;
|
|
570
|
-
}
|
|
571
|
-
const match = /\.(?<propriedade>[\w]+)/.exec(relationShip.fkKey.toString());
|
|
572
|
-
const propertyKey = match ? match.groups.propriedade : '';
|
|
573
|
-
const entity = this.entityStorage.get(relationShip.entity());
|
|
574
|
-
const property = Object.entries(entity.properties).find(([key, _value]) => key === propertyKey)?.[1];
|
|
575
|
-
return property.options.columnName;
|
|
576
|
-
}
|
|
577
225
|
// private conditionLogicalOperatorToSql<T extends typeof BaseEntity>(conditions: Condition<T>[], operator: 'AND' | 'OR'): string {
|
|
578
226
|
// const sqlParts = conditions.map(cond => this.conditionToSql(cond));
|
|
579
227
|
// return this.addLogicalOperatorToSql(sqlParts, operator);
|
|
@@ -586,57 +234,6 @@ export class SqlBuilder {
|
|
|
586
234
|
}
|
|
587
235
|
this.entity = entity;
|
|
588
236
|
}
|
|
589
|
-
transformToModel(model, statement, data) {
|
|
590
|
-
const instance = new model();
|
|
591
|
-
instance.$_isPersisted = true;
|
|
592
|
-
const entitiesByAlias = {
|
|
593
|
-
[statement.alias]: instance,
|
|
594
|
-
};
|
|
595
|
-
const entitiesOptions = new Map();
|
|
596
|
-
entitiesOptions.set(statement.alias, this.entityStorage.get(instance.constructor));
|
|
597
|
-
if (this.statements.join) {
|
|
598
|
-
this.statements.join.forEach(join => {
|
|
599
|
-
const joinInstance = new join.joinEntity();
|
|
600
|
-
joinInstance.$_isPersisted = true;
|
|
601
|
-
entitiesByAlias[join.joinAlias] = joinInstance;
|
|
602
|
-
entitiesOptions.set(join.joinAlias, this.entityStorage.get(joinInstance.constructor));
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
606
|
-
const index = key.indexOf('_');
|
|
607
|
-
const alias = key.substring(0, index);
|
|
608
|
-
const prop = key.substring(index + 1);
|
|
609
|
-
const entity = entitiesByAlias[alias];
|
|
610
|
-
if (!entity) {
|
|
611
|
-
return;
|
|
612
|
-
}
|
|
613
|
-
const ep = Object.entries(entitiesOptions.get(alias).properties).find(([_, value]) => value.options.columnName === prop);
|
|
614
|
-
const entityProperty = ep?.[1];
|
|
615
|
-
const keyProperty = ep?.[0];
|
|
616
|
-
if (entityProperty) {
|
|
617
|
-
if (extendsFrom(ValueObject, entityProperty.type.prototype)) {
|
|
618
|
-
// @ts-ignore
|
|
619
|
-
entity[keyProperty] = new entityProperty.type(value);
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
entity[keyProperty] = value;
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
if (this.statements.join) {
|
|
626
|
-
this.statements.join.forEach(join => {
|
|
627
|
-
const { joinAlias, originAlias, propertyKey } = join;
|
|
628
|
-
const originEntity = entitiesByAlias[originAlias];
|
|
629
|
-
const joinEntity = entitiesByAlias[joinAlias];
|
|
630
|
-
const property = entitiesOptions.get(originAlias).relations.find(rel => rel.propertyKey === propertyKey);
|
|
631
|
-
if (!originEntity || !joinEntity) {
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
// @ts-ignore
|
|
635
|
-
originEntity[propertyKey] = (property.type === Array) ? (originEntity[propertyKey]) ? [...originEntity[propertyKey], joinEntity] : [joinEntity] : joinEntity;
|
|
636
|
-
});
|
|
637
|
-
}
|
|
638
|
-
return instance;
|
|
639
|
-
}
|
|
640
237
|
/**
|
|
641
238
|
* Retrieves an alias for a given table name.
|
|
642
239
|
*
|
|
@@ -645,170 +242,91 @@ export class SqlBuilder {
|
|
|
645
242
|
* @returns {string} - The alias for the table name.
|
|
646
243
|
*/
|
|
647
244
|
getAlias(tableName) {
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
let uniqueAlias = `${alias}${counter}`;
|
|
651
|
-
while (this.aliases.has(uniqueAlias)) {
|
|
652
|
-
counter++;
|
|
653
|
-
uniqueAlias = `${alias}${counter}`;
|
|
654
|
-
}
|
|
245
|
+
const baseAlias = tableName.split('').shift() || '';
|
|
246
|
+
const uniqueAlias = this.generateUniqueAlias(baseAlias);
|
|
655
247
|
this.aliases.add(uniqueAlias);
|
|
656
248
|
return uniqueAlias;
|
|
657
249
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (e.relations) {
|
|
665
|
-
for (const relation of e.relations) {
|
|
666
|
-
if (relation.relation === 'many-to-one') {
|
|
667
|
-
// @ts-ignore
|
|
668
|
-
columns.push(`${alias}."${relation.columnName}" as "${alias}_${relation.columnName}"`);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
250
|
+
generateUniqueAlias(baseAlias) {
|
|
251
|
+
let counter = 1;
|
|
252
|
+
let candidate = `${baseAlias}${counter}`;
|
|
253
|
+
while (this.aliases.has(candidate)) {
|
|
254
|
+
counter++;
|
|
255
|
+
candidate = `${baseAlias}${counter}`;
|
|
671
256
|
}
|
|
672
|
-
return
|
|
257
|
+
return candidate;
|
|
673
258
|
}
|
|
674
259
|
withDefaultValues(values, entityOptions) {
|
|
675
|
-
|
|
260
|
+
this.applyDefaultProperties(values, entityOptions);
|
|
261
|
+
this.applyOnInsertProperties(values, entityOptions);
|
|
262
|
+
return values;
|
|
263
|
+
}
|
|
264
|
+
applyDefaultProperties(values, entityOptions) {
|
|
676
265
|
const defaultProperties = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.default);
|
|
677
266
|
for (const [key, property] of defaultProperties) {
|
|
678
|
-
|
|
679
|
-
if (typeof property.options.default === 'function') {
|
|
680
|
-
values[key] = eval(property.options.default());
|
|
681
|
-
}
|
|
682
|
-
else {
|
|
683
|
-
values[key] = eval(property.options.default);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
267
|
+
this.setDefaultValue(values, key, property);
|
|
686
268
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
269
|
+
}
|
|
270
|
+
setDefaultValue(values, key, property) {
|
|
271
|
+
if (typeof values[key] !== 'undefined')
|
|
272
|
+
return;
|
|
273
|
+
values[key] = typeof property.options.default === 'function'
|
|
274
|
+
? property.options.default()
|
|
275
|
+
: property.options.default;
|
|
276
|
+
}
|
|
277
|
+
applyOnInsertProperties(values, entityOptions) {
|
|
278
|
+
const properties = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.onInsert);
|
|
279
|
+
properties.forEach(([key, property]) => this.applyOnInsert(values, key, property));
|
|
280
|
+
}
|
|
281
|
+
applyOnInsert(values, key, property) {
|
|
282
|
+
values[key] = property.options.onInsert();
|
|
283
|
+
this.updatedColumns.push(`${this.statements.alias}."${key}" as "${this.statements.alias}_${key}"`);
|
|
692
284
|
}
|
|
693
285
|
withUpdatedValues(values, entityOptions) {
|
|
694
|
-
const
|
|
695
|
-
|
|
696
|
-
values[property.options.columnName] = property.options.onUpdate();
|
|
697
|
-
this.updatedColumns.push(`${this.statements.alias}."${property.options.columnName}" as "${this.statements.alias}_${property.options.columnName}"`);
|
|
698
|
-
});
|
|
286
|
+
const properties = Object.entries(entityOptions.properties).filter(([_, value]) => value.options.onUpdate);
|
|
287
|
+
properties.forEach(([key, property]) => this.applyOnUpdate(values, property));
|
|
699
288
|
return values;
|
|
700
289
|
}
|
|
290
|
+
applyOnUpdate(values, property) {
|
|
291
|
+
const columnName = property.options.columnName;
|
|
292
|
+
values[columnName] = property.options.onUpdate();
|
|
293
|
+
this.updatedColumns.push(`${this.statements.alias}."${columnName}" as "${this.statements.alias}_${columnName}"`);
|
|
294
|
+
}
|
|
701
295
|
callHook(type, model) {
|
|
702
296
|
const hooks = this.statements.hooks?.filter(hook => hook.type === type) || [];
|
|
703
297
|
const instance = model || this.statements.instance;
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
298
|
+
hooks.forEach(hook => this.executeHook(hook, instance, !model));
|
|
299
|
+
}
|
|
300
|
+
executeHook(hook, instance, shouldReflect) {
|
|
301
|
+
instance[hook.propertyName]();
|
|
302
|
+
if (shouldReflect)
|
|
303
|
+
this.reflectToValues();
|
|
710
304
|
}
|
|
711
305
|
reflectToValues() {
|
|
712
306
|
for (const key in this.statements.instance) {
|
|
713
|
-
if (
|
|
714
|
-
continue;
|
|
715
|
-
}
|
|
716
|
-
if (key.startsWith('_')) {
|
|
717
|
-
continue;
|
|
718
|
-
}
|
|
719
|
-
if (this.entity.properties[key]) {
|
|
720
|
-
this.statements.values[this.entity.properties[key].options.columnName] = this.statements.instance[key];
|
|
307
|
+
if (this.shouldSkipKey(key))
|
|
721
308
|
continue;
|
|
722
|
-
|
|
723
|
-
const rel = this.entity.relations.find(rel => rel.propertyKey === key);
|
|
724
|
-
if (rel) {
|
|
725
|
-
this.statements.values[rel.columnName] = this.statements.instance[key];
|
|
726
|
-
}
|
|
309
|
+
this.reflectKey(key);
|
|
727
310
|
}
|
|
728
311
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
const newValue = {};
|
|
732
|
-
for (const value in values) {
|
|
733
|
-
const columnName = getColumnName(value, options);
|
|
734
|
-
if (extendsFrom(ValueObject, values[value].constructor.prototype)) {
|
|
735
|
-
newValue[columnName] = values[value].getValue();
|
|
736
|
-
continue;
|
|
737
|
-
}
|
|
738
|
-
if (values[value] instanceof BaseEntity) {
|
|
739
|
-
// @ts-ignore
|
|
740
|
-
newValue[columnName] = values[value].id; // TODO: get primary key
|
|
741
|
-
continue;
|
|
742
|
-
}
|
|
743
|
-
newValue[columnName] = values[value];
|
|
312
|
+
shouldSkipKey(key) {
|
|
313
|
+
return key.startsWith('$') || key.startsWith('_');
|
|
744
314
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
for (const value in values) {
|
|
750
|
-
if (extendsFrom(ValueObject, values[value].constructor.prototype)) {
|
|
751
|
-
newValue[getColumnName(value, options)] = values[value].getValue();
|
|
752
|
-
continue;
|
|
315
|
+
reflectKey(key) {
|
|
316
|
+
if (this.entity.properties[key]) {
|
|
317
|
+
this.reflectProperty(key);
|
|
318
|
+
return;
|
|
753
319
|
}
|
|
754
|
-
|
|
320
|
+
this.reflectRelation(key);
|
|
755
321
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
const property = entity.properties[propertyKey];
|
|
760
|
-
const relation = entity.relations?.find(rel => rel.propertyKey === propertyKey);
|
|
761
|
-
if (propertyKey.startsWith('$')) {
|
|
762
|
-
return propertyKey;
|
|
763
|
-
}
|
|
764
|
-
if (!property) {
|
|
765
|
-
if (relation) {
|
|
766
|
-
return relation.columnName || propertyKey;
|
|
767
|
-
}
|
|
768
|
-
throw new Error('Property not found');
|
|
322
|
+
reflectProperty(key) {
|
|
323
|
+
const columnName = this.entity.properties[key].options.columnName;
|
|
324
|
+
this.statements.values[columnName] = this.statements.instance[key];
|
|
769
325
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
const entityOptions = entityStorage.get(entity);
|
|
775
|
-
// @ts-ignore
|
|
776
|
-
const instance = new entity();
|
|
777
|
-
if (!entityOptions) {
|
|
778
|
-
throw new Error('Entity not found');
|
|
779
|
-
}
|
|
780
|
-
const property = Object.entries(entityOptions.properties);
|
|
781
|
-
const relations = entityOptions.relations;
|
|
782
|
-
property.forEach(([key, property]) => {
|
|
783
|
-
if (property.options.onInsert && moment === 'insert') {
|
|
784
|
-
instance[key] = property.options.onInsert();
|
|
785
|
-
}
|
|
786
|
-
if (property.options.onInsert && moment === 'update') {
|
|
787
|
-
instance[key] = property.options.onUpdate();
|
|
788
|
-
}
|
|
789
|
-
if (key in values) {
|
|
790
|
-
instance[key] = values[property.options.columnName];
|
|
791
|
-
}
|
|
792
|
-
});
|
|
793
|
-
if (relations) {
|
|
794
|
-
for (const relation of relations) {
|
|
795
|
-
if (relation.relation === 'many-to-one') {
|
|
796
|
-
// @ts-ignore
|
|
797
|
-
instance[relation.propertyKey] = values[relation.columnName];
|
|
798
|
-
}
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
return instance;
|
|
802
|
-
}
|
|
803
|
-
function convertWhereObj(where, entity) {
|
|
804
|
-
let newWhere = {};
|
|
805
|
-
for (const key in where) {
|
|
806
|
-
if (where[key] instanceof Object) { // Se o valor atual é um objeto, chame a mesma função recursivamente
|
|
807
|
-
newWhere[getColumnName(key, entity)] = convertWhereObj(where[key], entity);
|
|
808
|
-
}
|
|
809
|
-
else {
|
|
810
|
-
newWhere[getColumnName(key, entity)] = where[key];
|
|
326
|
+
reflectRelation(key) {
|
|
327
|
+
const rel = this.entity.relations.find(rel => rel.propertyKey === key);
|
|
328
|
+
if (rel) {
|
|
329
|
+
this.statements.values[rel.columnName] = this.statements.instance[key];
|
|
811
330
|
}
|
|
812
331
|
}
|
|
813
|
-
return newWhere;
|
|
814
332
|
}
|