Last active
October 5, 2020 14:22
-
-
Save martyychang/2b1666caaba05bd4cf2fd0a9731942bf to your computer and use it in GitHub Desktop.
Generate Salesforce SELECT * query, Postgres CREATE TABLE statement and database-conf.xml content for a given object.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SobjectQueryGenerator { | |
private List<Schema.DescribeFieldResult> fieldDescList; | |
private Schema.DescribeSObjectResult sobjectDesc; | |
public SobjectQueryGenerator(Schema.DescribeSObjectResult sobjectDesc, Boolean includeCalculated) { | |
this.sobjectDesc = sobjectDesc; | |
this.fieldDescList = new List<Schema.DescribeFieldResult>(); | |
for (Schema.SObjectField eachField : this.sobjectDesc.fields.getMap().values()) { | |
Schema.DescribeFieldResult eachDfr = eachField.getDescribe(); | |
if (includeCalculated || eachDfr.isCalculated() == false) { | |
this.fieldDescList.add(eachDfr); | |
} | |
} | |
} | |
public String getDatabaseConfSqlString() { | |
List<String> fieldNames = new List<String>(); | |
List<String> fieldParams = new List<String>(); | |
Set<Schema.SoapType> castedTypes = new Set<Schema.SoapType> { | |
Schema.SoapType.BOOLEAN, | |
Schema.SoapType.DOUBLE, | |
Schema.SoapType.INTEGER | |
}; | |
for (Schema.DescribeFieldResult eachDfr : this.fieldDescList) { | |
String fieldName = this.getLowerCaseFieldName(eachDfr); | |
fieldNames.add(fieldName); | |
fieldParams.add( | |
!castedTypes.contains(eachDfr.getSoapType()) ? '@' + fieldName + '@' : | |
'CAST(@' + fieldName + '@ AS ' + this.getPostgresFieldType(eachDfr) + ')' | |
); | |
} | |
return String.join(new List<String> { | |
'INSERT INTO __schema__.' + this.sobjectDesc.getName().toLowerCase() + ' (', | |
String.join(fieldNames, ',\n'), | |
') VALUES (', | |
String.join(fieldParams, ',\n'), | |
')' | |
}, '\n'); | |
} | |
public String getDatabaseConfSqlParams() { | |
// Aggregate field names | |
List<String> fieldDefinitions = new List<String>(); | |
for (Schema.DescribeFieldResult eachDfr : this.fieldDescList) { | |
fieldDefinitions.add(this.getDatabaseConfSqlParamEntry(eachDfr)); | |
} | |
return String.join(new List<String> { | |
'<map>', | |
String.join(fieldDefinitions, '\n'), | |
'</map>' | |
}, '\n'); | |
} | |
public String getDatabaseConfSqlParamEntry(Schema.DescribeFieldResult fieldDesc) { | |
// Default the field name | |
String fieldName = this.getLowerCaseFieldName(fieldDesc); | |
// Figure out the type | |
Schema.SoapType fieldSoapType = fieldDesc.getSoapType(); | |
String fieldType = | |
fieldSoapType == Schema.SoapType.BOOLEAN ? 'java.lang.Boolean' : | |
fieldSoapType == Schema.SoapType.DATE ? 'java.sql.Date' : | |
fieldSoapType == Schema.SoapType.DATETIME ? 'java.sql.Timestamp' : | |
fieldSoapType == Schema.SoapType.DOUBLE ? 'java.lang.Double' : | |
fieldSoapType == Schema.SoapType.INTEGER ? 'java.lang.Integer' : | |
fieldSoapType == Schema.SoapType.TIME ? 'java.sql.Time' : | |
'java.lang.String'; // default | |
// Return the definition | |
return '<entry key="' + fieldName + '" value="' + fieldType + '"/>'; | |
} | |
public String getLowerCaseFieldName(Schema.DescribeFieldResult fieldDesc) { | |
String fieldName = fieldDesc.getName().toLowerCase(); | |
return fieldName.equals('id') ? 'sfid' : fieldName; | |
} | |
public String getSoqlQuery() { | |
List<String> fieldNames = new List<String>(); | |
for (Schema.DescribeFieldResult eachDfr : this.fieldDescList) { | |
fieldNames.add(eachDfr.getName()); | |
} | |
return String.join(new List<String> { | |
'SELECT', | |
String.join(fieldNames, ',\n'), | |
'FROM ' + this.sobjectDesc.getName() | |
}, '\n'); | |
} | |
public String getPostgresCreateTableQuery() { | |
List<String> fieldDefs = new List<String> { 'id serial' }; | |
for (Schema.DescribeFieldResult eachDfr : this.fieldDescList) { | |
fieldDefs.add(this.getPostgresFieldDefinition(eachDfr)); | |
} | |
// Return query | |
return String.join(new List<String> { | |
'CREATE TABLE __schema__.' + this.sobjectDesc.getName().toLowerCase() + ' (', | |
String.join(fieldDefs, ',\n'), | |
');' | |
}, '\n'); | |
} | |
public String getPostgresFieldDefinition(Schema.DescribeFieldResult fieldDesc) { | |
return this.getLowerCaseFieldName(fieldDesc) + ' ' + this.getPostgresFieldType(fieldDesc); | |
} | |
public String getPostgresFieldType(Schema.DescribeFieldResult dfr) { | |
return this.getPostgresFieldType(dfr.getSoapType(), dfr.getLength()); | |
} | |
public String getPostgresFieldType(Schema.SoapType fieldType, Integer length) { | |
return | |
fieldType == Schema.SoapType.BOOLEAN ? 'boolean' : | |
fieldType == Schema.SoapType.DATE ? 'date' : | |
fieldType == Schema.SoapType.DATETIME ? 'timestamp without time zone' : | |
fieldType == Schema.SoapType.DOUBLE ? 'double precision' : | |
fieldType == Schema.SoapType.ID ? 'character varying(18)' : | |
fieldType == Schema.SoapType.INTEGER ? 'integer' : | |
fieldType == Schema.SoapType.STRING ? 'character varying(' + length + ')' : | |
fieldType == Schema.SoapType.TIME ? 'time without time zone' : | |
'text'; // default, variable any length | |
} | |
public Messaging.SingleEmailMessage getSingleEmailMessage() { | |
Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); | |
email.setSubject(this.sobjectDesc.getName() + ' ...-conf.xml'); | |
email.setSaveAsActivity(false); | |
email.setPlainTextBody(String.join(new List<String> { | |
'Salesforce SOQL SELECT', '=====', this.getSoqlQuery(), '', | |
'Postgres CREATE TABLE', '=====', this.getPostgresCreateTableQuery(), '', | |
'database-conf.xml sqlString', '=====', this.getDatabaseConfSqlString(), '', | |
'database-conf.xml sqlParams', '=====', this.getDatabaseConfSqlParams() | |
}, '\n')); | |
return email; | |
} | |
} | |
SobjectQueryGenerator generator = new SobjectQueryGenerator(Schema.SObjectType.Task, false); | |
Messaging.SingleEmailMessage email = generator.getSingleEmailMessage(); | |
email.setTargetObjectId(UserInfo.getUserId()); | |
Messaging.sendEmail(new List<Messaging.Email> { email }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment