@mikro-orm/knex 7.0.0-dev.1 → 7.0.0-dev.2
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/AbstractSqlConnection.d.ts +2 -2
- package/AbstractSqlConnection.js +22 -25
- package/AbstractSqlDriver.d.ts +9 -7
- package/AbstractSqlDriver.js +175 -180
- package/AbstractSqlPlatform.d.ts +4 -4
- package/AbstractSqlPlatform.js +17 -21
- package/PivotCollectionPersister.d.ts +1 -1
- package/PivotCollectionPersister.js +5 -8
- package/SqlEntityManager.d.ts +4 -3
- package/SqlEntityManager.js +2 -6
- package/SqlEntityRepository.d.ts +2 -2
- package/SqlEntityRepository.js +2 -6
- package/dialects/index.d.ts +4 -4
- package/dialects/index.js +4 -20
- package/dialects/mssql/MsSqlNativeQueryBuilder.d.ts +1 -1
- package/dialects/mssql/MsSqlNativeQueryBuilder.js +21 -25
- package/dialects/mssql/index.d.ts +1 -1
- package/dialects/mssql/index.js +1 -17
- package/dialects/mysql/MySqlExceptionConverter.js +16 -19
- package/dialects/mysql/MySqlNativeQueryBuilder.d.ts +1 -1
- package/dialects/mysql/MySqlNativeQueryBuilder.js +13 -17
- package/dialects/mysql/MySqlPlatform.d.ts +5 -5
- package/dialects/mysql/MySqlPlatform.js +16 -20
- package/dialects/mysql/MySqlSchemaHelper.d.ts +5 -5
- package/dialects/mysql/MySqlSchemaHelper.js +8 -12
- package/dialects/mysql/index.d.ts +4 -4
- package/dialects/mysql/index.js +4 -20
- package/dialects/postgresql/PostgreSqlNativeQueryBuilder.d.ts +1 -1
- package/dialects/postgresql/PostgreSqlNativeQueryBuilder.js +2 -6
- package/dialects/postgresql/index.d.ts +1 -1
- package/dialects/postgresql/index.js +1 -17
- package/dialects/sqlite/BaseSqliteConnection.d.ts +1 -1
- package/dialects/sqlite/BaseSqliteConnection.js +7 -11
- package/dialects/sqlite/BaseSqlitePlatform.d.ts +4 -4
- package/dialects/sqlite/BaseSqlitePlatform.js +11 -15
- package/dialects/sqlite/SqliteExceptionConverter.js +16 -19
- package/dialects/sqlite/SqliteNativeQueryBuilder.d.ts +1 -1
- package/dialects/sqlite/SqliteNativeQueryBuilder.js +2 -6
- package/dialects/sqlite/SqliteSchemaHelper.d.ts +5 -5
- package/dialects/sqlite/SqliteSchemaHelper.js +22 -26
- package/dialects/sqlite/index.d.ts +5 -5
- package/dialects/sqlite/index.js +5 -21
- package/index.d.ts +11 -11
- package/index.js +13 -34
- package/package.json +5 -14
- package/query/ArrayCriteriaNode.d.ts +2 -2
- package/query/ArrayCriteriaNode.js +2 -6
- package/query/CriteriaNode.d.ts +1 -1
- package/query/CriteriaNode.js +26 -30
- package/query/CriteriaNodeFactory.d.ts +1 -1
- package/query/CriteriaNodeFactory.js +17 -21
- package/query/NativeQueryBuilder.d.ts +2 -2
- package/query/NativeQueryBuilder.js +33 -37
- package/query/ObjectCriteriaNode.d.ts +2 -2
- package/query/ObjectCriteriaNode.js +37 -41
- package/query/QueryBuilder.d.ts +7 -7
- package/query/QueryBuilder.js +172 -176
- package/query/QueryBuilderHelper.d.ts +4 -4
- package/query/QueryBuilderHelper.js +84 -88
- package/query/ScalarCriteriaNode.d.ts +2 -2
- package/query/ScalarCriteriaNode.js +12 -16
- package/query/enums.js +4 -7
- package/query/index.d.ts +9 -9
- package/query/index.js +9 -25
- package/schema/DatabaseSchema.d.ts +3 -3
- package/schema/DatabaseSchema.js +7 -11
- package/schema/DatabaseTable.d.ts +3 -3
- package/schema/DatabaseTable.js +26 -30
- package/schema/SchemaComparator.d.ts +4 -4
- package/schema/SchemaComparator.js +15 -19
- package/schema/SchemaHelper.d.ts +5 -5
- package/schema/SchemaHelper.js +22 -26
- package/schema/SqlSchemaGenerator.d.ts +4 -4
- package/schema/SqlSchemaGenerator.js +18 -21
- package/schema/index.d.ts +5 -5
- package/schema/index.js +5 -21
- package/typings.d.ts +5 -4
- package/typings.js +1 -2
- package/index.mjs +0 -232
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type Dictionary, type EntityData, type EntityKey, type EntityMetadata, type EntityProperty, type FlatQueryOrderMap, LockMode, type QBFilterQuery, RawQueryFragment } from '@mikro-orm/core';
|
|
2
|
-
import { JoinType, QueryType } from './enums';
|
|
3
|
-
import type { Field, JoinOptions } from '../typings';
|
|
4
|
-
import type { AbstractSqlDriver } from '../AbstractSqlDriver';
|
|
5
|
-
import { NativeQueryBuilder } from './NativeQueryBuilder';
|
|
2
|
+
import { JoinType, QueryType } from './enums.js';
|
|
3
|
+
import type { Field, JoinOptions } from '../typings.js';
|
|
4
|
+
import type { AbstractSqlDriver } from '../AbstractSqlDriver.js';
|
|
5
|
+
import { NativeQueryBuilder } from './NativeQueryBuilder.js';
|
|
6
6
|
/**
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const core_1 = require("@mikro-orm/core");
|
|
6
|
-
const enums_1 = require("./enums");
|
|
7
|
-
const NativeQueryBuilder_1 = require("./NativeQueryBuilder");
|
|
1
|
+
import { inspect } from 'node:util';
|
|
2
|
+
import { ALIAS_REPLACEMENT, ALIAS_REPLACEMENT_RE, ArrayType, isRaw, LockMode, OptimisticLockError, QueryOperator, QueryOrderNumeric, raw, RawQueryFragment, ReferenceKind, Utils, } from '@mikro-orm/core';
|
|
3
|
+
import { JoinType, QueryType } from './enums.js';
|
|
4
|
+
import { NativeQueryBuilder } from './NativeQueryBuilder.js';
|
|
8
5
|
/**
|
|
9
6
|
* @internal
|
|
10
7
|
*/
|
|
11
|
-
class QueryBuilderHelper {
|
|
8
|
+
export class QueryBuilderHelper {
|
|
12
9
|
entityName;
|
|
13
10
|
alias;
|
|
14
11
|
aliasMap;
|
|
@@ -25,16 +22,16 @@ class QueryBuilderHelper {
|
|
|
25
22
|
this.platform = this.driver.getPlatform();
|
|
26
23
|
this.metadata = this.driver.getMetadata();
|
|
27
24
|
}
|
|
28
|
-
mapper(field, type =
|
|
29
|
-
if (
|
|
30
|
-
return
|
|
25
|
+
mapper(field, type = QueryType.SELECT, value, alias) {
|
|
26
|
+
if (isRaw(field)) {
|
|
27
|
+
return raw(field.sql, field.params);
|
|
31
28
|
}
|
|
32
|
-
/*
|
|
29
|
+
/* v8 ignore next 3 */
|
|
33
30
|
if (typeof field !== 'string') {
|
|
34
31
|
return field;
|
|
35
32
|
}
|
|
36
33
|
const isTableNameAliasRequired = this.isTableNameAliasRequired(type);
|
|
37
|
-
const fields =
|
|
34
|
+
const fields = Utils.splitPrimaryKeys(field);
|
|
38
35
|
if (fields.length > 1) {
|
|
39
36
|
const parts = [];
|
|
40
37
|
for (const p of fields) {
|
|
@@ -59,7 +56,7 @@ class QueryBuilderHelper {
|
|
|
59
56
|
if (fields.length !== parts.length && Array.isArray(value)) {
|
|
60
57
|
value.forEach(row => {
|
|
61
58
|
if (Array.isArray(row)) {
|
|
62
|
-
const tmp =
|
|
59
|
+
const tmp = Utils.flatten(row);
|
|
63
60
|
row.length = 0;
|
|
64
61
|
row.push(...tmp);
|
|
65
62
|
}
|
|
@@ -68,9 +65,9 @@ class QueryBuilderHelper {
|
|
|
68
65
|
if (parts.length === 1) {
|
|
69
66
|
return parts[0];
|
|
70
67
|
}
|
|
71
|
-
return
|
|
68
|
+
return raw('(' + parts.map(part => this.platform.quoteIdentifier(part)).join(', ') + ')');
|
|
72
69
|
}
|
|
73
|
-
const rawField =
|
|
70
|
+
const rawField = RawQueryFragment.getKnownFragment(field);
|
|
74
71
|
if (rawField) {
|
|
75
72
|
return rawField;
|
|
76
73
|
}
|
|
@@ -89,7 +86,7 @@ class QueryBuilderHelper {
|
|
|
89
86
|
}
|
|
90
87
|
const noPrefix = prop && prop.persist === false;
|
|
91
88
|
if (prop?.fieldNameRaw) {
|
|
92
|
-
return
|
|
89
|
+
return raw(this.prefix(field, isTableNameAliasRequired));
|
|
93
90
|
}
|
|
94
91
|
if (prop?.formula) {
|
|
95
92
|
const alias2 = this.platform.quoteIdentifier(a).toString();
|
|
@@ -99,9 +96,9 @@ class QueryBuilderHelper {
|
|
|
99
96
|
if (!this.isTableNameAliasRequired(type)) {
|
|
100
97
|
value = value.replaceAll(alias2 + '.', '');
|
|
101
98
|
}
|
|
102
|
-
return
|
|
99
|
+
return raw(`${value}${as}`);
|
|
103
100
|
}
|
|
104
|
-
if (prop?.hasConvertToJSValueSQL && type !==
|
|
101
|
+
if (prop?.hasConvertToJSValueSQL && type !== QueryType.UPSERT) {
|
|
105
102
|
let valueSQL;
|
|
106
103
|
if (prop.fieldNames.length > 1 && fkIdx !== -1) {
|
|
107
104
|
const fk = prop.targetMeta.getPrimaryProps()[fkIdx];
|
|
@@ -113,9 +110,9 @@ class QueryBuilderHelper {
|
|
|
113
110
|
valueSQL = prop.customType.convertToJSValueSQL(prefixed, this.platform);
|
|
114
111
|
}
|
|
115
112
|
if (alias === null) {
|
|
116
|
-
return
|
|
113
|
+
return raw(valueSQL);
|
|
117
114
|
}
|
|
118
|
-
return
|
|
115
|
+
return raw(`${valueSQL} as ${this.platform.quoteIdentifier(alias ?? prop.fieldNames[fkIdx])}`);
|
|
119
116
|
}
|
|
120
117
|
// do not wrap custom expressions
|
|
121
118
|
if (!rawField) {
|
|
@@ -135,9 +132,9 @@ class QueryBuilderHelper {
|
|
|
135
132
|
}
|
|
136
133
|
const meta = this.metadata.find(this.entityName);
|
|
137
134
|
data = this.driver.mapDataToFieldNames(data, true, meta?.properties, convertCustomTypes);
|
|
138
|
-
if (!
|
|
139
|
-
/*
|
|
140
|
-
data[meta.getPrimaryProps()[0].fieldNames[0]] = this.platform.usesDefaultKeyword() ?
|
|
135
|
+
if (!Utils.hasObjectKeys(data) && meta && multi) {
|
|
136
|
+
/* v8 ignore next */
|
|
137
|
+
data[meta.getPrimaryProps()[0].fieldNames[0]] = this.platform.usesDefaultKeyword() ? raw('default') : undefined;
|
|
141
138
|
}
|
|
142
139
|
return data;
|
|
143
140
|
}
|
|
@@ -148,7 +145,7 @@ class QueryBuilderHelper {
|
|
|
148
145
|
const inverseJoinColumns = prop.referencedColumnNames;
|
|
149
146
|
const primaryKeys = prop.owner ? prop.joinColumns : prop2.referencedColumnNames;
|
|
150
147
|
schema ??= prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(prop.targetMeta);
|
|
151
|
-
cond =
|
|
148
|
+
cond = Utils.merge(cond, prop.where);
|
|
152
149
|
return {
|
|
153
150
|
prop, type, cond, ownerAlias, alias, table, schema,
|
|
154
151
|
joinColumns, inverseJoinColumns, primaryKeys,
|
|
@@ -179,7 +176,7 @@ class QueryBuilderHelper {
|
|
|
179
176
|
path: path.endsWith('[pivot]') ? path : `${path}[pivot]`,
|
|
180
177
|
},
|
|
181
178
|
};
|
|
182
|
-
if (type ===
|
|
179
|
+
if (type === JoinType.pivotJoin) {
|
|
183
180
|
return ret;
|
|
184
181
|
}
|
|
185
182
|
const prop2 = prop.owner ? pivotMeta.relations[1] : pivotMeta.relations[0];
|
|
@@ -191,7 +188,7 @@ class QueryBuilderHelper {
|
|
|
191
188
|
}
|
|
192
189
|
processJoins(qb, joins, schema) {
|
|
193
190
|
Object.values(joins).forEach(join => {
|
|
194
|
-
if ([
|
|
191
|
+
if ([JoinType.nestedInnerJoin, JoinType.nestedLeftJoin].includes(join.type)) {
|
|
195
192
|
return;
|
|
196
193
|
}
|
|
197
194
|
const { sql, params } = this.createJoinExpression(join, joins, schema);
|
|
@@ -201,9 +198,9 @@ class QueryBuilderHelper {
|
|
|
201
198
|
createJoinExpression(join, joins, schema) {
|
|
202
199
|
let table = join.table;
|
|
203
200
|
const method = {
|
|
204
|
-
[
|
|
205
|
-
[
|
|
206
|
-
[
|
|
201
|
+
[JoinType.nestedInnerJoin]: 'inner join',
|
|
202
|
+
[JoinType.nestedLeftJoin]: 'left join',
|
|
203
|
+
[JoinType.pivotJoin]: 'left join',
|
|
207
204
|
}[join.type] ?? join.type;
|
|
208
205
|
const conditions = [];
|
|
209
206
|
const params = [];
|
|
@@ -221,7 +218,7 @@ class QueryBuilderHelper {
|
|
|
221
218
|
return;
|
|
222
219
|
}
|
|
223
220
|
const left = join.prop.object && join.prop.fieldNameRaw
|
|
224
|
-
? join.prop.fieldNameRaw.replaceAll(
|
|
221
|
+
? join.prop.fieldNameRaw.replaceAll(ALIAS_REPLACEMENT, join.ownerAlias)
|
|
225
222
|
: this.platform.quoteIdentifier(`${join.ownerAlias}.${primaryKey}`);
|
|
226
223
|
conditions.push(`${left} = ${this.platform.quoteIdentifier(right)}`);
|
|
227
224
|
});
|
|
@@ -249,7 +246,7 @@ class QueryBuilderHelper {
|
|
|
249
246
|
}
|
|
250
247
|
const oldAlias = this.alias;
|
|
251
248
|
this.alias = join.alias;
|
|
252
|
-
const subquery = this._appendQueryCondition(
|
|
249
|
+
const subquery = this._appendQueryCondition(QueryType.SELECT, join.cond);
|
|
253
250
|
this.alias = oldAlias;
|
|
254
251
|
if (subquery.sql) {
|
|
255
252
|
conditions.push(subquery.sql);
|
|
@@ -261,7 +258,7 @@ class QueryBuilderHelper {
|
|
|
261
258
|
return { sql, params };
|
|
262
259
|
}
|
|
263
260
|
mapJoinColumns(type, join) {
|
|
264
|
-
if (join.prop && [
|
|
261
|
+
if (join.prop && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(join.prop.kind)) {
|
|
265
262
|
return join.prop.fieldNames.map((_fieldName, idx) => {
|
|
266
263
|
const columns = join.prop.owner ? join.joinColumns : join.inverseJoinColumns;
|
|
267
264
|
return this.mapper(`${join.alias}.${columns[idx]}`, type, undefined, `${join.alias}__${columns[idx]}`);
|
|
@@ -275,7 +272,7 @@ class QueryBuilderHelper {
|
|
|
275
272
|
isOneToOneInverse(field, meta) {
|
|
276
273
|
meta ??= this.metadata.find(this.entityName);
|
|
277
274
|
const prop = meta.properties[field.replace(/:ref$/, '')];
|
|
278
|
-
return prop && prop.kind ===
|
|
275
|
+
return prop && prop.kind === ReferenceKind.ONE_TO_ONE && !prop.owner;
|
|
279
276
|
}
|
|
280
277
|
getTableName(entityName) {
|
|
281
278
|
const meta = this.metadata.find(entityName);
|
|
@@ -316,11 +313,11 @@ class QueryBuilderHelper {
|
|
|
316
313
|
onConflict.forEach(item => {
|
|
317
314
|
const { fields, ignore } = item;
|
|
318
315
|
const sub = qb.onConflict({ fields, ignore });
|
|
319
|
-
|
|
316
|
+
Utils.runIfNotEmpty(() => {
|
|
320
317
|
let mergeParam = item.merge;
|
|
321
|
-
if (
|
|
318
|
+
if (Utils.isObject(item.merge)) {
|
|
322
319
|
mergeParam = {};
|
|
323
|
-
|
|
320
|
+
Utils.keys(item.merge).forEach(key => {
|
|
324
321
|
const k = this.mapper(key, type);
|
|
325
322
|
mergeParam[k] = item.merge[key];
|
|
326
323
|
});
|
|
@@ -372,20 +369,20 @@ class QueryBuilderHelper {
|
|
|
372
369
|
appendQuerySubCondition(type, cond, key) {
|
|
373
370
|
const parts = [];
|
|
374
371
|
const params = [];
|
|
375
|
-
const fields =
|
|
372
|
+
const fields = Utils.splitPrimaryKeys(key);
|
|
376
373
|
if (this.isSimpleRegExp(cond[key])) {
|
|
377
374
|
parts.push(`${this.platform.quoteIdentifier(this.mapper(key, type))} like ?`);
|
|
378
375
|
params.push(this.getRegExpParam(cond[key]));
|
|
379
376
|
return { sql: parts.join(' and '), params };
|
|
380
377
|
}
|
|
381
|
-
if (
|
|
378
|
+
if (Utils.isPlainObject(cond[key]) || cond[key] instanceof RegExp) {
|
|
382
379
|
return this.processObjectSubCondition(cond, key, type);
|
|
383
380
|
}
|
|
384
381
|
const op = cond[key] === null ? 'is' : '=';
|
|
385
|
-
const raw =
|
|
382
|
+
const raw = RawQueryFragment.getKnownFragment(key);
|
|
386
383
|
if (raw) {
|
|
387
|
-
const sql = raw.sql.replaceAll(
|
|
388
|
-
const value =
|
|
384
|
+
const sql = raw.sql.replaceAll(ALIAS_REPLACEMENT, this.alias);
|
|
385
|
+
const value = Utils.asArray(cond[key]);
|
|
389
386
|
params.push(...raw.params);
|
|
390
387
|
if (value.length > 0) {
|
|
391
388
|
const val = this.getValueReplacement(fields, value[0], params, key);
|
|
@@ -408,13 +405,13 @@ class QueryBuilderHelper {
|
|
|
408
405
|
const parts = [];
|
|
409
406
|
const params = [];
|
|
410
407
|
let value = cond[key];
|
|
411
|
-
const size =
|
|
412
|
-
if (
|
|
408
|
+
const size = Utils.getObjectKeysSize(value);
|
|
409
|
+
if (Utils.isPlainObject(value) && size === 0) {
|
|
413
410
|
return { sql: '', params };
|
|
414
411
|
}
|
|
415
412
|
// grouped condition for one field, e.g. `{ age: { $gte: 10, $lt: 50 } }`
|
|
416
413
|
if (size > 1) {
|
|
417
|
-
const rawField =
|
|
414
|
+
const rawField = RawQueryFragment.getKnownFragment(key);
|
|
418
415
|
const subCondition = Object.entries(value).map(([subKey, subValue]) => {
|
|
419
416
|
key = rawField?.clone().toString() ?? key;
|
|
420
417
|
return ({ [key]: { [subKey]: subValue } });
|
|
@@ -428,13 +425,13 @@ class QueryBuilderHelper {
|
|
|
428
425
|
value = this.platform.getRegExpValue(value);
|
|
429
426
|
}
|
|
430
427
|
// operators
|
|
431
|
-
const op = Object.keys(
|
|
432
|
-
/*
|
|
428
|
+
const op = Object.keys(QueryOperator).find(op => op in value);
|
|
429
|
+
/* v8 ignore next 3 */
|
|
433
430
|
if (!op) {
|
|
434
|
-
throw new Error(`Invalid query condition: ${
|
|
431
|
+
throw new Error(`Invalid query condition: ${inspect(cond, { depth: 5 })}`);
|
|
435
432
|
}
|
|
436
433
|
const replacement = this.getOperatorReplacement(op, value);
|
|
437
|
-
const fields =
|
|
434
|
+
const fields = Utils.splitPrimaryKeys(key);
|
|
438
435
|
if (fields.length > 1 && Array.isArray(value[op])) {
|
|
439
436
|
const singleTuple = !value[op].every((v) => Array.isArray(v));
|
|
440
437
|
if (!this.platform.allowsComparingTuples()) {
|
|
@@ -444,17 +441,17 @@ class QueryBuilderHelper {
|
|
|
444
441
|
return `(${mapped.map(field => `${this.platform.quoteIdentifier(field)} = ?`).join(' and ')})`;
|
|
445
442
|
});
|
|
446
443
|
parts.push(`(${conds.join(' or ')})`);
|
|
447
|
-
params.push(...
|
|
444
|
+
params.push(...Utils.flatten(value[op]));
|
|
448
445
|
return { sql: parts.join(' and '), params };
|
|
449
446
|
}
|
|
450
447
|
parts.push(...mapped.map(field => `${this.platform.quoteIdentifier(field)} = ?`));
|
|
451
|
-
params.push(...
|
|
448
|
+
params.push(...Utils.flatten(value[op]));
|
|
452
449
|
return { sql: parts.join(' and '), params };
|
|
453
450
|
}
|
|
454
451
|
if (singleTuple) {
|
|
455
|
-
const tmp = value[op].length === 1 &&
|
|
452
|
+
const tmp = value[op].length === 1 && Utils.isPlainObject(value[op][0]) ? fields.map(f => value[op][0][f]) : value[op];
|
|
456
453
|
const sql = `(${fields.map(() => '?').join(', ')})`;
|
|
457
|
-
value[op] =
|
|
454
|
+
value[op] = raw(sql, tmp);
|
|
458
455
|
}
|
|
459
456
|
}
|
|
460
457
|
if (this.subQueries[key]) {
|
|
@@ -465,11 +462,11 @@ class QueryBuilderHelper {
|
|
|
465
462
|
const [a, f] = this.splitField(key);
|
|
466
463
|
const prop = this.getProperty(f, a);
|
|
467
464
|
if (op === '$fulltext') {
|
|
468
|
-
/*
|
|
465
|
+
/* v8 ignore next 3 */
|
|
469
466
|
if (!prop) {
|
|
470
467
|
throw new Error(`Cannot use $fulltext operator on ${key}, property not found`);
|
|
471
468
|
}
|
|
472
|
-
const { sql, params: params2 } =
|
|
469
|
+
const { sql, params: params2 } = raw(this.platform.getFullTextWhereClause(prop), {
|
|
473
470
|
column: this.mapper(key, type, undefined, null),
|
|
474
471
|
query: value[op],
|
|
475
472
|
});
|
|
@@ -479,8 +476,8 @@ class QueryBuilderHelper {
|
|
|
479
476
|
else if (op === '$in' && Array.isArray(value[op]) && value[op].length === 0) {
|
|
480
477
|
parts.push(`1 = 0`);
|
|
481
478
|
}
|
|
482
|
-
else if (value[op] instanceof
|
|
483
|
-
const query = value[op] instanceof
|
|
479
|
+
else if (value[op] instanceof RawQueryFragment || value[op] instanceof NativeQueryBuilder) {
|
|
480
|
+
const query = value[op] instanceof NativeQueryBuilder ? value[op].toRaw() : value[op];
|
|
484
481
|
const mappedKey = this.mapper(key, type, query, null);
|
|
485
482
|
let sql = query.sql;
|
|
486
483
|
if (['$in', '$nin'].includes(op)) {
|
|
@@ -506,7 +503,7 @@ class QueryBuilderHelper {
|
|
|
506
503
|
}
|
|
507
504
|
return `(${tmp.join(', ')})`;
|
|
508
505
|
}
|
|
509
|
-
if (prop?.customType instanceof
|
|
506
|
+
if (prop?.customType instanceof ArrayType) {
|
|
510
507
|
const item = prop.customType.convertToDatabaseValue(value, this.platform, { fromQuery: true, key, mode: 'query' });
|
|
511
508
|
params.push(item);
|
|
512
509
|
}
|
|
@@ -522,7 +519,7 @@ class QueryBuilderHelper {
|
|
|
522
519
|
return '?';
|
|
523
520
|
}
|
|
524
521
|
getOperatorReplacement(op, value) {
|
|
525
|
-
let replacement =
|
|
522
|
+
let replacement = QueryOperator[op];
|
|
526
523
|
if (op === '$exists') {
|
|
527
524
|
replacement = value[op] ? 'is not' : 'is';
|
|
528
525
|
value[op] = null;
|
|
@@ -548,26 +545,26 @@ class QueryBuilderHelper {
|
|
|
548
545
|
const ret = [];
|
|
549
546
|
for (const key of Object.keys(orderBy)) {
|
|
550
547
|
const direction = orderBy[key];
|
|
551
|
-
const order =
|
|
552
|
-
const raw =
|
|
548
|
+
const order = Utils.isNumber(direction) ? QueryOrderNumeric[direction] : direction;
|
|
549
|
+
const raw = RawQueryFragment.getKnownFragment(key);
|
|
553
550
|
if (raw) {
|
|
554
551
|
ret.push(...this.platform.getOrderByExpression(this.platform.formatQuery(raw.sql, raw.params), order));
|
|
555
552
|
continue;
|
|
556
553
|
}
|
|
557
|
-
for (const f of
|
|
554
|
+
for (const f of Utils.splitPrimaryKeys(key)) {
|
|
558
555
|
// eslint-disable-next-line prefer-const
|
|
559
556
|
let [alias, field] = this.splitField(f, true);
|
|
560
557
|
alias = populate[alias] || alias;
|
|
561
558
|
const prop = this.getProperty(field, alias);
|
|
562
|
-
const noPrefix = (prop && prop.persist === false && !prop.formula && !prop.embedded) ||
|
|
559
|
+
const noPrefix = (prop && prop.persist === false && !prop.formula && !prop.embedded) || RawQueryFragment.isKnownFragment(f);
|
|
563
560
|
const column = this.mapper(noPrefix ? field : `${alias}.${field}`, type, undefined, null);
|
|
564
|
-
/*
|
|
565
|
-
const rawColumn =
|
|
561
|
+
/* v8 ignore next */
|
|
562
|
+
const rawColumn = Utils.isString(column) ? column.split('.').map(e => this.platform.quoteIdentifier(e)).join('.') : column;
|
|
566
563
|
const customOrder = prop?.customOrder;
|
|
567
564
|
let colPart = customOrder
|
|
568
565
|
? this.platform.generateCustomOrder(rawColumn, customOrder)
|
|
569
566
|
: rawColumn;
|
|
570
|
-
if (
|
|
567
|
+
if (isRaw(colPart)) {
|
|
571
568
|
colPart = this.platform.formatQuery(colPart.sql, colPart.params);
|
|
572
569
|
}
|
|
573
570
|
if (Array.isArray(order)) {
|
|
@@ -590,23 +587,23 @@ class QueryBuilderHelper {
|
|
|
590
587
|
qb.returning(returning.map(field => this.mapper(field, type)));
|
|
591
588
|
return;
|
|
592
589
|
}
|
|
593
|
-
if (type ===
|
|
590
|
+
if (type === QueryType.INSERT) {
|
|
594
591
|
const returningProps = meta.hydrateProps
|
|
595
592
|
.filter(prop => prop.returning || (prop.persist !== false && ((prop.primary && prop.autoincrement) || prop.defaultRaw)))
|
|
596
593
|
.filter(prop => !(prop.name in data));
|
|
597
594
|
if (returningProps.length > 0) {
|
|
598
|
-
qb.returning(
|
|
595
|
+
qb.returning(Utils.flatten(returningProps.map(prop => prop.fieldNames)));
|
|
599
596
|
}
|
|
600
597
|
return;
|
|
601
598
|
}
|
|
602
|
-
if (type ===
|
|
603
|
-
const returningProps = meta.hydrateProps.filter(prop => prop.fieldNames &&
|
|
599
|
+
if (type === QueryType.UPDATE) {
|
|
600
|
+
const returningProps = meta.hydrateProps.filter(prop => prop.fieldNames && isRaw(data[prop.fieldNames[0]]));
|
|
604
601
|
if (returningProps.length > 0) {
|
|
605
602
|
qb.returning(returningProps.flatMap(prop => {
|
|
606
603
|
if (prop.hasConvertToJSValueSQL) {
|
|
607
604
|
const aliased = this.platform.quoteIdentifier(prop.fieldNames[0]);
|
|
608
605
|
const sql = prop.customType.convertToJSValueSQL(aliased, this.platform) + ' as ' + this.platform.quoteIdentifier(prop.fieldNames[0]);
|
|
609
|
-
return [
|
|
606
|
+
return [raw(sql)];
|
|
610
607
|
}
|
|
611
608
|
return prop.fieldNames;
|
|
612
609
|
}));
|
|
@@ -633,8 +630,8 @@ class QueryBuilderHelper {
|
|
|
633
630
|
}
|
|
634
631
|
getLockSQL(qb, lockMode, lockTables = []) {
|
|
635
632
|
const meta = this.metadata.find(this.entityName);
|
|
636
|
-
if (lockMode ===
|
|
637
|
-
throw
|
|
633
|
+
if (lockMode === LockMode.OPTIMISTIC && meta && !meta.versionProperty) {
|
|
634
|
+
throw OptimisticLockError.lockFailed(this.entityName);
|
|
638
635
|
}
|
|
639
636
|
qb.lockMode(lockMode, lockTables);
|
|
640
637
|
}
|
|
@@ -648,14 +645,14 @@ class QueryBuilderHelper {
|
|
|
648
645
|
if (versionProperty.runtimeType === 'Date') {
|
|
649
646
|
sql = this.platform.getCurrentTimestampSQL(versionProperty.length);
|
|
650
647
|
}
|
|
651
|
-
qb.update({ [versionProperty.fieldNames[0]]:
|
|
648
|
+
qb.update({ [versionProperty.fieldNames[0]]: raw(sql) });
|
|
652
649
|
}
|
|
653
650
|
prefix(field, always = false, quote = false, idx) {
|
|
654
651
|
let ret;
|
|
655
652
|
if (!this.isPrefixed(field)) {
|
|
656
653
|
const alias = always ? (quote ? this.alias : this.platform.quoteIdentifier(this.alias)) + '.' : '';
|
|
657
654
|
const fieldName = this.fieldName(field, this.alias, always, idx);
|
|
658
|
-
if (fieldName instanceof
|
|
655
|
+
if (fieldName instanceof RawQueryFragment) {
|
|
659
656
|
return fieldName.sql;
|
|
660
657
|
}
|
|
661
658
|
ret = alias + fieldName;
|
|
@@ -664,7 +661,7 @@ class QueryBuilderHelper {
|
|
|
664
661
|
const [a, ...rest] = field.split('.');
|
|
665
662
|
const f = rest.join('.');
|
|
666
663
|
const fieldName = this.fieldName(f, a, always, idx);
|
|
667
|
-
if (fieldName instanceof
|
|
664
|
+
if (fieldName instanceof RawQueryFragment) {
|
|
668
665
|
return fieldName.sql;
|
|
669
666
|
}
|
|
670
667
|
ret = a + '.' + fieldName;
|
|
@@ -688,7 +685,7 @@ class QueryBuilderHelper {
|
|
|
688
685
|
// skip nesting parens if the value is simple = scalar or object without operators or with only single key, being the operator
|
|
689
686
|
const keys = Object.keys(sub);
|
|
690
687
|
const val = sub[keys[0]];
|
|
691
|
-
const simple = !
|
|
688
|
+
const simple = !Utils.isPlainObject(val) || Utils.getObjectKeysSize(val) === 1 || Object.keys(val).every(k => !Utils.isOperator(k));
|
|
692
689
|
if (keys.length === 1 && simple) {
|
|
693
690
|
this.append(() => this._appendQueryCondition(type, sub, operator), parts, params);
|
|
694
691
|
continue;
|
|
@@ -707,17 +704,17 @@ class QueryBuilderHelper {
|
|
|
707
704
|
}
|
|
708
705
|
if (prop.fieldNameRaw) {
|
|
709
706
|
if (!always) {
|
|
710
|
-
return
|
|
711
|
-
.replace(new RegExp(
|
|
707
|
+
return raw(prop.fieldNameRaw
|
|
708
|
+
.replace(new RegExp(ALIAS_REPLACEMENT_RE + '\\.?', 'g'), '')
|
|
712
709
|
.replace(this.platform.quoteIdentifier('') + '.', ''));
|
|
713
710
|
}
|
|
714
711
|
if (alias) {
|
|
715
|
-
return
|
|
712
|
+
return raw(prop.fieldNameRaw.replace(new RegExp(ALIAS_REPLACEMENT_RE, 'g'), alias));
|
|
716
713
|
}
|
|
717
|
-
/*
|
|
718
|
-
return
|
|
714
|
+
/* v8 ignore next */
|
|
715
|
+
return raw(prop.fieldNameRaw);
|
|
719
716
|
}
|
|
720
|
-
/*
|
|
717
|
+
/* v8 ignore next */
|
|
721
718
|
return prop.fieldNames?.[idx] ?? field;
|
|
722
719
|
}
|
|
723
720
|
getProperty(field, alias) {
|
|
@@ -726,7 +723,7 @@ class QueryBuilderHelper {
|
|
|
726
723
|
// check if `alias` is not matching an embedded property name instead of alias, e.g. `address.city`
|
|
727
724
|
if (alias && meta) {
|
|
728
725
|
const prop = meta.properties[alias];
|
|
729
|
-
if (prop?.kind ===
|
|
726
|
+
if (prop?.kind === ReferenceKind.EMBEDDED) {
|
|
730
727
|
// we want to select the full object property so hydration works as expected
|
|
731
728
|
if (prop.object) {
|
|
732
729
|
return prop;
|
|
@@ -745,16 +742,15 @@ class QueryBuilderHelper {
|
|
|
745
742
|
return undefined;
|
|
746
743
|
}
|
|
747
744
|
isTableNameAliasRequired(type) {
|
|
748
|
-
return [
|
|
745
|
+
return [QueryType.SELECT, QueryType.COUNT].includes(type);
|
|
749
746
|
}
|
|
750
747
|
processOnConflictCondition(cond, schema) {
|
|
751
748
|
const meta = this.metadata.get(this.entityName);
|
|
752
749
|
const tableName = meta.tableName;
|
|
753
750
|
for (const key of Object.keys(cond)) {
|
|
754
|
-
const mapped = this.mapper(key,
|
|
755
|
-
|
|
751
|
+
const mapped = this.mapper(key, QueryType.UPSERT);
|
|
752
|
+
Utils.renameKey(cond, key, tableName + '.' + mapped);
|
|
756
753
|
}
|
|
757
754
|
return cond;
|
|
758
755
|
}
|
|
759
756
|
}
|
|
760
|
-
exports.QueryBuilderHelper = QueryBuilderHelper;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CriteriaNode } from './CriteriaNode';
|
|
2
|
-
import type { IQueryBuilder, ICriteriaNodeProcessOptions } from '../typings';
|
|
1
|
+
import { CriteriaNode } from './CriteriaNode.js';
|
|
2
|
+
import type { IQueryBuilder, ICriteriaNodeProcessOptions } from '../typings.js';
|
|
3
3
|
/**
|
|
4
4
|
* @internal
|
|
5
5
|
*/
|
|
@@ -1,32 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const CriteriaNode_1 = require("./CriteriaNode");
|
|
6
|
-
const enums_1 = require("./enums");
|
|
7
|
-
const QueryBuilder_1 = require("./QueryBuilder");
|
|
1
|
+
import { ReferenceKind, Utils } from '@mikro-orm/core';
|
|
2
|
+
import { CriteriaNode } from './CriteriaNode.js';
|
|
3
|
+
import { JoinType } from './enums.js';
|
|
4
|
+
import { QueryBuilder } from './QueryBuilder.js';
|
|
8
5
|
/**
|
|
9
6
|
* @internal
|
|
10
7
|
*/
|
|
11
|
-
class ScalarCriteriaNode extends
|
|
8
|
+
export class ScalarCriteriaNode extends CriteriaNode {
|
|
12
9
|
process(qb, options) {
|
|
13
10
|
if (this.shouldJoin()) {
|
|
14
11
|
const path = this.getPath();
|
|
15
12
|
const parentPath = this.parent.getPath(); // the parent is always there, otherwise `shouldJoin` would return `false`
|
|
16
13
|
const nestedAlias = qb.getAliasForJoinPath(path) || qb.getNextAlias(this.prop?.pivotTable ?? this.entityName);
|
|
17
14
|
const field = this.aliased(this.prop.name, options?.alias);
|
|
18
|
-
const type = this.prop.kind ===
|
|
15
|
+
const type = this.prop.kind === ReferenceKind.MANY_TO_MANY ? JoinType.pivotJoin : JoinType.leftJoin;
|
|
19
16
|
qb.join(field, nestedAlias, undefined, type, path);
|
|
20
17
|
// select the owner as virtual property when joining from 1:1 inverse side, but only if the parent is root entity
|
|
21
|
-
if (this.prop.kind ===
|
|
18
|
+
if (this.prop.kind === ReferenceKind.ONE_TO_ONE && !parentPath.includes('.') && !qb._fields?.includes(field)) {
|
|
22
19
|
qb.addSelect(field);
|
|
23
20
|
}
|
|
24
21
|
}
|
|
25
|
-
if (this.payload instanceof
|
|
22
|
+
if (this.payload instanceof QueryBuilder) {
|
|
26
23
|
return this.payload.getNativeQuery().toRaw();
|
|
27
24
|
}
|
|
28
25
|
if (this.payload && typeof this.payload === 'object') {
|
|
29
|
-
const keys = Object.keys(this.payload).filter(key =>
|
|
26
|
+
const keys = Object.keys(this.payload).filter(key => Utils.isArrayOperator(key) && Array.isArray(this.payload[key]));
|
|
30
27
|
for (const key of keys) {
|
|
31
28
|
this.payload[key] = JSON.stringify(this.payload[key]);
|
|
32
29
|
}
|
|
@@ -41,11 +38,10 @@ class ScalarCriteriaNode extends CriteriaNode_1.CriteriaNode {
|
|
|
41
38
|
return false;
|
|
42
39
|
}
|
|
43
40
|
switch (this.prop.kind) {
|
|
44
|
-
case
|
|
45
|
-
case
|
|
46
|
-
case
|
|
41
|
+
case ReferenceKind.ONE_TO_MANY: return true;
|
|
42
|
+
case ReferenceKind.MANY_TO_MANY: return true;
|
|
43
|
+
case ReferenceKind.ONE_TO_ONE: return !this.prop.owner;
|
|
47
44
|
default: return false; // SCALAR, MANY_TO_ONE
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
|
-
exports.ScalarCriteriaNode = ScalarCriteriaNode;
|
package/query/enums.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.JoinType = exports.QueryType = void 0;
|
|
4
|
-
var QueryType;
|
|
1
|
+
export var QueryType;
|
|
5
2
|
(function (QueryType) {
|
|
6
3
|
QueryType["TRUNCATE"] = "TRUNCATE";
|
|
7
4
|
QueryType["SELECT"] = "SELECT";
|
|
@@ -10,8 +7,8 @@ var QueryType;
|
|
|
10
7
|
QueryType["UPDATE"] = "UPDATE";
|
|
11
8
|
QueryType["DELETE"] = "DELETE";
|
|
12
9
|
QueryType["UPSERT"] = "UPSERT";
|
|
13
|
-
})(QueryType || (
|
|
14
|
-
var JoinType;
|
|
10
|
+
})(QueryType || (QueryType = {}));
|
|
11
|
+
export var JoinType;
|
|
15
12
|
(function (JoinType) {
|
|
16
13
|
JoinType["leftJoin"] = "left join";
|
|
17
14
|
JoinType["innerJoin"] = "inner join";
|
|
@@ -20,4 +17,4 @@ var JoinType;
|
|
|
20
17
|
JoinType["pivotJoin"] = "pivot join";
|
|
21
18
|
JoinType["innerJoinLateral"] = "inner join lateral";
|
|
22
19
|
JoinType["leftJoinLateral"] = "left join lateral";
|
|
23
|
-
})(JoinType || (
|
|
20
|
+
})(JoinType || (JoinType = {}));
|
package/query/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export * from './enums';
|
|
2
|
-
export * from './QueryBuilderHelper';
|
|
3
|
-
export * from './QueryBuilder';
|
|
4
|
-
export * from './CriteriaNode';
|
|
5
|
-
export * from './ArrayCriteriaNode';
|
|
6
|
-
export * from './ObjectCriteriaNode';
|
|
7
|
-
export * from './ScalarCriteriaNode';
|
|
8
|
-
export * from './CriteriaNodeFactory';
|
|
9
|
-
export * from './NativeQueryBuilder';
|
|
1
|
+
export * from './enums.js';
|
|
2
|
+
export * from './QueryBuilderHelper.js';
|
|
3
|
+
export * from './QueryBuilder.js';
|
|
4
|
+
export * from './CriteriaNode.js';
|
|
5
|
+
export * from './ArrayCriteriaNode.js';
|
|
6
|
+
export * from './ObjectCriteriaNode.js';
|
|
7
|
+
export * from './ScalarCriteriaNode.js';
|
|
8
|
+
export * from './CriteriaNodeFactory.js';
|
|
9
|
+
export * from './NativeQueryBuilder.js';
|
package/query/index.js
CHANGED
|
@@ -1,25 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./enums"), exports);
|
|
18
|
-
__exportStar(require("./QueryBuilderHelper"), exports);
|
|
19
|
-
__exportStar(require("./QueryBuilder"), exports);
|
|
20
|
-
__exportStar(require("./CriteriaNode"), exports);
|
|
21
|
-
__exportStar(require("./ArrayCriteriaNode"), exports);
|
|
22
|
-
__exportStar(require("./ObjectCriteriaNode"), exports);
|
|
23
|
-
__exportStar(require("./ScalarCriteriaNode"), exports);
|
|
24
|
-
__exportStar(require("./CriteriaNodeFactory"), exports);
|
|
25
|
-
__exportStar(require("./NativeQueryBuilder"), exports);
|
|
1
|
+
export * from './enums.js';
|
|
2
|
+
export * from './QueryBuilderHelper.js';
|
|
3
|
+
export * from './QueryBuilder.js';
|
|
4
|
+
export * from './CriteriaNode.js';
|
|
5
|
+
export * from './ArrayCriteriaNode.js';
|
|
6
|
+
export * from './ObjectCriteriaNode.js';
|
|
7
|
+
export * from './ScalarCriteriaNode.js';
|
|
8
|
+
export * from './CriteriaNodeFactory.js';
|
|
9
|
+
export * from './NativeQueryBuilder.js';
|