clause.ts 2.69 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Copyright (C) 2017 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 { Filter } from "./filter";
import { Hash } from "../util/hash";
23 24
import { Dimension } from "./dimension";
import { Metric } from "./metric";
25

26
/** Parameters used to create a Clause object. */
27
export interface ClauseOptions {
28
    /** Set of filters that form the clause. */
29 30 31
    filters: Filter[];
}

32
/** Set of restrictions applied to a query united by the operator OR. */
33
export class Clause {
34
    /** Hash of components that unique identify the clause. */
35
    public readonly id: string;
36
    /** Set of filters the form the clause. */
37
    public readonly filters: Filter[];
38
    /** Set of attributes affected by this clause. */
39
    public readonly targets: (Metric|Dimension)[];
40

41 42 43 44
    /**
     * Create a clause object.
     * @param options - Parameters required to create a clause object.
     */
45
    constructor (options: ClauseOptions) {
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
        this.filters = options.filters.map((i) => i);
        const t = this.filters.map((i) => i.target).sort((a, b) => {
            return (a.name < b.name) ? -1 : 1;
        });
        if (t.length > 0) {
            this.targets = [t[0]];
            for (let i = 1; i < t.length; ++i) {
                if (t[i - 1] !== t[i])  {
                    this.targets.push(t[i]);
                }
            }
        }
        else {
            this.targets = [];
        }
61 62 63 64
        const filtersIds = this.filters.map((item) => item.id);
        this.id = Hash.sha1(filtersIds.sort());
    }

65 66 67 68 69 70 71 72
    /**
     * Checks if the targets of this clause is a sub set of
     * the given coverage set.
     * In other words, this clause could be applied to a view
     * which has the coverage set as set of metrics and dimensions
     * @param coverage - Set of attributes which will be verified if
     * contain all targets in the clause.
     */
73
    public isCovered(coverage: (Metric|Dimension)[]): boolean {
74
        return this.targets.every((i) => coverage.some((j) => i.name === j.name));
75
    }
76
}