Add new conditions and concatenation to FilterBuilder
[arvados-workbench2.git] / src / common / api / filter-builder.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as _ from "lodash";
6 import { Resource } from "./common-resource-service";
7
8 export default class FilterBuilder<T extends Resource = Resource> {
9
10     static create<T extends Resource = Resource>(resourcePrefix = "") {
11         return new FilterBuilder<T>(resourcePrefix);
12     }
13
14     constructor(
15         private resourcePrefix = "",
16         private filters = "") { }
17
18     public addEqual(field: keyof T, value?: string) {
19         return this.addCondition(field, "=", value);
20     }
21
22     public addLike(field: keyof T, value?: string) {
23         return this.addCondition(field, "like", value, "", "%");
24     }
25
26     public addILike(field: keyof T, value?: string) {
27         return this.addCondition(field, "ilike", value, "", "%");
28     }
29
30     public addIsA(field: keyof T, value?: string | string[]) {
31         return this.addCondition(field, "is_a", value);
32     }
33
34     public addIn(field: keyof T, value?: string | string[]) {
35         return this.addCondition(field, "in", value);
36     }
37
38     public concat<O extends Resource>(filterBuilder: FilterBuilder<O>) {
39         return new FilterBuilder(this.resourcePrefix, this.filters + this.getSeparator() + filterBuilder.getFilters());
40     }
41
42     public getFilters() {
43         return this.filters;
44     }
45
46     public serialize() {
47         return "[" + this.filters + "]";
48     }
49
50     private addCondition(field: keyof T, cond: string, value?: string | string[], prefix: string = "", postfix: string = "") {
51         if (value) {
52             value = typeof value === "string"
53                 ? `"${prefix}${value}${postfix}"`
54                 : `["${value.join(`","`)}"]`;
55
56             const resourcePrefix = this.resourcePrefix
57                 ? _.snakeCase(this.resourcePrefix) + "."
58                 : "";
59
60             this.filters += `${this.getSeparator()}["${resourcePrefix}${_.snakeCase(field.toString())}","${cond}",${value}]`;
61         }
62         return this;
63     }
64
65     private getSeparator () {
66         return this.filters ? "," : "";
67     }
68 }