Skip to content

Commit

Permalink
Add methods to retrieve specific records
Browse files Browse the repository at this point in the history
  • Loading branch information
wimvelzeboer committed Apr 6, 2022
1 parent 1e5eb56 commit 9a8bee4
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 0 deletions.
115 changes: 115 additions & 0 deletions sfdx-source/apex-common/main/classes/fflib_SObjects.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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<SObject> result = getRecords(new Set<Id> {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<Id, SObject> getRecordsById()
{
return new Map<Id, SObject>(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<SObject> getRecords(Set<Id> ids)
{
Map<Id, SObject> sObjectsByIds = getRecordsById();
List<SObject> result = new List<SObject>();
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<SObject> getRecordsNotIn(Set<Id> ids)
{
List<SObject> result = new List<SObject>();
for (SObject record : getRecords())
{
if (ids.contains(record.Id)) continue;

result.add(record);
}
return result;
}

public virtual List<SObject> getRecords()
{
return (List<SObject>) getObjects();
Expand Down Expand Up @@ -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<Id, SObject> accountById = account.getRecordByIdField(Account.Id);
*/
@TestVisible
protected virtual Map<Id, SObject> getRecordByIdField(Schema.SObjectField sObjectField)
{
Map<Id, SObject> result = new Map<Id, SObject>();
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<Id, List<SObject>> contactsByAccountId = contacts.getRecordsByIdField(Contact.AccountId);
*/
@TestVisible
protected virtual Map<Id, List<SObject>> getRecordsByIdField(Schema.SObjectField sObjectField)
{
Map<Id, List<SObject>> result = new Map<Id, List<SObject>>();
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<SObject> {record});
}
}
return result;
}

/**
* @param sObjectField The Schema.SObjectField to check its value for a Blank value
*
Expand Down
67 changes: 67 additions & 0 deletions sfdx-source/apex-common/test/classes/fflib_SObjectsTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -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<SObject>
{
new Account(Id = accountIdA, Name = 'A'),
new Account(Id = accountIdB, Name = 'B'),
new Account(Id = accountIdC, Name = 'C')
});

Set<Id> idsToRetrieve = new Set<Id> {accountIdA, accountIdC};

// Get just a subset of the domain
List<SObject> subSetRecords = domain.getRecords(idsToRetrieve);
Set<Id> resultIds = new Map<Id, SObject>(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<SObject> 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<SObject>
{
new Contact(AccountId = accountIdA),
new Contact(AccountId = accountIdB)
});
Map<Id, SObject> 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<SObject>
{
new Contact(AccountId = accountIdA),
new Contact(AccountId = accountIdA),
new Contact(AccountId = accountIdB)
});
Map<Id, List<SObject>> 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()
{
Expand Down

0 comments on commit 9a8bee4

Please sign in to comment.