Basic Features
Dynamic SOQL
SOQL.cls
class provide methods that allow build SOQL clauses dynamically.
// SELECT Id FROM Account LIMIT 100
SOQL.of(Account.sObjectType).with(new List<sObjectField> {
Account.Id, Account.Name
})
.setLimit(100)
.asList();
Automatic binding
All variables used in WHERE
condition are binded by default.
// SELECT Id, Name FROM Account WHERE Name = :v1
SOQL.of(Account.sObjectType).with(new List<sObjectField> {
Account.Id, Account.Name
})
.whereAre(SOQL.Filter.with(Account.Name).likeAny('Test'))
.asList();
// Binding Map
{
"v1" : "%Test%"
}
Control FLS
Object permission and field-level security is controlled by the framework. Developer can change FLS settings match business requirements.
User mode
By default all queries are in AccessLevel.USER_MODE
.
The object permissions, field-level security, and sharing rules of the current user are enforced.
System mode
Developer can change it by using .systemMode()
which apply AccessLevel.SYSTEM_MODE
.
The object and field-level permissions of the current user are ignored, and the record sharing rules are controlled by the sharingMode.
// SELECT Id FROM Account - skip FLS
SOQL.of(Account.sObjectType).with(new List<sObjectField> {
Account.Id, Account.Name
})
.systemMode()
.asList();
Control Sharings
Use the with sharing or without sharing keywords on a class to specify whether sharing rules must be enforced. Use the inherited sharing keyword on a class to run the class in the sharing mode of the class that called it.
with sharing
By default all queries will be executed with sharing
, because of AccessLevel.USER_MODE
which enforce sharing rules.
AccessLevel.USER_MODE
enforce object permissions and field-level security as well.
Developer can skip FLS by adding .systemMode()
and .withSharing()
.
// Query executed in without sharing
SOQL.of(Account.sObjectType).with(new List<sObjectField> {
Account.Id, Account.Name
})
.systemMode()
.withSharing()
.asList();
without sharing
Developer can control sharing rules by adding .systemMode()
(record sharing rules are controlled by the sharingMode) and .withoutSharing()
.
// Query executed in with sharing
SOQL.of(Account.sObjectType).with(new List<sObjectField> {
Account.Id, Account.Name
})
.systemMode()
.withoutSharing()
.asList();
inherited sharing
Developer can control sharing rules by adding .systemMode()
(record sharing rules are controlled by the sharingMode) by default it is inherited sharing
.
// Query executed in inherited sharing
SOQL.of(Account.sObjectType).with(new List<sObjectField> {
Account.Id, Account.Name
})
.systemMode()
.asList();
Mocking
public with sharing class ExampleController {
public static List<Account> getPartnerAccounts(String accountName) {
return AccountSelector.Query
.with(Account.BillingCity)
.with(Account.BillingCountry)
.whereAre(SOQL.FiltersGroup
.add(SOQL.Filter.with(Account.Name).likeAny(accountName))
.add(SOQL.Filter.recordType().equal('Partner'))
)
.mocking('ExampleController.getPartnerAccounts')
.asList();
}
}
@isTest
public class ExampleControllerTest {
public static List<Account> getPartnerAccounts(String accountName) {
List<Account> accounts = new List<Account>{
new Account(Name = 'MyAccount 1'),
new Account(Name = 'MyAccount 2')
};
SOQL.setMock('ExampleController.getPartnerAccounts', accounts);
// Test
List<Account> result = ExampleController.getAccounts('MyAccount');
Assert.areEqual(accounts, result);
}
}
Avoid duplicates
Generic SOQLs can be keep in selector class.
public inherited sharing class AccountSelector {
public static SOQL Selector {
get {
return SOQL.of(Account.sObjectType).with(new List<sObjectField>{
Account.Name,
Account.AccountNumber
})
.systemMode()
.withoutSharing();
}
}
public static SOQL getByRecordType(String rtDevName) {
return Selector.with(new List<sObjectField>{
Account.BillingCity,
Account.BillingCountry
}).whereAre(SOQL.Filter.recordType().equal(rtDevName);
}
public static SOQL getById(Id accountId) {
return Selector.whereAre(SOQL.Filter.id().equal(accountId));
}
}
Default configuration
The selector class can provide default SOQL configuration like default fields, FLS settings, and sharing rules.
public inherited sharing class AccountSelector {
public static SOQL Selector {
get {
return SOQL.of(Account.sObjectType)
.with(new List<sObjectField>{ // default fields
Account.Id,
Account.Name
})
.systemMode(); // default FLS mode
}
}
}