Skip to content

Commit

Permalink
perf(core): improve performance of QB a bit
Browse files Browse the repository at this point in the history
Related: #732
  • Loading branch information
B4nan committed Aug 13, 2020
1 parent 3645a20 commit efc044f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 30 deletions.
27 changes: 26 additions & 1 deletion packages/core/src/drivers/DatabaseDriver.ts
Expand Up @@ -2,7 +2,7 @@ import { EntityManagerType, FindOneOptions, FindOptions, IDatabaseDriver } from
import { EntityData, EntityMetadata, EntityProperty, FilterQuery, AnyEntity, Dictionary, Primary, PopulateOptions } from '../typings';
import { MetadataStorage } from '../metadata';
import { Connection, QueryResult, Transaction } from '../connections';
import { Configuration, ConnectionOptions, Utils } from '../utils';
import { Configuration, ConnectionOptions, Utils, ValidationError } from '../utils';
import { QueryOrder, QueryOrderMap } from '../enums';
import { Platform } from '../platforms';
import { Collection, ReferenceType } from '../entity';
Expand Down Expand Up @@ -125,6 +125,31 @@ export abstract class DatabaseDriver<C extends Connection> implements IDatabaseD
throw new Error(`${this.constructor.name} does not use ensureIndexes`);
}

protected inlineEmbeddables<T>(meta: EntityMetadata<T>, data: T): void {
Object.keys(data).forEach(k => {
if (Utils.isOperator(k)) {
Utils.asArray(data[k]).forEach(payload => this.inlineEmbeddables(meta, payload));
}
});

Object.values<EntityProperty>(meta.properties).forEach(prop => {
if (prop.reference === ReferenceType.EMBEDDED && Utils.isObject(data[prop.name])) {
const props = prop.embeddedProps;

Object.keys(data[prop.name]).forEach(kk => {
const operator = Object.keys(data[prop.name]).some(f => Utils.isOperator(f));

if (operator) {
throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.name, prop.name, data);
}

data[props[kk].name] = data[prop.name][props[kk].embedded![1]];
});
delete data[prop.name];
}
});
}

protected getPivotOrderBy(prop: EntityProperty, orderBy?: QueryOrderMap): QueryOrderMap {
if (orderBy) {
return orderBy;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/utils/QueryHelper.ts
@@ -1,4 +1,4 @@
import { Reference, wrap } from '../entity';
import { Reference } from '../entity';
import { Utils } from './Utils';
import { AnyEntity, Dictionary, EntityMetadata, FilterDef, FilterQuery } from '../typings';
import { GroupOperator } from '../enums';
Expand Down
8 changes: 6 additions & 2 deletions packages/knex/src/query/QueryBuilder.ts
@@ -1,4 +1,4 @@
import { QueryBuilder as KnexQueryBuilder, Raw, Transaction, Value, Ref } from 'knex';
import { QueryBuilder as KnexQueryBuilder, Raw, Ref, Transaction, Value } from 'knex';
import {
AnyEntity, Dictionary, EntityMetadata, EntityProperty, FlatQueryOrderMap, GroupOperator, LockMode, MetadataStorage, QBFilterQuery, QueryFlag,
QueryOrderMap, ReferenceType, QueryHelper, Utils, ValidationError, PopulateOptions,
Expand Down Expand Up @@ -44,7 +44,7 @@ export class QueryBuilder<T extends AnyEntity<T> = AnyEntity> {
readonly alias = `e0`,
private readonly connectionType?: 'read' | 'write',
private readonly em?: SqlEntityManager) {
this.select('*');
this._aliasMap[this.alias] = this.entityName;
}

select(fields: Field | Field[], distinct = false): this {
Expand Down Expand Up @@ -461,6 +461,10 @@ export class QueryBuilder<T extends AnyEntity<T> = AnyEntity> {
return;
}

if (!this.type) {
this.select('*');
}

const meta = this.metadata.find(this.entityName);
this._populate.forEach(({ field }) => {
const [fromAlias, fromField] = this.helper.splitField(field);
Expand Down
27 changes: 1 addition & 26 deletions packages/mongodb/src/MongoDriver.ts
@@ -1,7 +1,7 @@
import { ClientSession, ObjectId } from 'mongodb';
import {
DatabaseDriver, EntityData, AnyEntity, FilterQuery, EntityMetadata, EntityProperty, Configuration, Utils, ReferenceType, FindOneOptions, FindOptions,
QueryResult, Transaction, IDatabaseDriver, EntityManager, EntityManagerType, Dictionary, ValidationError, PopulateOptions,
QueryResult, Transaction, IDatabaseDriver, EntityManager, EntityManagerType, Dictionary, PopulateOptions,
} from '@mikro-orm/core';
import { MongoConnection } from './MongoConnection';
import { MongoPlatform } from './MongoPlatform';
Expand Down Expand Up @@ -178,31 +178,6 @@ export class MongoDriver extends DatabaseDriver<MongoConnection> {
})];
}

private inlineEmbeddables<T>(meta: EntityMetadata<T>, data: T): void {
Object.keys(data).forEach(k => {
if (Utils.isOperator(k)) {
Utils.asArray(data[k]).forEach(payload => this.inlineEmbeddables(meta, payload));
}
});

Object.values<EntityProperty>(meta.properties).forEach(prop => {
if (prop.reference === ReferenceType.EMBEDDED && Utils.isObject(data[prop.name])) {
const props = prop.embeddedProps;

Object.keys(data[prop.name]).forEach(kk => {
const operator = Object.keys(data[prop.name]).some(f => Utils.isOperator(f));

if (operator) {
throw ValidationError.cannotUseOperatorsInsideEmbeddables(meta.name, prop.name, data);
}

data[props[kk].name] = data[prop.name][props[kk].embedded![1]];
});
delete data[prop.name];
}
});
}

private renameFields<T>(entityName: string, data: T): T {
data = Object.assign({}, data); // copy first
Utils.renameKey(data, 'id', '_id');
Expand Down

0 comments on commit efc044f

Please sign in to comment.