Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Commit

Permalink
Added support for parent field filtering and including children queries
Browse files Browse the repository at this point in the history
* SObjectRepository.cls has a new constructor that will automatically add all fields to the query for the specified SObject type - essentially, it's 'select * from sobject'
* SObjectRepository.cls now uses QueryFilter.cls to handle filtering on fields from the base object, parent object and grandparent objects - the constructor used for QueryFilter.cls determines the type of filter
* Children queries can now be included in your queries generated by SObjectRepository.cls.
* Logging is now enabled by default (via the custom setting NebulaLoggerSettings__c)
* A custom app (cleverly called 'Nebula') has been added - it includes 1 tab for the NebulaLog__c object
* Updated some field descriptions & help text on the various custom settings
* SObjectRecordTypes.cls now uses QueryBuilder.cls for its query generation
* QueryBuilder.whereField() method has been replaced by QueryBuilder.filterBy() - it expects either a single instance or a list of QueryFilter.cls
* SObjectRepository.queryFactory is now SObjectRepository.Query
* Miscellaneous cleanup - variable name standardisation, whitespace, etc
* Removed the method ISObjectRepository.getCreatedSinceTimeValue
* Delete CollectionUtils.cls
* TestingUtils.setReadOnlyField() has been refactored to allow any object type as a value & to prevent duplicating fields on the returned SObject
  • Loading branch information
