| 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122 |
2x
88x
88x
88x
88x
92x
92x
92x
10x
10x
10x
28x
28x
28x
10x
82x
10x
10x
10x
20x
20x
20x
10x
72x
4x
4x
4x
4x
4x
68x
4x
4x
4x
4x
4x
4x
4x
4x
64x
640x
62x
62x
62x
92x
2x
2x
88x
36x
36x
36x
36x
4x
4x
4x
6x
6x
6x
4x
4x
| // @flow
import { forIn } from "lodash";
import { CharGenerator } from "./CharGenerator";
const singlePredicates = {
$sw: "STARTS WITH",
$ew: "ENDS WITH",
$contains: "CONTAINS",
$reg: "=~",
$eq: "=",
$in: "IN",
$gt: ">",
$gte: ">=",
$lt: "<",
$lte: "<=",
};
function _prepareWhere(
props: any,
variable: string
): { where: string[], flatProps: any } {
const where = [];
let flatProps = {};
Iif (!props) {
return { where: [], flatProps: {} };
}
forIn(props, (v, k) => {
const propChar = CharGenerator.next();
let found = false;
if (v.$or) {
found = true;
const whereOr = [];
for (const predicate of v.$or) {
const tmp = _prepareWhere({ [k]: predicate }, variable);
whereOr.push(...tmp.where);
flatProps = { ...flatProps, ...tmp.flatProps };
}
where.push(`(${whereOr.join(" OR ")})`);
} else if (v.$and) {
found = true;
const whereAnd = [];
for (const predicate of v.$and) {
const tmp = _prepareWhere({ [k]: predicate }, variable);
whereAnd.push(...tmp.where);
flatProps = { ...flatProps, ...tmp.flatProps };
}
where.push(`(${whereAnd.join(" AND ")})`);
} else if (v.$not) {
found = true;
const tmp = _prepareWhere({ [k]: v.$not }, variable);
Eif (tmp.where.length) {
where.push(`NOT ${tmp.where[0]}`);
flatProps = { ...flatProps, ...tmp.flatProps };
}
} else if (v.$between) {
found = true;
Eif (v.$between.length === 2) {
const [num1, num2] = v.$between;
const a = propChar;
const b = CharGenerator.next();
where.push(`{${a}} <= ${variable}.${k} <= {${b}}`);
flatProps[a] = num1 > num2 ? num2 : num1;
flatProps[b] = num1 > num2 ? num1 : num2;
}
// TODO error? flow should actually be able to handle this...
} else {
forIn(singlePredicates, (predicateString, predicateKey) => {
if (v[predicateKey]) {
found = true;
where.push(`${variable}.${k} ${predicateString} {${propChar}}`);
flatProps[propChar] = v[predicateKey];
}
});
}
if (!found) {
where.push(`${variable}.${k} = {${propChar}}`);
flatProps[propChar] = v;
}
});
return { where, flatProps };
}
export function prepareWhere(
props: any,
variable: string
): { where: string, flatProps: any } {
CharGenerator.start("a");
const { where, flatProps } = _prepareWhere(props, variable);
Iif (where.length === 0) {
return { where: "", flatProps: undefined };
}
return { where: "WHERE " + where.join(" AND "), flatProps };
}
export function prepareSet(
variable: string,
props: any
): { str: string, newProps: any } {
const sets = [];
const newProps: any = {};
forIn(props, (v, k) => {
Iif (k === "guid") return null;
sets.push(`${variable}.${k}={_u${k}}`);
newProps[`_u${k}`] = v;
});
Iif (!sets.length) throw new Error(`Nothing to update`);
return { str: sets.join(", "), newProps };
}
|