Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

New Query Builders

Pre-release
Pre-release
Compare
Choose a tag to compare
@jongpie jongpie released this 29 Aug 13:26
· 4 commits to master since this release

Query Builders

QueryBuilder.cls has been split into SObjectQueryBuilder.cls, AggregateResultQueryBuilder.cls and SearchQueryBuilder.cls

QueryBuilder.cls

  • QueryBuilder.cls is now an abstract class. It only contains protected methods for shared logic that is used by SObjectQueryBuilder.cls, AggregateQueryBuilder.cls and SearchQueryBuilder.cls. QueryBuilder.cls should not be used directly anymore.

SObjectQueryBuilder.cls

A new builder class that generates dynamic SOQL queries & returns a list of SObject

  • Several ways to add fields to your query:
    1. addFields(Schema.FieldSet fieldSet)
    2. addFields(List fields)
    3. addAllFields()
    4. addAllStandardFields()
    5. addAllCustomFields()
    6. addAllReadableFields()
    7. addAllEditableFields()

  • Name fields for lookups are automatically added to your query. For example, adding the contact object's field AccountId (a lookup to account):
    sobjectQueryBuilder.addField(Schema.Contact.AccountId)

    will result in your query having 2 fields added
    SELECT AccountId, Account.Name FROM Contact

  • New method for including children records

  • New method, getQueryLocator()

AggregateResultQueryBuilder.cls

A new builder class that generates dynamic SOQL queries & returns a list of AggregateResult

  • Several methods to add fields to group by
    1. groupBy(QueryDate queryDate);
    2. groupBy(Schema.FieldSet fieldSet);
    3. groupBy(Schema.SObjectField groupByField);
    4. groupBy(List<Schema.SObjectField> groupByFields);

  • Several aggregate methods - each method is overloaded to allow you to provide the string to use for a field alias
    1. avg(Schema.SObjectField sbojectField)
    2. count(Schema.SObjectField sbojectField)
    3. countDistinct(Schema.SObjectField sbojectField)
    4. max(Schema.SObjectField sbojectField)
    5. min(Schema.SObjectField sbojectField)
    6. sum(Schema.SObjectField sbojectField)

Since this is the first round of implementing the class, not all aggregate result features (like 'GROUP BY ROLLUP') have been implemented, but more will be added in the future.

SearchQueryBuilder.cls - generates SOSL queries

A new builder class that generates dynamic SOSL search queries & returns a list of a list of SObjects (that's not a typo, it's a list of lists)

  • Instances of ISObjectQueryBuilder can be used to determine which SObjects are returned in the results
// Scenario: Search leads and accounts for a specified search term

// Step 1: define your search term
String searchTerm = 'Acme';

// Step 2: create 1 SObjectQueryBuilder per SObject Type that you want to search. In this case, there is 1 for account, and 1 for lead
ISObjectQueryBuilder accountQuery = SObjectQueryBuilder(Schema.Account.SObjectType).filterBy(queryFilters));
ISObjectQueryBuilder leadQuery = SObjectQueryBuilder(Schema.Lead.SObjectType).filterBy(queryFilters));
List<ISObjectQueryBuilder> queryBuilders = new List<ISObjectQueryBuilder>{accountQuery, leadQuery};

// Step 3: Pass search term & the query builders for account & lead to SearchQueryBuilder
List<List<SObject>> searchResults = new SearchQueryBuilder(searchTerm, queryBuilders).getSearchResults();

QueryField.cls

  • Used to dynamically generate field string for SObject fields, including parent fields.
// Convert an SObjectField to a QueryField
QueryField qf = new QueryField(Schema.Account.Id);

// Convert a parent object's SObjectField to a QueryField
// This is the equivalent of 'contact.Account.CreatedBy.User.Profile.Name'
List<Schema.SObjectField> fieldChain = new List<Schema.SObjectField>{
    Schema.Contact.AccountId, Schema.Account.CreatedById, Schema.User.ProfileId, Schema.Profile.Name
};
QueryField parentField= new QueryField(fieldChain);

QueryFilter.cls

  • Completely changed the methods available to handle 3 filtering scenarios
    1. filterByField(QueryField queryField, QueryOperator operator, Object providedValue)
    2. filterByQueryDate(QueryDate queryDateToFilter, QueryOperator operator, Integer providedValue)
    3. filterBySubquery(QueryOperator inOrNotIn, Schema.SObjectField lookupFieldOnRelatedSObject)
    4. filterBySubquery(Schema.SObjectField lookupField, QueryOperator inOrNotIn, Schema.SObjectField lookupFieldOnRelatedSObject)
  • Added support for specifying 'AND' and 'OR' statements in a query. To use, provide a list of query filters that you want to be wrapped as a set of 'AND' or 'OR' statements to the corresponding method
    1. andFilterBy(List queryFilters)
    2. orFilterBy(List queryFilters)

QueryDate.cls

  • A new class that can be used in two ways
    1. Filter on a date/datetime field, using date functions
QueryDate qd = QueryDate.CALENDAR_MONTH(Schema.Lead.CreatedDate);
QueryFilter filter = new QueryFilter().filterByQueryDate(qd, QueryOperator.EQUALS, 3);
sobjectQueryBuilder.filterBy(filter);
System.assertEquals(filter.getValue(), 'CALENDAR_MONTH(CreatedDate) = 3');

// In SOQL, it would be written as
List<Lead> leads = [SELECT Id
FROM Lead
WHERE CALENDAR_MONTH(CreatedDate) = 3')];
  1. Group by a date function in an aggregate result
QueryDate qd = QueryDate.CALENDAR_MONTH(Schema.Lead.CreatedDate);
aggregateResultQueryBuilder.groupBy(qd);

// In SOQL, it would be written as
List<AggregateResult> results = [SELECT CALENDAR_MONTH(CreatedDate)
FROM Lead
GROUP BY CALENDAR_MONTH(CreatedDate)];

QueryFilterScope.cls

  • Added 3 new filter scope enums
    1. DELEGATED
    2. MY_TERRITORY - only works in orgs with territory management enabled
    3. MY_TEAM_TERRITORY - only works in orgs with territory management enabled

SObject Repository

DML.cls

  • All DML methods now return the corresponding list of database results - see IDML.cls. Previously, these were void methods. This change is inherited by SObjectRepository.cls as well (it extends DML.cls)

SObjectRepository.cls

  • The member variable sobjectRepository.Query has been removed. Each method now instead initializes an instance of SObjectQueryBuilder.cls
  • New member variable sobjectRepository.AggregateQuery, an instance of the new class AggregateResultQueryBuilder.cls - see 'Query Builders' section for more info

Record Types

SObjectRecordTypes.cls

  • Now requires the abstract method Schema.SObjectType getSObjectType() to be implemented

Settings

  • The custom setting NebulaRepositorySettings__c.object has been renamed to NebulaSObjectQueryBuilderSettings__c.object

Utilities

CollectionUtils.cls

  • Added 3 new methods for working with collections
    1. getLastItem
    2. pop
    3. splice

Environment.cls

  • New property, NamespacePrefix

Documentation

  • Started commenting classes & methods with ApexDoc. This will be an ongoing improvement.