-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathDataDictionary.cls
143 lines (125 loc) · 7.32 KB
/
DataDictionary.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* ============================================================================================
@author @reality_jung
@instruction
Copy and paste the entire code into the anonymous window, remove comments and run
Open "Files" tab and find the CSV file named, <Timestamp> - DataDictionary.csv
Beautify the CSV file
@credits Thanks for trailblazers who provided warm advices to improve the code.
=============================================================================================== */
/* ============================================================================================
1. Setup a string array of sObject
2. Build a string for database.query into FieldDefinition
3. Setup CSV file header columns
=============================================================================================== */
String[] sObjectTypes = new String[]{'Account','Contact','Lead','Opportunity','Campaign','CampaignMember'}; //add more objects, recommend runing 5 objects at a time
String queryFields ='QualifiedApiName,Description,DataType,IsCompactLayoutable,IsCompound,IsFieldHistoryTracked,'
+ 'IsHighScaleNumber,IsHtmlFormatted,IsIndexed,IsListFilterable,IsListSortable,IsListVisible,'
+ 'IsNillable,IsPolymorphicForeignKey,IsSearchPrefilterable,IsWorkflowFilterable,LastModifiedDate,NamespacePrefix' ;
Map<String,String> mapResult = new Map<String,String>();
String csvHeader = 'Object Name,Field Name,Label,Type,Length,Precision,ByteLength,Digit,Relationship Name,isCalculated,isCustom,isDependentPicklist,isRestrictedPicklist,isExternalID,TreatNULLasZERO,isUnique,isSearchPrefilterable,getDefaultValue,Help Text,Formula,Picklist Values,'+ queryFields+'\n'; // csv header
String csvStr = csvHeader;
/* ============================================================================================
Loop 1 : Loop through "sObjectTypes: string array and make database query into FieldDeinition
one object at a time.
Loop 1-1 : Loop through returned sObject list from the FieldDefinition and build a map collection with field API name as key and sObject as value
Loop 1-2 : Loop through each Schema.SObjectField and populate each field's metadata
Loop 1-2-1 : Loop through an array of PicklistEntry and cascade picklist's label values into a string
=============================================================================================== */
// LOOP 1
for(String sObjName : sObjectTypes){
String query = 'SELECT '
+ queryFields
+ ' FROM FieldDefinition WHERE EntityDefinitionId = \''
+ sObjName
+'\' ORDER BY Label ASC';
List<sObject> fieldDescribe = Database.query(query);
Map<String,sObject> fieldNameObject = new Map<String,sObject>();
// LOOP 1-1
for(sObject oneField : fieldDescribe) {
String fieldName = oneField.get('QualifiedApiName').toString().toLowerCase();
fieldNameObject.put(fieldName,oneField);
system.debug(fieldNameObject);
}
sObjectType t = ((sObject)Type.forName('Schema.'+sObjName).newInstance()).getSObjectType();
DescribeSobjectResult r = t.getDescribe();
Map<String, Schema.SObjectField> fieldMap = r.fields.getMap();
Set<String> fieldNames = fieldMap.keySet();
// LOOP 1-2
for(String fieldName : fieldNames) {
DescribeFieldResult tmptField = fieldMap.get(fieldName).getDescribe();
csvStr += sObjName+','
+ tmptField.getSObjectField() +','
+ tmptField.getLabel().escapeCsv() + ','
+ tmptField.getType() + ','
+ tmptField.getLength() + ','
+ tmptField.getPrecision() + ','
+ tmptField.getByteLength() + ','
+ tmptField.getDigits() + ','
+ tmptField.getRelationshipName() + ','
+ tmptField.isCalculated() + ','
+ tmptField.isCustom() + ','
+ tmptField.isDependentPicklist() + ','
+ tmptField.isRestrictedPicklist() + ','
+ tmptField.isExternalID() + ','
+ tmptField.isFormulaTreatNullNumberAsZero() + ','
+ tmptField.isUnique() + ','
+ tmptField.isSearchPrefilterable() + ','
+ tmptField.getDefaultValue() + ','
+ tmptField.getInlineHelpText()?.escapeCsv() +','; // Safe Navigator Operator
if(tmptField.getCalculatedFormula()!=null){ // prevents dereference error
csvStr += tmptField.getCalculatedFormula().escapeCsv()+',';
}else{
csvStr += tmptField.getCalculatedFormula()+',';
}
if(tmptField.getPicklistValues()!=null){ // get a list of pickvalues' labels from Schema.PicklistEntry
String[] values = new String[]{};
String value = '';
// LOOP 1-2-1
for(Schema.PicklistEntry picklist : tmptField.getPicklistValues()){
values.add(picklist.getLabel());
}
if(values != null) {
value = String.join(values,' | ').escapeCsv();
}
csvStr += value + ',';
}else{
csvStr += ''+',';
}
sObject o = fieldNameObject.get(fieldName); // initialize sObject o
if(o != null){
csvStr += (String)o.get('QualifiedApiName') + ','
+ ((String)o.get('Description'))?.escapeCsv() + ','
+ ((String)o.get('DataType')).escapeCsv() + ','
+ o.get('IsCompactLayoutable') + ','
+ o.get('IsCompound')+ ','
+ o.get('IsFieldHistoryTracked')+ ','
+ o.get('IsHighScaleNumber') + ','
+ o.get('IsHtmlFormatted') + ','
+ o.get('IsIndexed') + ','
+ o.get('IsListFilterable') + ','
+ o.get('IsListSortable')+ ','
+ o.get('IsListVisible') + ','
+ o.get('IsNillable')+ ','
+ o.get('IsPolymorphicForeignKey') + ','
+ o.get('IsSearchPrefilterable') + ','
+ o.get('IsWorkflowFilterable')+ ','
+ o.get('LastModifiedDate') + ','
+ (String)o.get('NamespacePrefix');
}
csvStr += '\n';
}
}
/* ============================================================================================
Build CSV file & Insert it as a ContentVersions record
Check the "Files" tab for the uploaded CSV file.
ContentVersion API: https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_objects_contentversion.htm
Blob API : https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_blob.htm
Safe Navigator Operator : https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SafeNavigationOperator.htm
=============================================================================================== */
blob csvBlob = Blob.valueOf(csvStr); // convert String to binary data
ContentVersion conVer = new ContentVersion();
conVer.Origin = 'C'; // Content document from the user's personal library
conVer.PathOnClient = System.Now().format() +' - DataDictionary.csv'; // Set the file name with the extension; will use in preview
conVer.Title = 'Data Dictionary - ' + String.join(sObjectTypes,'-')+ ' - ' +System.Now().format(); // Display name of the file
conVer.VersionData = csvBlob; // based on base64 encoded
INSERT conVer; //Insert ContentVersion