Skip to content

Commit 0d502bb

Browse files
committed
release v3.0
1 parent a86e8df commit 0d502bb

File tree

9 files changed

+1057
-1108
lines changed

9 files changed

+1057
-1108
lines changed

README.md

Lines changed: 400 additions & 451 deletions
Large diffs are not rendered by default.

apex-query/main/default/classes/Query.cls

Lines changed: 135 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ public virtual class Query implements Querable {
1919
public interface Querable extends Groupable {
2020
Integer getCount();
2121
Integer getCount(AccessLevel accessLevel);
22+
Integer getCount(Map<String, Object> bindingVars);
23+
Integer getCount(Map<String, Object> bindingVars, AccessLevel accessLevel);
2224
List<SObject> run();
2325
List<SObject> run(AccessLevel accessLevel);
26+
List<SObject> run(Map<String, Object> bindingVars);
27+
List<SObject> run(Map<String, Object> bindingVars, AccessLevel accessLevel);
2428
Database.QueryLocator getLocator();
2529
Database.QueryLocator getLocator(AccessLevel accessLevel);
30+
Database.QueryLocator getLocator(Map<String, Object> bindingVars);
31+
Database.QueryLocator getLocator(Map<String, Object> bindingVars, AccessLevel accessLevel);
2632

2733
Query whereBy(Filter whereClause);
2834
Query havingBy(Filter havingClause);
@@ -41,11 +47,12 @@ public virtual class Query implements Querable {
4147
void buildSOQL_Filter(List<String> fragments, TmpVars tmpVars);
4248
}
4349

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);
4653
}
4754

48-
public class Literal {
55+
public virtual class Literal {
4956
public String literal { get; set; }
5057

5158
private Literal(String literal) {
@@ -63,7 +70,7 @@ public virtual class Query implements Querable {
6370
}
6471
}
6572

66-
public class TmpVars {
73+
private class TmpVars {
6774
Map<String, Object> bindingVars = new Map<String, Object>();
6875
Integer tmpVarCount = 0;
6976

@@ -75,6 +82,9 @@ public virtual class Query implements Querable {
7582
}
7683
}
7784

85+
private String soql { get; set; }
86+
private TmpVars tmpVars { get; set; }
87+
7888
private String objectName { get; set; }
7989
private List<Object> selectFields = new List<Object>();
8090
private Map<String, Query> selectParent = new Map<String, Query>();
@@ -94,17 +104,17 @@ public virtual class Query implements Querable {
94104
private Boolean updateViewstat { get; set; }
95105
private Boolean forUpdate { get; set; }
96106

97-
public static Query of(String objectName) {
98-
return new Query(objectName);
99-
}
100-
101-
public Query() {
107+
protected Query() {
102108
}
103109

104110
private Query(String objectName) {
105111
this.objectName = objectName;
106112
}
107113

114+
public static Query of(String objectName) {
115+
return new Query(objectName);
116+
}
117+
108118
public Query whereBy(Filter whereClause) {
109119
this.whereClause = whereClause;
110120
return this;
@@ -155,40 +165,87 @@ public virtual class Query implements Querable {
155165
}
156166

157167
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);
160186
}
161187

162188
public List<SObject> run() {
163189
return this.run(AccessLevel.SYSTEM_MODE);
164190
}
165191

166192
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);
169211
}
170212

171213
public Database.QueryLocator getLocator() {
172214
return this.getLocator(AccessLevel.SYSTEM_MODE);
173215
}
174216

175217
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);
178219
}
179220

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);
182231

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);
186236
}
187237

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;
192249
}
193250

