From 9a8bee449be57c2c6369edfcc25b079c7814238c Mon Sep 17 00:00:00 2001 From: wimvelzeboer Date: Wed, 6 Apr 2022 09:41:23 +0100 Subject: [PATCH] Add methods to retrieve specific records --- .../main/classes/fflib_SObjects.cls | 115 ++++++++++++++++++ .../test/classes/fflib_SObjectsTest.cls | 67 ++++++++++ 2 files changed, 182 insertions(+) diff --git a/sfdx-source/apex-common/main/classes/fflib_SObjects.cls b/sfdx-source/apex-common/main/classes/fflib_SObjects.cls index 92089ace871..0ca4d5d6760 100644 --- a/sfdx-source/apex-common/main/classes/fflib_SObjects.cls +++ b/sfdx-source/apex-common/main/classes/fflib_SObjects.cls @@ -54,6 +54,61 @@ public virtual class fflib_SObjects SObjectDescribe = sObjectType.getDescribe(); } + /** + * @param id Domain containing primary key (Id field) values + * + * @return Returns only the SObjects from the domain matching the given Ids. + */ + public virtual SObject getRecord(Id id) + { + List result = getRecords(new Set {id}); + + return (result.size() == 0) ? null : result.get(0); + } + + /** + * @return Returns the contents of the Domain by their primary Key ('Id' field) + */ + public virtual Map getRecordsById() + { + return new Map(getRecords()); + } + + /** + * @param ids A Set containing primary key (Id field) values + * + * @return Returns only the SObjects from the domain matching the given Ids. + */ + public virtual List getRecords(Set ids) + { + Map sObjectsByIds = getRecordsById(); + List result = new List(); + for (Id id : ids) + { + if (sObjectsByIds.containsKey(id) == false) continue; + + result.add(sObjectsByIds.get(id)); + } + return result; + } + + /** + * @param ids A Set containing primary key (Id field) values + * + * @return Returns the SObjects from the domain which are not part of the given Ids. + */ + public virtual List getRecordsNotIn(Set ids) + { + List result = new List(); + for (SObject record : getRecords()) + { + if (ids.contains(record.Id)) continue; + + result.add(record); + } + return result; + } + public virtual List getRecords() { return (List) getObjects(); @@ -141,6 +196,66 @@ public virtual class fflib_SObjects return result; } + /** + * Get a map with the record mapped to the given Id field value + * Key fields containing null values are omitted + * This method is primarily intended for Id fields with a unique value. + * If duplicate Id values exists the maps value will be overwritten. + * + * @param sObjectField The field to use as key for the map + * + * @return Returns a map with the record mapped to the given Id field value + * + * @example + * Account account = Account.newInstance(records); + * Map accountById = account.getRecordByIdField(Account.Id); + */ + @TestVisible + protected virtual Map getRecordByIdField(Schema.SObjectField sObjectField) + { + Map result = new Map(); + for (SObject record : getRecords()) + { + if (record.get(sObjectField) == null) continue; + + result.put((Id) record.get(sObjectField), record); + } + return result; + } + + /** + * Get a map with the records mapped to the given Id field value + * Key fields containing null values are omitted + * + * @param sObjectField The field to use as key for the map + * + * @return Returns a map with the records mapped to the given Id field value + * + * @example + * Contacts contacts = Contacts.newInstance(records); + * Map> contactsByAccountId = contacts.getRecordsByIdField(Contact.AccountId); + */ + @TestVisible + protected virtual Map> getRecordsByIdField(Schema.SObjectField sObjectField) + { + Map> result = new Map>(); + for (SObject record : getRecords()) + { + Id fieldId = (Id) record.get(sObjectField); + if (fieldId == null) continue; + + if (result.containsKey(fieldId)) + { + result.get(fieldId).add(record); + } + else + { + result.put(fieldId, new List {record}); + } + } + return result; + } + /** * @param sObjectField The Schema.SObjectField to check its value for a Blank value * diff --git a/sfdx-source/apex-common/test/classes/fflib_SObjectsTest.cls b/sfdx-source/apex-common/test/classes/fflib_SObjectsTest.cls index d9dcd756b1d..844403e18c3 100644 --- a/sfdx-source/apex-common/test/classes/fflib_SObjectsTest.cls +++ b/sfdx-source/apex-common/test/classes/fflib_SObjectsTest.cls @@ -45,6 +45,73 @@ private class fflib_SObjectsTest ); } + @IsTest + static void itShouldReturnRecordsByIds() + { + final Id accountIdA = fflib_IDGenerator.generate(Schema.Account.SObjectType); + final Id accountIdB = fflib_IDGenerator.generate(Schema.Account.SObjectType); + final Id accountIdC = fflib_IDGenerator.generate(Schema.Account.SObjectType); + + fflib_SObjects domain = new fflib_SObjects( + new List + { + new Account(Id = accountIdA, Name = 'A'), + new Account(Id = accountIdB, Name = 'B'), + new Account(Id = accountIdC, Name = 'C') + }); + + Set idsToRetrieve = new Set {accountIdA, accountIdC}; + + // Get just a subset of the domain + List subSetRecords = domain.getRecords(idsToRetrieve); + Set resultIds = new Map(subSetRecords).keySet(); + System.assertEquals(2, subSetRecords.size(), 'Unexpected amount of record returned'); + System.assert(resultIds.containsAll(idsToRetrieve), 'Did not retrieve the correct records'); + + // Get all the other records + List allOtherRecords = domain.getRecordsNotIn(idsToRetrieve); + System.assertEquals(1, allOtherRecords.size(), 'Unexpected amount of record returned'); + System.assertEquals(accountIdB, allOtherRecords.get(0).Id, 'Did not retrieve the correct record'); + + // Get a single specific record + System.assertEquals(accountIdB, domain.getRecord(accountIdB).Id, 'Incorrect record retrieved from domain'); + } + + @IsTest + static void itShouldReturnRecordByIdField() + { + final Id accountIdA = fflib_IDGenerator.generate(Schema.Account.SObjectType); + final Id accountIdB = fflib_IDGenerator.generate(Schema.Account.SObjectType); + + fflib_SObjects domain = new fflib_SObjects( + new List + { + new Contact(AccountId = accountIdA), + new Contact(AccountId = accountIdB) + }); + Map contactByAccountId = domain.getRecordByIdField(Schema.Contact.AccountId); + System.assertEquals(2, contactByAccountId.size()); + } + + @IsTest + static void itShouldReturnRecordsByIdField() + { + final Id accountIdA = fflib_IDGenerator.generate(Schema.Account.SObjectType); + final Id accountIdB = fflib_IDGenerator.generate(Schema.Account.SObjectType); + + fflib_SObjects domain = new fflib_SObjects( + new List + { + new Contact(AccountId = accountIdA), + new Contact(AccountId = accountIdA), + new Contact(AccountId = accountIdB) + }); + Map> contactByAccountId = domain.getRecordsByIdField(Schema.Contact.AccountId); + System.assertEquals(2, contactByAccountId.size()); + System.assertEquals(2, contactByAccountId.get(accountIdA).size()); + System.assertEquals(1, contactByAccountId.get(accountIdB).size()); + } + @IsTest static void itShouldReturnRecordsWithFieldValues() {