Select Git revision
configParser.ts
-
Lucas Fernandes de Oliveira authored
Signed-off-by:
Lucas Fernandes de Oliveira <lfo14@inf.ufpr.br>
Lucas Fernandes de Oliveira authoredSigned-off-by:
Lucas Fernandes de Oliveira <lfo14@inf.ufpr.br>
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;
}
}
}