Skip to content

Commit d1d50c6

Browse files
committed
Added unionAll
1 parent 2742729 commit d1d50c6

File tree

6 files changed

+59
-5
lines changed

6 files changed

+59
-5
lines changed

src/model/EntityQuery.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,22 @@ export default class EntityQuery<T = any>
177177
});
178178
}
179179

180+
unionAll(... p: any[]) {
181+
182+
const p1 = Expression.parameter("p1", this.selectStatement.model);
183+
184+
return new EntityQuery({
185+
... this,
186+
selectStatement: {
187+
... this.selectStatement,
188+
where: null,
189+
joins: null,
190+
sourceParameter: p1,
191+
source: Expression.unionAll( this.selectStatement, ... p.map((x) => x.selectStatement))
192+
},
193+
});
194+
}
195+
180196
innerJoin(p, fx): any {
181197

182198
const pq = p as EntityQuery<any>;

src/model/IFilterWithParameter.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ export interface IBaseQuery<T> {
5555

5656
trace<DT>(this: DT, tracer: (text: string) => void): DT;
5757

58+
unionAll<DT>(this: DT, ... p: DT[]): DT;
59+
5860
/**
5961
* Inserts current sql statement into given entity source.
6062
* @param this query

src/query/ast/ExpressionToSql.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -765,16 +765,17 @@ export default class ExpressionToSql extends Visitor<ITextQuery> {
765765
}
766766

767767
visitUnionAllStatement(e: UnionAllStatement): ITextQuery {
768-
const all: ITextQuery = [];
768+
const all: ITextQuery = ["("];
769769
let first = true;
770770
for (const iterator of e.queries) {
771-
all.push(this.visit(iterator));
772-
if (first) {
771+
if (!first) {
772+
all.push(" UNION ALL ");
773+
} else {
773774
first = false;
774-
continue;
775775
}
776-
all.push(" UNION ALL ");
776+
all.push(this.visit(iterator));
777777
}
778+
all.push(")");
778779
return all;
779780
}
780781

src/query/ast/Expressions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ export abstract class Expression {
103103
return BinaryExpression.create({ left, right, operator: "=", assign: true});
104104
}
105105

106+
static unionAll(...queries: Expression[]) {
107+
return UnionAllStatement.create({
108+
queries
109+
});
110+
}
111+
106112
static create<T extends Expression>(this: IClassOf<T>, p: Partial<Omit<T, "type">>) {
107113
(p as any).type = (this as any).name;
108114
Object.setPrototypeOf(p, this.prototype);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import assert from "assert";
2+
import { TestConfig } from "../../TestConfig.js";
3+
import { createContext, headPhoneCategory, maleClothesCategory } from "../../model/createContext.js";
4+
import IdentityService from "../../../model/identity/IdentityService.js";
5+
import { User } from "../../model/ShoppingContext.js";
6+
7+
export default async function(this: TestConfig) {
8+
9+
if (!this.db) {
10+
return;
11+
}
12+
13+
const context = await createContext(this.driver);
14+
15+
context.changeSet.clear();
16+
17+
const pq = context.productCategories.where({ headPhoneCategory }, (p) => (x) => x.categoryID === p.headPhoneCategory);
18+
19+
const r = pq
20+
.unionAll(context.productCategories.where({ maleClothesCategory }, (p) => (x) => x.category.parentID === p.maleClothesCategory))
21+
.trace(console.log);
22+
23+
const n = await r.count();
24+
25+
assert(n > 0);
26+
27+
}

src/tests/model/createContext.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ function addFemaleClothes(context: ShoppingContext, owner: User) {
154154
});
155155
}
156156

157+
158+
export const maleClothesCategory = "clothes/male";
157159
function addMaleClothes(context: ShoppingContext, owner: User) {
158160
const category = context.categories.add({
159161
name: "Male Clothes",

0 commit comments

Comments
 (0)