Skip to content

Commit 8d686f6

Browse files
authored
V1.3.20 - Date Literal Function Support and RollupParentResetProcessor bugfix (#225)
* Fixes #179 by ensuring RollupParentResetProcessor recalcs always run first when multiple operations are enqueued. Also added logging for when those parent-level fields are reset * Added support for date literal functions, started exploring any possible issues associated with #224 * Swapping the ordering of some ALL ROWS calls around where ORDER BY is being used for full recalcs
1 parent 934e2c9 commit 8d686f6

13 files changed

+627
-48
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ You have several different options when it comes to making use of `Rollup`:
2222

2323
## Deployment
2424

25-
<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008SiVIAA0">
25+
<a href="https://login.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008SiaJAAS">
2626
<img alt="Deploy to Salesforce"
2727
src="./media/deploy-package-to-prod.png">
2828
</a>
2929

30-
<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008SiVIAA0">
30+
<a href="https://test.salesforce.com/packaging/installPackage.apexp?p0=04t6g000008SiaJAAS">
3131
<img alt="Deploy to Salesforce Sandbox"
3232
src="./media/deploy-package-to-sandbox.png">
3333
</a>

extra-tests/classes/RollupDateLiteralTests.cls

Lines changed: 326 additions & 2 deletions
Large diffs are not rendered by default.

extra-tests/classes/RollupEvaluatorTests.cls

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,13 @@ private class RollupEvaluatorTests {
689689
System.assertEquals(new List<String>{ 'Owner.Name' }, eval.getQueryFields());
690690
}
691691

692+
@IsTest
693+
static void shouldReturnDateFunctionFields() {
694+
String queryString = 'HOUR_IN_DAY(CreatedDate) = 15';
695+
RollupEvaluator.WhereFieldEvaluator eval = new RollupEvaluator.WhereFieldEvaluator(queryString, Account.SObjectType);
696+
System.assertEquals(new List<String>{ 'CreatedDate' }, eval.getQueryFields());
697+
}
698+
692699
@SuppressWarnings('PMD.ApexUnitTestClassShouldHaveAsserts')
693700
@IsTest
694701
static void shouldThrowExceptionForImproperlyEnteredWhereClause() {
@@ -1016,16 +1023,25 @@ private class RollupEvaluatorTests {
10161023
static void shouldProperlyEvaluateDateLiteral() {
10171024
String whereClause = 'CloseDate = THIS_YEAR';
10181025
RollupEvaluator.WhereFieldEvaluator eval = new RollupEvaluator.WhereFieldEvaluator(whereClause, Opportunity.SObjectType);
1019-
System.assertEquals(true, eval.matches(new Opportunity(CloseDate = System.today().addDays(-1))));
1026+
System.assertEquals(true, eval.matches(new Opportunity(CloseDate = System.today())));
10201027
System.assertEquals(false, eval.matches(new Opportunity(CloseDate = System.today().addYears(-1))));
10211028
}
10221029

10231030
@IsTest
1024-
static void shouldStripOutDateFunctionsFromSelectStatements() {
1025-
String whereClause = 'CALENDAR_YEAR(CreatedDate) = ' + System.today().year();
1026-
RollupEvaluator.WhereFieldEvaluator eval = new RollupEvaluator.WhereFieldEvaluator(whereClause, ContactPointAddress.SObjectType);
1027-
List<String> queryFields = eval.getQueryFields();
1028-
System.assertEquals(true, queryFields.isEmpty(), 'Query fields should have been empty but contained: ' + queryFields);
1031+
static void shouldProperlyEvaluateDateFunction() {
1032+
String whereClause = 'HOUR_IN_DAY(ReminderDateTime) = 5';
1033+
RollupEvaluator.WhereFieldEvaluator eval = new RollupEvaluator.WhereFieldEvaluator(whereClause, Task.SObjectType);
1034+
Time fifthHour = Time.newInstance(5, 0, 0, 0);
1035+
Datetime fifthHourDt = Datetime.newInstanceGmt(System.today(), fifthHour);
1036+
System.assertEquals(true, eval.matches(new Task(ReminderDateTime = fifthHourDt)));
1037+
}
1038+
1039+
@IsTest
1040+
static void shouldProperlyEvaluateLiteralDateFunctions() {
1041+
Date comparisonDate = Date.newInstance(2020, 3, 7);
1042+
String whereClause = 'DAY_ONLY(ReminderDateTime) = 2020-03-07';
1043+
RollupEvaluator.WhereFieldEvaluator eval = new RollupEvaluator.WhereFieldEvaluator(whereClause, Task.SObjectType);
1044+
System.assertEquals(true, eval.matches(new Task(ReminderDateTime = Datetime.newInstanceGmt(comparisonDate, Time.newInstance(0, 0, 0, 0)))));
10291045
}
10301046

10311047
@IsTest

extra-tests/classes/RollupFieldInitializerTests.cls

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ private class RollupFieldInitializerTests {
108108
* (java.math.BigDecimal and java.lang.Integer are in module java.base of loader 'bootstrap')
109109
*/
110110
RollupFieldInitializer init = RollupFieldInitializer.Current;
111+
// never ever fill out the Name field here; there's a reason it's blank
112+
// and it would cause this test to pass without exercising the actual underlying fix
111113
Account one = new Account();
112114
Account two = new Account();
113115

extra-tests/classes/RollupFullRecalcTests.cls

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ private class RollupFullRecalcTests {
99
}
1010

1111
@IsTest
12-
static void shouldSortFullRecalcsToEnd() {
12+
static void shouldSortParentResetProcessorsToBeginning() {
1313
RollupAsyncProcessor actualProcessor = RollupAsyncProcessor.getProcessor(
1414
new Rollup.FilterResults(),
1515
Contact.Id,
@@ -23,14 +23,26 @@ private class RollupFullRecalcTests {
2323
null,
2424
null
2525
);
26+
RollupParentResetProcessor resetProcessor = new RollupParentResetProcessor(
27+
new List<Rollup__mdt>(),
28+
null,
29+
'',
30+
new Set<Id>(),
31+
Rollup.InvocationPoint.FROM_APEX
32+
);
2633
List<RollupAsyncProcessor> processors = new List<RollupAsyncProcessor>{
34+
resetProcessor,
35+
actualProcessor,
36+
actualProcessor,
37+
resetProcessor,
2738
actualProcessor,
28-
new RollupDeferredFullRecalcProcessor(new List<Rollup__mdt>(), null, null, null, null),
29-
actualProcessor
39+
resetProcessor
3040
};
3141
processors.sort();
3242

33-
System.assertEquals(true, processors[2] instanceof RollupDeferredFullRecalcProcessor, processors);
43+
System.assertEquals(true, processors[0] instanceof RollupParentResetProcessor, processors[0]);
44+
System.assertEquals(true, processors[1] instanceof RollupParentResetProcessor, processors[0]);
45+
System.assertEquals(true, processors[2] instanceof RollupParentResetProcessor, processors[0]);
3446
}
3547

3648
@IsTest

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "apex-rollup",
3-
"version": "1.3.19",
3+
"version": "1.3.20",
44
"description": "Fast, configurable, elastically scaling custom rollup solution. Apex Invocable action, one-liner Apex trigger/CMDT-driven logic, and scheduled Apex-ready.",
55
"repository": {
66
"type": "git",

rollup/core/classes/Rollup.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1927,7 +1927,7 @@ global without sharing virtual class Rollup {
19271927
} else if (shouldQueue) {
19281928
return new RollupDeferredFullRecalcProcessor(matchingMeta, calcItemType, queryString, recordIds, invokePoint);
19291929
} else {
1930-
String queryWithOrderBy = (queryString + getFullRecalcQueryString(matchingMeta)).replace('ALL ROWS', '');
1930+
String queryWithOrderBy = (queryString + getFullRecalcQueryString(matchingMeta));
19311931
return new RollupFullBatchRecalculator(queryWithOrderBy, invokePoint, matchingMeta, calcItemType, recordIds);
19321932
}
19331933
}

rollup/core/classes/RollupAsyncProcessor.cls

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ global virtual without sharing class RollupAsyncProcessor extends Rollup impleme
1111
protected Boolean isProcessed = false;
1212
protected Boolean overridesRunCalc = false;
1313
protected FullRecalcProcessor fullRecalcProcessor;
14+
protected Boolean shouldSortToFront = false;
1415

1516
private RollupRelationshipFieldFinder.Traversal traversal;
1617
private Map<SObjectType, Set<String>> lookupObjectToUniqueFieldNames;
@@ -209,9 +210,9 @@ global virtual without sharing class RollupAsyncProcessor extends Rollup impleme
209210
Integer numberToReturn = 0;
210211
if (otherRollup instanceof RollupAsyncProcessor) {
211212
RollupAsyncProcessor that = (RollupAsyncProcessor) otherRollup;
212-
if (this.op == null && that.op != null) {
213+
if (this.shouldSortToFront == false && that.shouldSortToFront) {
213214
numberToReturn = 1;
214-
} else if (that.op == null && this.op != null) {
215+
} else if (that.shouldSortToFront == false && this.shouldSortToFront) {
215216
numberToReturn = -1;
216217
} else if (this.op != null && that.op != null) {
217218
Boolean thisDelete = this.op.name().contains('DELETE');

0 commit comments

Comments
 (0)