fixed order by issue in distinct query and in regular query

This commit is contained in:
Umed Khudoiberdiev 2016-04-22 12:55:38 +05:00
parent ae45dce2a1
commit 59792baf49
4 changed files with 38 additions and 11 deletions

View File

@ -306,11 +306,16 @@ export class QueryBuilder<Entity> {
const mainAlias = this.aliasMap.mainAlias.name;
if (this.firstResult || this.maxResults) {
const metadata = this.connection.getEntityMetadata(this.fromEntity.alias.target);
const idsQuery = this.clone()
.select(`DISTINCT(${mainAlias}.${metadata.primaryColumn.name}) as ids`)
.setOffset(this.firstResult)
.setLimit(this.maxResults)
.getSql();
let idsQuery = `SELECT DISTINCT(distinctAlias.${mainAlias}_${metadata.primaryColumn.name}) as ids`;
if (this.orderBys)
idsQuery += ", " + this.orderBys.map(orderBy => orderBy.sort.replace(".", "_")).join(", ");
idsQuery += ` FROM (${this.getSql()}) distinctAlias`;
if (this.orderBys)
idsQuery += " ORDER BY " + this.orderBys.map(order => "distinctAlias." + order.sort.replace(".", "_") + " " + order.order).join(", ");
if (this.maxResults)
idsQuery += " LIMIT " + this.maxResults;
if (this.firstResult)
idsQuery += " OFFSET " + this.firstResult;
return this.connection.driver
.query<any[]>(idsQuery)
.then((results: any[]) => {
@ -338,7 +343,7 @@ export class QueryBuilder<Entity> {
getCount(): Promise<number> {
const mainAlias = this.aliasMap.mainAlias.name;
const metadata = this.connection.getEntityMetadata(this.fromEntity.alias.target);
const countQuery = this.clone()
const countQuery = this.clone({ skipOrderBys: true })
.select(`COUNT(DISTINCT(${mainAlias}.${metadata.primaryColumn.name})) as cnt`)
.getSql();
return this.connection.driver
@ -346,7 +351,7 @@ export class QueryBuilder<Entity> {
.then(results => parseInt(results[0]["cnt"]));
}
clone() {
clone(options?: { skipOrderBys?: boolean }) {
const qb = new QueryBuilder(this.connection);
switch (this.type) {
@ -402,7 +407,9 @@ export class QueryBuilder<Entity> {
}
});
this.orderBys.forEach(orderBy => qb.addOrderBy(orderBy.sort, orderBy.order));
if (!options || !options.skipOrderBys)
this.orderBys.forEach(orderBy => qb.addOrderBy(orderBy.sort, orderBy.order));
Object.keys(this.parameters).forEach(key => qb.setParameter(key, this.parameters[key]));
qb.setLimit(this.limit)

View File

@ -3,6 +3,7 @@ import {Alias} from "../alias/Alias";
import * as _ from "lodash";
import {EntityMetadata} from "../../metadata-builder/metadata/EntityMetadata";
import {Connection} from "../../connection/Connection";
import {OrmUtils} from "../../util/OrmUtils";
/**
* Transforms raw sql results returned from the database into entity object.
@ -40,12 +41,13 @@ export class RawSqlResultsToEntityTransformer {
if (!metadata.hasPrimaryKey)
throw new Error("Metadata does not have primary key. You must have it to make convertation to object possible.");
const groupedRawResults = _.groupBy(rawSqlResults, result => alias.getPrimaryKeyValue(result, metadata.primaryColumn));
return Object.keys(groupedRawResults)
.map(key => this.transformIntoSingleResult(groupedRawResults[key], alias, metadata))
const groupedResults = OrmUtils.groupBy(rawSqlResults, result => alias.getPrimaryKeyValue(result, metadata.primaryColumn));
return groupedResults
.map(group => this.transformIntoSingleResult(group.items, alias, metadata))
.filter(res => !!res);
}
/**
* Transforms set of data results into single entity.
*/

View File

@ -0,0 +1,17 @@
export class OrmUtils {
static groupBy<T, R>(array: T[], propertyCallback: (item: T) => R): { id: R, items: T[] }[] {
return array.reduce((groupedArray, value) => {
const key = propertyCallback(value);
let grouped = groupedArray.find(i => i.id === key);
if (!grouped) {
grouped = { id: key, items: [] };
groupedArray.push(grouped);
}
grouped.items.push(value);
return groupedArray;
}, [] as Array<{ id: R, items: T[] }>);
}
}

View File

@ -77,6 +77,7 @@ describe("insertion", function() {
});
it("should have inserted post in the database", function() {
postRepository.findById(savedPost.id).then(p => console.log(p));
return postRepository.findById(savedPost.id).should.eventually.eql({
id: savedPost.id,
text: "Hello post",