Skip to content

Commit 9a8bee4

Browse files
committed
Add methods to retrieve specific records
1 parent 1e5eb56 commit 9a8bee4

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

sfdx-source/apex-common/main/classes/fflib_SObjects.cls

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,61 @@ public virtual class fflib_SObjects
5454
SObjectDescribe = sObjectType.getDescribe();
5555
}
5656

57+
/**
58+
* @param id Domain containing primary key (Id field) values
59+
*
60+
* @return Returns only the SObjects from the domain matching the given Ids.
61+
*/
62+
public virtual SObject getRecord(Id id)
63+
{
64+
List<SObject> result = getRecords(new Set<Id> {id});
65+
66+
return (result.size() == 0) ? null : result.get(0);
67+
}
68+
69+
/**
70+
* @return Returns the contents of the Domain by their primary Key ('Id' field)
71+
*/
72+
public virtual Map<Id, SObject> getRecordsById()
73+
{
74+
return new Map<Id, SObject>(getRecords());
75+
}
76+
77+
/**
78+
* @param ids A Set containing primary key (Id field) values
79+
*
80+
* @return Returns only the SObjects from the domain matching the given Ids.
81+
*/
82+
public virtual List<SObject> getRecords(Set<Id> ids)
83+
{
84+
Map<Id, SObject> sObjectsByIds = getRecordsById();
85+
List<SObject> result = new List<SObject>();
86+
for (Id id : ids)
87+
{
88+
if (sObjectsByIds.containsKey(id) == false) continue;
89+
90+
result.add(sObjectsByIds.get(id));
91+
}
92+
return result;
93+
}
94+
95+
/**
96+
* @param ids A Set containing primary key (Id field) values
97+
*
98+
* @return Returns the SObjects from the domain which are not part of the given Ids.
99+
*/
100+
public virtual List<SObject> getRecordsNotIn(Set<Id> ids)
101+
{
102+
List<SObject> result = new List<SObject>();
103+
for (SObject record : getRecords())
104+
{
105+
if (ids.contains(record.Id)) continue;
106+
107+
result.add(record);
108+
}
109+
return result;
110+
}
111+
57112
public virtual List<SObject> getRecords()
58113
{
59114
return (List<SObject>) getObjects();
@@ -141,6 +196,66 @@ public virtual class fflib_SObjects
141196
return result;
142197
}
143198

