@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
package/AbstractSqlDriver.d.ts
CHANGED
|
@@ -15,23 +15,23 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
15
15
|
getPlatform(): Platform;
|
|
16
16
|
createEntityManager(useContext?: boolean): this[typeof EntityManagerType];
|
|
17
17
|
private createQueryBuilderFromOptions;
|
|
18
|
-
find<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName:
|
|
19
|
-
findOne<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName:
|
|
18
|
+
find<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: EntityName<T>, where: ObjectQuery<T>, options?: FindOptions<T, P, F, E>): Promise<EntityData<T>[]>;
|
|
19
|
+
findOne<T extends object, P extends string = never, F extends string = PopulatePath.ALL, E extends string = never>(entityName: EntityName<T>, where: ObjectQuery<T>, options?: FindOneOptions<T, P, F, E>): Promise<EntityData<T> | null>;
|
|
20
20
|
protected hasToManyJoins<T extends object>(hint: PopulateOptions<T>, meta: EntityMetadata<T>): boolean;
|
|
21
|
-
findVirtual<T extends object>(entityName:
|
|
22
|
-
countVirtual<T extends object>(entityName:
|
|
23
|
-
protected findFromVirtual<T extends object>(entityName:
|
|
21
|
+
findVirtual<T extends object>(entityName: EntityName<T>, where: ObjectQuery<T>, options: FindOptions<T, any, any, any>): Promise<EntityData<T>[]>;
|
|
22
|
+
countVirtual<T extends object>(entityName: EntityName<T>, where: ObjectQuery<T>, options: CountOptions<T, any>): Promise<number>;
|
|
23
|
+
protected findFromVirtual<T extends object>(entityName: EntityName<T>, where: ObjectQuery<T>, options: FindOptions<T, any> | CountOptions<T, any>, type: QueryType): Promise<EntityData<T>[] | number>;
|
|
24
24
|
protected streamFromVirtual<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, options: StreamOptions<T, any>): AsyncIterableIterator<EntityData<T>>;
|
|
25
25
|
protected wrapVirtualExpressionInSubquery<T extends object>(meta: EntityMetadata<T>, expression: string, where: FilterQuery<T>, options: FindOptions<T, any>, type: QueryType): Promise<T[] | number>;
|
|
26
26
|
protected wrapVirtualExpressionInSubqueryStream<T extends object>(meta: EntityMetadata<T>, expression: string, where: FilterQuery<T>, options: FindOptions<T, any, any, any>, type: QueryType.SELECT): AsyncIterableIterator<T>;
|
|
27
27
|
mapResult<T extends object>(result: EntityData<T>, meta: EntityMetadata<T>, populate?: PopulateOptions<T>[], qb?: QueryBuilder<T, any, any, any>, map?: Dictionary): EntityData<T> | null;
|
|
28
28
|
private mapJoinedProps;
|
|
29
|
-
count<T extends object>(entityName:
|
|
30
|
-
nativeInsert<T extends object>(entityName:
|
|
31
|
-
nativeInsertMany<T extends object>(entityName:
|
|
32
|
-
nativeUpdate<T extends object>(entityName:
|
|
33
|
-
nativeUpdateMany<T extends object>(entityName:
|
|
34
|
-
nativeDelete<T extends object>(entityName:
|
|
29
|
+
count<T extends object>(entityName: EntityName<T>, where: any, options?: CountOptions<T>): Promise<number>;
|
|
30
|
+
nativeInsert<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T>): Promise<QueryResult<T>>;
|
|
31
|
+
nativeInsertMany<T extends object>(entityName: EntityName<T>, data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T>, transform?: (sql: string) => string): Promise<QueryResult<T>>;
|
|
32
|
+
nativeUpdate<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>, data: EntityDictionary<T>, options?: NativeInsertUpdateOptions<T> & UpsertOptions<T>): Promise<QueryResult<T>>;
|
|
33
|
+
nativeUpdateMany<T extends object>(entityName: EntityName<T>, where: FilterQuery<T>[], data: EntityDictionary<T>[], options?: NativeInsertUpdateManyOptions<T> & UpsertManyOptions<T>): Promise<QueryResult<T>>;
|
|
34
|
+
nativeDelete<T extends object>(entityName: EntityName<T>, where: FilterQuery<T> | string | any, options?: DeleteOptions<T>): Promise<QueryResult<T>>;
|
|
35
35
|
/**
|
|
36
36
|
* Fast comparison for collection snapshots that are represented by PK arrays.
|
|
37
37
|
* Compares scalars via `===` and fallbacks to Utils.equals()` for more complex types like Buffer.
|
|
@@ -69,8 +69,8 @@ export declare abstract class AbstractSqlDriver<Connection extends AbstractSqlCo
|
|
|
69
69
|
ctx?: Transaction;
|
|
70
70
|
connectionType?: ConnectionType;
|
|
71
71
|
}): ConnectionType;
|
|
72
|
-
protected extractManyToMany<T>(
|
|
73
|
-
protected processManyToMany<T extends object>(meta: EntityMetadata<T
|
|
72
|
+
protected extractManyToMany<T>(meta: EntityMetadata<T>, data: EntityDictionary<T>): EntityData<T>;
|
|
73
|
+
protected processManyToMany<T extends object>(meta: EntityMetadata<T>, pks: Primary<T>[], collections: EntityData<T>, clear: boolean, options?: DriverMethodOptions): Promise<void>;
|
|
74
74
|
lockPessimistic<T extends object>(entity: T, options: LockOptions): Promise<void>;
|
|
75
75
|
protected buildPopulateWhere<T extends object>(meta: EntityMetadata<T>, joinedProps: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'populateWhere'>): ObjectQuery<T>;
|
|
76
76
|
protected buildOrderBy<T extends object>(qb: QueryBuilder<T, any, any, any>, meta: EntityMetadata<T>, populate: PopulateOptions<T>[], options: Pick<FindOptions<any>, 'strategy' | 'orderBy' | 'populateOrderBy'>): QueryOrderMap<T>[];
|
package/AbstractSqlDriver.js
CHANGED
|
@@ -25,7 +25,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
25
25
|
const connectionType = this.resolveConnectionType({ ctx: options.ctx, connectionType: options.connectionType });
|
|
26
26
|
const populate = this.autoJoinOneToOneOwner(meta, options.populate, options.fields);
|
|
27
27
|
const joinedProps = this.joinedProps(meta, populate, options);
|
|
28
|
-
const qb = this.createQueryBuilder(meta.
|
|
28
|
+
const qb = this.createQueryBuilder(meta.class, options.ctx, connectionType, false, options.logging, undefined, options.em);
|
|
29
29
|
const fields = this.buildFields(meta, populate, joinedProps, qb, qb.alias, options);
|
|
30
30
|
const orderBy = this.buildOrderBy(qb, meta, populate, options);
|
|
31
31
|
const populateWhere = this.buildPopulateWhere(meta, joinedProps, options);
|
|
@@ -66,8 +66,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
66
66
|
}
|
|
67
67
|
async find(entityName, where, options = {}) {
|
|
68
68
|
options = { populate: [], orderBy: [], ...options };
|
|
69
|
-
const meta = this.metadata.
|
|
70
|
-
if (meta
|
|
69
|
+
const meta = this.metadata.get(entityName);
|
|
70
|
+
if (meta.virtual) {
|
|
71
71
|
return this.findVirtual(entityName, where, options);
|
|
72
72
|
}
|
|
73
73
|
const qb = await this.createQueryBuilderFromOptions(meta, where, options);
|
|
@@ -167,7 +167,12 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
167
167
|
async wrapVirtualExpressionInSubquery(meta, expression, where, options, type) {
|
|
168
168
|
const qb = await this.createQueryBuilderFromOptions(meta, where, options);
|
|
169
169
|
qb.setFlag(QueryFlag.DISABLE_PAGINATE);
|
|
170
|
-
const isCursorPagination = [
|
|
170
|
+
const isCursorPagination = [
|
|
171
|
+
options.first,
|
|
172
|
+
options.last,
|
|
173
|
+
options.before,
|
|
174
|
+
options.after,
|
|
175
|
+
].some(v => v != null);
|
|
171
176
|
const native = qb.getNativeQuery(false);
|
|
172
177
|
if (type === QueryType.COUNT) {
|
|
173
178
|
native
|
|
@@ -221,7 +226,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
221
226
|
return;
|
|
222
227
|
}
|
|
223
228
|
const pivotRefJoin = prop.kind === ReferenceKind.MANY_TO_MANY && ref;
|
|
224
|
-
const meta2 =
|
|
229
|
+
const meta2 = prop.targetMeta;
|
|
225
230
|
let path = parentJoinPath ? `${parentJoinPath}.${prop.name}` : `${meta.name}.${prop.name}`;
|
|
226
231
|
if (!parentJoinPath) {
|
|
227
232
|
path = '[populate]' + path;
|
|
@@ -317,10 +322,10 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
317
322
|
if (prop.kind === ReferenceKind.EMBEDDED && (prop.object || meta.embeddable)) {
|
|
318
323
|
const item = parseJsonSafe(relationPojo[prop.name]);
|
|
319
324
|
if (Array.isArray(item)) {
|
|
320
|
-
relationPojo[prop.name] = item.map(row => row == null ? row : this.comparator.mapResult(prop.
|
|
325
|
+
relationPojo[prop.name] = item.map(row => row == null ? row : this.comparator.mapResult(prop.targetMeta, row));
|
|
321
326
|
}
|
|
322
327
|
else {
|
|
323
|
-
relationPojo[prop.name] = item == null ? item : this.comparator.mapResult(prop.
|
|
328
|
+
relationPojo[prop.name] = item == null ? item : this.comparator.mapResult(prop.targetMeta, item);
|
|
324
329
|
}
|
|
325
330
|
}
|
|
326
331
|
}
|
|
@@ -377,19 +382,18 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
377
382
|
}
|
|
378
383
|
async nativeInsert(entityName, data, options = {}) {
|
|
379
384
|
options.convertCustomTypes ??= true;
|
|
380
|
-
const meta = this.metadata.
|
|
381
|
-
const collections = this.extractManyToMany(
|
|
382
|
-
const pks = meta?.primaryKeys ?? [this.config.getNamingStrategy().referenceColumnName()];
|
|
385
|
+
const meta = this.metadata.get(entityName);
|
|
386
|
+
const collections = this.extractManyToMany(meta, data);
|
|
383
387
|
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes, options.loggerContext).withSchema(this.getSchemaName(meta, options));
|
|
384
388
|
const res = await this.rethrow(qb.insert(data).execute('run', false));
|
|
385
389
|
res.row = res.row || {};
|
|
386
390
|
let pk;
|
|
387
|
-
if (
|
|
388
|
-
pk = Utils.getPrimaryKeyCond(data,
|
|
391
|
+
if (meta.primaryKeys.length > 1) { // owner has composite pk
|
|
392
|
+
pk = Utils.getPrimaryKeyCond(data, meta.primaryKeys);
|
|
389
393
|
}
|
|
390
394
|
else {
|
|
391
395
|
/* v8 ignore next */
|
|
392
|
-
res.insertId = data[
|
|
396
|
+
res.insertId = data[meta.primaryKeys[0]] ?? res.insertId ?? res.row[meta.primaryKeys[0]];
|
|
393
397
|
pk = [res.insertId];
|
|
394
398
|
}
|
|
395
399
|
await this.processManyToMany(meta, pk, collections, false, options);
|
|
@@ -398,23 +402,22 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
398
402
|
async nativeInsertMany(entityName, data, options = {}, transform) {
|
|
399
403
|
options.processCollections ??= true;
|
|
400
404
|
options.convertCustomTypes ??= true;
|
|
401
|
-
const meta = this.metadata.
|
|
402
|
-
const collections = options.processCollections ? data.map(d => this.extractManyToMany(
|
|
403
|
-
const pks = this.getPrimaryKeyFields(
|
|
405
|
+
const meta = this.metadata.get(entityName).root;
|
|
406
|
+
const collections = options.processCollections ? data.map(d => this.extractManyToMany(meta, d)) : [];
|
|
407
|
+
const pks = this.getPrimaryKeyFields(meta);
|
|
404
408
|
const set = new Set();
|
|
405
409
|
data.forEach(row => Utils.keys(row).forEach(k => set.add(k)));
|
|
406
|
-
const props = [...set].map(name => meta
|
|
410
|
+
const props = [...set].map(name => meta.properties[name] ?? { name, fieldNames: [name] });
|
|
407
411
|
let fields = Utils.flatten(props.map(prop => prop.fieldNames));
|
|
408
412
|
const duplicates = Utils.findDuplicates(fields);
|
|
409
413
|
const params = [];
|
|
410
414
|
if (duplicates.length) {
|
|
411
415
|
fields = Utils.unique(fields);
|
|
412
416
|
}
|
|
413
|
-
|
|
414
|
-
const tableName = meta ? this.getTableName(meta, options) : this.platform.quoteIdentifier(entityName);
|
|
417
|
+
const tableName = this.getTableName(meta, options);
|
|
415
418
|
let sql = `insert into ${tableName} `;
|
|
416
419
|
sql += fields.length > 0 ? '(' + fields.map(k => this.platform.quoteIdentifier(k)).join(', ') + ')' : `(${this.platform.quoteIdentifier(pks[0])})`;
|
|
417
|
-
if (
|
|
420
|
+
if (this.platform.usesOutputStatement()) {
|
|
418
421
|
const returningProps = meta.props
|
|
419
422
|
.filter(prop => prop.persist !== false && prop.defaultRaw || prop.autoincrement || prop.generated)
|
|
420
423
|
.filter(prop => !(prop.name in data[0]) || isRaw(data[0][prop.name]));
|
|
@@ -531,13 +534,13 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
531
534
|
}
|
|
532
535
|
async nativeUpdate(entityName, where, data, options = {}) {
|
|
533
536
|
options.convertCustomTypes ??= true;
|
|
534
|
-
const meta = this.metadata.
|
|
535
|
-
const pks = this.getPrimaryKeyFields(
|
|
536
|
-
const collections = this.extractManyToMany(
|
|
537
|
+
const meta = this.metadata.get(entityName);
|
|
538
|
+
const pks = this.getPrimaryKeyFields(meta);
|
|
539
|
+
const collections = this.extractManyToMany(meta, data);
|
|
537
540
|
let res = { affectedRows: 0, insertId: 0, row: {} };
|
|
538
541
|
if (Utils.isPrimaryKey(where) && pks.length === 1) {
|
|
539
542
|
/* v8 ignore next */
|
|
540
|
-
where = { [meta
|
|
543
|
+
where = { [meta.primaryKeys[0] ?? pks[0]]: where };
|
|
541
544
|
}
|
|
542
545
|
if (Utils.hasObjectKeys(data)) {
|
|
543
546
|
const qb = this.createQueryBuilder(entityName, options.ctx, 'write', options.convertCustomTypes, options.loggerContext)
|
|
@@ -561,7 +564,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
561
564
|
qb.update(data).where(where);
|
|
562
565
|
// reload generated columns and version fields
|
|
563
566
|
const returning = [];
|
|
564
|
-
meta
|
|
567
|
+
meta.props
|
|
565
568
|
.filter(prop => (prop.generated && !prop.primary) || prop.version)
|
|
566
569
|
.forEach(prop => returning.push(prop.name));
|
|
567
570
|
qb.returning(returning);
|
|
@@ -593,7 +596,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
593
596
|
}
|
|
594
597
|
return this.rethrow(qb.execute('run', false));
|
|
595
598
|
}
|
|
596
|
-
const collections = options.processCollections ? data.map(d => this.extractManyToMany(
|
|
599
|
+
const collections = options.processCollections ? data.map(d => this.extractManyToMany(meta, d)) : [];
|
|
597
600
|
const keys = new Set();
|
|
598
601
|
const fields = new Set();
|
|
599
602
|
const returning = new Set();
|
|
@@ -606,7 +609,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
606
609
|
}
|
|
607
610
|
}
|
|
608
611
|
// reload generated columns and version fields
|
|
609
|
-
meta
|
|
612
|
+
meta.props
|
|
610
613
|
.filter(prop => prop.generated || prop.version || prop.primary)
|
|
611
614
|
.forEach(prop => returning.add(prop.name));
|
|
612
615
|
const pkCond = Utils.flatten(meta.primaryKeys.map(pk => meta.properties[pk].fieldNames)).map(pk => `${this.platform.quoteIdentifier(pk)} = ?`).join(' and ');
|
|
@@ -699,8 +702,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
699
702
|
return res;
|
|
700
703
|
}
|
|
701
704
|
async nativeDelete(entityName, where, options = {}) {
|
|
702
|
-
const meta = this.metadata.
|
|
703
|
-
const pks = this.getPrimaryKeyFields(
|
|
705
|
+
const meta = this.metadata.get(entityName);
|
|
706
|
+
const pks = this.getPrimaryKeyFields(meta);
|
|
704
707
|
if (Utils.isPrimaryKey(where) && pks.length === 1) {
|
|
705
708
|
where = { [pks[0]]: where };
|
|
706
709
|
}
|
|
@@ -753,7 +756,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
753
756
|
}
|
|
754
757
|
if (coll.property.kind === ReferenceKind.ONE_TO_MANY) {
|
|
755
758
|
const cols = coll.property.referencedColumnNames;
|
|
756
|
-
const qb = this.createQueryBuilder(coll.property.
|
|
759
|
+
const qb = this.createQueryBuilder(coll.property.targetMeta.class, options?.ctx, 'write')
|
|
757
760
|
.withSchema(this.getSchemaName(meta, options));
|
|
758
761
|
if (coll.getSnapshot() === undefined) {
|
|
759
762
|
if (coll.property.orphanRemoval) {
|
|
@@ -774,7 +777,6 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
774
777
|
await this.rethrow(query.execute());
|
|
775
778
|
continue;
|
|
776
779
|
}
|
|
777
|
-
/* v8 ignore next */
|
|
778
780
|
const pivotMeta = this.metadata.find(coll.property.pivotEntity);
|
|
779
781
|
let schema = pivotMeta.schema;
|
|
780
782
|
if (schema === '*') {
|
|
@@ -802,10 +804,10 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
802
804
|
if (owners.length === 0) {
|
|
803
805
|
return {};
|
|
804
806
|
}
|
|
805
|
-
const pivotMeta = this.metadata.
|
|
807
|
+
const pivotMeta = this.metadata.get(prop.pivotEntity);
|
|
806
808
|
const pivotProp1 = pivotMeta.relations[prop.owner ? 1 : 0];
|
|
807
809
|
const pivotProp2 = pivotMeta.relations[prop.owner ? 0 : 1];
|
|
808
|
-
const ownerMeta =
|
|
810
|
+
const ownerMeta = pivotProp2.targetMeta;
|
|
809
811
|
const cond = {
|
|
810
812
|
[pivotProp2.name]: { $in: ownerMeta.compositePK ? owners : owners.map(o => o[0]) },
|
|
811
813
|
};
|
|
@@ -820,7 +822,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
820
822
|
const fields = pivotJoin
|
|
821
823
|
? [pivotProp1.name, pivotProp2.name]
|
|
822
824
|
: [pivotProp1.name, pivotProp2.name, ...childFields];
|
|
823
|
-
const res = await this.find(pivotMeta.
|
|
825
|
+
const res = await this.find(pivotMeta.class, where, {
|
|
824
826
|
ctx,
|
|
825
827
|
...options,
|
|
826
828
|
fields,
|
|
@@ -830,7 +832,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
830
832
|
populateWhere: undefined,
|
|
831
833
|
// @ts-ignore
|
|
832
834
|
_populateWhere: 'infer',
|
|
833
|
-
populateFilter: !Utils.isEmpty(options?.populateFilter) ? { [pivotProp2.name]: options?.populateFilter } : undefined,
|
|
835
|
+
populateFilter: !Utils.isEmpty(options?.populateFilter) || RawQueryFragment.hasObjectFragments(options?.populateFilter) ? { [pivotProp2.name]: options?.populateFilter } : undefined,
|
|
834
836
|
});
|
|
835
837
|
const map = {};
|
|
836
838
|
for (const owner of owners) {
|
|
@@ -844,7 +846,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
844
846
|
return map;
|
|
845
847
|
}
|
|
846
848
|
getPivotOrderBy(prop, pivotProp, orderBy, parentOrderBy) {
|
|
847
|
-
if (!Utils.isEmpty(orderBy)) {
|
|
849
|
+
if (!Utils.isEmpty(orderBy) || RawQueryFragment.hasObjectFragments(orderBy)) {
|
|
848
850
|
return Utils.asArray(orderBy).map(o => ({ [pivotProp.name]: o }));
|
|
849
851
|
}
|
|
850
852
|
if (prop.kind === ReferenceKind.MANY_TO_MANY && Utils.asArray(parentOrderBy).some(o => o[prop.name])) {
|
|
@@ -852,7 +854,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
852
854
|
.filter(o => o[prop.name])
|
|
853
855
|
.map(o => ({ [pivotProp.name]: o[prop.name] }));
|
|
854
856
|
}
|
|
855
|
-
if (!Utils.isEmpty(prop.orderBy)) {
|
|
857
|
+
if (!Utils.isEmpty(prop.orderBy) || RawQueryFragment.hasObjectFragments(prop.orderBy)) {
|
|
856
858
|
return Utils.asArray(prop.orderBy).map(o => ({ [pivotProp.name]: o }));
|
|
857
859
|
}
|
|
858
860
|
if (prop.fixedOrder) {
|
|
@@ -865,8 +867,8 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
865
867
|
}
|
|
866
868
|
async *stream(entityName, where, options) {
|
|
867
869
|
options = { populate: [], orderBy: [], ...options };
|
|
868
|
-
const meta = this.metadata.
|
|
869
|
-
if (meta
|
|
870
|
+
const meta = this.metadata.get(entityName);
|
|
871
|
+
if (meta.virtual) {
|
|
870
872
|
yield* this.streamFromVirtual(entityName, where, options);
|
|
871
873
|
return;
|
|
872
874
|
}
|
|
@@ -1003,7 +1005,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1003
1005
|
if (ref && !hint.filter && (prop.kind === ReferenceKind.MANY_TO_ONE || (prop.kind === ReferenceKind.ONE_TO_ONE && prop.owner))) {
|
|
1004
1006
|
continue;
|
|
1005
1007
|
}
|
|
1006
|
-
const meta2 =
|
|
1008
|
+
const meta2 = prop.targetMeta;
|
|
1007
1009
|
const pivotRefJoin = prop.kind === ReferenceKind.MANY_TO_MANY && ref;
|
|
1008
1010
|
const tableAlias = qb.getNextAlias(prop.name);
|
|
1009
1011
|
const field = `${options.parentTableAlias}.${prop.name}`;
|
|
@@ -1114,26 +1116,20 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1114
1116
|
}
|
|
1115
1117
|
return 'write';
|
|
1116
1118
|
}
|
|
1117
|
-
extractManyToMany(
|
|
1118
|
-
if (!this.metadata.has(entityName)) {
|
|
1119
|
-
return {};
|
|
1120
|
-
}
|
|
1119
|
+
extractManyToMany(meta, data) {
|
|
1121
1120
|
const ret = {};
|
|
1122
|
-
|
|
1121
|
+
for (const prop of meta.relations) {
|
|
1123
1122
|
if (prop.kind === ReferenceKind.MANY_TO_MANY && data[prop.name]) {
|
|
1124
1123
|
ret[prop.name] = data[prop.name].map((item) => Utils.asArray(item));
|
|
1125
1124
|
delete data[prop.name];
|
|
1126
1125
|
}
|
|
1127
|
-
}
|
|
1126
|
+
}
|
|
1128
1127
|
return ret;
|
|
1129
1128
|
}
|
|
1130
1129
|
async processManyToMany(meta, pks, collections, clear, options) {
|
|
1131
|
-
if (!meta) {
|
|
1132
|
-
return;
|
|
1133
|
-
}
|
|
1134
1130
|
for (const prop of meta.relations) {
|
|
1135
1131
|
if (collections[prop.name]) {
|
|
1136
|
-
const pivotMeta = this.metadata.
|
|
1132
|
+
const pivotMeta = this.metadata.get(prop.pivotEntity);
|
|
1137
1133
|
const persister = new PivotCollectionPersister(pivotMeta, this, options?.ctx, options?.schema, options?.loggerContext);
|
|
1138
1134
|
persister.enqueueUpdate(prop, collections[prop.name], clear, pks);
|
|
1139
1135
|
await this.rethrow(persister.execute());
|
|
@@ -1142,7 +1138,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1142
1138
|
}
|
|
1143
1139
|
async lockPessimistic(entity, options) {
|
|
1144
1140
|
const meta = helper(entity).__meta;
|
|
1145
|
-
const qb = this.createQueryBuilder(
|
|
1141
|
+
const qb = this.createQueryBuilder(meta.class, options.ctx, undefined, undefined, options.logging).withSchema(options.schema ?? meta.schema);
|
|
1146
1142
|
const cond = Utils.getPrimaryKeyCond(entity, meta.primaryKeys);
|
|
1147
1143
|
qb.select(raw('1')).where(cond).setLockMode(options.lockMode, options.lockTableAliases);
|
|
1148
1144
|
await this.rethrow(qb.execute());
|
|
@@ -1152,21 +1148,21 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1152
1148
|
for (const hint of joinedProps) {
|
|
1153
1149
|
const [propName] = hint.field.split(':', 2);
|
|
1154
1150
|
const prop = meta.properties[propName];
|
|
1155
|
-
if (!Utils.isEmpty(prop.where)) {
|
|
1151
|
+
if (!Utils.isEmpty(prop.where) || RawQueryFragment.hasObjectFragments(prop.where)) {
|
|
1156
1152
|
where[prop.name] = Utils.copy(prop.where);
|
|
1157
1153
|
}
|
|
1158
1154
|
if (hint.children) {
|
|
1159
1155
|
const inner = this.buildPopulateWhere(prop.targetMeta, hint.children, {});
|
|
1160
|
-
if (!Utils.isEmpty(inner)) {
|
|
1156
|
+
if (!Utils.isEmpty(inner) || RawQueryFragment.hasObjectFragments(inner)) {
|
|
1161
1157
|
where[prop.name] ??= {};
|
|
1162
1158
|
Object.assign(where[prop.name], inner);
|
|
1163
1159
|
}
|
|
1164
1160
|
}
|
|
1165
1161
|
}
|
|
1166
|
-
if (Utils.isEmpty(options.populateWhere)) {
|
|
1162
|
+
if (Utils.isEmpty(options.populateWhere) && !RawQueryFragment.hasObjectFragments(options.populateWhere)) {
|
|
1167
1163
|
return where;
|
|
1168
1164
|
}
|
|
1169
|
-
if (Utils.isEmpty(where)) {
|
|
1165
|
+
if (Utils.isEmpty(where) && !RawQueryFragment.hasObjectFragments(where)) {
|
|
1170
1166
|
return options.populateWhere;
|
|
1171
1167
|
}
|
|
1172
1168
|
/* v8 ignore next */
|
|
@@ -1178,31 +1174,31 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1178
1174
|
// as `options.populateWhere` will be always recomputed to respect filters
|
|
1179
1175
|
const populateWhereAll = options._populateWhere !== 'infer' && !Utils.isEmpty(options._populateWhere);
|
|
1180
1176
|
const path = (populateWhereAll ? '[populate]' : '') + meta.className;
|
|
1177
|
+
const optionsOrderBy = Utils.asArray(options.orderBy);
|
|
1181
1178
|
const populateOrderBy = this.buildPopulateOrderBy(qb, meta, Utils.asArray(options.populateOrderBy ?? options.orderBy), path, !!options.populateOrderBy);
|
|
1182
1179
|
const joinedPropsOrderBy = this.buildJoinedPropsOrderBy(qb, meta, joinedProps, options, path);
|
|
1183
|
-
return [...
|
|
1180
|
+
return [...optionsOrderBy, ...populateOrderBy, ...joinedPropsOrderBy];
|
|
1184
1181
|
}
|
|
1185
1182
|
buildPopulateOrderBy(qb, meta, populateOrderBy, parentPath, explicit, parentAlias = qb.alias) {
|
|
1186
1183
|
const orderBy = [];
|
|
1187
1184
|
for (let i = 0; i < populateOrderBy.length; i++) {
|
|
1188
1185
|
const orderHint = populateOrderBy[i];
|
|
1189
|
-
for (const
|
|
1190
|
-
const
|
|
1191
|
-
if (
|
|
1192
|
-
const sql =
|
|
1193
|
-
const
|
|
1194
|
-
orderBy.push({ [
|
|
1186
|
+
for (const field of Utils.getObjectQueryKeys(orderHint)) {
|
|
1187
|
+
const childOrder = orderHint[field];
|
|
1188
|
+
if (RawQueryFragment.isKnownFragmentSymbol(field)) {
|
|
1189
|
+
const { sql, params } = RawQueryFragment.getKnownFragment(field);
|
|
1190
|
+
const key = raw(sql.replace(new RegExp(ALIAS_REPLACEMENT_RE, 'g'), parentAlias), params);
|
|
1191
|
+
orderBy.push({ [key]: childOrder });
|
|
1195
1192
|
continue;
|
|
1196
1193
|
}
|
|
1197
|
-
const prop = meta.properties[
|
|
1194
|
+
const prop = meta.properties[field];
|
|
1198
1195
|
if (!prop) {
|
|
1199
|
-
throw new Error(`Trying to order by not existing property ${meta.className}.${
|
|
1196
|
+
throw new Error(`Trying to order by not existing property ${meta.className}.${field}`);
|
|
1200
1197
|
}
|
|
1201
1198
|
let path = parentPath;
|
|
1202
|
-
const meta2 =
|
|
1203
|
-
const childOrder = orderHint[prop.name];
|
|
1199
|
+
const meta2 = prop.targetMeta;
|
|
1204
1200
|
if (prop.kind !== ReferenceKind.SCALAR && (![ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(prop.kind) || !prop.owner || Utils.isPlainObject(childOrder))) {
|
|
1205
|
-
path += `.${
|
|
1201
|
+
path += `.${field}`;
|
|
1206
1202
|
}
|
|
1207
1203
|
if (prop.kind === ReferenceKind.MANY_TO_MANY && typeof childOrder !== 'object') {
|
|
1208
1204
|
path += '[pivot]';
|
|
@@ -1228,9 +1224,9 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1228
1224
|
}
|
|
1229
1225
|
continue;
|
|
1230
1226
|
}
|
|
1231
|
-
const order = typeof childOrder === 'object' ? childOrder[
|
|
1227
|
+
const order = typeof childOrder === 'object' ? childOrder[field] : childOrder;
|
|
1232
1228
|
if (order) {
|
|
1233
|
-
orderBy.push({ [`${propAlias}.${
|
|
1229
|
+
orderBy.push({ [`${propAlias}.${field}`]: order });
|
|
1234
1230
|
}
|
|
1235
1231
|
}
|
|
1236
1232
|
}
|
|
@@ -1249,22 +1245,23 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1249
1245
|
}
|
|
1250
1246
|
const join = qb.getJoinForPath(path, { matchPopulateJoins: true });
|
|
1251
1247
|
const propAlias = qb.getAliasForJoinPath(join ?? path, { matchPopulateJoins: true });
|
|
1252
|
-
const meta2 =
|
|
1248
|
+
const meta2 = prop.targetMeta;
|
|
1253
1249
|
if (prop.kind === ReferenceKind.MANY_TO_MANY && prop.fixedOrder && join) {
|
|
1254
1250
|
const alias = ref ? propAlias : join.ownerAlias;
|
|
1255
1251
|
orderBy.push({ [`${alias}.${prop.fixedOrderColumn}`]: QueryOrder.ASC });
|
|
1256
1252
|
}
|
|
1257
1253
|
if (propOrderBy) {
|
|
1258
1254
|
for (const item of Utils.asArray(propOrderBy)) {
|
|
1259
|
-
for (const field of Utils.
|
|
1260
|
-
const
|
|
1261
|
-
if (
|
|
1262
|
-
const sql
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1255
|
+
for (const field of Utils.getObjectQueryKeys(item)) {
|
|
1256
|
+
const order = item[field];
|
|
1257
|
+
if (RawQueryFragment.isKnownFragmentSymbol(field)) {
|
|
1258
|
+
const { sql, params } = RawQueryFragment.getKnownFragment(field);
|
|
1259
|
+
const sql2 = propAlias ? sql.replace(new RegExp(ALIAS_REPLACEMENT_RE, 'g'), propAlias) : sql;
|
|
1260
|
+
const key = raw(sql2, params);
|
|
1261
|
+
orderBy.push({ [key]: order });
|
|
1265
1262
|
continue;
|
|
1266
1263
|
}
|
|
1267
|
-
orderBy.push({ [`${propAlias}.${field}`]:
|
|
1264
|
+
orderBy.push({ [`${propAlias}.${field}`]: order });
|
|
1268
1265
|
}
|
|
1269
1266
|
}
|
|
1270
1267
|
}
|
|
@@ -1332,7 +1329,7 @@ export class AbstractSqlDriver extends DatabaseDriver {
|
|
|
1332
1329
|
const prop = QueryHelper.findProperty(rootPropName, {
|
|
1333
1330
|
metadata: this.metadata,
|
|
1334
1331
|
platform: this.platform,
|
|
1335
|
-
entityName: meta.
|
|
1332
|
+
entityName: meta.class,
|
|
1336
1333
|
where: {},
|
|
1337
1334
|
aliasMap: qb.getAliasMap(),
|
|
1338
1335
|
});
|
|
@@ -120,7 +120,7 @@ export class PivotCollectionPersister {
|
|
|
120
120
|
for (const item of chunk) {
|
|
121
121
|
cond.$or.push(item.getCondition());
|
|
122
122
|
}
|
|
123
|
-
await this.driver.nativeDelete(this.meta.
|
|
123
|
+
await this.driver.nativeDelete(this.meta.class, cond, {
|
|
124
124
|
ctx: this.ctx,
|
|
125
125
|
schema: this.schema,
|
|
126
126
|
loggerContext: this.loggerContext,
|
|
@@ -131,7 +131,7 @@ export class PivotCollectionPersister {
|
|
|
131
131
|
const filtered = this.collectStatements(this.inserts);
|
|
132
132
|
for (let i = 0; i < filtered.length; i += this.batchSize) {
|
|
133
133
|
const chunk = filtered.slice(i, i + this.batchSize);
|
|
134
|
-
await this.driver.nativeInsertMany(this.meta.
|
|
134
|
+
await this.driver.nativeInsertMany(this.meta.class, chunk, {
|
|
135
135
|
ctx: this.ctx,
|
|
136
136
|
schema: this.schema,
|
|
137
137
|
convertCustomTypes: false,
|
|
@@ -144,7 +144,7 @@ export class PivotCollectionPersister {
|
|
|
144
144
|
const filtered = this.collectStatements(this.upserts);
|
|
145
145
|
for (let i = 0; i < filtered.length; i += this.batchSize) {
|
|
146
146
|
const chunk = filtered.slice(i, i + this.batchSize);
|
|
147
|
-
await this.driver.nativeUpdateMany(this.meta.
|
|
147
|
+
await this.driver.nativeUpdateMany(this.meta.class, [], chunk, {
|
|
148
148
|
ctx: this.ctx,
|
|
149
149
|
schema: this.schema,
|
|
150
150
|
convertCustomTypes: false,
|
package/SqlEntityManager.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export declare class SqlEntityManager<Driver extends AbstractSqlDriver = Abstrac
|
|
|
27
27
|
getKysely<TDB = undefined, TOptions extends GetKyselyOptions = GetKyselyOptions>(options?: TOptions): Kysely<TDB extends undefined ? InferKyselyDB<EntitiesFromManager<this>, TOptions> : TDB>;
|
|
28
28
|
execute<T extends QueryResult | EntityData<AnyEntity> | EntityData<AnyEntity>[] = EntityData<AnyEntity>[]>(query: string | NativeQueryBuilder | RawQueryFragment, params?: any[], method?: 'all' | 'get' | 'run', loggerContext?: LoggingOptions): Promise<T>;
|
|
29
29
|
getRepository<T extends object, U extends EntityRepository<T> = SqlEntityRepository<T>>(entityName: EntityName<T>): GetRepository<T, U>;
|
|
30
|
-
protected applyDiscriminatorCondition<Entity extends object>(entityName:
|
|
30
|
+
protected applyDiscriminatorCondition<Entity extends object>(entityName: EntityName<Entity>, where: FilterQuery<Entity>): FilterQuery<Entity>;
|
|
31
31
|
}
|
|
32
32
|
type EntitiesFromManager<TEntityManager extends EntityManager<any>> = NonNullable<TEntityManager['~entities']> extends any[] ? (Extract<NonNullable<TEntityManager['~entities']>[number], EntitySchemaWithMeta>) : never;
|
|
33
33
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/sql",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.115",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -56,6 +56,6 @@
|
|
|
56
56
|
"@mikro-orm/core": "^6.6.2"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@mikro-orm/core": "7.0.0-dev.
|
|
59
|
+
"@mikro-orm/core": "7.0.0-dev.115"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/plugin/transformer.js
CHANGED
|
@@ -706,7 +706,7 @@ export class MikroTransformer extends OperationNodeTransformer {
|
|
|
706
706
|
* Find entity metadata by table name or entity name
|
|
707
707
|
*/
|
|
708
708
|
findEntityMetadata(name) {
|
|
709
|
-
const byEntity = this.metadata.
|
|
709
|
+
const byEntity = this.metadata.getByClassName(name, false);
|
|
710
710
|
if (byEntity) {
|
|
711
711
|
return byEntity;
|
|
712
712
|
}
|
package/query/CriteriaNode.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type EntityKey, type EntityProperty, type MetadataStorage } from '@mikro-orm/core';
|
|
1
|
+
import { type EntityKey, type EntityProperty, type MetadataStorage, type RawQueryFragmentSymbol, type EntityName } from '@mikro-orm/core';
|
|
2
2
|
import type { ICriteriaNode, ICriteriaNodeProcessOptions, IQueryBuilder } from '../typings.js';
|
|
3
3
|
/**
|
|
4
4
|
* Helper for working with deeply nested where/orderBy/having criteria. Uses composite pattern to build tree from the payload.
|
|
@@ -7,14 +7,14 @@ import type { ICriteriaNode, ICriteriaNodeProcessOptions, IQueryBuilder } from '
|
|
|
7
7
|
*/
|
|
8
8
|
export declare class CriteriaNode<T extends object> implements ICriteriaNode<T> {
|
|
9
9
|
protected readonly metadata: MetadataStorage;
|
|
10
|
-
readonly entityName:
|
|
10
|
+
readonly entityName: EntityName<T>;
|
|
11
11
|
readonly parent?: ICriteriaNode<T> | undefined;
|
|
12
|
-
readonly key?: EntityKey<T> | undefined;
|
|
12
|
+
readonly key?: (EntityKey<T> | RawQueryFragmentSymbol) | undefined;
|
|
13
13
|
readonly strict: boolean;
|
|
14
14
|
payload: any;
|
|
15
15
|
prop?: EntityProperty<T>;
|
|
16
16
|
index?: number;
|
|
17
|
-
constructor(metadata: MetadataStorage, entityName:
|
|
17
|
+
constructor(metadata: MetadataStorage, entityName: EntityName<T>, parent?: ICriteriaNode<T> | undefined, key?: (EntityKey<T> | RawQueryFragmentSymbol) | undefined, validate?: boolean, strict?: boolean);
|
|
18
18
|
process(qb: IQueryBuilder<T>, options?: ICriteriaNodeProcessOptions): any;
|
|
19
19
|
unwrap(): any;
|
|
20
20
|
shouldInline(payload: any): boolean;
|
package/query/CriteriaNode.js
CHANGED
|
@@ -20,7 +20,7 @@ export class CriteriaNode {
|
|
|
20
20
|
this.key = key;
|
|
21
21
|
this.strict = strict;
|
|
22
22
|
const meta = parent && metadata.find(parent.entityName);
|
|
23
|
-
if (meta && key) {
|
|
23
|
+
if (meta && key && !RawQueryFragment.isKnownFragmentSymbol(key)) {
|
|
24
24
|
const pks = Utils.splitPrimaryKeys(key);
|
|
25
25
|
if (pks.length > 1) {
|
|
26
26
|
return;
|
|
@@ -29,8 +29,8 @@ export class CriteriaNode {
|
|
|
29
29
|
this.prop = meta.props.find(prop => prop.name === k || (prop.fieldNames?.length === 1 && prop.fieldNames[0] === k && prop.persist !== false));
|
|
30
30
|
const isProp = this.prop || meta.props.find(prop => (prop.fieldNames || []).includes(k));
|
|
31
31
|
// do not validate if the key is prefixed or type casted (e.g. `k::text`)
|
|
32
|
-
if (validate && !isProp && !k.includes('.') && !k.includes('::') && !Utils.isOperator(k)
|
|
33
|
-
throw new Error(`Trying to query by not existing property ${entityName}.${k}`);
|
|
32
|
+
if (validate && !isProp && !k.includes('.') && !k.includes('::') && !Utils.isOperator(k)) {
|
|
33
|
+
throw new Error(`Trying to query by not existing property ${Utils.className(entityName)}.${k}`);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -50,11 +50,9 @@ export class CriteriaNode {
|
|
|
50
50
|
shouldRename(payload) {
|
|
51
51
|
const type = this.prop ? this.prop.kind : null;
|
|
52
52
|
const composite = this.prop?.joinColumns ? this.prop.joinColumns.length > 1 : false;
|
|
53
|
-
const
|
|
54
|
-
const scalar = payload === null || Utils.isPrimaryKey(payload) || payload instanceof RegExp || payload instanceof Date ||
|
|
55
|
-
const
|
|
56
|
-
const keys = plainObject ? Object.keys(payload) : [];
|
|
57
|
-
const operator = plainObject && keys.every(k => Utils.isOperator(k, false));
|
|
53
|
+
const rawField = RawQueryFragment.isKnownFragmentSymbol(this.key);
|
|
54
|
+
const scalar = payload === null || Utils.isPrimaryKey(payload) || payload instanceof RegExp || payload instanceof Date || rawField;
|
|
55
|
+
const operator = Utils.isPlainObject(payload) && Utils.getObjectQueryKeys(payload).every(k => Utils.isOperator(k, false));
|
|
58
56
|
if (composite) {
|
|
59
57
|
return true;
|
|
60
58
|
}
|
|
@@ -81,10 +79,10 @@ export class CriteriaNode {
|
|
|
81
79
|
getPath(addIndex = false) {
|
|
82
80
|
// use index on parent only if we are processing to-many relation
|
|
83
81
|
const addParentIndex = this.prop && [ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(this.prop.kind);
|
|
84
|
-
const parentPath = this.parent?.getPath(addParentIndex) ?? this.entityName;
|
|
82
|
+
const parentPath = this.parent?.getPath(addParentIndex) ?? Utils.className(this.entityName);
|
|
85
83
|
const index = addIndex && this.index != null ? `[${this.index}]` : '';
|
|
86
84
|
// ignore group operators to allow easier mapping (e.g. for orderBy)
|
|
87
|
-
const key = this.key && !['$and', '$or', '$not'].includes(this.key) ? '.' + this.key : '';
|
|
85
|
+
const key = this.key && !RawQueryFragment.isKnownFragmentSymbol(this.key) && !['$and', '$or', '$not'].includes(this.key) ? '.' + this.key : '';
|
|
88
86
|
const ret = parentPath + index + key;
|
|
89
87
|
if (this.isPivotJoin()) {
|
|
90
88
|
// distinguish pivot table join from target entity join
|
|
@@ -96,9 +94,9 @@ export class CriteriaNode {
|
|
|
96
94
|
if (!this.key || !this.prop) {
|
|
97
95
|
return false;
|
|
98
96
|
}
|
|
99
|
-
const
|
|
100
|
-
const scalar = this.payload === null || Utils.isPrimaryKey(this.payload) || this.payload instanceof RegExp || this.payload instanceof Date ||
|
|
101
|
-
const operator = Utils.isObject(this.payload) &&
|
|
97
|
+
const rawField = RawQueryFragment.isKnownFragmentSymbol(this.key);
|
|
98
|
+
const scalar = this.payload === null || Utils.isPrimaryKey(this.payload) || this.payload instanceof RegExp || this.payload instanceof Date || rawField;
|
|
99
|
+
const operator = Utils.isObject(this.payload) && Utils.getObjectQueryKeys(this.payload).every(k => Utils.isOperator(k, false));
|
|
102
100
|
return this.prop.kind === ReferenceKind.MANY_TO_MANY && (scalar || operator);
|
|
103
101
|
}
|
|
104
102
|
getPivotPath(path) {
|
|
@@ -111,6 +109,7 @@ export class CriteriaNode {
|
|
|
111
109
|
return this.strict;
|
|
112
110
|
}
|
|
113
111
|
/** @ignore */
|
|
112
|
+
/* v8 ignore next */
|
|
114
113
|
[Symbol.for('nodejs.util.inspect.custom')]() {
|
|
115
114
|
const o = {};
|
|
116
115
|
['entityName', 'key', 'index', 'payload']
|