@@ -19,10 +19,16 @@ public virtual class Query implements Querable {
19
19
public interface Querable extends Groupable {
20
20
Integer getCount ();
21
21
Integer getCount (AccessLevel accessLevel );
22
+ Integer getCount (Map <String , Object > bindingVars );
23
+ Integer getCount (Map <String , Object > bindingVars , AccessLevel accessLevel );
22
24
List <SObject > run ();
23
25
List <SObject > run (AccessLevel accessLevel );
26
+ List <SObject > run (Map <String , Object > bindingVars );
27
+ List <SObject > run (Map <String , Object > bindingVars , AccessLevel accessLevel );
24
28
Database.QueryLocator getLocator ();
25
29
Database.QueryLocator getLocator (AccessLevel accessLevel );
30
+ Database.QueryLocator getLocator (Map <String , Object > bindingVars );
31
+ Database.QueryLocator getLocator (Map <String , Object > bindingVars , AccessLevel accessLevel );
26
32
27
33
Query whereBy (Filter whereClause );
28
34
Query havingBy (Filter havingClause );
@@ -41,11 +47,12 @@ public virtual class Query implements Querable {
41
47
void buildSOQL_Filter (List <String > fragments , TmpVars tmpVars );
42
48
}
43
49
44
- public interface CompositeFilter extends Filter {
45
- CompositeFilter add (Filter filter );
50
+ public interface LogicalFilter extends Filter {
51
+ LogicalFilter add (Filter filter );
52
+ LogicalFilter addAll (List <Filter > filters );
46
53
}
47
54
48
- public class Literal {
55
+ public virtual class Literal {
49
56
public String literal { get ; set ; }
50
57
51
58
private Literal (String literal ) {
@@ -63,7 +70,7 @@ public virtual class Query implements Querable {
63
70
}
64
71
}
65
72
66
- public class TmpVars {
73
+ private class TmpVars {
67
74
Map <String , Object > bindingVars = new Map <String , Object >();
68
75
Integer tmpVarCount = 0 ;
69
76
@@ -75,6 +82,9 @@ public virtual class Query implements Querable {
75
82
}
76
83
}
77
84
85
+ private String soql { get ; set ; }
86
+ private TmpVars tmpVars { get ; set ; }
87
+
78
88
private String objectName { get ; set ; }
79
89
private List <Object > selectFields = new List <Object >();
80
90
private Map <String , Query > selectParent = new Map <String , Query >();
@@ -94,17 +104,17 @@ public virtual class Query implements Querable {
94
104
private Boolean updateViewstat { get ; set ; }
95
105
private Boolean forUpdate { get ; set ; }
96
106
97
- public static Query of (String objectName ) {
98
- return new Query (objectName );
99
- }
100
-
101
- public Query () {
107
+ protected Query () {
102
108
}
103
109
104
110
private Query (String objectName ) {
105
111
this .objectName = objectName ;
106
112
}
107
113
114
+ public static Query of (String objectName ) {
115
+ return new Query (objectName );
116
+ }
117
+
108
118
public Query whereBy (Filter whereClause ) {
109
119
this .whereClause = whereClause ;
110
120
return this ;
@@ -155,40 +165,87 @@ public virtual class Query implements Querable {
155
165
}
156
166
157
167
public Integer getCount (AccessLevel accessLevel ) {
158
- TmpVars tmpVars = new TmpVars ();
159
- return Database .countQueryWithBinds (this .buildSOQL (tmpVars ), tmpVars .bindingVars , accessLevel );
168
+ return this .getCount (null , accessLevel );
169
+ }
170
+
171
+ public Integer getCount (Map <String , Object > bindingVars ) {
172
+ return this .getCount (bindingVars , AccessLevel .SYSTEM_MODE );
173
+ }
174
+
175
+ public Integer getCount (Map <String , Object > bindingVars , AccessLevel accessLevel ) {
176
+ buildSOQL ();
177
+ if (bindingVars == null ) {
178
+ bindingVars = new Map <String , Object >();
179
+ }
180
+ bindingVars .putAll (this .tmpVars .bindingVars );
181
+
182
+ if (Test .isRunningTest ()) {
183
+ return 0 ;
184
+ }
185
+ return Database .countQueryWithBinds (this .soql , bindingVars , accessLevel );
160
186
}
161
187
162
188
public List <SObject > run () {
163
189
return this .run (AccessLevel .SYSTEM_MODE );
164
190
}
165
191
166
192
public List <SObject > run (AccessLevel accessLevel ) {
167
- TmpVars tmpVars = new TmpVars ();
168
- return Database .queryWithBinds (this .buildSOQL (tmpVars ), tmpVars .bindingVars , accessLevel );
193
+ return this .run (null , accessLevel );
194
+ }
195
+
196
+ public List <SObject > run (Map <String , Object > bindingVars ) {
197
+ return this .run (bindingVars , AccessLevel .SYSTEM_MODE );
198
+ }
199
+
200
+ public List <SObject > run (Map <String , Object > bindingVars , AccessLevel accessLevel ) {
201
+ buildSOQL ();
202
+ if (bindingVars == null ) {
203
+ bindingVars = new Map <String , Object >();
204
+ }
205
+ bindingVars .putAll (this .tmpVars .bindingVars );
206
+
207
+ if (Test .isRunningTest ()) {
208
+ return new List <SObject >();
209
+ }
210
+ return Database .queryWithBinds (this .soql , bindingVars , accessLevel );
169
211
}
170
212
171
213
public Database.QueryLocator getLocator () {
172
214
return this .getLocator (AccessLevel .SYSTEM_MODE );
173
215
}
174
216
175
217
public Database.QueryLocator getLocator (AccessLevel accessLevel ) {
176
- TmpVars tmpVars = new TmpVars ();
177
- return Database .getQueryLocatorWithBinds (this .buildSOQL (tmpVars ), tmpVars .bindingVars , accessLevel );
218
+ return this .getLocator (null , accessLevel );
178
219
}
179
220
180
- // ====================
181
- // #region SOQL Builder
221
+ public Database.QueryLocator getLocator (Map <String , Object > bindingVars ) {
222
+ return this .getLocator (bindingVars , AccessLevel .SYSTEM_MODE );
223
+ }
224
+
225
+ public Database.QueryLocator getLocator (Map <String , Object > bindingVars , AccessLevel accessLevel ) {
226
+ buildSOQL ();
227
+ if (bindingVars == null ) {
228
+ bindingVars = new Map <String , Object >();
229
+ }
230
+ bindingVars .putAll (this .tmpVars .bindingVars );
182
231
183
- public String build () {
184
- TmpVars tmpVars = new TmpVars ();
185
- return buildSOQL (tmpVars );
232
+ if (Test .isRunningTest ()) {
233
+ return null ;
234
+ }
235
+ return Database .getQueryLocatorWithBinds (this .soql , tmpVars .bindingVars , accessLevel );
186
236
}
187
237
188
- private String buildSOQL (TmpVars tmpVars ) {
189
- List <String > fragments = new List <String >();
190
- this .buildSOQL (fragments , tmpVars , this .objectName , 0 );
191
- return String .join (fragments , ' ' );
238
+ // ====================
239
+ // #region SOQL Builder
240
+
241
+ public String buildSOQL () {
242
+ if (this .soql == null ) {
243
+ this .tmpVars = new TmpVars ();
244
+ List <String > fragments = new List <String >();
245
+ this .buildSOQL (fragments , this .tmpVars , this .objectName , 0 );
246
+ this .soql = String .join (fragments , ' ' );
247
+ }
248
+ return this .soql ;
192
249
}
193
250
194
251
private void buildSOQL (List <String > fragments , TmpVars tmpVars , String fromName , Integer level ) {
@@ -342,21 +399,26 @@ public virtual class Query implements Querable {
342
399
// ====================
343
400
344
401
// =====================
345
- // #region Logical Filter
346
- private virtual class LogicalFilter implements CompositeFilter {
402
+ // #region Logic Filter
403
+ private virtual class LogicalFilterImpl implements LogicalFilter {
347
404
private List <Filter > filters { get ; set ; }
348
405
private String operator { get ; set ; }
349
406
350
- private LogicalFilter (String operator , List <Filter > filters ) {
407
+ private LogicalFilterImpl (String operator , List <Filter > filters ) {
351
408
this .operator = operator ;
352
409
this .filters = filters ;
353
410
}
354
411
355
- public CompositeFilter add (Filter filter ) {
412
+ public LogicalFilter add (Filter filter ) {
356
413
this .filters .add (filter );
357
414
return this ;
358
415
}
359
416
417
+ public LogicalFilter addAll (List <Filter > filters ) {
418
+ this .filters .addAll (filters );
419
+ return this ;
420
+ }
421
+
360
422
public virtual void buildSOQL_Filter (List <String > fragments , TmpVars tmpVars ) {
361
423
if (this .filters .isEmpty ()) {
362
424
return ;
@@ -376,15 +438,15 @@ public virtual class Query implements Querable {
376
438
}
377
439
}
378
440
379
- private class NotLogicalFilter extends LogicalFilter {
441
+ private class NotLogicalFilter extends LogicalFilterImpl {
380
442
private NotLogicalFilter (Filter filter ) {
381
443
super (' NOT' , new List <Filter >{ filter });
382
444
}
383
445
384
446
public override void buildSOQL_Filter (List <String > fragments , TmpVars tmpVars ) {
385
447
Filter filter = this .filters [0 ];
386
448
fragments .add (this .operator );
387
- if (filter instanceof CompositeFilter ) {
449
+ if (filter instanceof LogicalFilter ) {
388
450
filter .buildSOQL_Filter (fragments , tmpVars );
389
451
} else {
390
452
fragments .add (' (' );
@@ -398,20 +460,12 @@ public virtual class Query implements Querable {
398
460
return new NotLogicalFilter (filter );
399
461
}
400
462
401
- public static CompositeFilter orx () {
402
- return new LogicalFilter (' OR ' , new List <Filter >());
463
+ public static LogicalFilter orx () {
464
+ return new LogicalFilterImpl (' OR ' , new List <Filter >());
403
465
}
404
466
405
- public static CompositeFilter orx (List <Filter > filters ) {
406
- return new LogicalFilter (' OR ' , filters );
407
- }
408
-
409
- public static CompositeFilter andx () {
410
- return new LogicalFilter (' AND ' , new List <Filter >());
411
- }
412
-
413
- public static CompositeFilter andx (List <Filter > filters ) {
414
- return new LogicalFilter (' AND ' , filters );
467
+ public static LogicalFilter andx () {
468
+ return new LogicalFilterImpl (' AND ' , new List <Filter >());
415
469
}
416
470
417
471
// #endregion
@@ -468,7 +522,7 @@ public virtual class Query implements Querable {
468
522
}
469
523
470
524
private class NotLikeFilter extends ComparisonFilter {
471
- private NotLikeFilter (String fieldOrFunc , String value ) {
525
+ private NotLikeFilter (String fieldOrFunc , Object value ) {
472
526
super (fieldOrFunc , ' LIKE ' , value );
473
527
}
474
528
@@ -505,18 +559,11 @@ public virtual class Query implements Querable {
505
559
public static Filter eq (String fieldOrFunc , Object value ) {
506
560
return new ComparisonFilter (fieldOrFunc , ' = ' , value );
507
561
}
508
- public static Filter eqNull (String fieldOrFunc ) {
509
- return new ComparisonFilter (fieldOrFunc , ' = ' , null );
510
- }
511
562
512
563
public static Filter ne (String fieldOrFunc , Object value ) {
513
564
return new ComparisonFilter (fieldOrFunc , ' != ' , value );
514
565
}
515
566
516
- public static Filter neNull (String fieldOrFunc ) {
517
- return new ComparisonFilter (fieldOrFunc , ' != ' , null );
518
- }
519
-
520
567
public static Filter gt (String fieldOrFunc , Object value ) {
521
568
return new ComparisonFilter (fieldOrFunc , ' > ' , value );
522
569
}
@@ -533,6 +580,10 @@ public virtual class Query implements Querable {
533
580
return new ComparisonFilter (fieldOrFunc , ' <= ' , value );
534
581
}
535
582
583
+ public static Filter between (String fieldOrFunc , Object minValue , Object maxValue ) {
584
+ return andx ().add (gte (fieldOrFunc , minValue )).add (lte (fieldOrFunc , maxValue ));
585
+ }
586
+
536
587
public static Filter likex (String field , String value ) {
537
588
return new ComparisonFilter (field , ' LIKE ' , value );
538
589
}
@@ -557,8 +608,21 @@ public virtual class Query implements Querable {
557
608
return new MultiComparisonFilter (field , ' EXCLUDES ' , values );
558
609
}
559
610
560
- public static Filter between (String fieldOrFunc , Object minValue , Object maxValue ) {
561
- return andx ().add (gte (fieldOrFunc , minValue )).add (lte (fieldOrFunc , maxValue ));
611
+ // VarLiteral
612
+ public static Filter likex (String field , VarLiteral value ) {
613
+ return new ComparisonFilter (field , ' LIKE ' , value );
614
+ }
615
+
616
+ public static Filter nlike (String field , VarLiteral value ) {
617
+ return new NotLikeFilter (field , value );
618
+ }
619
+
620
+ public static Filter inx (String fieldOrFunc , VarLiteral values ) {
621
+ return new ComparisonFilter (fieldOrFunc , ' IN ' , values );
622
+ }
623
+
624
+ public static Filter nin (String fieldOrFunc , VarLiteral values ) {
625
+ return new ComparisonFilter (fieldOrFunc , ' NOT IN ' , values );
562
626
}
563
627
564
628
// #endregion
@@ -1141,6 +1205,9 @@ public virtual class Query implements Querable {
1141
1205
public interface CurrencyFunction extends SelectFunction {
1142
1206
}
1143
1207
1208
+ public interface TimezoneFunction {
1209
+ }
1210
+
1144
1211
public virtual class FunctionImpl implements Function {
1145
1212
private String function { get ; set ; }
1146
1213
private Object fieldOrFunc { get ; set ; }
@@ -1358,6 +1425,22 @@ public virtual class Query implements Querable {
1358
1425
// #endregion
1359
1426
// ===============================
1360
1427
1428
+ // ====================
1429
+ // #region VAR Literal
1430
+
1431
+ public class VarLiteral extends Literal {
1432
+ public VarLiteral (String literal ) {
1433
+ super (literal );
1434
+ }
1435
+ }
1436
+
1437
+ public static VarLiteral var (String name ) {
1438
+ return new VarLiteral (' :' + name );
1439
+ }
1440
+
1441
+ // #endregion
1442
+ // ====================
1443
+
1361
1444
// ====================
1362
1445
// #region Date Literal
1363
1446
public static Literal YESTERDAY () {
0 commit comments