Skip to content

Commit 269a787

Browse files
authored
Fixes Set handling in filterWhere (#44)
* Fixes #43 by upgrading SOQl.cls to API version 58, where Set<T> always implements Iterable<T> to simplify string joining for Set operators * Bumped all metadata to API v58.0 (Summer '23 release) * Updated all references to classes & enums in the Schema & System namespaces to explicitly include the namespaces
1 parent 293bec3 commit 269a787

18 files changed

+93
-88
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,38 @@
22

33
A dynamic SOQL query & SOSL search library for Salesforce Apex
44

5-
## Unlocked Package - no namespace - v3.1.1
5+
## Unlocked Package - no namespace - v3.1.2
66

7-
[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsMOQA0)
8-
[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsMOQA0)
7+
[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsbQQAS)
8+
[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsbQQAS)
99

1010
Install with SF CLI:
1111

1212
```shell
13-
sf package install --apex-compile package --wait 20 --security-type AdminsOnly --package 04t5Y000001TsMOQA0
13+
sf package install --apex-compile package --wait 20 --security-type AdminsOnly --package 04t5Y000001TsbQQAS
1414
```
1515

1616
Install with SFDX CLI:
1717

1818
```shell
19-
sfdx force:package:install --apexcompile package --wait 20 --securitytype AdminsOnly --package 04t5Y000001TsMOQA0
19+
sfdx force:package:install --apexcompile package --wait 20 --securitytype AdminsOnly --package 04t5Y000001TsbQQAS
2020
```
2121

22-
## Unlocked Package - `Nebula` namespace - v3.1.1
22+
## Unlocked Package - `Nebula` namespace - v3.1.2
2323

24-
[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsMTQA0)
25-
[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsMTQA0)
24+
[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsbVQAS)
25+
[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001TsbVQAS)
2626

2727
Install with SF CLI:
2828

2929
```shell
30-
sf package install --apex-compile package --wait 20 --security-type AdminsOnly --package 04t5Y000001TsMTQA0
30+
sf package install --apex-compile package --wait 20 --security-type AdminsOnly --package 04t5Y000001TsbVQAS
3131
```
3232

3333
Install with SFDX CLI:
3434

3535
```shell
36-
sfdx force:package:install --apexcompile package --wait 20 --securitytype AdminsOnly --package 04t5Y000001TsMTQA0
36+
sfdx force:package:install --apexcompile package --wait 20 --securitytype AdminsOnly --package 04t5Y000001TsbVQAS
3737
```
3838

3939
## Features

nebula-query-and-search/main/classes/AggregateQuery.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ global class AggregateQuery extends SOQL {
202202
super.doGetLimitCountString() +
203203
super.doGetOffetString();
204204

205-
System.debug(LoggingLevel.FINEST, this.query);
205+
System.debug(System.LoggingLevel.FINEST, this.query);
206206
return this.query;
207207
}
208208

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

nebula-query-and-search/main/classes/Query.cls

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ global class Query extends SOQL {
332332
// If additional builder methods are later called, the builder methods will set hasChanged = true
333333
this.hasChanged = false;
334334

335-
System.debug(LoggingLevel.FINEST, this.query);
335+
System.debug(System.LoggingLevel.FINEST, this.query);
336336
return this.query;
337337
}
338338

@@ -361,7 +361,7 @@ global class Query extends SOQL {
361361
super.doGetLimitCountString() +
362362
')';
363363

364-
System.debug(LoggingLevel.FINEST, childQuery);
364+
System.debug(System.LoggingLevel.FINEST, childQuery);
365365
return childQuery;
366366
}
367367

@@ -378,7 +378,7 @@ global class Query extends SOQL {
378378
super.doGetLimitCountString() +
379379
')';
380380

381-
System.debug(LoggingLevel.FINEST, subquery);
381+
System.debug(System.LoggingLevel.FINEST, subquery);
382382
return subquery;
383383
}
384384

@@ -391,7 +391,7 @@ global class Query extends SOQL {
391391

392392
String searchQuery = this.getSObjectType() + sobjectTypeOptions;
393393

394-
System.debug(LoggingLevel.FINEST, searchQuery);
394+
System.debug(System.LoggingLevel.FINEST, searchQuery);
395395
return searchQuery;
396396
}
397397

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

nebula-query-and-search/main/classes/RecordSearch.cls

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ global class RecordSearch extends SOSL {
9494
// If additional builder methods are later called, the builder methods will set hasChanged = true
9595
this.hasChanged = false;
9696

97-
System.debug(LoggingLevel.FINEST, this.searchQuery);
97+
System.debug(System.LoggingLevel.FINEST, this.searchQuery);
9898
return this.searchQuery;
9999
}
100100

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

nebula-query-and-search/main/classes/SOQL.cls

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ global abstract class SOQL implements Comparable {
410410
private final String isoCurrency;
411411

412412
public IsoCurrency(String isoCode, Decimal currencyAmount) {
413-
if (!UserInfo.isMultiCurrencyOrganization()) {
413+
if (!System.UserInfo.isMultiCurrencyOrganization()) {
414414
throw new SOQLException('IsoCurrency is only supported in multi-currency orgs');
415415
}
416416
this.isoCurrency = isoCode + currencyAmount;
@@ -522,7 +522,7 @@ global abstract class SOQL implements Comparable {
522522
Integer lastFieldIndex = fields.size() - 1;
523523
List<String> queryFieldPieces = new List<String>();
524524
for (Integer i = 0; i < fields.size(); i++) {
525-
SObjectField field = fields[i];
525+
Schema.SObjectField field = fields[i];
526526
// If any field in the chain is not accessible, then the user cant access the data, so return an empty list
527527
if (!field.getDescribe().isAccessible()) {
528528
return null;
@@ -619,10 +619,8 @@ global abstract class SOQL implements Comparable {
619619
private String formatObjectForQueryString(Object valueToFormat) {
620620
if (valueToFormat == null) {
621621
return null;
622-
} else if (valueToFormat instanceof List<Object>) {
623-
return this.convertListToQueryString((List<Object>) valueToFormat);
624-
} else if (valueToFormat instanceof Set<Object>) {
625-
return this.convertSetToQueryString(valueToFormat);
622+
} else if (valueToFormat instanceof Iterable<Object>) {
623+
return this.convertIterableToQueryString((Iterable<Object>) valueToFormat);
626624
} else if (valueToFormat instanceof Map<Object, Object>) {
627625
return this.convertMapToQueryString(valueToFormat);
628626
} else if (valueToFormat instanceof Date) {
@@ -653,26 +651,19 @@ global abstract class SOQL implements Comparable {
653651
return input;
654652
}
655653

656-
private String convertListToQueryString(List<Object> valueList) {
654+
private String convertIterableToQueryString(Iterable<Object> valueIterable) {
657655
List<String> parsedValueList = new List<String>();
658-
for (Object value : valueList) {
656+
Iterator<Object> valueIterator = valueIterable.iterator();
657+
while (valueIterator.hasNext()) {
658+
Object value = valueIterator.next();
659659
parsedValueList.add(this.formatObjectForQueryString(value));
660660
}
661661
return '(' + String.join(parsedValueList, ', ') + ')';
662662
}
663663

664-
private String convertSetToQueryString(Object valueSet) {
665-
String unformattedString = String.valueOf(valueSet).replace('{', '').replace('}', '');
666-
List<String> parsedValueList = new List<String>();
667-
for (String collectionItem : unformattedString.split(',')) {
668-
parsedValueList.add(this.formatObjectForQueryString(collectionItem));
669-
}
670-
return '(' + String.join(parsedValueList, ', ') + ')';
671-
}
672-
673664
private String convertMapToQueryString(Object valueMap) {
674665
Map<String, Object> untypedMap = (Map<String, Object>) Json.deserializeUntyped(Json.serialize(valueMap));
675-
return this.convertSetToQueryString(untypedMap.keySet());
666+
return this.convertIterableToQueryString(untypedMap.keySet());
676667
}
677668
}
678669
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

nebula-query-and-search/tests/classes/AggregateQuery_Tests.cls

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ private class AggregateQuery_Tests {
5959
static void it_should_cache_results() {
6060
AggregateQuery aggregateQuery = new AggregateQuery(Schema.Opportunity.SObjectType);
6161
aggregateQuery.cacheResults();
62-
System.assertEquals(0, Limits.getQueries());
62+
System.assertEquals(0, System.Limits.getQueries());
6363

6464
for (Integer i = 0; i < 3; i++) {
6565
aggregateQuery.getResults();
6666
}
6767

68-
System.assertEquals(1, Limits.getQueries());
68+
System.assertEquals(1, System.Limits.getQueries());
6969
}
7070

7171
@IsTest
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

nebula-query-and-search/tests/classes/Query_Tests.cls

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@ private class Query_Tests {
1818
List<Account> accounts = simpleAccountQuery.getResults();
1919
}
2020

21+
@IsTest
22+
static void it_should_correctly_represent_sets_in_query_filters() {
23+
String expectedName = 'someName';
24+
String expectedQueryString = 'SELECT Id, Name FROM Account WHERE Name IN (\'' + expectedName + '\')';
25+
26+
String actualQuery = new Query(Schema.Account.SObjectType)
27+
.filterWhere(Schema.Account.Name, SOQL.Operator.IS_IN, new Set<String>{ expectedName })
28+
.getQuery();
29+
30+
System.Assert.areEqual(expectedQueryString, actualQuery);
31+
}
32+
2133
@IsTest
2234
static void it_should_return_results_for_an_advanced_query() {
2335
Datetime now = System.now();
@@ -31,11 +43,11 @@ private class Query_Tests {
3143
' AND LastModifiedDate <= ' +
3244
now.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'Greenwich Mean Time') +
3345
' AND Profile.Id != \'' +
34-
UserInfo.getProfileId() +
46+
System.UserInfo.getProfileId() +
3547
'\'' +
3648
' ORDER BY Profile.CreatedBy.LastModifiedDate ASC NULLS FIRST, Name ASC NULLS FIRST, Email ASC NULLS FIRST' +
3749
' LIMIT 100 OFFSET 1 FOR VIEW';
38-
List<SObjectField> fieldsToQuery = new List<SObjectField>{ Schema.User.IsActive, Schema.User.Alias };
50+
List<Schema.SObjectField> fieldsToQuery = new List<Schema.SObjectField>{ Schema.User.IsActive, Schema.User.Alias };
3951

4052
Query userQuery = new Query(Schema.User.SObjectType)
4153
.addFields(fieldsToQuery)
@@ -47,7 +59,7 @@ private class Query_Tests {
4759
.includeFormattedValues()
4860
.usingScope(SOQL.Scope.MINE)
4961
.filterWhere(Schema.User.IsActive, SOQL.Operator.EQUALS, true)
50-
.filterWhere(new SOQL.QueryField(Schema.User.SObjectType, 'Profile.Id'), SOQL.Operator.NOT_EQUAL_TO, UserInfo.getProfileId())
62+
.filterWhere(new SOQL.QueryField(Schema.User.SObjectType, 'Profile.Id'), SOQL.Operator.NOT_EQUAL_TO, System.UserInfo.getProfileId())
5163
.filterWhere(Schema.User.LastModifiedDate, SOQL.Operator.LESS_THAN_OR_EQUAL_TO, now)
5264
.filterWhere(Schema.User.LastLoginDate, SOQL.Operator.GREATER_THAN_OR_EQUAL_TO, new SOQL.DateLiteral(SOQL.RelativeDateLiteral.LAST_N_DAYS, 3))
5365
.filterWhere(Schema.User.CreatedDate, SOQL.Operator.LESS_THAN_OR_EQUAL_TO, new SOQL.DateLiteral(SOQL.FixedDateLiteral.LAST_WEEK))
@@ -118,7 +130,7 @@ private class Query_Tests {
118130
' END' +
119131
' FROM Task';
120132

121-
Test.startTest();
133+
System.Test.startTest();
122134

123135
Map<Schema.SObjectType, List<Schema.SObjectField>> fieldsBySObjectType = new Map<Schema.SObjectType, List<Schema.SObjectField>>();
124136

@@ -133,7 +145,7 @@ private class Query_Tests {
133145
// Query the task object
134146
Query taskQuery = new Query(Schema.Task.SObjectType).addPolymorphicFields(Schema.Task.WhoId, fieldsBySObjectType);
135147

136-
Test.stopTest();
148+
System.Test.stopTest();
137149

138150
System.assertEquals(expectedQuery, taskQuery.getQuery());
139151
}
@@ -232,7 +244,7 @@ private class Query_Tests {
232244
@IsTest
233245
static void it_should_return_results_when_filtering_with_iso_currency() {
234246
// If multi-currency isn't enabled, then we cannot use IsoCurrency, so skip running this test
235-
if (!UserInfo.isMultiCurrencyOrganization()) {
247+
if (!System.UserInfo.isMultiCurrencyOrganization()) {
236248
return;
237249
}
238250

@@ -249,20 +261,20 @@ private class Query_Tests {
249261
Query userQuery = new Query(Schema.User.SObjectType).limitTo(1);
250262

251263
// First, verify that caching is not enabled by default
252-
System.assertEquals(0, Limits.getQueries());
264+
System.assertEquals(0, System.Limits.getQueries());
253265
for (Integer i = 0; i < loops; i++) {
254266
userQuery.getResults();
255267
}
256-
System.assertEquals(loops, Limits.getQueries());
268+
System.assertEquals(loops, System.Limits.getQueries());
257269

258-
Test.startTest();
270+
System.Test.startTest();
259271

260272
userQuery.cacheResults();
261273
for (Integer i = 0; i < loops; i++) {
262274
userQuery.getResults();
263275
}
264-
System.assertEquals(1, Limits.getQueries());
276+
System.assertEquals(1, System.Limits.getQueries());
265277

266-
Test.stopTest();
278+
System.Test.stopTest();
267279
}
268280
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
22
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
3-
<apiVersion>57.0</apiVersion>
3+
<apiVersion>58.0</apiVersion>
44
<status>Active</status>
55
</ApexClass>

0 commit comments

Comments
 (0)