1212*/
1313public abstract class QueryBuilder extends NebulaCore {
1414
15+ private static Map <Integer , List <SObject >> cachedQueryResultsByHashCode = new Map <Integer , List <SObject >>();
16+ private static Map <Integer , List <List <SObject >>> cachedSearchResultsByHashCode = new Map <Integer , List <List <SObject >>>();
17+
1518 protected List <String > whereClauseList ;
1619 protected List <String > orderByList ;
1720 protected Integer limitCount ;
1821
1922 protected SObjectType sobjectType ;
2023 protected Map <String , Schema .SObjectField > sobjectTypeFieldMap ;
2124
25+ private Boolean cacheResults ;
26+
2227 public QueryBuilder () {
2328 this .currentModule = NebulaCore .Module .QUERY_BUILDER ;
2429
25- this .whereClauseList = new List <String >();
26- this .orderByList = new List <String >();
30+ this .whereClauseList = new List <String >();
31+ this .orderByList = new List <String >();
32+ this .cacheResults = false ;
33+ }
34+
35+ protected void doCacheResults () {
36+ this .cacheResults = true ;
2737 }
2838
2939 protected void doFilterBy (IQueryFilter queryFilter ) {
@@ -83,19 +93,13 @@ public abstract class QueryBuilder extends NebulaCore {
8393 }
8494
8595 protected List <SObject > doGetQueryResults (String query ) {
86- List <SObject > results = Database .query (query );
87-
88- this .logResults (query , results );
89-
90- return results ;
96+ if (this .cacheResults ) return this .getCachedQuery (query );
97+ else return this .executeQuery (query );
9198 }
9299
93100 protected List <List <SObject >> doGetSearchResults (String query ) {
94- List <List <SObject >> results = Search .query (query );
95-
96- this .logResults (query , results );
97-
98- return results ;
101+ if (this .cacheResults ) return this .getCachedSearch (query );
102+ else return this .executeSearch (query );
99103 }
100104
101105 private void filterByWithSeparator (List <IQueryFilter > queryFilters , String separator ) {
@@ -108,6 +112,41 @@ public abstract class QueryBuilder extends NebulaCore {
108112 this .whereClauseList .add (orStatement );
109113 }
110114
115+ private List <SObject > getCachedQuery (String query ) {
116+ Integer hashCode = query .hashCode ();
117+
118+ Boolean isCached = cachedQueryResultsByHashCode .containsKey (hashCode );
119+ if (! isCached ) cachedQueryResultsByHashCode .put (hashCode , this .executeQuery (query ));
120+
121+ // Always return a deep clone so the original cached version is never modified
122+ return cachedQueryResultsByHashCode .get (hashCode ).deepClone (true , true , true );
123+ }
124+
125+ private List <SObject > executeQuery (String query ) {
126+ List <SObject > results = Database .query (query );
127+ this .logResults (query , results );
128+ return results ;
129+ }
130+
131+ private List <List <SObject >> getCachedSearch (String query ) {
132+ Integer hashCode = query .hashCode ();
133+
134+ Boolean isCached = cachedSearchResultsByHashCode .containsKey (hashCode );
135+ if (! isCached ) cachedSearchResultsByHashCode .put (hashCode , this .executeSearch (query ));
136+
137+ // Always return a deep clone so the original cached version is never modified
138+ List <List <SObject >> cachedResults = cachedSearchResultsByHashCode .get (hashCode );
139+ List <List <SObject >> deepClonedResults = new List <List <SObject >>();
140+ for (List < SObject > cachedListOfResults : cachedResults ) deepClonedResults .add (cachedListOfResults .deepClone (true , true , true ));
141+ return deepClonedResults ;
142+ }
143+
144+ private List <List <SObject >> executeSearch (String query ) {
145+ List <List <SObject >> results = Search .query (query );
146+ this .logResults (query , results );
147+ return results ;
148+ }
149+
111150 private void logResults (String query , List <Object > results ) {
112151 String logEntry = ' Query:\n ' + query + ' \n\n Results:\n ' + JSON .serializePretty (results );
113152 Logger .addEntry (this , logEntry );
0 commit comments