199+
/**
200+
* Get a map with the record mapped to the given Id field value
201+
* Key fields containing null values are omitted
202+
* This method is primarily intended for Id fields with a unique value.
203+
* If duplicate Id values exists the maps value will be overwritten.
204+
*
205+
* @param sObjectField The field to use as key for the map
206+
*
207+
* @return Returns a map with the record mapped to the given Id field value
208+
*
209+
* @example
210+
* Account account = Account.newInstance(records);
211+
* Map<Id, SObject> accountById = account.getRecordByIdField(Account.Id);
212+
*/
213+
@TestVisible
214+
protected virtual Map<Id, SObject> getRecordByIdField(Schema.SObjectField sObjectField)
215+
{
216+
Map<Id, SObject> result = new Map<Id, SObject>();
217+
for (SObject record : getRecords())
218+
{
219+
if (record.get(sObjectField) == null) continue;
220+
221+
result.put((Id) record.get(sObjectField), record);
222+
}
223+
return result;
224+
}
225+
226+
/**
227+
* Get a map with the records mapped to the given Id field value
228+
* Key fields containing null values are omitted
229+
*
230+
* @param sObjectField The field to use as key for the map
231+
*
232+
* @return Returns a map with the records mapped to the given Id field value
233+
*
234+
* @example
235+
* Contacts contacts = Contacts.newInstance(records);
236+
* Map<Id, List<SObject>> contactsByAccountId = contacts.getRecordsByIdField(Contact.AccountId);
237+
*/
238+
@TestVisible
239+
protected virtual Map<Id, List<SObject>> getRecordsByIdField(Schema.SObjectField sObjectField)
240+
{
241+
Map<Id, List<SObject>> result = new Map<Id, List<SObject>>();
242+
for (SObject record : getRecords())
243+
{
244+
Id fieldId = (Id) record.get(sObjectField);
245+
if (fieldId == null) continue;
246+
247+
if (result.containsKey(fieldId))
248+
{
249+
result.get(fieldId).add(record);
250+
}
251+
else
252+
{
253+
result.put(fieldId, new List<SObject> {record});
254+
}
255+
}
256+
return result;
257+
}
258+
144259
/**
145260
* @param sObjectField The Schema.SObjectField to check its value for a Blank value
146261
*

sfdx-source/apex-common/test/classes/fflib_SObjectsTest.cls

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,73 @@ private class fflib_SObjectsTest
4545
);
4646
}
4747

48+
@IsTest
49+
static void itShouldReturnRecordsByIds()
50+
{
51+
final Id accountIdA = fflib_IDGenerator.generate(Schema.Account.SObjectType);
52+
final Id accountIdB = fflib_IDGenerator.generate(Schema.Account.SObjectType);
53+
final Id accountIdC = fflib_IDGenerator.generate(Schema.Account.SObjectType);
54+
55+
fflib_SObjects domain = new fflib_SObjects(
56+
new List<SObject>
57+
{
58+
new Account(Id = accountIdA, Name = 'A'),
59+
new Account(Id = accountIdB, Name = 'B'),
60+
new Account(Id = accountIdC, Name = 'C')
61+
});
62+
63+
Set<Id> idsToRetrieve = new Set<Id> {accountIdA, accountIdC};
64+
65+
// Get just a subset of the domain
66+
List<SObject> subSetRecords = domain.getRecords(idsToRetrieve);
67+
Set<Id> resultIds = new Map<Id, SObject>(subSetRecords).keySet();
68+
System.assertEquals(2, subSetRecords.size(), 'Unexpected amount of record returned');
69+
System.assert(resultIds.containsAll(idsToRetrieve), 'Did not retrieve the correct records');
70+
71+
// Get all the other records
72+
List<SObject> allOtherRecords = domain.getRecordsNotIn(idsToRetrieve);
73+
System.assertEquals(1, allOtherRecords.size(), 'Unexpected amount of record returned');
74+
System.assertEquals(accountIdB, allOtherRecords.get(0).Id, 'Did not retrieve the correct record');
75+
76+
// Get a single specific record
77+
System.assertEquals(accountIdB, domain.getRecord(accountIdB).Id, 'Incorrect record retrieved from domain');
78+
}
79+
80+
@IsTest
81+
static void itShouldReturnRecordByIdField()
82+
{
83+
final Id accountIdA = fflib_IDGenerator.generate(Schema.Account.SObjectType);
84+
final Id accountIdB = fflib_IDGenerator.generate(Schema.Account.SObjectType);
85+
86+
fflib_SObjects domain = new fflib_SObjects(
87+
new List<SObject>
88+
{
89+
new Contact(AccountId = accountIdA),
90+
new Contact(AccountId = accountIdB)
91+
});
92+
Map<Id, SObject> contactByAccountId = domain.getRecordByIdField(Schema.Contact.AccountId);
93+
System.assertEquals(2, contactByAccountId.size());
94+
}
95+
96+
@IsTest
97+
static void itShouldReturnRecordsByIdField()
98+
{
99+
final Id accountIdA = fflib_IDGenerator.generate(Schema.Account.SObjectType);
100+
final Id accountIdB = fflib_IDGenerator.generate(Schema.Account.SObjectType);
101+
102+
fflib_SObjects domain = new fflib_SObjects(
103+
new List<SObject>
104+
{
105+
new Contact(AccountId = accountIdA),
106+
new Contact(AccountId = accountIdA),
107+
new Contact(AccountId = accountIdB)
108+
});
109+
Map<Id, List<SObject>> contactByAccountId = domain.getRecordsByIdField(Schema.Contact.AccountId);
110+
System.assertEquals(2, contactByAccountId.size());
111+
System.assertEquals(2, contactByAccountId.get(accountIdA).size());
112+
System.assertEquals(1, contactByAccountId.get(accountIdB).size());
113+
}
114+
48115
@IsTest
49116
static void itShouldReturnRecordsWithFieldValues()
50117
{

0 commit comments

Comments
 (0)