| 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 |
1x
44x
44x
44x
44x
46x
46x
46x
5x
5x
5x
14x
14x
14x
5x
41x
5x
5x
5x
10x
10x
10x
5x
36x
2x
2x
2x
2x
2x
34x
2x
2x
2x
2x
2x
2x
2x
2x
32x
320x
31x
31x
31x
46x
1x
1x
44x
18x
18x
18x
18x
| // @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) => {
if (k === "guid") return null;
sets.push(`${variable}.${k}={_u${k}}`);
newProps[`_u${k}`] = v;
});
if (!sets.length) throw new Error(`Nothing to update`);
return { str: sets.join(" "), newProps };
}
|