jongpie authored Jun 9, 2017
1 parent 4d7c0bc commit 0d4630c
Show file tree
Hide file tree
Showing 91 changed files with 2,026 additions and 673 deletions.
7 changes: 7 additions & 0 deletions src/applications/Nebula.app
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomApplication xmlns="http://soap.sforce.com/2006/04/metadata">
<defaultLandingTab>NebulaLog__c</defaultLandingTab>
<formFactors>Large</formFactors>
<label>Nebula</label>
<tab>NebulaLog__c</tab>
</CustomApplication>
84 changes: 84 additions & 0 deletions src/classes/DML.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*************************************************************************************************
* This file is part of the Nebula Framework project, released under the MIT License. *
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. *
*************************************************************************************************/
public abstract class DML extends NebulaCore implements IDML {

private Schema.SObjectType sobjectType;

public DML(Schema.SObjectType sobjectType) {
this.sobjectType = sobjectType;
}

public virtual void insertRecords(SObject record) {
this.insertRecords(new List<SObject>{record});
}

public virtual void insertRecords(List<SObject> records) {
Database.insert(records);
}

public virtual void updateRecords(SObject record) {
this.updateRecords(new List<SObject>{record});
}

public virtual void updateRecords(List<SObject> records) {
Database.update(records);
}

public virtual void upsertRecords(SObject record) {
this.upsertRecords(this.castRecords(record));
}

public virtual void upsertRecords(List<SObject> records) {
Database.upsert(records);
}

public virtual void undeleteRecords(SObject record) {
this.undeleteRecords(new List<SObject>{record});
}

public virtual void undeleteRecords(List<SObject> records) {
Database.undelete(records);
}

public virtual void deleteRecords(SObject record) {
this.deleteRecords(new List<SObject>{record});
}

public virtual void deleteRecords(List<SObject> records) {
Database.delete(records);
}

public virtual void hardDeleteRecords(SObject record) {
this.hardDeleteRecords(new List<SObject>{record});
}

public virtual void hardDeleteRecords(List<SObject> records) {
this.deleteRecords(records);
if(!records.isEmpty()) Database.emptyRecycleBin(records);
}

// Not all objects will have external ID fields, so these methods are protected (instead of public)
// Any object that needs an upsert by external ID can expose these methods in their repos
protected virtual void upsertRecords(SObject record, Schema.SObjectField externalIdField) {
this.upsertRecords(this.castRecords(record), externalIdField);
}

protected virtual void upsertRecords(List<SObject> records, Schema.SObjectField externalIdField) {
Database.upsert(records, externalIdField);
}

private List<SObject> castRecords(SObject record) {
// Salesforce will only allow upsert calls for SObjects if a declared-type list is passed in.
// This is fine for the bulk method, where we can assume the caller is passing in an explicit list, but for a single record,
// the only way to successfully perform the upsert is to dynamically spin up a list of the SObject's type

String listType = 'List<' + this.sobjectType + '>';
List<SObject> castRecords = (List<SObject>)Type.forName(listType).newInstance();
castRecords.add(record);

return castRecords;
}

}
5 changes: 5 additions & 0 deletions src/classes/DML.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
62 changes: 62 additions & 0 deletions src/classes/DMLMock.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*************************************************************************************************
* This file is part of the Nebula Framework project, released under the MIT License. *
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. *
*************************************************************************************************/
@isTest
public class DMLMock {

public virtual class Base implements IDML {

public void insertRecords(SObject record) {
this.insertRecords(new List<SObject>{record});
}

public void insertRecords(List<SObject> recordList) {
TestingUtils.generateIds(recordList);
TestingUtils.insertedRecords.addAll(recordList);
}

public void updateRecords(SObject record) {
this.updateRecords(new List<SObject>{record});
}

public void updateRecords(List<SObject> recordList) {
TestingUtils.updatedRecords.addAll(recordList);
}

public void upsertRecords(SObject record) {
this.upsertRecords(new List<SObject>{record});
}

public void upsertRecords(List<SObject> recordList) {
TestingUtils.generateIds(recordList);
TestingUtils.upsertedRecords.addAll(recordList);
}

public void undeleteRecords(SObject record) {
this.undeleteRecords(new List<SObject>{record});
}

public void undeleteRecords(List<SObject> recordList) {
TestingUtils.undeletedRecords.addAll(recordList);
}

public void deleteRecords(SObject record) {
this.deleteRecords(new List<SObject>{record});
}

public void deleteRecords(List<SObject> recordList) {
if(recordList != null) TestingUtils.deletedRecords.addAll(recordList);
}

public void hardDeleteRecords(SObject record) {
this.hardDeleteRecords(new List<SObject>{record});
}

public void hardDeleteRecords(List<SObject> recordList) {
this.deleteRecords(recordList);
}

}

}
5 changes: 5 additions & 0 deletions src/classes/DMLMock.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
89 changes: 89 additions & 0 deletions src/classes/DMLMock_Tests.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*************************************************************************************************
* This file is part of the Nebula Framework project, released under the MIT License. *
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. *
*************************************************************************************************/
@isTest
private class DMLMock_Tests {

static IDML dmlRepo = new DMLMock.Base();
static Schema.Contact con = createContact();

@isTest
static void it_should_fake_dml_insert() {
Test.startTest();
dmlRepo.insertRecords(con);
Test.stopTest();

System.assert(TestingUtils.insertedRecords.size() > 0);
}

@isTest
static void it_should_fake_dml_update() {
Test.startTest();
dmlRepo.updateRecords(con);
Test.stopTest();

System.assert(!TestingUtils.updatedRecords.isEmpty());
}

@isTest
static void it_should_fake_dml_upsert() {
Test.startTest();
dmlRepo.upsertRecords(con);
Test.stopTest();

System.assert(!TestingUtils.upsertedRecords.isEmpty());
}

@isTest
static void it_should_fake_dml_delete() {
Test.startTest();
dmlRepo.deleteRecords(con);
Test.stopTest();

System.assert(!TestingUtils.deletedRecords.isEmpty());
}

@isTest
static void it_should_fake_dml_hard_delete() {
Test.startTest();
dmlRepo.hardDeleteRecords(con);
Test.stopTest();

System.assert(!TestingUtils.deletedRecords.isEmpty());
}

@isTest
static void it_should_fake_dml_undelete() {
Test.startTest();
dmlRepo.undeleteRecords(con);
Test.stopTest();

System.assert(!TestingUtils.undeletedRecords.isEmpty());
}

@isTest
static void it_should_mock_updating_read_only_fields_when_updating_data() {
Schema.Lead l = new Schema.Lead();
l = (Lead)TestingUtils.setReadOnlyField(l, Schema.Lead.IsConverted, true);

Test.startTest();
dmlRepo.updateRecords(l);
Test.stoptest();

SObject record = TestingUtils.updatedRecords[0];
System.assert(record instanceof Schema.Lead);
System.assert(record.get('IsConverted') != null);
}

private static Contact createContact() {
con = new Contact();
con.Email = 'rightHandMan@hamilton.com';
con.FirstName = 'George';
con.LastName = 'Washington';
con.LeadSource = 'Web';

return con;
}

}
5 changes: 5 additions & 0 deletions src/classes/DMLMock_Tests.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
2 changes: 1 addition & 1 deletion src/classes/Environment.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>38.0</apiVersion>
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
2 changes: 1 addition & 1 deletion src/classes/Environment_Tests.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>38.0</apiVersion>
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
11 changes: 11 additions & 0 deletions src/classes/Exceptions.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*************************************************************************************************
* This file is part of the Nebula Framework project, released under the MIT License. *
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. *
*************************************************************************************************/
public without sharing class Exceptions {

public class InvalidOperationException extends Exception {}
public class RecordTypeException extends Exception {}
public class SObjectTriggerHandlerException extends Exception {}

}
5 changes: 5 additions & 0 deletions src/classes/Exceptions.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
20 changes: 20 additions & 0 deletions src/classes/IDML.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*************************************************************************************************
* This file is part of the Nebula Framework project, released under the MIT License. *
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. *
*************************************************************************************************/
public interface IDML {

void insertRecords(SObject record);
void insertRecords(List<SObject> recordList);
void updateRecords(SObject record);
void updateRecords(List<SObject> recordList);
void upsertRecords(SObject record);
void upsertRecords(List<SObject> recordList);
void undeleteRecords(SObject record);
void undeleteRecords(List<SObject> recordList);
void deleteRecords(SObject record);
void deleteRecords(List<SObject> recordList);
void hardDeleteRecords(SObject record);
void hardDeleteRecords(List<SObject> recordList);

}
5 changes: 5 additions & 0 deletions src/classes/IDML.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
2 changes: 1 addition & 1 deletion src/classes/INebulaCore.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>38.0</apiVersion>
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
9 changes: 9 additions & 0 deletions src/classes/IQueryArgumentFormatter.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*************************************************************************************************
* This file is part of the Nebula Framework project, released under the MIT License. *
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. *
*************************************************************************************************/
public interface IQueryArgumentFormatter {

String getValue();

}
5 changes: 5 additions & 0 deletions src/classes/IQueryArgumentFormatter.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
14 changes: 11 additions & 3 deletions src/classes/IQueryBuilder.cls
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
*************************************************************************************************/
public interface IQueryBuilder {

// SOQL buildermethods
IQueryBuilder whereField(Schema.SObjectField field, QueryOperator operator, Object value);
// Query builder methods
IQueryBuilder filterBy(IQueryFilter queryFilter);
IQueryBuilder filterBy(List<IQueryFilter> queryFilters);

IQueryBuilder includeChildrenRecords(Schema.SObjectField childToParentRelationshipField, ISObjectRepository childSObjectRepository);
IQueryBuilder includeChildrenRecords(Map<Schema.SObjectField, ISObjectRepository> childFieldToChildSObjectRepositoryrMap);

IQueryBuilder orderBy(Schema.SObjectField orderByField);
IQueryBuilder orderBy(Schema.SObjectField orderByField, QuerySortOrder sortOrder);
IQueryBuilder orderBy(Schema.SObjectField orderByField, QuerySortOrder sortOrder, QueryNullSortOrder nullSortOrder);
IQueryBuilder orderBy(Schema.SObjectField orderByField, QuerySortOrder sortOrder, QueryNullSortOrder nullsSortOrder);

IQueryBuilder limitCount(Integer limitCount);
IQueryBuilder setAsUpdate();
Expand All @@ -20,4 +24,8 @@ public interface IQueryBuilder {
List<SObject> getQueryResults();
List<SObject> getSearchResults(String searchTerm, QuerySearchGroup searchGroup);

// Get the dyanmic query strings
String getQuery();
String getQuery(Schema.SObjectField sobjectField);

}
2 changes: 1 addition & 1 deletion src/classes/IQueryBuilder.cls-meta.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>38.0</apiVersion>
<apiVersion>39.0</apiVersion>
<status>Active</status>
</ApexClass>
Loading

0 comments on commit 0d4630c

Please sign in to comment.