From 47edbd303f6e889b2ea887ef1c7cc63cb1b5f972 Mon Sep 17 00:00:00 2001 From: Lucas Fernandes de Oliveira <lfo14@inf.ufpr.br> Date: Fri, 18 Aug 2017 11:30:12 -0300 Subject: [PATCH] Issue #39: Add MAX and MIN aggregations Signed-off-by: Lucas Fernandes de Oliveira <lfo14@inf.ufpr.br> --- config/ci_test.yaml.example | 10 +++++++ src/adapter/postgres.spec.ts | 2 ++ src/adapter/postgres.ts | 4 +++ src/common/types.ts | 4 ++- src/core/engine.spec.ts | 47 ++++++++++++++----------------- src/util/configParser.ts | 4 +++ test/postgres/fixtures/view8.json | 10 +++---- test/scenario.ts | 6 ++-- 8 files changed, 52 insertions(+), 35 deletions(-) diff --git a/config/ci_test.yaml.example b/config/ci_test.yaml.example index 8bab1978..f9f7ef30 100644 --- a/config/ci_test.yaml.example +++ b/config/ci_test.yaml.example @@ -93,6 +93,8 @@ schema: - "dim:6" metrics: - "met:9" + - "met:10" + - "met:11" - alias: "view 9" data: "test/postgres/fixtures/view9.json" @@ -146,6 +148,14 @@ schema: name: "met:9" dataType: "integer" aggregation: "count" + - + name: "met:10" + dataType: "integer" + aggregation: "max" + - + name: "met:11" + dataType: "integer" + aggregation: "min" dimensions: - name: "dim:0" diff --git a/src/adapter/postgres.spec.ts b/src/adapter/postgres.spec.ts index e002335d..4db63388 100644 --- a/src/adapter/postgres.spec.ts +++ b/src/adapter/postgres.spec.ts @@ -166,6 +166,8 @@ describe("postgres adapter", () => { expect(parseInt(result[0]["met:0"], 10)).to.be.equal(15); expect(parseInt(result[0]["met:1"], 10)).to.be.equal(3); expect(parseInt(result[0]["met:6"], 10)).to.be.equal(5); + expect(parseInt(result[0]["met:10"], 10)).to.be.equal(5); + expect(parseInt(result[0]["met:11"], 10)).to.be.equal(1); done(); }); }); diff --git a/src/adapter/postgres.ts b/src/adapter/postgres.ts index 0c326896..9035c374 100644 --- a/src/adapter/postgres.ts +++ b/src/adapter/postgres.ts @@ -213,6 +213,10 @@ export class PostgresAdapter extends Adapter { return "AVG"; case AggregationType.COUNT: return (origin) ? "COUNT" : "SUM"; + case AggregationType.MAX: + return "MAX"; + case AggregationType.MIN: + return "MIN"; default: return ""; } diff --git a/src/common/types.ts b/src/common/types.ts index 9757e7af..661fce35 100644 --- a/src/common/types.ts +++ b/src/common/types.ts @@ -22,7 +22,9 @@ export enum AggregationType { NONE, SUM, AVG, - COUNT + COUNT, + MAX, + MIN }; export enum RelationType { diff --git a/src/core/engine.spec.ts b/src/core/engine.spec.ts index 4498640c..95812055 100644 --- a/src/core/engine.spec.ts +++ b/src/core/engine.spec.ts @@ -22,7 +22,6 @@ import { expect } from "chai"; import { Engine } from "./engine"; import { Metric } from "./metric"; -import { Dimension } from "./dimension"; import { Filter, FilterOperator } from "./filter"; import { Clause } from "./clause"; import { View } from "./view"; @@ -31,25 +30,33 @@ import { engineScenario } from "../../test/scenario"; describe("engine class", () => { const engine = new Engine(); - const met = engineScenario.metrics; - const dim = engineScenario.dimensions; - const subdim = engineScenario.subDimensions; + const met = engineScenario.metrics.sort((a, b) => { + const aValue = parseInt(a.name.split(":")[1], 10); + const bValue = parseInt(b.name.split(":")[1], 10); + return aValue - bValue; + }); + const dim = engineScenario.dimensions.sort((a, b) => { + const aValue = parseInt(a.name.split(":")[1], 10); + const bValue = parseInt(b.name.split(":")[1], 10); + return aValue - bValue; + }); + const subdim = engineScenario.subDimensions.sort((a, b) => { + const aValue = parseInt(a.name.split(":")[1], 10); + const bValue = parseInt(b.name.split(":")[1], 10); + return aValue - bValue; + }); const views = engineScenario.views; - for (let i = 0; i < 10; ++i) { - engine.addMetric(met[i]); - engine.addDimension(dim[i]); - if (i < 5) { - engine.addDimension(subdim[i]); - } - } + met.forEach((item) => engine.addMetric(item)); + dim.forEach((item) => engine.addDimension(item)); + subdim.forEach((item) => engine.addDimension(item)); views.forEach((view) => engine.addView(view)); it("should be create a fill that cover all metrics and dimensions", () => { let query = { - metrics : met - , dimensions : dim + metrics : met.slice(0) + , dimensions : dim.slice(0) }; let optimalView = engine.query(query); expect(optimalView).to.be.an("object"); @@ -59,20 +66,8 @@ describe("engine class", () => { expect(optimalView.metrics).to.be.an("array"); expect(optimalView.dimensions).to.be.an("array"); expect(optimalView.childViews).to.be.an("array"); - expect(optimalView.metrics).to.have.length(10); + expect(optimalView.metrics).to.have.length(12); expect(optimalView.dimensions).to.have.length(9); - let metAux: number[] = optimalView.metrics.sort().map((item: Metric) => { - return Number(item.name.split(":")[1]); - }); - let dimAux: number[] = optimalView.dimensions.sort().map((item: Dimension) => { - return Number(item.name.split(":")[1]); - }); - - for (let i: number = 0; i < 9; ++i) { - expect(dimAux[i]).to.be.equal(i); - expect(metAux[i]).to.be.equal(i); - } - expect(metAux[9]).to.be.equal(9); }); it("should throw an exception, query with non-existent metric", () => { let error: boolean = false; diff --git a/src/util/configParser.ts b/src/util/configParser.ts index 83105036..e2d10ec9 100644 --- a/src/util/configParser.ts +++ b/src/util/configParser.ts @@ -271,6 +271,10 @@ export class ConfigParser { return AggregationType.AVG; case "count": return AggregationType.COUNT; + case "min": + return AggregationType.MIN; + case "max": + return AggregationType.MAX; default: return AggregationType.NONE; } diff --git a/test/postgres/fixtures/view8.json b/test/postgres/fixtures/view8.json index 40725b32..6d4641c9 100644 --- a/test/postgres/fixtures/view8.json +++ b/test/postgres/fixtures/view8.json @@ -1,7 +1,7 @@ [ -{"dim:5":"t","dim:6":"1","met:9":"1"}, -{"dim:5":"t","dim:6":"2","met:9":"2"}, -{"dim:5":"t","dim:6":"3","met:9":"3"}, -{"dim:5":"f","dim:6":"4","met:9":"4"}, -{"dim:5":"f","dim:6":"5","met:9":"5"} +{"dim:5":"t","dim:6":"1","met:9":"1","met:10":"1","met:11":"1"}, +{"dim:5":"t","dim:6":"2","met:9":"2","met:10":"2","met:11":"2"}, +{"dim:5":"t","dim:6":"3","met:9":"3","met:10":"3","met:11":"3"}, +{"dim:5":"f","dim:6":"4","met:9":"4","met:10":"4","met:11":"4"}, +{"dim:5":"f","dim:6":"5","met:9":"5","met:10":"5","met:11":"5"} ] diff --git a/test/scenario.ts b/test/scenario.ts index 0d1be6fb..0a48d94e 100644 --- a/test/scenario.ts +++ b/test/scenario.ts @@ -127,7 +127,7 @@ const clauses: { [key: string]: Clause } = { }; const wrongMet = new Metric({ - name: "met:11", + name: "met:-1", aggregation: AggregationType.COUNT, dataType: "integer" }); @@ -204,11 +204,11 @@ const dateView = new View({ }); const aggrView = new View({ - metrics: [mets[0], mets[1], mets[6]], + metrics: [mets[0], mets[1], mets[6], mets[10], mets[11]], dimensions: [], materialized: false, origin: false, - childViews: [views[0], views[2], views[4]] + childViews: [views[0], views[2], views[3], views[4], views[7], views[8]] }); const clauseView = new View({ -- GitLab