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

configParser.ts

Blame
  • configParser.ts 6.47 KiB
    /*
     * Copyright (C) 2017 Centro de Computacao Cientifica e Software Livre
     * Departamento de Informatica - Universidade Federal do Parana
     *
     * This file is part of blendb.
     *
     * blendb 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.
     *
     * blendb 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 blendb.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    import { Metric, MetricOptions } from "../core/metric";
    import { Dimension, DimensionOptions } from "../core/dimension";
    import { View, ViewOptions, LoadView } from "../core/view";
    import { AggregationType, RelationType } from "../common/types";
    import { PoolConfig } from "pg";
    import * as fs from "fs";
    import * as yaml from "js-yaml";
    
    export interface ViewParsingOptions {
        alias: string;
        data: string;
        origin?: boolean;
        dimensions: string[];
        metrics: string[];
    }
    
    interface MetricStrOptions {
        name: string;
        aggregation: string;
        dataType: string;
    }
    
    export interface DimensionStrOptions {
        name: string;
        dataType: string;
        parent?: string;
        relation?: string;
    }
    
    interface ConfigSchema {
        views: ViewParsingOptions[];
        metrics: MetricStrOptions[];
        dimensions: DimensionStrOptions[];
    }
    
    interface ConfigFile {
        connection: PoolConfig;
        struct: LoadStruct;
        schema: ConfigSchema;
    }
    
    export interface LoadStruct{
        create: boolean;
        insert: boolean;
    }
    
    export interface ParsedConfig {
        connection: PoolConfig;
        views: View[];
        metrics: Metric[];
        dimensions: Dimension[];
        struct: LoadStruct;
        loadViews: LoadView[];
    }
    
    export class ConfigParser {
        public static parse(configPath: string): ParsedConfig {
            let config: ConfigFile = yaml.safeLoad(fs.readFileSync(configPath, {
                encoding: "utf-8"
            }));
    
            let metricsOpts = config.schema.metrics;
            let viewsOpts = config.schema.views;
            let dimensionsOpts = config.schema.dimensions;
            let parsed: ParsedConfig = {
                connection: config.connection,
                views: [],
                metrics: [],
                dimensions: [],
                struct: config.struct,
                loadViews: []
            };
    
            let metMap: Map<string, Metric> = new Map();
            let dimMap: Map<string, Dimension> = new Map();
    
            for (let i = 0; i < metricsOpts.length; ++i) {
                let met = new Metric(this.parseMetOpts(metricsOpts[i]));
                parsed.metrics.push(met);
                metMap.set(met.name, met);
            }
    
            for (let i = 0; i < dimensionsOpts.length; ++i) {
                let dim = new Dimension(this.parseDimOpts(dimensionsOpts[i], parsed.dimensions));
                parsed.dimensions.push(dim);
                dimMap.set(dim.name, dim);
            }
    
            for (let i = 0; i < viewsOpts.length; ++i) {
                if (!viewsOpts[i].metrics) {
                    viewsOpts[i].metrics = [];
                }
                let viewOpts = ConfigParser.parseViewOpt(viewsOpts[i], metMap, dimMap);
                let view = new View(viewOpts);
                parsed.views.push(view);
                let loadView: LoadView = {view: view, data: viewsOpts[i].data};
                parsed.loadViews.push(loadView);
            }
    
            return parsed;
        }
    
        public static parseViewOpt(opts: ViewParsingOptions,
                                   metMap: Map<string, Metric>,
                                   dimMap: Map<string, Dimension>): ViewOptions {
    
            let viewOpt: ViewOptions = {
                metrics: [],
                dimensions: [],
                materialized: true,
                origin: opts.origin,
                childViews: [],
            };
    
            for (let i = 0; i < opts.metrics.length; ++i) {
                if (metMap.has(opts.metrics[i])) {
                    viewOpt.metrics.push(metMap.get(opts.metrics[i]));
                }
    
                else {
                    throw new Error("[Parsing error] Non exist metric set to view " + opts.alias);
                }
            }
    
            for (let i = 0; i < opts.dimensions.length; ++i) {
                if (dimMap.has(opts.dimensions[i])) {
                    viewOpt.dimensions.push(dimMap.get(opts.dimensions[i]));
                }
    
                else {
                    throw new Error("[Parsing error] Non exist dimension set to view " + opts.alias);
                }
            }
            return viewOpt;
        }
    
        public static parseDimOpts (opts: DimensionStrOptions, dims: Dimension[]): DimensionOptions {
            if (opts.parent || opts.relation) {
                for (let i = 0; i < dims.length; ++i) {
                    if (dims[i].name === opts.parent) {
                        return {
                            name: opts.name,
                            dataType: opts.dataType,
                            parent: dims[i],
                            relation: this.strToRelationType(opts.relation)
                        };
                    }
                }
    
                throw new Error("[Parsing error] Parent for subdimension " + opts.name + "  not found");
            }
            return {
                name: opts.name,
                dataType: opts.dataType,
                parent: null,
                relation: RelationType.NONE
            };
        }
    
        private static parseMetOpts (opts: MetricStrOptions): MetricOptions {
            return {
                name: opts.name,
                aggregation: this.strToAggregationType(opts.aggregation),
                dataType : opts.dataType
            };
        }
    
        private static strToAggregationType (str: string): AggregationType {
            switch (str) {
                case "sum":
                    return AggregationType.SUM;
                case "avg":
                    return AggregationType.AVG;
                case "count":
                    return AggregationType.COUNT;
                default:
                    return AggregationType.NONE;
            }
        }
    
        private static strToRelationType (str: string): RelationType {
            switch (str) {
                case "day":
                    return RelationType.DAY;
                case "month":
                    return RelationType.MONTH;
                case "year":
                    return RelationType.YEAR;
                case "dayofweek":
                    return RelationType.DAYOFWEEK;
                default:
                    return RelationType.NONE;
            }
        }
    }