diff --git a/sfdx-source/apex-extensions/main/unitOfWork/classes/fflib_SObjectUnitOfWork2.cls b/sfdx-source/apex-extensions/main/unitOfWork/classes/fflib_SObjectUnitOfWork2.cls index 2d39517..483dc7e 100644 --- a/sfdx-source/apex-extensions/main/unitOfWork/classes/fflib_SObjectUnitOfWork2.cls +++ b/sfdx-source/apex-extensions/main/unitOfWork/classes/fflib_SObjectUnitOfWork2.cls @@ -11,8 +11,106 @@ public virtual with sharing class fflib_SObjectUnitOfWork2 super(sObjectTypes, dml); } - public virtual void registerDirty(fflib_ISObjects domain) + public void registerNew(fflib_ISObjects domain, Schema.SObjectField relatedToParentField, SObject relatedToParentRecord) { - registerDirty(domain.getRecords()); + registerNew(domain.getRecords(), relatedToParentField, relatedToParentRecord); + } + /** + * Register newly created records to be inserted when commitWork is called, + * it also provides a reference to the single parent record instance (should also be registered as new separately) + * + * @param records newly created records of the same SObjectType to be inserted during commitWork + * @param relatedToParentField A SObjectField reference to the child field that associates the child record with its parent + * @param relatedToParentRecord A SObject instance of the parent record (should also be registered as new separately) + * + * To be removed after merged of https://github.com/apex-enterprise-patterns/fflib-apex-common/pull/400 + **/ + public void registerNew(List records, Schema.SObjectField relatedToParentField, SObject relatedToParentRecord) + { + if (records.isEmpty()) return; + + // Only validate the first record, by definition of the method signature all records should be new and of the same type. + Schema.SObjectType sObjectType = records.get(0).getSObjectType(); + String sObjectName = sObjectType.getDescribe().getName(); + assertForNonEventSObjectType(sObjectName); + assertForSupportedSObjectType(m_newListByType, sObjectName); + + for (SObject record : records) + { + if (record.getSObjectType() != sObjectType) + throw new UnitOfWorkException('All records should be of the same SObjectType'); + if (record.Id != null) + throw new UnitOfWorkException('Only new records can be registered as new'); + + m_newListByType.get(sObjectName).add(record); + if (relatedToParentRecord != null && relatedToParentField != null) + registerRelationship(record, relatedToParentField, relatedToParentRecord); + } + } + + public void registerDirty(fflib_ISObjects domain, Schema.SObjectField relatedToParentField, SObject relatedToParentRecord) + { + registerDirty(domain.getRecords(), relatedToParentField, relatedToParentRecord); + } + /** + * Register existing records to be updated when commitWork is called, + * it provide a reference to the parent record instance (should also be registered as new separately) + * + * @param records Existing records to be updated during commitWork + * @param relatedToParentField A SObjectField reference to the child field that associates the child record with its parent + * @param relatedToParentRecord A SObject instance of the parent record (should also be registered as new separately) + * + * To be removed after merged of https://github.com/apex-enterprise-patterns/fflib-apex-common/pull/400 + **/ + public void registerDirty(List records, Schema.SObjectField relatedToParentField, SObject relatedToParentRecord) + { + if (records.isEmpty()) return; + + // Only validate the first record, by definition of the method signature all records should be new and of the same type. + Schema.SObjectType sObjectType = records.get(0).getSObjectType(); + String sObjectName = sObjectType.getDescribe().getName(); + assertForNonEventSObjectType(sObjectName); + assertForSupportedSObjectType(m_dirtyMapByType, sObjectName); + + for (SObject record : records) + { + if (record.getSObjectType() != sObjectType) + throw new UnitOfWorkException('All records should be of the same SObjectType'); + if (record.Id == null) + throw new UnitOfWorkException('New records cannot be registered as dirty'); + + m_dirtyMapByType.get(sObjectName).put(record.Id, record); + if (relatedToParentRecord != null && relatedToParentField != null) + registerRelationship(record, relatedToParentField, relatedToParentRecord); + } + } + + // To be removed after merged of https://github.com/apex-enterprise-patterns/fflib-apex-common/pull/400 + private void assertForNonEventSObjectType(String sObjectType) + { + if (sObjectType.length() > 3 && sObjectType.right(3) == '__e') + { + throw new UnitOfWorkException( + String.format( + 'SObject type {0} must use registerPublishBeforeTransaction or ' + + 'registerPublishAfterTransaction methods to be used within this unit of work', + new List { sObjectType } + ) + ); + } + } + + // To be removed after merged of https://github.com/apex-enterprise-patterns/fflib-apex-common/pull/400 + private void assertForSupportedSObjectType(Map theMap, String sObjectType) + { + if (!theMap.containsKey(sObjectType)) + { + throw new UnitOfWorkException( + String.format( + 'SObject type {0} is not supported by this unit of work', + new List { sObjectType } + ) + ); + } } } \ No newline at end of file