Skip to content

Commit d40b69a

Browse files
committed
#279 - Adicionar opção no database-builder para permitir concatenar colunas em uma projeção ou where.
1 parent 20b95f1 commit d40b69a

7 files changed

Lines changed: 148 additions & 24 deletions

File tree

src/core/projections-helper.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Projection } from "../crud/enums/projection";
2-
import { ExpressionOrColumn, TypeProjection, Utils } from "./utils";
2+
import { ExpressionOrColumn, ExpressionProjection, Utils } from "./utils";
33
import { ProjectionsUtils } from "./projections-utils";
44
import { ProjectionCompiled } from "../crud/projection-compiled";
55

@@ -21,13 +21,29 @@ export class ProjectionsHelper<T> {
2121
return this._result;
2222
}
2323

24+
public exp<TReturn>(
25+
expression?: ExpressionOrColumn<TReturn, T>,
26+
alias: string = "",
27+
args?: any[]
28+
): ProjectionsHelper<T> {
29+
return this.getResult(this._projectionsUtils.apply(expression, [], alias, args));
30+
}
31+
32+
public concat(
33+
alias: string,
34+
...projections: Array<ExpressionProjection<any, T>>
35+
): ProjectionsHelper<T> {
36+
return this.group(alias, ...projections);
37+
}
38+
2439
public group(
2540
alias: string,
26-
...projections: Array<TypeProjection<T>>
41+
...projections: Array<ExpressionProjection<any, T>>
2742
): ProjectionsHelper<T> {
2843
const projectionsCompiled = new ProjectionCompiled();
2944
projections.forEach((projection) => {
30-
const compiled = Utils.resolveProjection(projection);
45+
const compiled = Utils.resolveExpressionProjection(projection);
46+
// const compiled = Utils.resolveProjection(projection);
3147
projectionsCompiled.projection += `${compiled.projection} `;
3248
projectionsCompiled.params = projectionsCompiled.params.concat(compiled.params);
3349
});

src/core/utils.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ export type TypeWhere<T> = Expression<T> | ValueTypeToParse | ColumnRef | Projec
2929

3030
export type TypeProjection<T> = ProjectionsHelper<T> | ColumnRef | PlanRef;
3131

32+
export type ExpressionProjection<TReturn, T> = TypeProjection<T> | ExpressionOrColumn<TReturn, T>;
33+
3234
export type ProjectionOrValue<T> = ProjectionBuilder<T> | ProjectionsHelper<T> | ValueTypeToParse;
3335

3436
export class Utils {
@@ -184,7 +186,8 @@ export class Utils {
184186
params: [expression]
185187
};
186188
case (ExpressionOrValueEnum.Projection):
187-
const compiled = this.resolveProjection(expression as ProjectionsHelper<T>);
189+
const compiled = this.resolveExpressionProjection(expression as ProjectionsHelper<T>);
190+
// const compiled = this.resolveProjection(expression as ProjectionsHelper<T>);
188191
return {
189192
column: compiled.projection,
190193
params: compiled.params
@@ -197,17 +200,34 @@ export class Utils {
197200
}
198201
}
199202

200-
public static resolveProjection<T>(expression: TypeProjection<T>): ProjectionCompiled {
201-
if (this.isProjectionsHelper(expression)) {
202-
return (expression as ProjectionsHelper<T>)._compiled();
203+
// public static resolveProjection<T>(projection: TypeProjection<T>): ProjectionCompiled {
204+
// if (this.isProjectionsHelper(projection)) {
205+
// return (projection as ProjectionsHelper<T>)._compiled();
206+
// }
207+
// if (this.isColumnRef(projection)) {
208+
// return new ProjectionCompiled((projection as ColumnRef).result());
209+
// }
210+
// if (this.isPlanRef(projection)) {
211+
// return new ProjectionCompiled((projection as PlanRef).result());
212+
// }
213+
// return new ProjectionCompiled(projection + "");
214+
// }
215+
216+
public static resolveExpressionProjection<TReturn, T>(projection: ExpressionProjection<TReturn, T>): ProjectionCompiled {
217+
if (this.isProjectionsHelper(projection)) {
218+
return (projection as ProjectionsHelper<T>)._compiled();
203219
}
204-
if (this.isColumnRef(expression)) {
205-
return new ProjectionCompiled((expression as ColumnRef).result());
220+
if (this.isColumnRef(projection)) {
221+
return new ProjectionCompiled((projection as ColumnRef).result());
206222
}
207-
if (this.isPlanRef(expression)) {
208-
return new ProjectionCompiled((expression as PlanRef).result());
223+
if (this.isPlanRef(projection)) {
224+
return new ProjectionCompiled((projection as PlanRef).result());
209225
}
210-
return new ProjectionCompiled(expression + "");
226+
// const expressionOrColumn = this.expressionOrColumn(projection as ExpressionOrColumn<TReturn, T>);
227+
// if(expressionOrColumn === ExpressionOrColumnEnum.Expression){
228+
// return this.getColumn(projection as Expression)
229+
// }
230+
return new ProjectionCompiled(this.getColumn(projection as ExpressionOrColumn<TReturn, T>));
211231
}
212232

213233
public static getValue<TReturn, T>(instance: any, expression: ExpressionOrColumn<TReturn, T>): TReturn {

src/crud/having-builder.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ export class HavingBuilder<T>
1717
}
1818

1919
protected getColumnParams(expression: ProjectionsHelper<T>): ColumnParams {
20-
const compiled = Utils.resolveProjection(expression);
20+
const compiled = Utils.resolveExpressionProjection(expression);
21+
// const compiled = Utils.resolveProjection(expression);
2122
return {
2223
column: compiled.projection,
2324
params: compiled.params

src/crud/projection-builder.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { PlanRef } from "../core/plan-ref";
1+
import { QueryCompiled } from "../core/query-compiled";
22
import { ProjectionsUtils } from "../core/projections-utils";
33
import { BuilderCompiled } from "../core/builder-compiled";
44
import { MapperTable } from "../mapper-table";
5-
import { ExpressionOrColumn, TypeProjection, Utils } from "../core/utils";
5+
import { ExpressionOrColumn, ExpressionProjection, Utils } from "../core/utils";
66
import { ColumnRef } from "../core/column-ref";
7-
import { QueryCompiled } from "../core/query-compiled";
7+
import { PlanRef } from "../core/plan-ref";
88
import { ProjectionCompiled } from "./projection-compiled";
99
import { Projection } from "./enums/projection";
1010
import { ProjectionCase } from "./projection-case";
@@ -44,10 +44,10 @@ export class ProjectionBuilder<T> {
4444
return new ProjectionsHelper(this._typeT, this._aliasTable, false);
4545
}
4646

47-
public ref<TReturn>(expression: ExpressionOrColumn<TReturn, T>): ColumnRef {
47+
public ref<TReturn>(expression: ExpressionOrColumn<TReturn, T>, alias: string = this._aliasTable): ColumnRef {
4848
return new ColumnRef(
4949
Utils.getColumn(expression),
50-
this._aliasTable
50+
alias
5151
);
5252
}
5353

@@ -57,7 +57,8 @@ export class ProjectionBuilder<T> {
5757

5858
public group(
5959
alias: string,
60-
...projections: Array<TypeProjection<T>>
60+
...projections: Array<ExpressionProjection<any, T>>
61+
// ...projections: Array<TypeProjection<T>>
6162
): ProjectionBuilder<T> {
6263
const groupCompiled = this.proj().group(alias, ...projections)._compiled();
6364
this.apply(

src/crud/query/query-builder-base.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ export abstract class QueryBuilderBase<T, TQuery extends QueryBuilderBase<T, TQu
8181
return Object.assign({ __proto__: (this._getInstance() as any).__proto__ }, this._getInstance());
8282
}
8383

84-
public ref<TReturn>(expression: ExpressionOrColumn<TReturn, T>): ColumnRef {
84+
public ref<TReturn>(expression: ExpressionOrColumn<TReturn, T>, alias: string = this.alias): ColumnRef {
8585
return new ColumnRef(
8686
Utils.getColumn(expression),
87-
this.alias
87+
alias
8888
);
8989
}
9090

src/crud/where-base-builder.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DatabaseHelper } from "../database-helper";
22
import { LambdaExpression } from "lambda-expression";
3-
import { Utils, ValueType, ValueTypeToParse } from "../core/utils";
3+
import { Utils, ValueType, ValueTypeToParse, ExpressionOrColumn, ExpressionProjection } from "../core/utils";
44
import { QueryCompilable } from "../core/query-compilable";
55
import { WhereCompiled } from "./where-compiled";
66
import { Condition } from "./enums/condition";
@@ -9,6 +9,7 @@ import { DatabaseBuilderError } from "../core/errors";
99
import { WhereBaseBuilderContract } from "./where-base-builder-contract";
1010
import { ColumnParams } from "../core/column-params";
1111
import { ColumnRef } from "../core/column-ref";
12+
import { ProjectionsHelper } from "../core/projections-helper";
1213

1314
export abstract class WhereBaseBuilder<
1415
T,
@@ -34,8 +35,25 @@ export abstract class WhereBaseBuilder<
3435
this._databaseHelper = new DatabaseHelper();
3536
}
3637

37-
public ref(column: string, alias: string = this._alias): ColumnRef {
38-
return new ColumnRef(column, alias);
38+
public proj(): ProjectionsHelper<T> {
39+
return new ProjectionsHelper(this._typeT, this._alias, false);
40+
}
41+
42+
public concat(
43+
...projections: Array<ExpressionProjection<any, T>>
44+
): ProjectionsHelper<T> {
45+
return this.proj().concat("", ...projections);
46+
}
47+
48+
// public ref(column: string, alias: string = this._alias): ColumnRef {
49+
// return new ColumnRef(column, alias);
50+
// }
51+
52+
public ref<TReturn>(expression: ExpressionOrColumn<TReturn, T>, alias: string = this._alias): ColumnRef {
53+
return new ColumnRef(
54+
Utils.getColumn(expression),
55+
alias
56+
);
3957
}
4058

4159
public not(): TWhere {

src/test/where.spec.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { JoinQueryBuilder } from "./../crud/query/join-query-builder";
12
import { ReferencesModelTest } from "./models/reference-model-test";
23
import { expect } from "chai";
34
import { TestClazz } from "./models/test-clazz";
@@ -492,4 +493,71 @@ describe("Where", () => {
492493
expect(result.query).to.equal("SELECT tes.* FROM TestClazz AS tes WHERE tes.id NOT IN (?, ?, ?, ?) AND tes.referenceTest_id IN (SELECT ref.id AS id FROM ReferencesModelTest AS ref WHERE ref.name = ?) OR (tes.description IN (?, ?) OR tes.disabled IN (?))");
493494
});
494495

496+
it("projection concat 1", () => {
497+
const query = new Query(TestClazz);
498+
query
499+
.projection(projection => {
500+
projection.group("iddescription", projection.proj().exp(x => x.id),
501+
projection.plan("||"), projection.proj().exp(x => x.description));
502+
})
503+
.where(where => {
504+
where.equal(x => x.id, 2);
505+
});
506+
const result = query.compile();
507+
expect(result.params.length).to.equal(1);
508+
expect(result.params[0]).to.equal(2);
509+
expect(result.query).to.equal("SELECT (tes.id || tes.description) AS iddescription FROM TestClazz AS tes WHERE tes.id = ?");
510+
});
511+
512+
it("projection concat 2", () => {
513+
const query = new Query(TestClazz);
514+
query
515+
.projection(projection => {
516+
projection.group("iddescription", projection.ref(x => x.id), "||", projection.ref(x => x.description));
517+
})
518+
.where(where => {
519+
where.equal(x => x.id, 2);
520+
});
521+
const result = query.compile();
522+
expect(result.params.length).to.equal(1);
523+
expect(result.params[0]).to.equal(2);
524+
expect(result.query).to.equal("SELECT (tes.id || tes.description) AS iddescription FROM TestClazz AS tes WHERE tes.id = ?");
525+
});
526+
527+
it("projection concat cross query", () => {
528+
const query = new Query(TestClazz);
529+
let joinReferenceModelTest: JoinQueryBuilder<ReferencesModelTest>;
530+
query.join(ReferencesModelTest,
531+
on => on.equal(x => x.id, query.ref(x => x.referenceTest.id)),
532+
join => {
533+
joinReferenceModelTest = join;
534+
});
535+
query
536+
.projection(projection => {
537+
projection.group("idname", projection.ref(x => x.id), "||", joinReferenceModelTest.ref(x => x.name));
538+
})
539+
.where(where => {
540+
where.equal(x => x.id, 2);
541+
});
542+
const result = query.compile();
543+
expect(result.params.length).to.equal(1);
544+
expect(result.params[0]).to.equal(2);
545+
expect(result.query).to.equal("SELECT (tes.id || ref.name) AS idname FROM TestClazz AS tes LEFT JOIN ReferencesModelTest AS ref ON (ref.id = tes.referenceTest_id) WHERE tes.id = ?");
546+
});
547+
548+
it("where concat", () => {
549+
const query = new Query(TestClazz);
550+
query
551+
.projection(projection => {
552+
projection.group("iddescription", projection.ref(x => x.id), "||", projection.ref(x => x.description));
553+
})
554+
.where(where => {
555+
where.equal(where.concat(where.ref(x => x.id), "||", where.ref(x => x.description)), 2 + "isso");
556+
});
557+
const result = query.compile();
558+
expect(result.params.length).to.equal(1);
559+
expect(result.params[0]).to.equal("2isso");
560+
expect(result.query).to.equal("SELECT (tes.id || tes.description) AS iddescription FROM TestClazz AS tes WHERE (tes.id || tes.description) = ?");
561+
});
562+
495563
});

0 commit comments

Comments
 (0)