Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 72bfa44

Browse files
committed
Allow developers to opt out of sorting select fields in queries built by QueryFactory, in order to improve performance.
1 parent c6734e4 commit 72bfa44

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

fflib/src/classes/fflib_QueryFactory.cls

+23-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
7373
**/
7474
private Boolean enforceFLS;
7575

76+
private Boolean sortSelectFields = true;
77+
7678
/**
7779
* The relationship and subselectQueryMap variables are used to support subselect queries. Subselects can be added to
7880
* a query, as long as it isn't a subselect query itself. You may have many subselects inside
@@ -173,6 +175,17 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
173175
return this;
174176
}
175177

178+
/**
179+
* Sets a flag to indicate that this query should have ordered
180+
* query fields in the select statement (this at a small cost to performance).
181+
* If you are processing large query sets, you should switch this off.
182+
* @param whether or not select fields should be sorted in the soql statement.
183+
**/
184+
public fflib_QueryFactory setSortSelectFields(Boolean doSort){
185+
this.sortSelectFields = doSort;
186+
return this;
187+
}
188+
176189
/**
177190
* Selects a single field from the SObject specified in {@link #table}.
178191
* Selecting fields is idempotent, if this field is already selected calling this method will have no additional impact.
@@ -408,6 +421,10 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
408421
}
409422

410423
fflib_QueryFactory subselectQuery = new fflib_QueryFactory(relationship);
424+
425+
//The child queryFactory should be configured in the same way as the parent by default - can override after if required
426+
subSelectQuery.setSortSelectFields(sortSelectFields);
427+
411428
if(assertIsAccessible){
412429
subSelectQuery.assertIsAccessible();
413430
}
@@ -537,13 +554,17 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
537554
if (fields.size() == 0){
538555
if (enforceFLS) fflib_SecurityUtils.checkFieldIsReadable(table, 'Id');
539556
result += 'Id ';
540-
}else{
557+
}else if(sortSelectFields){
541558
List<QueryField> fieldsToQuery = new List<QueryField>(fields);
542559
fieldsToQuery.sort(); //delegates to QueryFilter's comparable implementation
543560
for(QueryField field:fieldsToQuery){
544561
result += field + ', ';
545562
}
546-
}
563+
}else{
564+
for (QueryField field : fields)
565+
result += field + ', ';
566+
}
567+
547568
if(subselectQueryMap != null && !subselectQueryMap.isEmpty()){
548569
for (fflib_QueryFactory childRow : subselectQueryMap.values()){
549570
result += ' (' + childRow.toSOQL() + '), ';

fflib/src/classes/fflib_QueryFactoryTest.cls

+29
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,35 @@ private class fflib_QueryFactoryTest {
775775
System.assert(qf.getSubselectQueries().get(0).getOrderings().size() == 0);
776776
System.assert(qf2.getSubselectQueries().get(0).getOrderings().size() == 1);
777777
}
778+
779+
@isTest
780+
static void testSoql_unsortedSelectFields(){
781+
//Given
782+
fflib_QueryFactory qf = new fflib_QueryFactory(User.SObjectType);
783+
qf.selectFields(new List<String>{
784+
'Id',
785+
'FirstName',
786+
'LastName',
787+
'CreatedBy.Name',
788+
'CreatedBy.Manager',
789+
'LastModifiedBy.Email'
790+
});
791+
792+
qf.setSortSelectFields(false);
793+
794+
String orderedQuery =
795+
'SELECT '
796+
+'FirstName, Id, LastName, ' //less joins come first, alphabetically
797+
+'CreatedBy.ManagerId, CreatedBy.Name, LastModifiedBy.Email ' //alphabetical on the same number of joins'
798+
+'FROM User';
799+
800+
//When
801+
String actualSoql = qf.toSOQL();
802+
803+
//Then
804+
System.assertNotEquals(orderedQuery, actualSoql);
805+
}
806+
778807

779808
public static User createTestUser_noAccess(){
780809
User usr;

0 commit comments

Comments
 (0)