FilterBuilder

Date: 2021-01-27
(() => {
    const getEq = (a, b) => `[${a}] = '${b}'`;
    const getOr = (...args) => `(${Array.from(args).join(" OR ")})`;
    const getAnd = (...args) => `(${Array.from(args).join(" AND ")})`;
    const getWhere = (...args) => `WHERE ${Array.from(args).join(" AND ")}`;

    const eq = (a, b) => getEq(a, b);
    const and = (...args) => getAnd(...args);
    const or = (...args) => getOr(...args);
    const where = (...args) => getWhere(...args);

    const result = where(eq("Name", "x"), or(eq("Age", "12"), and(eq("Name", "empty"), eq("Name", "e"))));
    console.log(result);
    //> WHERE [Name] = 'x' AND ([Age] = '12' OR ([Name] = 'empty' AND [Name] = 'e'))
})();
export interface IVariableResult {
    getValue(): any;
}

export interface IBooleanResult {
    evaluate(): boolean;
    asString(): string;
}

export interface IBooleanProvider {
    field(name: string): IVariableResult;
    var(value: string): IVariableResult;
    val(value: string): IVariableResult;

    eq(a: IVariableResult, b: IVariableResult): IBooleanResult;
    notEq(a: IVariableResult, b: IVariableResult): IBooleanResult;
    not(a: IBooleanResult): IBooleanResult;

    greaterThen(a: IVariableResult, b: IVariableResult): IBooleanResult;
    greaterThenEquals(a: IVariableResult, b: IVariableResult): IBooleanResult;
    lessThen(a: IVariableResult, b: IVariableResult): IBooleanResult;
    lessThenEquals(a: IVariableResult, b: IVariableResult): IBooleanResult;

    contains(a: IVariableResult, b: Array<IVariableResult>): IBooleanResult;
    notContains(a: IVariableResult, b: Array<IVariableResult>): IBooleanResult;

    and(...args: Array<IBooleanResult>): IBooleanResult;
    or(...args: Array<IBooleanResult>): IBooleanResult;
    where(...args: Array<IBooleanResult>): IBooleanResult;
}

export class VariableResult implements IVariableResult {
    s: string;
    constructor(s: string) {
        this.s = s;
    }
    getValue() {
        return this.s;
    }
}

export class BooleanResult implements IBooleanResult {
    s: string;
    constructor(s: string) {
        this.s = s;
    }
    evaluate(): boolean {
        throw new Error("Method not implemented.");
    }
    asString(): string {
        return this.s;
    }
}

export class BooleanProvider implements IBooleanProvider {
    field(name: string): IVariableResult {
        return new VariableResult(`[${name}]`);
    }
    var(name: string): IVariableResult {
        return new VariableResult(`:${name}]`);
    }
    val(value: any): IVariableResult {
        if (typeof value === null) {
            return new VariableResult('NULL');
        }
        if (typeof value === 'number') {
            return new VariableResult(`'${value}'`);
        }
        return new VariableResult(`'${String(value).replace(/'/g, "''")}'`);
    }

    eq(a: IVariableResult, b: IVariableResult): IBooleanResult {
        return new BooleanResult(`${a.getValue()} = ${b.getValue()}`);
    }
    notEq(a: IVariableResult, b: IVariableResult): IBooleanResult {
        return new BooleanResult(`${a.getValue()} != ${b.getValue()}`);
    }
    not(a: IBooleanResult): IBooleanResult {
        return new BooleanResult(`!(${a.asString()})`);
    }
    greaterThen(a: IVariableResult, b: IVariableResult): IBooleanResult {
        return new BooleanResult(`${a.getValue()} > ${b.getValue()}`);
    }
    greaterThenEquals(a: IVariableResult, b: IVariableResult): IBooleanResult {
        return new BooleanResult(`${a.getValue()} >= ${b.getValue()}`);
    }
    lessThen(a: IVariableResult, b: IVariableResult): IBooleanResult {
        return new BooleanResult(`${a.getValue()} < ${b.getValue()}`);
    }
    lessThenEquals(a: IVariableResult, b: IVariableResult): IBooleanResult {
        return new BooleanResult(`${a.getValue()} <= ${b.getValue()}`);
    }
    contains(a: IVariableResult, b: IVariableResult[]): IBooleanResult {
        return new BooleanResult(`${a.getValue()} IN (${b.map(x => x.getValue()).join(",")})`);
    }
    notContains(a: IVariableResult, b: IVariableResult[]): IBooleanResult {
        return new BooleanResult(`${a.getValue()} NOT IN (${b.map(x => x.getValue()).join(",")})`);
    }
    and(...args: IBooleanResult[]): IBooleanResult {
        return new BooleanResult(`(${Array.from(args).map(x => x.asString()).join(" AND ")})`);
    }
    or(...args: IBooleanResult[]): IBooleanResult {
        return new BooleanResult(`(${Array.from(args).map(x => x.asString()).join(" OR ")})`);
    }
    where(...args: IBooleanResult[]): IBooleanResult {
        return new BooleanResult(`WHERE ${Array.from(args).map(x => x.asString()).join(" AND ")}`);
    }
}

var p = new BooleanProvider();

const field = p.field.bind(p);
const val = p.val.bind(p);

const eq = p.eq.bind(p);
const and = p.and.bind(p);
const or = p.or.bind(p);
const where = p.where.bind(p);

const result = where(
    eq(field("Name"), val("x")),
    or(
        eq(field("Age"), val(12)),
        and(
            eq(field("Name"), val("I like to 'move' it")),
            eq(field("Name"), val("e")))
    )
);

console.log("=====================");
console.log(result.asString());
console.log("=====================");
45060cookie-checkFilterBuilder