Commit edf43239 authored by Lucas Fernandes de Oliveira's avatar Lucas Fernandes de Oliveira

Merge branch 'issue/39' into 'master'

Issue #39: Add MAX and MIN aggregations

See merge request !30
parents fb2c228f 47edbd30
Pipeline #11538 passed with stage
in 43 seconds
...@@ -93,6 +93,8 @@ schema: ...@@ -93,6 +93,8 @@ schema:
- "dim:6" - "dim:6"
metrics: metrics:
- "met:9" - "met:9"
- "met:10"
- "met:11"
- -
alias: "view 9" alias: "view 9"
data: "test/postgres/fixtures/view9.json" data: "test/postgres/fixtures/view9.json"
...@@ -146,6 +148,14 @@ schema: ...@@ -146,6 +148,14 @@ schema:
name: "met:9" name: "met:9"
dataType: "integer" dataType: "integer"
aggregation: "count" aggregation: "count"
-
name: "met:10"
dataType: "integer"
aggregation: "max"
-
name: "met:11"
dataType: "integer"
aggregation: "min"
dimensions: dimensions:
- -
name: "dim:0" name: "dim:0"
......
...@@ -166,6 +166,8 @@ describe("postgres adapter", () => { ...@@ -166,6 +166,8 @@ describe("postgres adapter", () => {
expect(parseInt(result[0]["met:0"], 10)).to.be.equal(15); 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:1"], 10)).to.be.equal(3);
expect(parseInt(result[0]["met:6"], 10)).to.be.equal(5); 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(); done();
}); });
}); });
......
...@@ -213,6 +213,10 @@ export class PostgresAdapter extends Adapter { ...@@ -213,6 +213,10 @@ export class PostgresAdapter extends Adapter {
return "AVG"; return "AVG";
case AggregationType.COUNT: case AggregationType.COUNT:
return (origin) ? "COUNT" : "SUM"; return (origin) ? "COUNT" : "SUM";
case AggregationType.MAX:
return "MAX";
case AggregationType.MIN:
return "MIN";
default: default:
return ""; return "";
} }
......
...@@ -22,7 +22,9 @@ export enum AggregationType { ...@@ -22,7 +22,9 @@ export enum AggregationType {
NONE, NONE,
SUM, SUM,
AVG, AVG,
COUNT COUNT,
MAX,
MIN
}; };
export enum RelationType { export enum RelationType {
......
...@@ -22,7 +22,6 @@ import { expect } from "chai"; ...@@ -22,7 +22,6 @@ import { expect } from "chai";
import { Engine } from "./engine"; import { Engine } from "./engine";
import { Metric } from "./metric"; import { Metric } from "./metric";
import { Dimension } from "./dimension";
import { Filter, FilterOperator } from "./filter"; import { Filter, FilterOperator } from "./filter";
import { Clause } from "./clause"; import { Clause } from "./clause";
import { View } from "./view"; import { View } from "./view";
...@@ -31,25 +30,33 @@ import { engineScenario } from "../../test/scenario"; ...@@ -31,25 +30,33 @@ import { engineScenario } from "../../test/scenario";
describe("engine class", () => { describe("engine class", () => {
const engine = new Engine(); const engine = new Engine();
const met = engineScenario.metrics; const met = engineScenario.metrics.sort((a, b) => {
const dim = engineScenario.dimensions; const aValue = parseInt(a.name.split(":")[1], 10);
const subdim = engineScenario.subDimensions; 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; const views = engineScenario.views;
for (let i = 0; i < 10; ++i) { met.forEach((item) => engine.addMetric(item));
engine.addMetric(met[i]); dim.forEach((item) => engine.addDimension(item));
engine.addDimension(dim[i]); subdim.forEach((item) => engine.addDimension(item));
if (i < 5) {
engine.addDimension(subdim[i]);
}
}
views.forEach((view) => engine.addView(view)); views.forEach((view) => engine.addView(view));
it("should be create a fill that cover all metrics and dimensions", () => { it("should be create a fill that cover all metrics and dimensions", () => {
let query = { let query = {
metrics : met metrics : met.slice(0)
, dimensions : dim , dimensions : dim.slice(0)
}; };
let optimalView = engine.query(query); let optimalView = engine.query(query);
expect(optimalView).to.be.an("object"); expect(optimalView).to.be.an("object");
...@@ -59,20 +66,8 @@ describe("engine class", () => { ...@@ -59,20 +66,8 @@ describe("engine class", () => {
expect(optimalView.metrics).to.be.an("array"); expect(optimalView.metrics).to.be.an("array");
expect(optimalView.dimensions).to.be.an("array"); expect(optimalView.dimensions).to.be.an("array");
expect(optimalView.childViews).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); 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", () => { it("should throw an exception, query with non-existent metric", () => {
let error: boolean = false; let error: boolean = false;
......
...@@ -271,6 +271,10 @@ export class ConfigParser { ...@@ -271,6 +271,10 @@ export class ConfigParser {
return AggregationType.AVG; return AggregationType.AVG;
case "count": case "count":
return AggregationType.COUNT; return AggregationType.COUNT;
case "min":
return AggregationType.MIN;
case "max":
return AggregationType.MAX;
default: default:
return AggregationType.NONE; return AggregationType.NONE;
} }
......
[ [
{"dim:5":"t","dim:6":"1","met:9":"1"}, {"dim:5":"t","dim:6":"1","met:9":"1","met:10":"1","met:11":"1"},
{"dim:5":"t","dim:6":"2","met:9":"2"}, {"dim:5":"t","dim:6":"2","met:9":"2","met:10":"2","met:11":"2"},
{"dim:5":"t","dim:6":"3","met:9":"3"}, {"dim:5":"t","dim:6":"3","met:9":"3","met:10":"3","met:11":"3"},
{"dim:5":"f","dim:6":"4","met:9":"4"}, {"dim:5":"f","dim:6":"4","met:9":"4","met:10":"4","met:11":"4"},
{"dim:5":"f","dim:6":"5","met:9":"5"} {"dim:5":"f","dim:6":"5","met:9":"5","met:10":"5","met:11":"5"}
] ]
...@@ -127,7 +127,7 @@ const clauses: { [key: string]: Clause } = { ...@@ -127,7 +127,7 @@ const clauses: { [key: string]: Clause } = {
}; };
const wrongMet = new Metric({ const wrongMet = new Metric({
name: "met:11", name: "met:-1",
aggregation: AggregationType.COUNT, aggregation: AggregationType.COUNT,
dataType: "integer" dataType: "integer"
}); });
...@@ -204,11 +204,11 @@ const dateView = new View({ ...@@ -204,11 +204,11 @@ const dateView = new View({
}); });
const aggrView = 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: [], dimensions: [],
materialized: false, materialized: false,
origin: 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({ const clauseView = new View({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment