Skip to content

Instantly share code, notes, and snippets.

@jsullivanlive
Forked from kevinohara80/Async.cls
Created March 19, 2014 22:27
Show Gist options
  • Save jsullivanlive/9652762 to your computer and use it in GitHub Desktop.
Save jsullivanlive/9652762 to your computer and use it in GitHub Desktop.
/*
* Author: Kevin O'Hara
* Date: 02/10/2012
*
* Description: The Async class aims to circumvent a limitation of asynchronous (@future)
* methods in Salesforce. The current @future implementation will only allow for primitives
* or collections of primitives to be passed into an @future method. The Async class uses
* native JSON serialization/deserialization to allow for passing an SObject, or List<SObject>
* into an asynchronous method for DML operations. A helper method is also included for making
* the serialization processes simpler.
*/
public class Async {
/***********************/
/* ASYNC DML METHODS */
/***********************/
// insert sobjects
@future
public static void insertSObjects(String jsonString) {
List<SObject> sObjs = new List<SObject>();
try {
sObjs = (List<SObject>) JSON.deserialize(jsonString, List<SObject>.class);
} catch (Exception e) {
System.debug('Error in JSON deserialization');
}
if(!sObjs.isEmpty()) {
try {
insert sObjs;
} catch (Exception e) {
System.debug('Error inserting SObjects');
}
}
}
// upsert sobjects
@future
public static void upsertSObjects(String jsonString) {
List<SObject> sObjs = new List<SObject>();
try {
sObjs = (List<SObject>) JSON.deserialize(jsonString, List<SObject>.class);
} catch (Exception e) {
System.debug('Error in JSON deserialization');
}
if(!sObjs.isEmpty()) {
try {
upsert sObjs;
} catch (Exception e) {
System.debug('Error upserting SObjects');
}
}
}
// update sobjects
@future
public static void updateSObjects(String jsonString) {
List<SObject> sObjs = new List<SObject>();
try {
sObjs = (List<SObject>) JSON.deserialize(jsonString, List<SObject>.class);
} catch (Exception e) {
System.debug('Error in JSON deserialization');
}
if(!sObjs.isEmpty()) {
try {
update sObjs;
} catch (Exception e) {
System.debug('Error updating SObjects');
}
}
}
// delete sobjects
@future
public static void deleteSObjects(String jsonString) {
List<SObject> sObjs = new List<SObject>();
try {
sObjs = (List<SObject>) JSON.deserialize(jsonString, List<SObject>.class);
} catch (Exception e) {
System.debug('Error in JSON deserialization');
}
if(!sObjs.isEmpty()) {
try {
delete sObjs;
} catch (Exception e) {
System.debug('Error deleting SObjects');
}
}
}
/***********************/
/* HELPER METHODS */
/***********************/
// list of sobjects
public static String prepare(List<SObject> sObjs) {
try {
return JSON.serialize(sObjs);
} catch (Exception e) {
System.debug('Error in SObject List serialization');
}
}
// single sobject
public static String prepare(SObject sObj) {
try {
return JSON.serialize(new List<SObject>{sObj});
} catch (Exception e) {
System.debug('Error in SObject serialization');
}
}
}
@isTest
private class Async_Test {
static List<Lead> leads;
static {
leads = new List<Lead>();
Lead l1 = new Lead();
l1.FirstName = 'Test1';
l1.LastName = 'TestLast1';
l1.Email = '[email protected]';
l1.Status = 'New';
l1.Company = 'Test Co';
leads.add(l1);
Lead l2 = new Lead();
l2.FirstName = 'Test2';
l2.LastName = 'TestLast2';
l2.Email = '[email protected]';
l2.Status = 'New';
l2.Company = 'Test Co';
leads.add(l2);
}
static testMethod void testInsertList() {
Async.insertSObjects(Async.prepare(leads));
}
static testMethod void testInsertSingle() {
Async.insertSObjects(Async.prepare(leads.get(0)));
}
static testMethod void testUpdateList() {
insert leads;
for(Lead l : leads) {
l.FirstName = 'NewName';
}
Async.updateSObjects(Async.prepare(leads));
}
static testMethod void testUpdateSingle() {
insert leads;
leads.get(0).FirstName = 'NewName';
Async.updateSObjects(Async.prepare(leads.get(0)));
}
static testMethod void testUpsertList() {
insert leads;
for(Lead l : leads) {
l.FirstName = 'NewName';
}
Async.upsertSObjects(Async.prepare(leads));
}
static testMethod void testUpsertSingle() {
insert leads;
leads.get(0).FirstName = 'NewName';
Async.upsertSObjects(Async.prepare(leads.get(0)));
}
static testMethod void testDeleteList() {
insert leads;
for(Lead l : leads) {
l.FirstName = 'NewName';
}
Async.deleteSObjects(Async.prepare(leads));
}
static testMethod void testDeleteSingle() {
insert leads;
leads.get(0).FirstName = 'NewName';
Async.deleteSObjects(Async.prepare(leads.get(0)));
}
static testMethod void forceSingleInsertFailure() {
SObject s;
Async.insertSObjects(Async.prepare(s));
}
static testMethod void forceListInsertFailure() {
List<SObject> s = new List<SObject>();
Async.insertSObjects(Async.prepare(s));
}
static testMethod void forceSingleUpdateFailure() {
SObject s;
Async.updateSObjects(Async.prepare(s));
}
static testMethod void forceListUpdateFailure() {
List<SObject> s = new List<SObject>();
Async.updateSObjects(Async.prepare(s));
}
static testMethod void forceSingleUpsertFailure() {
SObject s;
Async.upsertSObjects(Async.prepare(s));
}
static testMethod void forceListUpsertFailure() {
List<SObject> s = new List<SObject>();
Async.upsertSObjects(Async.prepare(s));
}
static testMethod void forceSingleDeleteFailure() {
SObject s;
Async.deleteSObjects(Async.prepare(s));
}
static testMethod void forceListDeleteFailure() {
List<SObject> s = new List<SObject>();
Async.deleteSObjects(Async.prepare(s));
}
}
// EXAMPLE
// 1. Query some leads
List<Lead> lds = [SELECT Id, FirstName, LastName FROM Lead LIMIT 2];
// 2. Make some changes
for(Lead l : lds) {
l.FirstName = 'BLAHHH';
}
// 3. Use the prepare() helper method to serialize to JSON, then call the appropriate DML function
Async.updateSObjects(Async.prepare(lds));
// RESULT: Your DML is offloaded to an async request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment