Skip to content

Instantly share code, notes, and snippets.

@the-last-byte
Last active August 21, 2023 05:17
Show Gist options
  • Save the-last-byte/50011f11e2582c315b2b99a803a340a0 to your computer and use it in GitHub Desktop.
Save the-last-byte/50011f11e2582c315b2b99a803a340a0 to your computer and use it in GitHub Desktop.
Script that prints a CSV of the Salesforce Schema to the console. This output can be imported into LucidChart (using the MySQL option) to create an ERD from your current schema.
/**
* Should only name, required, and lookup fields be exported. Set this to true
* if a (probably much smaller) result showing primarily objects and relationships
* is desired.
*/
final Boolean keyFieldsOnly = false;
/**
* Optional. List of SObject API names to return. If this is empty, all SObjects
* will be returned.
*/
final Set<String> objectApiNamesToInclude = new Set<String> {
//Optional - Add SObject API names here to filter which objects to export
};
final String dbms = 'mysql';
final String TABLE_SCHEMA = 'Schema';
final Map<String, SObjectType> globalDescribe = Schema.getGlobalDescribe();
final Set<String> keySetToUse = objectApiNamesToInclude?.isEmpty() == false
? objectApiNamesToInclude
: globalDescribe.keySet();
final List<String> rows = new List<String> {
//Header row
'dbms,' +
'TABLE_SCHEMA,' +
'TABLE_NAME,' +
'COLUMN_NAME,' +
'ORDINAL_POSITION,' +
'DATA_TYPE,' +
'CHARACTER_MAXIMUM_LENGTH,' +
'CONSTRAINT_TYPE,' +
'REFERENCED_TABLE_SCHEMA,' +
'REFERENCED_TABLE_NAME,' +
'REFERENCED_COLUMN_NAME'
};
for(String key : keySetToUse) {
final SObjectType objectType = globalDescribe.get(key);
Assert.isNotNull(key, 'Unable to find SObjectType: ' + key);
final DescribeSObjectResult describe = objectType.getDescribe();
Integer ordinalPosition = 1;
for(SObjectField field : describe.fields.getMap().values()) {
final DescribeFieldResult fieldDescribe = field.getDescribe();
if(keyFieldsOnly && fieldDescribe.getName() != 'Id' && fieldDescribe.getReferenceTo().isEmpty() && fieldDescribe.isNameField() == false && fieldDescribe.isUnique() == false) {
continue;
}
String constraintType = null;
String referencedSchema = null;
String referencedObject = null;
String referencedField = null;
if(fieldDescribe.getName() == 'Id') {
constraintType = 'PRIMARY KEY';
} else if(!fieldDescribe.getReferenceTo().isEmpty()) {
constraintType = 'FOREIGN KEY';
referencedObject = fieldDescribe.getReferenceTo()[0].getDescribe().getName();
referencedField = 'Id';//fieldDescribe.getRelationshipName();
referencedSchema = TABLE_SCHEMA;
}
final List<String> rowFields = new List<String> {
dbms,
TABLE_SCHEMA,
describe.getName(),
fieldDescribe.getName(),
String.valueOf(ordinalPosition++),
resolveDataType(fieldDescribe),
fieldDescribe.getLength() == 0
? ''
: String.valueOf(fieldDescribe.getLength()),
constraintType,
referencedSchema,
referencedObject,
referencedField
};
rows.add(String.join(rowFields, ', '));
}
}
//Print the CSV to the console
System.debug('\n\n' + String.join(rows, '\n'));
public static String resolveDataType(DescribeFieldResult describe) {
switch on describe.getType() {
when ADDRESS {
return 'address';
}
when ANYTYPE {
return 'any';
}
when BASE64 {
return 'base64';
}
when BOOLEAN {
return 'checkbox';
}
when COMBOBOX {
return 'picklist';
}
when COMPLEXVALUE {
return 'other';
}
when CURRENCY {
return 'currency';
}
when DATACATEGORYGROUPREFERENCE {
return 'other';
}
when DATE {
return 'date';
}
when DATETIME {
return 'datetime';
}
when DOUBLE {
return 'double';
}
when EMAIL {
return 'email';
}
when ENCRYPTEDSTRING {
return 'encrypted';
}
when ID {
return 'Id';
}
when INTEGER {
return 'integer';
}
when JSON {
return 'json';
}
when LOCATION {
return 'coordinates';
}
when LONG {
return 'long';
}
when MULTIPICKLIST {
return 'multi-picklist';
}
when PERCENT {
return 'percent';
}
when PHONE {
return 'phone';
}
when PICKLIST {
return 'picklist';
}
when REFERENCE {
final List<SObjectType> referenceTo = describe.getReferenceTo();
if(referenceTo.isEmpty()) {
return 'Lookup';
}
return 'Lookup(' + referenceTo[0].getDescribe().getName() + ')';
}
when SOBJECT {
return 'sobject';
}
when STRING {
return 'string';
}
when TEXTAREA {
return 'textarea';
}
when TIME {
return 'time';
}
when URL {
return 'url';
}
when else {
return 'text';
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment