Merge branch 'master'
[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 "../../models/resource";
7
8 export class FilterBuilder<T extends Resource = Resource> {
9     static create<T extends Resource = Resource>(resourcePrefix = "") {
10         return new FilterBuilder<T>(resourcePrefix);
11     }
12
13     constructor(
14         private resourcePrefix = "",
15         private filters = "") { }
16
17     public addEqual(field: keyof T, value?: string) {
18         return this.addCondition(field, "=", value);
19     }
20
21     public addLike(field: keyof T, value?: string) {
22         return this.addCondition(field, "like", value, "%", "%");
23     }
24
25     public addILike(field: keyof T, value?: string) {
26         return this.addCondition(field, "ilike", value, "%", "%");
27     }
28
29     public addIsA(field: keyof T, value?: string | string[]) {
30         return this.addCondition(field, "is_a", value);
31     }
32
33     public addIn(field: keyof T, value?: string | string[]) {
34         return this.addCondition(field, "in", value);
35     }
36
37     public concat<O extends Resource>(filterBuilder: FilterBuilder<O>) {
38         return new FilterBuilder(this.resourcePrefix, this.filters + (this.filters && filterBuilder.filters ? "," : "") + filterBuilder.getFilters());
39     }
40
41     public getFilters() {
42         return this.filters;
43     }
44
45     public serialize() {
46         return "[" + this.filters + "]";
47     }
48
49     private addCondition(field: keyof T, cond: string, value?: string | string[], prefix: string = "", postfix: string = "") {
50         if (value) {
51             value = typeof value === "string"
52                 ? `"${prefix}${value}${postfix}"`
53                 : `["${value.join(`","`)}"]`;
54
55             const resourcePrefix = this.resourcePrefix
56                 ? _.snakeCase(this.resourcePrefix) + "."
57                 : "";
58
59             this.filters += `${this.filters ? "," : ""}["${resourcePrefix}${_.snakeCase(field.toString())}","${cond}",${value}]`;
60         }
61         return this;
62     }
63 }