@mikro-orm/sql 7.0.0-dev.113 → 7.0.0-dev.115
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/AbstractSqlDriver.d.ts +13 -13
- package/AbstractSqlDriver.js +75 -78
- package/PivotCollectionPersister.js +3 -3
- package/SqlEntityManager.d.ts +1 -1
- package/package.json +2 -2
- package/plugin/transformer.js +1 -1
- package/query/CriteriaNode.d.ts +4 -4
- package/query/CriteriaNode.js +12 -13
- package/query/CriteriaNodeFactory.d.ts +6 -6
- package/query/CriteriaNodeFactory.js +19 -17
- package/query/NativeQueryBuilder.js +1 -2
- package/query/ObjectCriteriaNode.js +27 -27
- package/query/QueryBuilder.d.ts +12 -14
- package/query/QueryBuilder.js +73 -94
- package/query/QueryBuilderHelper.d.ts +10 -9
- package/query/QueryBuilderHelper.js +62 -45
- package/query/ScalarCriteriaNode.js +1 -1
- package/schema/DatabaseSchema.js +3 -7
- package/schema/SchemaHelper.d.ts +2 -2
- package/schema/SchemaHelper.js +2 -3
- package/schema/SqlSchemaGenerator.js +2 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/typings.d.ts +5 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ALIAS_REPLACEMENT, ALIAS_REPLACEMENT_RE, ArrayType, isRaw, LockMode, OptimisticLockError, QueryOperator, QueryOrderNumeric, raw,
|
|
1
|
+
import { ALIAS_REPLACEMENT, ALIAS_REPLACEMENT_RE, ArrayType, inspect, isRaw, LockMode, OptimisticLockError, QueryOperator, QueryOrderNumeric, raw, Raw, ReferenceKind, Utils, ValidationError, } from '@mikro-orm/core';
|
|
2
2
|
import { JoinType, QueryType } from './enums.js';
|
|
3
3
|
import { NativeQueryBuilder } from './NativeQueryBuilder.js';
|
|
4
4
|
/**
|
|
@@ -25,6 +25,9 @@ export class QueryBuilderHelper {
|
|
|
25
25
|
if (isRaw(field)) {
|
|
26
26
|
return raw(field.sql, field.params);
|
|
27
27
|
}
|
|
28
|
+
if (Raw.isKnownFragmentSymbol(field)) {
|
|
29
|
+
return Raw.getKnownFragment(field);
|
|
30
|
+
}
|
|
28
31
|
/* v8 ignore next */
|
|
29
32
|
if (typeof field !== 'string') {
|
|
30
33
|
return field;
|
|
@@ -60,16 +63,11 @@ export class QueryBuilderHelper {
|
|
|
60
63
|
}
|
|
61
64
|
return raw('(' + parts.map(part => this.platform.quoteIdentifier(part)).join(', ') + ')');
|
|
62
65
|
}
|
|
63
|
-
const rawField = RawQueryFragment.getKnownFragment(field);
|
|
64
|
-
if (rawField) {
|
|
65
|
-
return rawField;
|
|
66
|
-
}
|
|
67
66
|
const aliasPrefix = isTableNameAliasRequired ? this.alias + '.' : '';
|
|
68
67
|
const [a, f] = this.splitField(field);
|
|
69
68
|
const prop = this.getProperty(f, a);
|
|
70
69
|
const fkIdx2 = prop?.fieldNames.findIndex(name => name === f) ?? -1;
|
|
71
70
|
const fkIdx = fkIdx2 === -1 ? 0 : fkIdx2;
|
|
72
|
-
let ret = field;
|
|
73
71
|
// embeddable nested path instead of a regular property with table alias, reset alias
|
|
74
72
|
if (prop?.name === a && prop.embeddedProps[f]) {
|
|
75
73
|
return aliasPrefix + prop.fieldNames[fkIdx];
|
|
@@ -107,10 +105,7 @@ export class QueryBuilderHelper {
|
|
|
107
105
|
}
|
|
108
106
|
return raw(`${valueSQL} as ${this.platform.quoteIdentifier(alias ?? prop.fieldNames[fkIdx])}`);
|
|
109
107
|
}
|
|
110
|
-
|
|
111
|
-
if (!rawField) {
|
|
112
|
-
ret = this.prefix(field, false, false, fkIdx);
|
|
113
|
-
}
|
|
108
|
+
let ret = this.prefix(field, false, false, fkIdx);
|
|
114
109
|
if (alias) {
|
|
115
110
|
ret += ' as ' + alias;
|
|
116
111
|
}
|
|
@@ -133,7 +128,7 @@ export class QueryBuilderHelper {
|
|
|
133
128
|
}
|
|
134
129
|
joinOneToReference(prop, ownerAlias, alias, type, cond = {}, schema) {
|
|
135
130
|
const prop2 = prop.targetMeta.properties[prop.mappedBy || prop.inversedBy];
|
|
136
|
-
const table = this.getTableName(prop.
|
|
131
|
+
const table = this.getTableName(prop.targetMeta.class);
|
|
137
132
|
const joinColumns = prop.owner ? prop.referencedColumnNames : prop2.joinColumns;
|
|
138
133
|
const inverseJoinColumns = prop.referencedColumnNames;
|
|
139
134
|
const primaryKeys = prop.owner ? prop.joinColumns : prop2.referencedColumnNames;
|
|
@@ -147,7 +142,7 @@ export class QueryBuilderHelper {
|
|
|
147
142
|
joinManyToOneReference(prop, ownerAlias, alias, type, cond = {}, schema) {
|
|
148
143
|
return {
|
|
149
144
|
prop, type, cond, ownerAlias, alias,
|
|
150
|
-
table: this.getTableName(prop.
|
|
145
|
+
table: this.getTableName(prop.targetMeta.class),
|
|
151
146
|
schema: prop.targetMeta?.schema === '*' ? '*' : this.driver.getSchemaName(prop.targetMeta, { schema }),
|
|
152
147
|
joinColumns: prop.referencedColumnNames,
|
|
153
148
|
primaryKeys: prop.fieldNames,
|
|
@@ -172,7 +167,7 @@ export class QueryBuilderHelper {
|
|
|
172
167
|
if (type === JoinType.pivotJoin) {
|
|
173
168
|
return ret;
|
|
174
169
|
}
|
|
175
|
-
const prop2 = prop.owner ?
|
|
170
|
+
const prop2 = pivotMeta.relations[prop.owner ? 1 : 0];
|
|
176
171
|
ret[`${pivotAlias}.${prop2.name}#${alias}`] = this.joinManyToOneReference(prop2, pivotAlias, alias, type, cond, schema);
|
|
177
172
|
ret[`${pivotAlias}.${prop2.name}#${alias}`].path = path;
|
|
178
173
|
const tmp = prop2.referencedTableName.split('.');
|
|
@@ -243,7 +238,7 @@ export class QueryBuilderHelper {
|
|
|
243
238
|
this.alias = oldAlias;
|
|
244
239
|
if (subquery.sql) {
|
|
245
240
|
conditions.push(subquery.sql);
|
|
246
|
-
params.push(
|
|
241
|
+
subquery.params.forEach(p => params.push(p));
|
|
247
242
|
}
|
|
248
243
|
if (conditions.length > 0) {
|
|
249
244
|
sql += ` on ${conditions.join(' and ')}`;
|
|
@@ -269,7 +264,7 @@ export class QueryBuilderHelper {
|
|
|
269
264
|
}
|
|
270
265
|
getTableName(entityName) {
|
|
271
266
|
const meta = this.metadata.find(entityName);
|
|
272
|
-
return meta
|
|
267
|
+
return meta?.tableName ?? Utils.className(entityName);
|
|
273
268
|
}
|
|
274
269
|
/**
|
|
275
270
|
* Checks whether the RE can be rewritten to simple LIKE query
|
|
@@ -332,7 +327,7 @@ export class QueryBuilderHelper {
|
|
|
332
327
|
_appendQueryCondition(type, cond, operator) {
|
|
333
328
|
const parts = [];
|
|
334
329
|
const params = [];
|
|
335
|
-
for (const k of
|
|
330
|
+
for (const k of Utils.getObjectQueryKeys(cond)) {
|
|
336
331
|
if (k === '$and' || k === '$or') {
|
|
337
332
|
if (operator) {
|
|
338
333
|
this.append(() => this.appendGroupCondition(type, k, cond[k]), parts, params, operator);
|
|
@@ -344,7 +339,7 @@ export class QueryBuilderHelper {
|
|
|
344
339
|
if (k === '$not') {
|
|
345
340
|
const res = this._appendQueryCondition(type, cond[k]);
|
|
346
341
|
parts.push(`not (${res.sql})`);
|
|
347
|
-
params.push(
|
|
342
|
+
res.params.forEach(p => params.push(p));
|
|
348
343
|
continue;
|
|
349
344
|
}
|
|
350
345
|
this.append(() => this.appendQuerySubCondition(type, cond, k), parts, params);
|
|
@@ -362,7 +357,6 @@ export class QueryBuilderHelper {
|
|
|
362
357
|
appendQuerySubCondition(type, cond, key) {
|
|
363
358
|
const parts = [];
|
|
364
359
|
const params = [];
|
|
365
|
-
const fields = Utils.splitPrimaryKeys(key);
|
|
366
360
|
if (this.isSimpleRegExp(cond[key])) {
|
|
367
361
|
parts.push(`${this.platform.quoteIdentifier(this.mapper(key, type))} like ?`);
|
|
368
362
|
params.push(this.getRegExpParam(cond[key]));
|
|
@@ -372,19 +366,21 @@ export class QueryBuilderHelper {
|
|
|
372
366
|
return this.processObjectSubCondition(cond, key, type);
|
|
373
367
|
}
|
|
374
368
|
const op = cond[key] === null ? 'is' : '=';
|
|
375
|
-
|
|
376
|
-
|
|
369
|
+
if (Raw.isKnownFragmentSymbol(key)) {
|
|
370
|
+
const raw = Raw.getKnownFragment(key);
|
|
377
371
|
const sql = raw.sql.replaceAll(ALIAS_REPLACEMENT, this.alias);
|
|
378
372
|
const value = Utils.asArray(cond[key]);
|
|
379
373
|
params.push(...raw.params);
|
|
380
374
|
if (value.length > 0) {
|
|
381
|
-
const
|
|
375
|
+
const k = key;
|
|
376
|
+
const val = this.getValueReplacement([k], value[0], params, k);
|
|
382
377
|
parts.push(`${sql} ${op} ${val}`);
|
|
383
378
|
return { sql: parts.join(' and '), params };
|
|
384
379
|
}
|
|
385
380
|
parts.push(sql);
|
|
386
381
|
return { sql: parts.join(' and '), params };
|
|
387
382
|
}
|
|
383
|
+
const fields = Utils.splitPrimaryKeys(key);
|
|
388
384
|
if (this.subQueries[key]) {
|
|
389
385
|
const val = this.getValueReplacement(fields, cond[key], params, key);
|
|
390
386
|
parts.push(`(${this.subQueries[key]}) ${op} ${val}`);
|
|
@@ -404,9 +400,7 @@ export class QueryBuilderHelper {
|
|
|
404
400
|
}
|
|
405
401
|
// grouped condition for one field, e.g. `{ age: { $gte: 10, $lt: 50 } }`
|
|
406
402
|
if (size > 1) {
|
|
407
|
-
const rawField = RawQueryFragment.getKnownFragment(key);
|
|
408
403
|
const subCondition = Object.entries(value).map(([subKey, subValue]) => {
|
|
409
|
-
key = rawField?.clone().toString() ?? key;
|
|
410
404
|
return ({ [key]: { [subKey]: subValue } });
|
|
411
405
|
});
|
|
412
406
|
for (const sub of subCondition) {
|
|
@@ -424,7 +418,8 @@ export class QueryBuilderHelper {
|
|
|
424
418
|
throw ValidationError.invalidQueryCondition(cond);
|
|
425
419
|
}
|
|
426
420
|
const replacement = this.getOperatorReplacement(op, value);
|
|
427
|
-
const
|
|
421
|
+
const rawField = Raw.isKnownFragmentSymbol(key);
|
|
422
|
+
const fields = rawField ? [key] : Utils.splitPrimaryKeys(key);
|
|
428
423
|
if (fields.length > 1 && Array.isArray(value[op])) {
|
|
429
424
|
const singleTuple = !value[op].every((v) => Array.isArray(v));
|
|
430
425
|
if (!this.platform.allowsComparingTuples()) {
|
|
@@ -452,12 +447,12 @@ export class QueryBuilderHelper {
|
|
|
452
447
|
parts.push(`(${this.subQueries[key]}) ${replacement} ${val}`);
|
|
453
448
|
return { sql: parts.join(' and '), params };
|
|
454
449
|
}
|
|
455
|
-
const [a, f] = this.splitField(key);
|
|
456
|
-
const prop = this.getProperty(f, a);
|
|
450
|
+
const [a, f] = rawField ? [] : this.splitField(key);
|
|
451
|
+
const prop = f && this.getProperty(f, a);
|
|
457
452
|
if (op === '$fulltext') {
|
|
458
453
|
/* v8 ignore next */
|
|
459
454
|
if (!prop) {
|
|
460
|
-
throw new Error(`Cannot use $fulltext operator on ${key}, property not found`);
|
|
455
|
+
throw new Error(`Cannot use $fulltext operator on ${String(key)}, property not found`);
|
|
461
456
|
}
|
|
462
457
|
const { sql, params: params2 } = raw(this.platform.getFullTextWhereClause(prop), {
|
|
463
458
|
column: this.mapper(key, type, undefined, null),
|
|
@@ -469,7 +464,7 @@ export class QueryBuilderHelper {
|
|
|
469
464
|
else if (['$in', '$nin'].includes(op) && Array.isArray(value[op]) && value[op].length === 0) {
|
|
470
465
|
parts.push(`1 = ${op === '$in' ? 0 : 1}`);
|
|
471
466
|
}
|
|
472
|
-
else if (value[op] instanceof
|
|
467
|
+
else if (value[op] instanceof Raw || value[op] instanceof NativeQueryBuilder) {
|
|
473
468
|
const query = value[op] instanceof NativeQueryBuilder ? value[op].toRaw() : value[op];
|
|
474
469
|
const mappedKey = this.mapper(key, type, query, null);
|
|
475
470
|
let sql = query.sql;
|
|
@@ -501,7 +496,7 @@ export class QueryBuilderHelper {
|
|
|
501
496
|
params.push(item);
|
|
502
497
|
}
|
|
503
498
|
else {
|
|
504
|
-
value.forEach(
|
|
499
|
+
value.forEach(p => params.push(p));
|
|
505
500
|
}
|
|
506
501
|
return `(${value.map(() => '?').join(', ')})`;
|
|
507
502
|
}
|
|
@@ -528,6 +523,31 @@ export class QueryBuilderHelper {
|
|
|
528
523
|
}
|
|
529
524
|
return replacement;
|
|
530
525
|
}
|
|
526
|
+
validateQueryOrder(orderBy) {
|
|
527
|
+
const strKeys = [];
|
|
528
|
+
const rawKeys = [];
|
|
529
|
+
for (const key of Utils.getObjectQueryKeys(orderBy)) {
|
|
530
|
+
const raw = Raw.getKnownFragment(key);
|
|
531
|
+
if (raw) {
|
|
532
|
+
rawKeys.push(raw);
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
strKeys.push(key);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
if (strKeys.length > 0 && rawKeys.length > 0) {
|
|
539
|
+
const example = [
|
|
540
|
+
...strKeys.map(key => ({ [key]: orderBy[key] })),
|
|
541
|
+
...rawKeys.map(rawKey => ({ [`raw('${rawKey.sql}')`]: orderBy[rawKey] })),
|
|
542
|
+
];
|
|
543
|
+
throw new Error([
|
|
544
|
+
`Invalid "orderBy": You are mixing field-based keys and raw SQL fragments inside a single object.`,
|
|
545
|
+
`This is not allowed because object key order cannot reliably preserve evaluation order.`,
|
|
546
|
+
`To fix this, split them into separate objects inside an array:\n`,
|
|
547
|
+
`orderBy: ${inspect(example, { depth: 5 }).replace(/"raw\('(.*)'\)"/g, `[raw('$1')]`)}`,
|
|
548
|
+
].join('\n'));
|
|
549
|
+
}
|
|
550
|
+
}
|
|
531
551
|
getQueryOrder(type, orderBy, populate) {
|
|
532
552
|
if (Array.isArray(orderBy)) {
|
|
533
553
|
return orderBy.flatMap(o => this.getQueryOrder(type, o, populate));
|
|
@@ -536,11 +556,11 @@ export class QueryBuilderHelper {
|
|
|
536
556
|
}
|
|
537
557
|
getQueryOrderFromObject(type, orderBy, populate) {
|
|
538
558
|
const ret = [];
|
|
539
|
-
for (const key of
|
|
559
|
+
for (const key of Utils.getObjectQueryKeys(orderBy)) {
|
|
540
560
|
const direction = orderBy[key];
|
|
541
561
|
const order = typeof direction === 'number' ? QueryOrderNumeric[direction] : direction;
|
|
542
|
-
|
|
543
|
-
|
|
562
|
+
if (Raw.isKnownFragmentSymbol(key)) {
|
|
563
|
+
const raw = Raw.getKnownFragment(key);
|
|
544
564
|
ret.push(...this.platform.getOrderByExpression(this.platform.formatQuery(raw.sql, raw.params), order));
|
|
545
565
|
continue;
|
|
546
566
|
}
|
|
@@ -549,7 +569,7 @@ export class QueryBuilderHelper {
|
|
|
549
569
|
let [alias, field] = this.splitField(f, true);
|
|
550
570
|
alias = populate[alias] || alias;
|
|
551
571
|
const prop = this.getProperty(field, alias);
|
|
552
|
-
const noPrefix = (prop?.persist === false && !prop.formula && !prop.embedded) ||
|
|
572
|
+
const noPrefix = (prop?.persist === false && !prop.formula && !prop.embedded) || Raw.isKnownFragment(f);
|
|
553
573
|
const column = this.mapper(noPrefix ? field : `${alias}.${field}`, type, undefined, null);
|
|
554
574
|
/* v8 ignore next */
|
|
555
575
|
const rawColumn = typeof column === 'string' ? column.split('.').map(e => this.platform.quoteIdentifier(e)).join('.') : column;
|
|
@@ -624,7 +644,7 @@ export class QueryBuilderHelper {
|
|
|
624
644
|
getLockSQL(qb, lockMode, lockTables = [], joinsMap) {
|
|
625
645
|
const meta = this.metadata.find(this.entityName);
|
|
626
646
|
if (lockMode === LockMode.OPTIMISTIC && meta && !meta.versionProperty) {
|
|
627
|
-
throw OptimisticLockError.lockFailed(this.entityName);
|
|
647
|
+
throw OptimisticLockError.lockFailed(Utils.className(this.entityName));
|
|
628
648
|
}
|
|
629
649
|
if (lockMode !== LockMode.OPTIMISTIC && lockTables.length === 0 && joinsMap) {
|
|
630
650
|
const joins = Object.values(joinsMap);
|
|
@@ -652,7 +672,7 @@ export class QueryBuilderHelper {
|
|
|
652
672
|
if (!this.isPrefixed(field)) {
|
|
653
673
|
const alias = always ? (quote ? this.alias : this.platform.quoteIdentifier(this.alias)) + '.' : '';
|
|
654
674
|
const fieldName = this.fieldName(field, this.alias, always, idx);
|
|
655
|
-
if (fieldName instanceof
|
|
675
|
+
if (fieldName instanceof Raw) {
|
|
656
676
|
return fieldName.sql;
|
|
657
677
|
}
|
|
658
678
|
ret = alias + fieldName;
|
|
@@ -661,7 +681,7 @@ export class QueryBuilderHelper {
|
|
|
661
681
|
const [a, ...rest] = field.split('.');
|
|
662
682
|
const f = rest.join('.');
|
|
663
683
|
const fieldName = this.fieldName(f, a, always, idx);
|
|
664
|
-
if (fieldName instanceof
|
|
684
|
+
if (fieldName instanceof Raw) {
|
|
665
685
|
return fieldName.sql;
|
|
666
686
|
}
|
|
667
687
|
ret = a + '.' + fieldName;
|
|
@@ -683,7 +703,7 @@ export class QueryBuilderHelper {
|
|
|
683
703
|
}
|
|
684
704
|
for (const sub of subCondition) {
|
|
685
705
|
// skip nesting parens if the value is simple = scalar or object without operators or with only single key, being the operator
|
|
686
|
-
const keys =
|
|
706
|
+
const keys = Utils.getObjectQueryKeys(sub);
|
|
687
707
|
const val = sub[keys[0]];
|
|
688
708
|
const simple = !Utils.isPlainObject(val) || Utils.getObjectKeysSize(val) === 1 || Object.keys(val).every(k => !Utils.isOperator(k));
|
|
689
709
|
if (keys.length === 1 && simple) {
|
|
@@ -719,9 +739,9 @@ export class QueryBuilderHelper {
|
|
|
719
739
|
}
|
|
720
740
|
getProperty(field, alias) {
|
|
721
741
|
const entityName = this.aliasMap[alias]?.entityName || this.entityName;
|
|
722
|
-
const meta = this.metadata.
|
|
742
|
+
const meta = this.metadata.get(entityName);
|
|
723
743
|
// check if `alias` is not matching an embedded property name instead of alias, e.g. `address.city`
|
|
724
|
-
if (alias
|
|
744
|
+
if (alias) {
|
|
725
745
|
const prop = meta.properties[alias];
|
|
726
746
|
if (prop?.kind === ReferenceKind.EMBEDDED) {
|
|
727
747
|
// we want to select the full object property so hydration works as expected
|
|
@@ -733,13 +753,10 @@ export class QueryBuilderHelper {
|
|
|
733
753
|
return nest(prop);
|
|
734
754
|
}
|
|
735
755
|
}
|
|
736
|
-
if (meta) {
|
|
737
|
-
|
|
738
|
-
return meta.properties[field];
|
|
739
|
-
}
|
|
740
|
-
return meta.relations.find(prop => prop.fieldNames?.some(name => field === name));
|
|
756
|
+
if (meta.properties[field]) {
|
|
757
|
+
return meta.properties[field];
|
|
741
758
|
}
|
|
742
|
-
return
|
|
759
|
+
return meta.relations.find(prop => prop.fieldNames?.some(name => field === name));
|
|
743
760
|
}
|
|
744
761
|
isTableNameAliasRequired(type) {
|
|
745
762
|
return [QueryType.SELECT, QueryType.COUNT].includes(type);
|
|
@@ -12,7 +12,7 @@ export class ScalarCriteriaNode extends CriteriaNode {
|
|
|
12
12
|
if (this.shouldJoin(qb, nestedAlias)) {
|
|
13
13
|
const path = this.getPath();
|
|
14
14
|
const parentPath = this.parent.getPath(); // the parent is always there, otherwise `shouldJoin` would return `false`
|
|
15
|
-
const nestedAlias = qb.getAliasForJoinPath(path) || qb.getNextAlias(this.prop?.
|
|
15
|
+
const nestedAlias = qb.getAliasForJoinPath(path) || qb.getNextAlias(this.prop?.pivotEntity ?? this.entityName);
|
|
16
16
|
const field = this.aliased(this.prop.name, options?.alias);
|
|
17
17
|
const type = this.prop.kind === ReferenceKind.MANY_TO_MANY ? JoinType.pivotJoin : JoinType.leftJoin;
|
|
18
18
|
qb.join(field, nestedAlias, undefined, type, path);
|
package/schema/DatabaseSchema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReferenceKind,
|
|
1
|
+
import { ReferenceKind, isRaw, } from '@mikro-orm/core';
|
|
2
2
|
import { DatabaseTable } from './DatabaseTable.js';
|
|
3
3
|
/**
|
|
4
4
|
* @internal
|
|
@@ -108,15 +108,11 @@ export class DatabaseSchema {
|
|
|
108
108
|
table.addIndex(meta, { properties: meta.props.filter(prop => prop.primary).map(prop => prop.name) }, 'primary');
|
|
109
109
|
for (const check of meta.checks) {
|
|
110
110
|
const columnName = check.property ? meta.properties[check.property].fieldNames[0] : undefined;
|
|
111
|
-
|
|
112
|
-
const raw = RawQueryFragment.getKnownFragment(expression);
|
|
113
|
-
if (raw) {
|
|
114
|
-
expression = platform.formatQuery(raw.sql, raw.params);
|
|
115
|
-
}
|
|
111
|
+
const expression = isRaw(check.expression) ? platform.formatQuery(check.expression.sql, check.expression.params) : check.expression;
|
|
116
112
|
table.addCheck({
|
|
117
113
|
name: check.name,
|
|
118
114
|
expression,
|
|
119
|
-
definition: `check (${
|
|
115
|
+
definition: `check (${expression})`,
|
|
120
116
|
columnName,
|
|
121
117
|
});
|
|
122
118
|
}
|
package/schema/SchemaHelper.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Connection, type Dictionary } from '@mikro-orm/core';
|
|
1
|
+
import { type Connection, type Dictionary, RawQueryFragment } from '@mikro-orm/core';
|
|
2
2
|
import type { AbstractSqlConnection } from '../AbstractSqlConnection.js';
|
|
3
3
|
import type { AbstractSqlPlatform } from '../AbstractSqlPlatform.js';
|
|
4
4
|
import type { CheckDef, Column, ForeignKey, IndexDef, Table, TableDifference } from '../typings.js';
|
|
@@ -39,7 +39,7 @@ export declare abstract class SchemaHelper {
|
|
|
39
39
|
getNamespaces(connection: AbstractSqlConnection): Promise<string[]>;
|
|
40
40
|
protected mapIndexes(indexes: IndexDef[]): Promise<IndexDef[]>;
|
|
41
41
|
mapForeignKeys(fks: any[], tableName: string, schemaName?: string): Dictionary;
|
|
42
|
-
normalizeDefaultValue(defaultValue: string, length?: number, defaultValues?: Dictionary<string[]>): string | number;
|
|
42
|
+
normalizeDefaultValue(defaultValue: string | RawQueryFragment, length?: number, defaultValues?: Dictionary<string[]>): string | number;
|
|
43
43
|
getCreateDatabaseSQL(name: string): string;
|
|
44
44
|
getDropDatabaseSQL(name: string): string;
|
|
45
45
|
getCreateNamespaceSQL(name: string): string;
|
package/schema/SchemaHelper.js
CHANGED
|
@@ -323,9 +323,8 @@ export class SchemaHelper {
|
|
|
323
323
|
if (defaultValue == null) {
|
|
324
324
|
return defaultValue;
|
|
325
325
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
return this.platform.formatQuery(raw.sql, raw.params);
|
|
326
|
+
if (defaultValue instanceof RawQueryFragment) {
|
|
327
|
+
return this.platform.formatQuery(defaultValue.sql, defaultValue.params);
|
|
329
328
|
}
|
|
330
329
|
const genericValue = defaultValue.replace(/\(\d+\)/, '(?)').toLowerCase();
|
|
331
330
|
const norm = defaultValues[genericValue];
|
|
@@ -114,7 +114,7 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
114
114
|
await this.execute(this.helper.disableForeignKeysSQL());
|
|
115
115
|
const schema = options?.schema ?? this.config.get('schema', this.platform.getDefaultSchemaName());
|
|
116
116
|
for (const meta of this.getOrderedMetadata(schema).reverse()) {
|
|
117
|
-
await this.driver.createQueryBuilder(meta.
|
|
117
|
+
await this.driver.createQueryBuilder(meta.class, this.em?.getTransactionContext(), 'write', false)
|
|
118
118
|
.withSchema(schema)
|
|
119
119
|
.truncate()
|
|
120
120
|
.execute();
|
|
@@ -197,7 +197,7 @@ export class SqlSchemaGenerator extends AbstractSchemaGenerator {
|
|
|
197
197
|
const toSchema = this.getTargetSchema(options.schema);
|
|
198
198
|
const schemas = toSchema.getNamespaces();
|
|
199
199
|
const fromSchema = options.fromSchema ?? (await DatabaseSchema.create(this.connection, this.platform, this.config, options.schema, schemas, undefined, this.options.skipTables));
|
|
200
|
-
const wildcardSchemaTables =
|
|
200
|
+
const wildcardSchemaTables = [...this.metadata.getAll().values()].filter(meta => meta.schema === '*').map(meta => meta.tableName);
|
|
201
201
|
fromSchema.prune(options.schema, wildcardSchemaTables);
|
|
202
202
|
toSchema.prune(options.schema, wildcardSchemaTables);
|
|
203
203
|
return { fromSchema, toSchema };
|