Skip to content
Snippets Groups Projects
Select Git revision
  • develop default protected
  • tg-felipe
  • issue/97
  • issue/63
  • icde-2019-experiments
  • issue/85
  • master
  • issue/20
  • refactor/engine
  • issue/6
  • feature/diagrams
  • wip-transformers
12 results

postgres.ts

Blame
  • Forked from C3SL / blendb
    182 commits behind the upstream repository.
    postgres.ts 4.67 KiB
    /*
     * 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  "";
            }
    
        }
    }