-
Notifications
You must be signed in to change notification settings - Fork 20
/
Query.cls
110 lines (99 loc) · 3.54 KB
/
Query.cls
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
public class Query {
public enum Operator {
EQUALS,
NOT_EQUALS,
LESS_THAN,
LESS_THAN_OR_EQUAL,
GREATER_THAN,
GREATER_THAN_OR_EQUAL
}
private final SObjectField field;
private final Operator operator;
private final List<Object> predicates;
private static Boolean isSet = false;
private static final String EMPTY = '\'\'';
public Query(SObjectField field, Operator operator, Object predicate) {
this(field, operator, new List<Object>{ predicate });
}
public Query(SObjectField field, Operator operator, List<Object> predicates) {
this.field = field;
this.operator = operator;
this.predicates = predicates;
}
public override String toString() {
String fieldName = this.field.getDescribe().getName();
String predName = this.getPredicate(this.predicates);
return fieldName + ' ' + this.getOperator() + ' ' + predName;
}
public Boolean isEmpty() {
return this.getPredicate(this.predicates) == EMPTY;
}
public Boolean equals(Object thatObject) {
if(thatObject instanceof Query) {
Query that = (Query) thatObject;
return this.toString() == that.toString();
}
return false;
}
private String getOperator() {
Boolean isList = this.predicates.size() > 1;
switch on this.operator {
when EQUALS {
return isList || isSet ? 'in' : '=';
}
when NOT_EQUALS {
return isList || isSet ? 'not in' : '!=';
}
when LESS_THAN {
return '<';
}
when LESS_THAN_OR_EQUAL {
return '<=';
}
when GREATER_THAN {
return '>';
}
when GREATER_THAN_OR_EQUAL {
return '>=';
}
when else {
return null;
}
}
}
private String getPredicate(Object predicate) {
if(predicate == null) {
return 'null';
} else if(predicate instanceof Datetime) {
//the most annoying one
Datetime dt = (Datetime) predicate;
return dt.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'Greenwich Mean Time');
} else if(predicate instanceof List<Object>) {
List<Object> predicates = (List<Object>) predicate;
if(predicates.isEmpty()) {
return EMPTY;
}
List<String> innerStrings = new List<String>();
for(Object innerPred : predicates) {
//recurse for string value
String innerString = this.getPredicate(innerPred);
innerStrings.add(innerString);
}
String start = innerStrings.size() > 1 ? '(' : '';
String ending = innerStrings.size() > 1 ? ')' : '';
return start + String.join(innerStrings, ',') + ending;
} else if(predicate instanceof String) {
String input = (String) predicate;
return '\'' + String.escapeSingleQuotes(input) + '\'';
}
String predValue = String.valueOf(predicate);
//fun fact - you can detect a list
//but you can't detect a set!
if(predValue.startsWith('{') && predValue.endsWith('}')) {
List<String> setInner = predValue.substring(1, predValue.length() -1).split(',');
isSet = setInner.size() > 1;
return this.getPredicate(setInner);
}
return predValue;
}
}