194251
private void buildSOQL(List<String> fragments, TmpVars tmpVars, String fromName, Integer level) {
@@ -342,21 +399,26 @@ public virtual class Query implements Querable {
342399
// ====================
343400

344401
// =====================
345-
// #region Logical Filter
346-
private virtual class LogicalFilter implements CompositeFilter {
402+
// #region Logic Filter
403+
private virtual class LogicalFilterImpl implements LogicalFilter {
347404
private List<Filter> filters { get; set; }
348405
private String operator { get; set; }
349406

350-
private LogicalFilter(String operator, List<Filter> filters) {
407+
private LogicalFilterImpl(String operator, List<Filter> filters) {
351408
this.operator = operator;
352409
this.filters = filters;
353410
}
354411

355-
public CompositeFilter add(Filter filter) {
412+
public LogicalFilter add(Filter filter) {
356413
this.filters.add(filter);
357414
return this;
358415
}
359416

417+
public LogicalFilter addAll(List<Filter> filters) {
418+
this.filters.addAll(filters);
419+
return this;
420+
}
421+
360422
public virtual void buildSOQL_Filter(List<String> fragments, TmpVars tmpVars) {
361423
if (this.filters.isEmpty()) {
362424
return;
@@ -376,15 +438,15 @@ public virtual class Query implements Querable {
376438
}
377439
}
378440

379-
private class NotLogicalFilter extends LogicalFilter {
441+
private class NotLogicalFilter extends LogicalFilterImpl {
380442
private NotLogicalFilter(Filter filter) {
381443
super('NOT', new List<Filter>{ filter });
382444
}
383445

384446
public override void buildSOQL_Filter(List<String> fragments, TmpVars tmpVars) {
385447
Filter filter = this.filters[0];
386448
fragments.add(this.operator);
387-
if (filter instanceof CompositeFilter) {
449+
if (filter instanceof LogicalFilter) {
388450
filter.buildSOQL_Filter(fragments, tmpVars);
389451
} else {
390452
fragments.add('(');
@@ -398,20 +460,12 @@ public virtual class Query implements Querable {
398460
return new NotLogicalFilter(filter);
399461
}
400462

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>());
403465
}
404466

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>());
415469
}
416470

417471
// #endregion
@@ -468,7 +522,7 @@ public virtual class Query implements Querable {
468522
}
469523

470524
private class NotLikeFilter extends ComparisonFilter {
471-
private NotLikeFilter(String fieldOrFunc, String value) {
525+
private NotLikeFilter(String fieldOrFunc, Object value) {
472526
super(fieldOrFunc, ' LIKE ', value);
473527
}
474528

@@ -505,18 +559,11 @@ public virtual class Query implements Querable {
505559
public static Filter eq(String fieldOrFunc, Object value) {
506560
return new ComparisonFilter(fieldOrFunc, ' = ', value);
507561
}
508-
public static Filter eqNull(String fieldOrFunc) {
509-
return new ComparisonFilter(fieldOrFunc, ' = ', null);
510-
}
511562

512563
public static Filter ne(String fieldOrFunc, Object value) {
513564
return new ComparisonFilter(fieldOrFunc, ' != ', value);
514565
}
515566

516-
public static Filter neNull(String fieldOrFunc) {
517-
return new ComparisonFilter(fieldOrFunc, ' != ', null);
518-
}
519-
520567
public static Filter gt(String fieldOrFunc, Object value) {
521568
return new ComparisonFilter(fieldOrFunc, ' > ', value);
522569
}
@@ -533,6 +580,10 @@ public virtual class Query implements Querable {
533580
return new ComparisonFilter(fieldOrFunc, ' <= ', value);
534581
}
535582

583+
public static Filter between(String fieldOrFunc, Object minValue, Object maxValue) {
584+
return andx().add(gte(fieldOrFunc, minValue)).add(lte(fieldOrFunc, maxValue));
585+
}
586+
536587
public static Filter likex(String field, String value) {
537588
return new ComparisonFilter(field, ' LIKE ', value);
538589
}
@@ -557,8 +608,21 @@ public virtual class Query implements Querable {
557608
return new MultiComparisonFilter(field, ' EXCLUDES ', values);
558609
}
559610

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);
562626
}
563627

564628
// #endregion
@@ -1141,6 +1205,9 @@ public virtual class Query implements Querable {
11411205
public interface CurrencyFunction extends SelectFunction {
11421206
}
11431207

1208+
public interface TimezoneFunction {
1209+
}
1210+
11441211
public virtual class FunctionImpl implements Function {
11451212
private String function { get; set; }
11461213
private Object fieldOrFunc { get; set; }
@@ -1358,6 +1425,22 @@ public virtual class Query implements Querable {
13581425
// #endregion
13591426
// ===============================
13601427

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+
13611444
// ====================
13621445
// #region Date Literal
13631446
public static Literal YESTERDAY() {

0 commit comments

Comments
 (0)