Skip to content
Snippets Groups Projects

Issue #6: Create selector of optimal View and sql query generator for Postgres adpter

Merged Issue #6: Create selector of optimal View and sql query generator for Postgres adpter
11 unresolved threads
Merged Lucas Fernandes de Oliveira requested to merge issue/6 into master
11 unresolved threads
7 files
+ 518
0
Compare changes
  • Side-by-side
  • Inline
Files
7
+ 137
0
 
/*
 
* Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
 
* Departamento de Informatica - Universidade Federal do Parana
 
*
 
* This file is part of blend.
 
*
 
* blend is free software: you can redistribute it and/or modify
 
* it under the terms of the GNU General Public License as published by
 
* the Free Software Foundation, either version 3 of the License, or
 
* (at your option) any later version.
 
*
 
* blend is distributed in the hope that it will be useful,
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
* GNU General Public License for more details.
 
*
 
* You should have received a copy of the GNU General Public License
 
* along with blend. If not, see <http://www.gnu.org/licenses/>.
 
*/
 
 
import { View } from "../core/view";
 
import { Adapter } from "../core/adapter";
 
import { AggregationType } from "../common/aggregationType";
 
 
interface ParsedView {
 
query: string;
 
view: View;
 
};
 
 
export class PostgresAdapter extends Adapter{
 
public getDataFromView(view: View): string {
 
// buildQueryFromView does not put the final ;, it need to be put apart
 
return this.buildQueryFromView(view) + ";\n";
 
}
 
 
public materializeView(view: View): string {
 
return null;
 
}
 
 
private buildQueryFromView (view: View): string {
 
let sql = "(\n";
 
let metrics = view.metrics.map((metric: string) => {
 
let aggrType = view.getAggregationtype(metric);
 
let func = this.getAggregateFunction(aggrType);
 
let extMetric = func + "(" + metric + ")";
 
return extMetric;
 
});
 
 
if (view.materialized) {
 
sql += "SELECT " + metrics.join(", ") + ", " + dimensions.join(", ") + "\n";
 
sql += "FROM " + "view_" + view.id + "\n";
 
sql += "GROUP BY " + view.dimensions.join(", ") + "\n";
 
sql += ")\n";
 
return sql;
 
}
 
 
else {
 
let children: ParsedView[] = view.childViews.map((item: View, idx: number) => {
 
return {
 
query: this.queryfyView(item, childAlias, degree + 1),
 
view: item
 
};
 
});
 
 
let covered = new Map();
 
view.dimensions.forEach((item: string) => covered.set(item, ""));
 
view.metrics.forEach((item: string) => covered.set(item, ""));
 
 
let projection = "SELECT ";
 
let viewsFrom = "FROM";
 
let selection = "WHERE ";
 
let grouping = "GROUP BY ";
 
 
let elements = [];
 
let group = [];
 
 
children.forEach((child: ParsedView) => {
 
let selected = [];
 
child.view.dimensions.forEach((dimension: string) => {
 
let first = covered.get(dimension);
 
let extDimension = "view_" + child.view.id + "." + dimension;
 
if (first === "") {
 
covered.set(dimension, child.view.id);
 
elements.push(extDimension);
 
group.push(extDimension);
 
}
 
 
else {
 
let extFirst = "view_" + first + "." + dimension;
 
selected.push(extDimension + " = " + extFirst);
 
}
 
});
 
 
child.view.metrics.forEach((metric: string) => {
 
let first = covered.get(metric);
 
let aggrType = child.view.getAggregateFunction(metric);
 
let func = this.geAggregateFunction(aggrType);
 
let extMetric = func + "(view_" + child.view.id + "." + metric + ")";
 
if (first === "") {
 
covered.set(metric, child.view.id);
 
elements.push(extMetric);
 
}
 
 
});
 
 
viewsFrom += "\n" + child.query;
 
 
if (selected.length > 0) {
 
selection += selected.join(" AND ");
 
}
 
});
 
 
projection += elements.join(", ") + "\n";
 
selection += "\n";
 
grouping += group.join(", ") + "\n";
 
 
sql += projection + viewsFrom + selection + grouping + ")";
 
return sql;
 
}
 
 
return sql;
 
}
 
 
private getAggregateFunction(aggrType: AggregationType): string {
 
switch (aggrType) {
 
case AggregationType.SUM:
 
return "SUM";
 
case AggregationType.AVG:
 
return "AVG";
 
case AggregationType.COUNT:
 
return "COUNT";
 
default:
 
return "";
 
}
 
 
}
 
}
Loading