Issue #27: Fix count aggregation

Signed-off-by: Lucas Fernandes de Oliveira's avatarLucas Fernandes de Oliveira <lfo14@inf.ufpr.br>
parent 562d002f
Pipeline #11089 passed with stage
in 46 seconds
......@@ -17,6 +17,7 @@ schema:
-
alias: "View 0"
data: "test/postgres/fixtures/view0.json"
origin: true
dimensions:
- "dim:0"
- "dim:7"
......@@ -27,6 +28,7 @@ schema:
-
alias: "View 1"
data: "test/postgres/fixtures/view1.json"
origin: true
dimensions:
- "dim:1"
- "dim:8"
......@@ -36,6 +38,7 @@ schema:
-
alias: "View 2"
data: "test/postgres/fixtures/view2.json"
origin: true
dimensions:
- "dim:2"
metrics:
......@@ -44,6 +47,7 @@ schema:
-
alias: "View 3"
data: "test/postgres/fixtures/view3.json"
origin: true
dimensions:
- "dim:2"
- "dim:3"
......@@ -51,6 +55,7 @@ schema:
-
alias: "View 4"
data: "test/postgres/fixtures/view4.json"
origin: true
dimensions:
- "dim:2"
- "dim:7"
......@@ -58,6 +63,7 @@ schema:
-
alias: "View 5"
data: "test/postgres/fixtures/view5.json"
origin: true
dimensions:
- "dim:3"
metrics:
......@@ -65,6 +71,7 @@ schema:
-
alias: "View 6"
data: "test/postgres/fixtures/view6.json"
origin: true
dimensions:
- "dim:4"
metrics:
......@@ -72,6 +79,7 @@ schema:
-
alias: "View 7"
data: "test/postgres/fixtures/view7.json"
origin: true
dimensions:
- "dim:4"
- "dim:5"
......@@ -79,6 +87,7 @@ schema:
-
alias: "View 8"
data: "test/postgres/fixtures/view8.json"
origin: true
dimensions:
- "dim:5"
- "dim:6"
......
......@@ -148,4 +148,25 @@ describe("postgres adapter", () => {
done();
});
});
it("should get data from view with all types of agreggation", (done) => {
let view = adapterScenario.aggrView;
adapter.getDataFromView(view, (err, result) => {
expect(err).to.be.a("null");
expect(result).to.be.an("array");
expect(result).to.have.length(1);
expect(result[0]).to.be.an("object");
let keys: string[] = [];
keys = keys.concat(view.metrics.map((item) => item.name));
keys = keys.concat(view.dimensions.map((item) => item.name));
result.forEach((row) => {
expect(row).to.be.an("object");
expect(row).to.have.all.keys(keys);
});
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);
done();
});
});
});
......@@ -66,7 +66,7 @@ export class PostgresAdapter extends Adapter {
view. So is possible only get useful data in the sub-querys.
*/
let strMetrics = metrics.map((metric) => {
let func = this.getAggregateFunction(metric.aggregation);
let func = this.getAggregateFunction(metric.aggregation, view.origin);
let quotedName = "\"" + metric.name + "\"";
let extMetric = func + "(" + quotedName + ") AS " + quotedName;
return extMetric;
......@@ -167,7 +167,8 @@ export class PostgresAdapter extends Adapter {
});
child.metrics.forEach((metric: Metric) => {
let func = this.getAggregateFunction(metric.aggregation);
// Only materialized views can have origin as true
let func = this.getAggregateFunction(metric.aggregation, false);
let quotedName = "\"" + metric.name + "\"";
let extMetric = func + "(" + child.alias + "." + quotedName + ") AS " + quotedName;
elements.push(extMetric);
......@@ -189,14 +190,14 @@ export class PostgresAdapter extends Adapter {
}
}
private getAggregateFunction(aggrType: AggregationType): string {
private getAggregateFunction(aggrType: AggregationType, origin: boolean): string {
switch (aggrType) {
case AggregationType.SUM:
return "SUM";
case AggregationType.AVG:
return "AVG";
case AggregationType.COUNT:
return "COUNT";
return (origin) ? "COUNT" : "SUM";
default:
return "";
}
......
......@@ -112,6 +112,7 @@ export class Engine {
metrics: q.metrics,
dimensions: q.dimensions,
materialized: false,
origin: false, // Never a dynamic generated view will be origin
childViews: optimalViews
};
......
......@@ -36,6 +36,7 @@ export interface ChildView {
export interface ViewOptions {
metrics: Metric[];
dimensions: Dimension[];
origin: boolean;
materialized?: boolean;
childViews?: ChildView[];
}
......@@ -45,12 +46,14 @@ export class View {
public readonly metrics: Metric[];
public readonly dimensions: Dimension[];
public readonly materialized: boolean;
public readonly origin: boolean;
public childViews: ChildView[];
constructor (options: ViewOptions) {
this.metrics = options.metrics.sort();
this.dimensions = options.dimensions.sort();
this.materialized = options.materialized || false;
this.origin = options.origin || false;
this.childViews = (options.childViews) ? options.childViews : [];
// calculate the id of the view based on it's metrics and dimensions
......
......@@ -29,6 +29,7 @@ import * as yaml from "js-yaml";
export interface ViewParsingOptions {
alias: string;
data: string;
origin?: boolean;
dimensions: string[];
metrics: string[];
}
......@@ -127,6 +128,7 @@ export class ConfigParser {
metrics: [],
dimensions: [],
materialized: true,
origin: opts.origin,
childViews: [],
};
......
......@@ -93,16 +93,19 @@ describe("graph class", () => {
new View({
metrics: [],
dimensions: [dims[0], dims[1]],
origin: true,
materialized: true
}),
new View({
metrics: [],
dimensions: [dims[2], dims[3]],
origin: true,
materialized: true
}),
new View({
metrics: [],
dimensions: dims,
origin: true,
materialized: true
})
];
......@@ -127,6 +130,7 @@ describe("graph class", () => {
let view = new View({
metrics: [],
dimensions: [dims[0], dims[1]],
origin: true,
materialized: true
});
......@@ -148,6 +152,7 @@ describe("graph class", () => {
let view = new View({
metrics: [],
dimensions: dims,
origin: true,
materialized: true
});
......@@ -169,6 +174,7 @@ describe("graph class", () => {
let view = new View({
metrics: [],
dimensions: [dim],
origin: true,
materialized: true
});
......@@ -186,6 +192,7 @@ describe("graph class", () => {
let view = new View({
metrics: [],
dimensions: [dim],
origin: true,
materialized: true
});
......@@ -220,31 +227,37 @@ describe("graph class", () => {
new View({
metrics: [mets[0]],
dimensions: [dims[0]],
origin: true,
materialized: true
}),
new View({
metrics: [mets[1]],
dimensions: [dims[1]],
origin: true,
materialized: true
}),
new View({
metrics: [mets[2]],
dimensions: [dims[2]],
origin: true,
materialized: true
}),
new View({
metrics: [],
dimensions: dims,
origin: true,
materialized: true
}),
new View({
metrics: mets,
dimensions: dims,
origin: true,
materialized: true
}),
new View({
metrics: [mets[0], mets[1]],
dimensions: [dims[0], dims[1]],
origin: true,
materialized: true
}),
];
......@@ -286,6 +299,7 @@ describe("graph class", () => {
let view = new View({
metrics: [],
dimensions: [dims[0]],
origin: true,
materialized: true
});
......@@ -324,6 +338,7 @@ describe("graph class", () => {
let view = new View({
metrics: [],
dimensions: [dims[0]],
origin: true,
materialized: true
});
......
......@@ -41,6 +41,7 @@ interface AdapterScenario {
subDimensionView: View;
join4View: View;
dateView: View;
aggrView: View;
}
interface DataCtrlScenario {
......@@ -128,6 +129,7 @@ const dateView = new View({
metrics: [],
dimensions: dateSubDim,
materialized: false,
origin: false,
childViews: [{
view: views[0],
metrics: [],
......@@ -135,10 +137,30 @@ const dateView = new View({
}]
});
const aggrView = new View({
metrics: [mets[0], mets[1], mets[6]],
dimensions: [],
materialized: false,
origin: false,
childViews: [
{
view: views[0],
metrics: [mets[0], mets[1]],
dimensions: []
},
{
view: views[2],
metrics: [mets[6]],
dimensions: []
}
]
});
const subDimView = new View({
metrics: [mets[0]],
dimensions: [subdims[0], subdims[1], dims[7], dims[8]],
materialized: false,
origin: false,
childViews: [
{
view: views[0],
......@@ -162,6 +184,7 @@ const join4View = new View({
metrics: [mets[0], mets[1], mets[2], mets[3], mets[4], mets[5]],
dimensions: [dims[2], dims[7], dims[8]],
materialized: false,
origin: false,
childViews: [
{
view: views[0],
......@@ -190,6 +213,7 @@ const noSelView = new View({
metrics: [mets[0], mets[3]],
dimensions: [],
materialized: false,
origin: false,
childViews: [
{
view: views[0],
......@@ -208,6 +232,7 @@ const withSelView = new View({
metrics: [mets[0], mets[1]],
dimensions: [dims[7], dims[8]],
materialized: false,
origin: false,
childViews: [
{
view: views[0],
......@@ -237,7 +262,8 @@ export const adapterScenario: AdapterScenario = {
withSelectionView: withSelView,
subDimensionView: subDimView,
join4View: join4View,
dateView: dateView
dateView: dateView,
aggrView: aggrView
};
export const dataCtrlScenario: DataCtrlScenario = {
......
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