Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add domain methods to retrieve specific records #405

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -233,6 +288,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 field 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 @@ -87,6 +87,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