Skip to content

Commit c6734e4

Browse files
committed
Improved QueryFactory performance when building queries with lots of select fields, by reducing overhead associated with sorting select fields and generating the qualified field names.
1 parent 6bcdb4b commit c6734e4

File tree

2 files changed

+46
-32
lines changed

2 files changed

+46
-32
lines changed

fflib/src/classes/fflib_QueryFactory.cls

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -675,57 +675,70 @@ public class fflib_QueryFactory { //No explicit sharing declaration - inherit fr
675675
}
676676
public override String toString(){
677677
String result = '';
678-
Iterator<Schema.sObjectField> i = fields.iterator();
679-
while(i.hasNext()){
680-
String fieldName = i.next().getDescribe().getName();
681-
if(fieldName.endsWithIgnoreCase('Id') && i.hasNext())
682-
fieldName = fieldName.removeEndIgnoreCase('Id');
683-
if(fieldName.endsWithIgnoreCase('__c') && i.hasNext())
684-
fieldName = fieldName.removeEndIgnoreCase('__c')+'__r';
685-
result += fieldName + (i.hasNext() ? '.' :'');
678+
Integer size = fields.size();
679+
for (Integer i=0; i<size; i++)
680+
{
681+
if (i>0)
682+
{
683+
if (result.endsWithIgnoreCase('Id'))
684+
result = result.removeEndIgnoreCase('Id');
685+
else if (result.endsWithIgnoreCase('__c')) {
686+
result = result.removeEndIgnoreCase('__c') + '__r';
687+
}
688+
result += '.';
689+
}
690+
result += fields[i].getDescribe().getName();
686691
}
687692
return result;
688693
}
689694
public integer hashCode(){
690695
return String.valueOf(this.fields).hashCode();
691696
}
692697
public boolean equals(Object obj){
693-
if(!(obj instanceof QueryField))
698+
//Easy checks first
699+
if(obj == null || !(obj instanceof QueryField))
694700
return false;
695-
if( String.valueOf(((QueryField) obj).fields) != String.valueOf(this.fields))
701+
702+
if (this === obj)
703+
return true;
704+
705+
//Detailed checks
706+
QueryField other = (QueryField)obj;
707+
Integer size = fields.size();
708+
if (size != other.fields.size())
696709
return false;
697-
Set<Schema.SObjectField> objFields = new Set<Schema.SObjectField>();
698-
objFields.addAll( ((QueryField)obj).fields );
699-
objFields.retainAll(this.fields);
700-
objFields.removeAll(this.fields);
701-
return objFields.size() == 0;
710+
711+
for (Integer i=0; i<size; i++)
712+
if (fields[i] != (other.fields[i]))
713+
return false;
714+
715+
return true;
702716
}
703717
/**
704-
* Allows sorting QueryField instances, which means we'll get deterministic field ordering by just sorting the parent
705-
* QueryFactory's array when toSOQL'ing.
718+
* Allows sorting QueryField instances.
706719
*
707720
* Returns:
708721
* - Objects that are not QueryField instances as -2, which functions as -1 but with more flair
709-
* - QueryField instances with less joins in their path as -1
710-
* - QueryField instances with an equal number of joins and alphabetically first as an undefined negative integer
711-
* - equals as 0
712-
* - anything else an undefined positive integer (usually, but not always 1)
722+
* - Equivalent QueryFields return 0.
723+
* - QueryFields with more joins give +1, while fewer joins give -1
724+
* - For anything else, compare the toStrings of this and the supplied object.
713725
**/
714726
public Integer compareTo(Object o){
715-
if(!(o instanceof QueryField))
727+
if(o == null || !(o instanceof QueryField))
716728
return -2; //We can't possibly do a sane comparison against an unknwon type, go athead and let it "win"
717-
QueryField that = (QueryField) o;
718-
if(this.fields.size() < that.fields.size()){
729+
730+
if (this === o)
731+
return 0;
732+
733+
QueryField other = (QueryField)o;
734+
Integer size = fields.size();
735+
Integer sizeOther = other.fields.size();
736+
if (size < sizeOther)
719737
return -1;
720-
}else if( this.fields.size() == that.fields.size() ){
721-
if(this.equals(that)){
722-
return 0;
723-
}else{
724-
return this.toString().compareTo(that.toString());
725-
}
726-
}else{
738+
if (size > sizeOther)
727739
return 1;
728-
}
740+
741+
return this.toString().compareTo(other.toString());
729742
}
730743
}
731744

fflib/src/classes/fflib_QueryFactoryTest.cls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ private class fflib_QueryFactoryTest {
630630
User.SObjectType.fields.Name
631631
});
632632
System.assertEquals(-2, qf.compareTo(otherType));
633+
System.assertEquals(-2, qf.compareTo(null));
633634
System.assertEquals(0, qf.compareTo(qf));
634635
System.assertEquals(
635636
0,

0 commit comments

Comments
 (0)