Permalink
Browse files

feat(QueryBuilder): add support for derived tables

  • Loading branch information...
RWOverdijk committed Jun 3, 2017
1 parent a0235e1 commit e3d4de2e9c5ba16a77515acf69627c7de0464517
Showing with 71 additions and 1 deletion.
  1. +26 −1 src/EntityRepository.ts
  2. +45 −0 src/QueryBuilder.ts
@@ -66,14 +66,39 @@ export class EntityRepository<T> {
alias = alias || this.mapping.getTableName();
if (!statement) {
let connection = this.entityManager.getStore(this.entity).getConnection(Store.ROLE_SLAVE);
let connection = this.getConnection();
statement = connection(`${this.mapping.getTableName()} as ${alias}`);
}
return new QueryBuilder(this.entityManager, statement, this.mapping, alias);
}
/**
* Get a new query builder that will be applied on the derived table (query builder).
*
* e.g. `select count(*) from (select * from user) as user0;`
*
* @param {QueryBuilder} derivedFrom
* @param {string} [alias]
*
* @returns {QueryBuilder}
*/
public getDerivedQueryBuilder(derivedFrom: QueryBuilder<T>, alias?: string): QueryBuilder<T> {
return this.getQueryBuilder().from(derivedFrom, alias);
}
/**
* Get a raw knex connection
*
* @param {string} [role] Defaults to slave
*
* @returns {knex}
*/
public getConnection(role: string = Store.ROLE_SLAVE): knex {
return this.entityManager.getStore(this.entity).getConnection(role);
}
/**
* Find entities based on provided criteria.
*
@@ -48,6 +48,11 @@ export class QueryBuilder<T> {
*/
private groupBys: Array<{groupBy: string | Array<string>}> = [];
/**
* @type {QueryBuilder}
*/
private derivedFrom: {derived: QueryBuilder<T>, alias: string};
/**
* @type {Array}
*/
@@ -571,6 +576,7 @@ export class QueryBuilder<T> {
this.whereCriteria.applyStaged();
this.havingCriteria.applyStaged();
this.onCriteria.applyStaged();
this.applyFrom();
this.applySelects();
this.applyOrderBys();
this.applyGroupBys();
@@ -580,6 +586,24 @@ export class QueryBuilder<T> {
return this;
}
/**
* Apply the provided derived values.
*
* @returns {QueryBuilder}
*/
private applyFrom(): this {
if (this.derivedFrom) {
let {derived, alias} = this.derivedFrom;
// this.statement
this.statement.from(this.statement['client'].raw(`(${this.derivedFrom.derived.getQuery().getSQL()}) as ${alias}`));
this.derivedFrom = null;
}
return this;
}
/**
* Apply the staged selects to the query.
*
@@ -922,6 +946,27 @@ export class QueryBuilder<T> {
return this;
}
/**
* Select `.from()` a derived table (QueryBuilder).
*
* .from(queryBuilder, 'foo');
*
* @param {QueryBuilder} derived
* @param {string} [alias] alias
*
* @returns {QueryBuilder}
*/
public from(derived: QueryBuilder<T>, alias?: string): this {
if (!alias) {
alias = this.createAlias(derived.getHostMapping().getTableName());
}
this.derivedFrom = {alias, derived};
this.prepared = false;
return this;
}
/**
* Sets the having clause.
*

0 comments on commit e3d4de2

Please sign in to comment.