Skip to content
Snippets Groups Projects
Commit f26a4419 authored by Lucas Fernandes de Oliveira's avatar Lucas Fernandes de Oliveira
Browse files

Issue #27: Fix count aggregation

parent 562d002f
No related branches found
No related tags found
1 merge request!19Issue #27: Fix count aggregation
Pipeline #
...@@ -17,6 +17,7 @@ schema: ...@@ -17,6 +17,7 @@ schema:
- -
alias: "View 0" alias: "View 0"
data: "test/postgres/fixtures/view0.json" data: "test/postgres/fixtures/view0.json"
origin: true
dimensions: dimensions:
- "dim:0" - "dim:0"
- "dim:7" - "dim:7"
...@@ -27,6 +28,7 @@ schema: ...@@ -27,6 +28,7 @@ schema:
- -
alias: "View 1" alias: "View 1"
data: "test/postgres/fixtures/view1.json" data: "test/postgres/fixtures/view1.json"
origin: true
dimensions: dimensions:
- "dim:1" - "dim:1"
- "dim:8" - "dim:8"
...@@ -36,6 +38,7 @@ schema: ...@@ -36,6 +38,7 @@ schema:
- -
alias: "View 2" alias: "View 2"
data: "test/postgres/fixtures/view2.json" data: "test/postgres/fixtures/view2.json"
origin: true
dimensions: dimensions:
- "dim:2" - "dim:2"
metrics: metrics:
...@@ -44,6 +47,7 @@ schema: ...@@ -44,6 +47,7 @@ schema:
- -
alias: "View 3" alias: "View 3"
data: "test/postgres/fixtures/view3.json" data: "test/postgres/fixtures/view3.json"
origin: true
dimensions: dimensions:
- "dim:2" - "dim:2"
- "dim:3" - "dim:3"
...@@ -51,6 +55,7 @@ schema: ...@@ -51,6 +55,7 @@ schema:
- -
alias: "View 4" alias: "View 4"
data: "test/postgres/fixtures/view4.json" data: "test/postgres/fixtures/view4.json"
origin: true
dimensions: dimensions:
- "dim:2" - "dim:2"
- "dim:7" - "dim:7"
...@@ -58,6 +63,7 @@ schema: ...@@ -58,6 +63,7 @@ schema:
- -
alias: "View 5" alias: "View 5"
data: "test/postgres/fixtures/view5.json" data: "test/postgres/fixtures/view5.json"
origin: true
dimensions: dimensions:
- "dim:3" - "dim:3"
metrics: metrics:
...@@ -65,6 +71,7 @@ schema: ...@@ -65,6 +71,7 @@ schema:
- -
alias: "View 6" alias: "View 6"
data: "test/postgres/fixtures/view6.json" data: "test/postgres/fixtures/view6.json"
origin: true
dimensions: dimensions:
- "dim:4" - "dim:4"
metrics: metrics:
...@@ -72,6 +79,7 @@ schema: ...@@ -72,6 +79,7 @@ schema:
- -
alias: "View 7" alias: "View 7"
data: "test/postgres/fixtures/view7.json" data: "test/postgres/fixtures/view7.json"
origin: true
dimensions: dimensions:
- "dim:4" - "dim:4"
- "dim:5" - "dim:5"
...@@ -79,6 +87,7 @@ schema: ...@@ -79,6 +87,7 @@ schema:
- -
alias: "View 8" alias: "View 8"
data: "test/postgres/fixtures/view8.json" data: "test/postgres/fixtures/view8.json"
origin: true
dimensions: dimensions:
- "dim:5" - "dim:5"
- "dim:6" - "dim:6"
......
...@@ -148,4 +148,25 @@ describe("postgres adapter", () => { ...@@ -148,4 +148,25 @@ describe("postgres adapter", () => {
done(); 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 { ...@@ -66,7 +66,7 @@ export class PostgresAdapter extends Adapter {
view. So is possible only get useful data in the sub-querys. view. So is possible only get useful data in the sub-querys.
*/ */
let strMetrics = metrics.map((metric) => { let strMetrics = metrics.map((metric) => {
let func = this.getAggregateFunction(metric.aggregation); let func = this.getAggregateFunction(metric.aggregation, view.origin);
let quotedName = "\"" + metric.name + "\""; let quotedName = "\"" + metric.name + "\"";
let extMetric = func + "(" + quotedName + ") AS " + quotedName; let extMetric = func + "(" + quotedName + ") AS " + quotedName;
return extMetric; return extMetric;
...@@ -167,7 +167,8 @@ export class PostgresAdapter extends Adapter { ...@@ -167,7 +167,8 @@ export class PostgresAdapter extends Adapter {
}); });
child.metrics.forEach((metric: Metric) => { 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 quotedName = "\"" + metric.name + "\"";
let extMetric = func + "(" + child.alias + "." + quotedName + ") AS " + quotedName; let extMetric = func + "(" + child.alias + "." + quotedName + ") AS " + quotedName;
elements.push(extMetric); elements.push(extMetric);
...@@ -189,14 +190,14 @@ export class PostgresAdapter extends Adapter { ...@@ -189,14 +190,14 @@ export class PostgresAdapter extends Adapter {
} }
} }
private getAggregateFunction(aggrType: AggregationType): string { private getAggregateFunction(aggrType: AggregationType, origin: boolean): string {
switch (aggrType) { switch (aggrType) {
case AggregationType.SUM: case AggregationType.SUM:
return "SUM"; return "SUM";
case AggregationType.AVG: case AggregationType.AVG:
return "AVG"; return "AVG";
case AggregationType.COUNT: case AggregationType.COUNT:
return "COUNT"; return (origin) ? "COUNT" : "SUM";
default: default:
return ""; return "";
} }
......
...@@ -112,6 +112,7 @@ export class Engine { ...@@ -112,6 +112,7 @@ export class Engine {
metrics: q.metrics, metrics: q.metrics,
dimensions: q.dimensions, dimensions: q.dimensions,
materialized: false, materialized: false,
origin: false, // Never a dynamic generated view will be origin
childViews: optimalViews childViews: optimalViews
}; };
......
...@@ -36,6 +36,7 @@ export interface ChildView { ...@@ -36,6 +36,7 @@ export interface ChildView {
export interface ViewOptions { export interface ViewOptions {
metrics: Metric[]; metrics: Metric[];
dimensions: Dimension[]; dimensions: Dimension[];
origin: boolean;
materialized?: boolean; materialized?: boolean;
childViews?: ChildView[]; childViews?: ChildView[];
} }
...@@ -45,12 +46,14 @@ export class View { ...@@ -45,12 +46,14 @@ export class View {
public readonly metrics: Metric[]; public readonly metrics: Metric[];
public readonly dimensions: Dimension[]; public readonly dimensions: Dimension[];
public readonly materialized: boolean; public readonly materialized: boolean;
public readonly origin: boolean;
public childViews: ChildView[]; public childViews: ChildView[];
constructor (options: ViewOptions) { constructor (options: ViewOptions) {
this.metrics = options.metrics.sort(); this.metrics = options.metrics.sort();
this.dimensions = options.dimensions.sort(); this.dimensions = options.dimensions.sort();
this.materialized = options.materialized || false; this.materialized = options.materialized || false;
this.origin = options.origin || false;
this.childViews = (options.childViews) ? options.childViews : []; this.childViews = (options.childViews) ? options.childViews : [];
// calculate the id of the view based on it's metrics and dimensions // calculate the id of the view based on it's metrics and dimensions
......
...@@ -29,6 +29,7 @@ import * as yaml from "js-yaml"; ...@@ -29,6 +29,7 @@ import * as yaml from "js-yaml";
export interface ViewParsingOptions { export interface ViewParsingOptions {
alias: string; alias: string;
data: string; data: string;
origin?: boolean;
dimensions: string[]; dimensions: string[];
metrics: string[]; metrics: string[];
} }
...@@ -127,6 +128,7 @@ export class ConfigParser { ...@@ -127,6 +128,7 @@ export class ConfigParser {
metrics: [], metrics: [],
dimensions: [], dimensions: [],
materialized: true, materialized: true,
origin: opts.origin,
childViews: [], childViews: [],
}; };
......
...@@ -93,16 +93,19 @@ describe("graph class", () => { ...@@ -93,16 +93,19 @@ describe("graph class", () => {
new View({ new View({
metrics: [], metrics: [],
dimensions: [dims[0], dims[1]], dimensions: [dims[0], dims[1]],
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: [], metrics: [],
dimensions: [dims[2], dims[3]], dimensions: [dims[2], dims[3]],
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: [], metrics: [],
dimensions: dims, dimensions: dims,
origin: true,
materialized: true materialized: true
}) })
]; ];
...@@ -127,6 +130,7 @@ describe("graph class", () => { ...@@ -127,6 +130,7 @@ describe("graph class", () => {
let view = new View({ let view = new View({
metrics: [], metrics: [],
dimensions: [dims[0], dims[1]], dimensions: [dims[0], dims[1]],
origin: true,
materialized: true materialized: true
}); });
...@@ -148,6 +152,7 @@ describe("graph class", () => { ...@@ -148,6 +152,7 @@ describe("graph class", () => {
let view = new View({ let view = new View({
metrics: [], metrics: [],
dimensions: dims, dimensions: dims,
origin: true,
materialized: true materialized: true
}); });
...@@ -169,6 +174,7 @@ describe("graph class", () => { ...@@ -169,6 +174,7 @@ describe("graph class", () => {
let view = new View({ let view = new View({
metrics: [], metrics: [],
dimensions: [dim], dimensions: [dim],
origin: true,
materialized: true materialized: true
}); });
...@@ -186,6 +192,7 @@ describe("graph class", () => { ...@@ -186,6 +192,7 @@ describe("graph class", () => {
let view = new View({ let view = new View({
metrics: [], metrics: [],
dimensions: [dim], dimensions: [dim],
origin: true,
materialized: true materialized: true
}); });
...@@ -220,31 +227,37 @@ describe("graph class", () => { ...@@ -220,31 +227,37 @@ describe("graph class", () => {
new View({ new View({
metrics: [mets[0]], metrics: [mets[0]],
dimensions: [dims[0]], dimensions: [dims[0]],
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: [mets[1]], metrics: [mets[1]],
dimensions: [dims[1]], dimensions: [dims[1]],
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: [mets[2]], metrics: [mets[2]],
dimensions: [dims[2]], dimensions: [dims[2]],
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: [], metrics: [],
dimensions: dims, dimensions: dims,
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: mets, metrics: mets,
dimensions: dims, dimensions: dims,
origin: true,
materialized: true materialized: true
}), }),
new View({ new View({
metrics: [mets[0], mets[1]], metrics: [mets[0], mets[1]],
dimensions: [dims[0], dims[1]], dimensions: [dims[0], dims[1]],
origin: true,
materialized: true materialized: true
}), }),
]; ];
...@@ -286,6 +299,7 @@ describe("graph class", () => { ...@@ -286,6 +299,7 @@ describe("graph class", () => {
let view = new View({ let view = new View({
metrics: [], metrics: [],
dimensions: [dims[0]], dimensions: [dims[0]],
origin: true,
materialized: true materialized: true
}); });
...@@ -324,6 +338,7 @@ describe("graph class", () => { ...@@ -324,6 +338,7 @@ describe("graph class", () => {
let view = new View({ let view = new View({
metrics: [], metrics: [],
dimensions: [dims[0]], dimensions: [dims[0]],
origin: true,
materialized: true materialized: true
}); });
......
...@@ -41,6 +41,7 @@ interface AdapterScenario { ...@@ -41,6 +41,7 @@ interface AdapterScenario {
subDimensionView: View; subDimensionView: View;
join4View: View; join4View: View;
dateView: View; dateView: View;
aggrView: View;
} }
interface DataCtrlScenario { interface DataCtrlScenario {
...@@ -128,6 +129,7 @@ const dateView = new View({ ...@@ -128,6 +129,7 @@ const dateView = new View({
metrics: [], metrics: [],
dimensions: dateSubDim, dimensions: dateSubDim,
materialized: false, materialized: false,
origin: false,
childViews: [{ childViews: [{
view: views[0], view: views[0],
metrics: [], metrics: [],
...@@ -135,10 +137,30 @@ const dateView = new View({ ...@@ -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({ const subDimView = new View({
metrics: [mets[0]], metrics: [mets[0]],
dimensions: [subdims[0], subdims[1], dims[7], dims[8]], dimensions: [subdims[0], subdims[1], dims[7], dims[8]],
materialized: false, materialized: false,
origin: false,
childViews: [ childViews: [
{ {
view: views[0], view: views[0],
...@@ -162,6 +184,7 @@ const join4View = new View({ ...@@ -162,6 +184,7 @@ const join4View = new View({
metrics: [mets[0], mets[1], mets[2], mets[3], mets[4], mets[5]], metrics: [mets[0], mets[1], mets[2], mets[3], mets[4], mets[5]],
dimensions: [dims[2], dims[7], dims[8]], dimensions: [dims[2], dims[7], dims[8]],
materialized: false, materialized: false,
origin: false,
childViews: [ childViews: [
{ {
view: views[0], view: views[0],
...@@ -190,6 +213,7 @@ const noSelView = new View({ ...@@ -190,6 +213,7 @@ const noSelView = new View({
metrics: [mets[0], mets[3]], metrics: [mets[0], mets[3]],
dimensions: [], dimensions: [],
materialized: false, materialized: false,
origin: false,
childViews: [ childViews: [
{ {
view: views[0], view: views[0],
...@@ -208,6 +232,7 @@ const withSelView = new View({ ...@@ -208,6 +232,7 @@ const withSelView = new View({
metrics: [mets[0], mets[1]], metrics: [mets[0], mets[1]],
dimensions: [dims[7], dims[8]], dimensions: [dims[7], dims[8]],
materialized: false, materialized: false,
origin: false,
childViews: [ childViews: [
{ {
view: views[0], view: views[0],
...@@ -237,7 +262,8 @@ export const adapterScenario: AdapterScenario = { ...@@ -237,7 +262,8 @@ export const adapterScenario: AdapterScenario = {
withSelectionView: withSelView, withSelectionView: withSelView,
subDimensionView: subDimView, subDimensionView: subDimView,
join4View: join4View, join4View: join4View,
dateView: dateView dateView: dateView,
aggrView: aggrView
}; };
export const dataCtrlScenario: DataCtrlScenario = { export const dataCtrlScenario: DataCtrlScenario = {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment