From 22cd9d4cb83b3990de8e67cf7f8f6c7cbaddd2b3 Mon Sep 17 00:00:00 2001 From: Piotr Gajek Date: Mon, 15 May 2023 11:08:37 +0200 Subject: [PATCH] selector interface (#25) * selector interface * update documentation --- force-app/main/default/classes/SOQL.cls | 4 ++ .../classes/selector/AccountSelector.cls | 22 ++++---- .../classes/selector/ExampleController.cls | 2 +- website/docs/basic-features.md | 31 +++++------ website/docs/examples/debug.md | 20 ++++--- website/docs/examples/fls.md | 20 ++++--- website/docs/examples/group-by.md | 10 ++-- website/docs/examples/limit.md | 18 +++---- website/docs/examples/mocking.md | 8 +-- website/docs/examples/offset.md | 18 +++---- website/docs/examples/order-by.md | 20 ++++--- website/docs/examples/result.md | 26 +++++----- website/docs/examples/scope.md | 22 ++++---- website/docs/examples/select.md | 52 ++++++++----------- website/docs/examples/sharing-settings.md | 22 ++++---- website/docs/examples/subquery.md | 18 +++---- website/docs/examples/where.md | 18 +++---- website/docs/key-concepts.md | 22 ++++---- 18 files changed, 161 insertions(+), 192 deletions(-) diff --git a/force-app/main/default/classes/SOQL.cls b/force-app/main/default/classes/SOQL.cls index 99923e8..d1943f3 100644 --- a/force-app/main/default/classes/SOQL.cls +++ b/force-app/main/default/classes/SOQL.cls @@ -38,6 +38,10 @@ public inherited sharing class SOQL implements Queryable { } } + public interface Selector { + SOQL query(); + } + public interface Queryable { SOQL of(SObjectType ofObject); diff --git a/force-app/main/default/classes/selector/AccountSelector.cls b/force-app/main/default/classes/selector/AccountSelector.cls index 8a44748..a4fb49a 100644 --- a/force-app/main/default/classes/selector/AccountSelector.cls +++ b/force-app/main/default/classes/selector/AccountSelector.cls @@ -1,18 +1,16 @@ -public with sharing class AccountSelector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Name, - Account.AccountNumber - }) - .systemMode() - .withoutSharing(); - } +public with sharing class AccountSelector implements SOQL.Selector { + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Name, + Account.AccountNumber + }) + .systemMode() + .withoutSharing(); } public static SOQL byRecordType(String rt) { - return query.with(new List{ + return query().with(new List{ Account.BillingCity, Account.BillingCountry }).whereAre(SOQL.Filter.recordType().equal(rt)); diff --git a/force-app/main/default/classes/selector/ExampleController.cls b/force-app/main/default/classes/selector/ExampleController.cls index 4544a4e..0e3a5b8 100644 --- a/force-app/main/default/classes/selector/ExampleController.cls +++ b/force-app/main/default/classes/selector/ExampleController.cls @@ -1,7 +1,7 @@ public with sharing class ExampleController { public static List getPartnerAccounts(String accountName) { - return AccountSelector.query + return AccountSelector.query() .with(Account.BillingCity) .with(Account.BillingCountry) .whereAre(SOQL.FilterGroup diff --git a/website/docs/basic-features.md b/website/docs/basic-features.md index 9d730e7..a825ff9 100644 --- a/website/docs/basic-features.md +++ b/website/docs/basic-features.md @@ -125,7 +125,7 @@ Mocked queries won't make any SOQL's and simply return data set in method defini public with sharing class ExampleController { public static List getPartnerAccounts(String accountName) { - return AccountSelector.query + return AccountSelector.query() .with(Account.BillingCity) .with(Account.BillingCountry) .whereAre(SOQL.FilterGroup @@ -220,20 +220,19 @@ private class ExampleControllerTest { Generic SOQLs can be keep in selector class. ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType).with(new List{ + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ Account.Name, Account.AccountNumber }) .systemMode() .withoutSharing(); - } } - public static SOQL getByRecordType(String rtDevName) { + public static SOQL byRecordType(String rtDevName) { return query.with(new List{ Account.BillingCity, Account.BillingCountry @@ -247,16 +246,14 @@ public inherited sharing class AccountSelector { The selector class can provide default SOQL configuration like default fields, FLS settings, and sharing rules. ```apex -public inherited sharing class AccountSelector { - - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ // default fields - Account.Id, - Account.Name - }).systemMode(); // default FLS mode - } +public inherited sharing class AccountSelector implements SOQL.Selector { + + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ // default fields + Account.Id, + Account.Name + }).systemMode(); // default FLS mode } } ``` diff --git a/website/docs/examples/debug.md b/website/docs/examples/debug.md index 2234bdb..ece64de 100644 --- a/website/docs/examples/debug.md +++ b/website/docs/examples/debug.md @@ -7,23 +7,21 @@ sidebar_position: 14 See query String in debug logs. ```apex -public inherited sharing class AccountSelector { - - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } +public inherited sharing class AccountSelector implements SOQL.Selector { + + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccounts() { - return AccountSelector.query + return AccountSelector.query() .with(new List{ Account.BillingCity, Account.BillingCountry, diff --git a/website/docs/examples/fls.md b/website/docs/examples/fls.md index 571e6ce..b27a21f 100644 --- a/website/docs/examples/fls.md +++ b/website/docs/examples/fls.md @@ -9,24 +9,22 @@ Enforce or bypass FLS. `USER_MODE` is a default option. You can set `SYSTEM_MODE` for all queries by adding `.systemMode()` to selector class. ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }) - .systemMode(); //default FLS mode - } + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }) + .systemMode(); //default FLS mode } } public with sharing class MyController { public static List getAccountInSystemMode() { - return AccountSelector.query + return AccountSelector.query() .userMode() //override selector FLS mode .toList(); } diff --git a/website/docs/examples/group-by.md b/website/docs/examples/group-by.md index d9022f4..e9b0370 100644 --- a/website/docs/examples/group-by.md +++ b/website/docs/examples/group-by.md @@ -12,19 +12,17 @@ FROM Lead GROUP BY LeadSource ``` ```apex -public inherited sharing class LeadSelector { +public inherited sharing class LeadSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Lead.SObjectType); - } + public static SOQL query() { + return SOQL.of(Lead.SObjectType); } } public with sharing class MyController { public static List getGroupedLeads() { - return LeadSelector.query + return LeadSelector.query() .with(Lead.LeadSource) .groupBy(Lead.LeadSource) .toAggregated(); diff --git a/website/docs/examples/limit.md b/website/docs/examples/limit.md index 9c75cb7..7611d57 100644 --- a/website/docs/examples/limit.md +++ b/website/docs/examples/limit.md @@ -12,23 +12,21 @@ FROM Account LIMIT 1000 ``` ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SQOL query { - get { - return SQOL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } + public static SQOL query() { + return SQOL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccountsWithLimit() { - return AccountSelector.query + return AccountSelector.query() .setLimit(1000) .toList(); } diff --git a/website/docs/examples/mocking.md b/website/docs/examples/mocking.md index 6f13ef3..de7f8e1 100644 --- a/website/docs/examples/mocking.md +++ b/website/docs/examples/mocking.md @@ -13,7 +13,7 @@ Set mocking ID in Query declaration. public with sharing class ExampleController { public static List getAccountByName(String accountName) { - return AccountSelector.query + return AccountSelector.query() .with(Account.BillingCity) .with(Account.BillingCountry) .whereAre(SOQL.FilterGroup @@ -56,7 +56,7 @@ Set mocking ID in Query declaration. public with sharing class ExampleController { public static List getPartnerAccounts(String accountName) { - return AccountSelector.query + return AccountSelector.query() .with(Account.BillingCity) .with(Account.BillingCountry) .whereAre(SOQL.FilterGroup @@ -102,7 +102,7 @@ Set mocking ID in Query declaration. public with sharing class ExampleController { public static List getPartnerAccountsCount(String accountName) { - return AccountSelector.query + return AccountSelector.query() .whereAre(SOQL.FilterGroup .add(SOQL.Filter.with(Account.Name).contains(accountName)) .add(SOQL.Filter.recordType().equal('Partner')) @@ -143,7 +143,7 @@ Set mocking ID in Query declaration. public with sharing class ExampleController { public static List getPartnerAccounts(String accountName) { - return AccountSelector.query + return AccountSelector.query() .with(Account.BillingCity) .with(Account.BillingCountry) .whereAre(SOQL.FilterGroup diff --git a/website/docs/examples/offset.md b/website/docs/examples/offset.md index 710459c..316685a 100644 --- a/website/docs/examples/offset.md +++ b/website/docs/examples/offset.md @@ -12,23 +12,21 @@ FROM Account OFFSET 1000 ``` ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccountsWithOffset() { - return AccountSelector.query + return AccountSelector.query() .offset(1000) .toList(); } diff --git a/website/docs/examples/order-by.md b/website/docs/examples/order-by.md index 987ed3f..3179c5f 100644 --- a/website/docs/examples/order-by.md +++ b/website/docs/examples/order-by.md @@ -12,24 +12,22 @@ FROM Account ORDER BY Industry DESC NULLS FIRST, Id ASC NULLS FIRST ``` ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Lead.SObjectType) - .with(new List{ - Account.Id, - Account.Name, - Account.Industry - }); - } + public static SOQL query() { + return SOQL.of(Lead.SObjectType) + .with(new List{ + Account.Id, + Account.Name, + Account.Industry + }); } } public with sharing class MyController { public static List getAccounts() { - return AccountSelector.query + return AccountSelector.query() .orderBy(Account.Industry).sortDesc() .orderBy(Account.Id) .toList(); diff --git a/website/docs/examples/result.md b/website/docs/examples/result.md index 6ee7edf..3b6e2a4 100644 --- a/website/docs/examples/result.md +++ b/website/docs/examples/result.md @@ -7,52 +7,50 @@ sidebar_position: 15 Execut SOQL and get results. ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static Account getAccountById(Id accountId) { - return (Account) AccountSelector.query + return (Account) AccountSelector.query() .whereAre(SOQL.Filter.id().equal(accountId)) .toObject(); } public static List getAccountsByIds(List accountIds) { - return AccountSelector.query + return AccountSelector.query() .whereAre(SOQL.Filter.id().isIn(accountIds)) .toList(); } public static List getUniqueAccountNameAmount() { - return AccountSelector.query + return AccountSelector.query() .count(Account.Name, 'names') .toAggregated(); } public static Integer countAccounts() { - return AccountSelector.query + return AccountSelector.query() .count() .toInteger(); } public static Map getAccountMap() { - return AccountSelector.query + return AccountSelector.query() .toMap(); } public static Database.QueryLocator getAccountQueryLocator() { - return AccountSelector.query + return AccountSelector.query() .toQueryLocator(); } } diff --git a/website/docs/examples/scope.md b/website/docs/examples/scope.md index 5c2499b..f1c2097 100644 --- a/website/docs/examples/scope.md +++ b/website/docs/examples/scope.md @@ -16,29 +16,27 @@ FROM Account USING SCOPE TEAM ``` ```apex -public inherited sharing class AccountSelector { - - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } +public inherited sharing class AccountSelector implements SOQL.Selector { + + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getMineAccounts() { - return AccountSelector.query + return AccountSelector.query() .mineScope() .toList(); } public static List getTeamAccounts() { - return AccountSelector.query + return AccountSelector.query() .myTeamScope() .toList(); } diff --git a/website/docs/examples/select.md b/website/docs/examples/select.md index e9ad754..fc97250 100644 --- a/website/docs/examples/select.md +++ b/website/docs/examples/select.md @@ -15,23 +15,21 @@ SELECT Id, Name, BillingCity, BillingState, BillingStreet, BillingCountry FROM Account ``` ```apex -public inherited sharing class AccountSelector { - - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ //default fields - Account.Id, - Account.Name - }); - } +public inherited sharing class AccountSelector implements SOQL.Selector { + + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ //default fields + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccounts() { - return AccountSelector.query + return AccountSelector.query() .with(new List{ Account.BillingCity, Account.BillingState, @@ -51,23 +49,21 @@ SELECT Id, Name, CreatedBy.Id, CreatedBy.Name FROM Account ``` ```apex -public inherited sharing class AccountSelector { - - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) //default fields - .with(new List{ - Account.Id, - Account.Name - }); - } +public inherited sharing class AccountSelector implements SOQL.Selector { + + public static SOQL query() { + return SOQL.of(Account.SObjectType) //default fields + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccountsWithCreatedBy() { - return AccountSelector.query + return AccountSelector.query() .with('CreatedBy', new List{ User.Id, User.Name @@ -84,23 +80,21 @@ SELECT COUNT() FROM Account SELECT COUNT(Name) names FROM Account ``` ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType); - } + public static SOQL query() { + return SOQL.of(Account.SObjectType); } } public with sharing class MyController { public static Integer getAccountAmount() { - return AccountSelector.query.count().toInteger(); + return AccountSelector.query().count().toInteger(); } public static Integer getUniqueAccountNameAmount() { - return AccountSelector.query.count(Account.Name, 'names').toAggregated()[0].names; + return AccountSelector.query().count(Account.Name, 'names').toAggregated()[0].names; } } ``` diff --git a/website/docs/examples/sharing-settings.md b/website/docs/examples/sharing-settings.md index a3b3a4c..141a50f 100644 --- a/website/docs/examples/sharing-settings.md +++ b/website/docs/examples/sharing-settings.md @@ -11,30 +11,28 @@ Control sharing rules behavior. You can control sharing rules only in `.systemMode()`. ```apex -public inherited sharing class AccountSelector { - - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } +public inherited sharing class AccountSelector implements SOQL.Selector { + + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccountsWithSharing() { - return AccountSelector.query + return AccountSelector.query() .systemMode() .withSharing() .toList(); } public static List getAccountsWithoutSharing() { - return AccountSelector.query + return AccountSelector.query() .systemMode() .withoutSharing() .toList(); diff --git a/website/docs/examples/subquery.md b/website/docs/examples/subquery.md index b8cc04d..2f1b7b6 100644 --- a/website/docs/examples/subquery.md +++ b/website/docs/examples/subquery.md @@ -12,23 +12,21 @@ SELECT Id, Name, ( ) FROM Account ``` ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getAccountsWithContacts() { - return AccountSelector.query + return AccountSelector.query() .with(SOQL.SubQuery.of('Contacts') .with(new List{ Contact.Id, diff --git a/website/docs/examples/where.md b/website/docs/examples/where.md index eb3df80..3f2881c 100644 --- a/website/docs/examples/where.md +++ b/website/docs/examples/where.md @@ -12,23 +12,21 @@ FROM Account WHERE Id = :accountId OR Name LIKE :'%' + accountName + '%' ``` ```apex -public inherited sharing class AccountSelector { +public inherited sharing class AccountSelector implements SOQL.Selector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Id, - Account.Name - }); - } + public static SOQL query() + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Id, + Account.Name + }); } } public with sharing class MyController { public static List getByIdOrName(Id accountId, String accountName) { - return AccountSelector.query + return AccountSelector.query() .whereAre(SOQL.FilterGroup .add(SOQL.Filter.id().equal(accountId)) .add(SOQL.Filter.with(Account.Name).contains(accountName)) diff --git a/website/docs/key-concepts.md b/website/docs/key-concepts.md index 21d035b..02050b8 100644 --- a/website/docs/key-concepts.md +++ b/website/docs/key-concepts.md @@ -71,17 +71,15 @@ Most of the SOQLs on the project are one-time queries executed for specific busi 4. **Keep Selector Strengths** - Set default Selector configuration (default fields, sharing settings), keep generic methods. ```apex -public with sharing class AccountSelector { - public static SOQL query { - get { - return SOQL.of(Account.SObjectType) - .with(new List{ - Account.Name, - Account.AccountNumber - }) - .systemMode() - .withoutSharing(); - } +public with sharing class AccountSelector implements SOQL.Selector { + public static SOQL query() { + return SOQL.of(Account.SObjectType) + .with(new List{ + Account.Name, + Account.AccountNumber + }) + .systemMode() + .withoutSharing(); } public static SOQL getByRecordType(String rt) { @@ -97,7 +95,7 @@ public with sharing class AccountSelector { public with sharing class ExampleController { public static List getAccounts(String accountName) { - return AccountSelector.query + return AccountSelector.query() .with(Account.BillingCity) .with(Account.BillingCountry) .whereAre(SOQL.Filter.with(Account.Name).contains(accountName))