forked from jamessimone/apex-dml-mocking
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Repository.cls
163 lines (142 loc) · 5.46 KB
/
Repository.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
public virtual without sharing class Repository implements IRepository {
private final IDML dml;
private final List<Schema.SObjectField> queryFields;
protected final Schema.SObjectType repoType;
private final Set<String> selectFields;
private final Map<Schema.SObjectField, String> childToRelationshipNames;
private final Map<String, Object> bindVars = new Map<String, Object>();
private System.AccessLevel accessLevel = System.AccessLevel.SYSTEM_MODE;
private Boolean baseSelectUsed = false;
public Repository(Schema.SObjectType repoType, List<Schema.SObjectField> queryFields, RepoFactory repoFactory) {
this(repoFactory);
this.queryFields = queryFields;
this.repoType = repoType;
this.selectFields = new Set<String>();
this.childToRelationshipNames = this.getChildRelationshipNames(repoType);
}
protected Repository(RepoFactory repoFactory) {
this.dml = repoFactory.getDml();
}
// SOQL
public virtual List<SObject> get(Query query) {
return this.get(new List<Query>{ query });
}
public virtual List<SObject> get(List<Query> queries) {
String finalQuery = this.getFinalQuery(queries);
return this.performQuery(finalQuery);
}
public virtual List<SObject> getAll() {
return this.get(new List<Query>());
}
public void addParentFields(List<Schema.SObjectField> parentTypes, List<Schema.SObjectField> parentFields) {
String parentBase = '';
for (SObjectField parentId : parentTypes) {
parentBase += parentId.getDescribe().getRelationshipName() + '.';
}
for (SObjectField parentField : parentFields) {
this.selectFields.add(parentBase + parentField.getDescribe().getName());
}
}
public void addChildFields(Schema.SObjectField childFieldToken, List<Schema.SObjectField> childFields) {
if (this.childToRelationshipNames.containsKey(childFieldToken)) {
String baseSubselect = '(SELECT {0} FROM {1})';
Set<String> childFieldNames = new Set<String>{ 'Id' };
for (SObjectField childField : childFields) {
childFieldNames.add(childField.getDescribe().getName());
}
this.selectFields.add(
String.format(
baseSubselect,
new List<String>{
String.join(new List<String>(childFieldNames), ','),
this.childToRelationshipNames.get(childFieldToken)
}
)
);
}
}
public Repository setAccessLevel(System.AccessLevel accessLevel) {
this.accessLevel = accessLevel;
return this;
}
protected virtual Set<String> addSelectFields() {
this.baseSelectUsed = true;
Set<String> fieldStrings = new Set<String>{ 'Id' };
for (SObjectField field : this.queryFields) {
fieldStrings.add(field.getDescribe().getName());
}
return fieldStrings;
}
protected virtual String getFinalQuery(List<Query> queries) {
return this.getSelectAndFrom() + this.addWheres(queries);
}
private Map<Schema.SObjectField, String> getChildRelationshipNames(Schema.SObjectType repoType) {
Map<Schema.SObjectField, String> localChildToRelationshipNames = new Map<Schema.SObjectField, String>();
for (Schema.ChildRelationship childRelationship : repoType.getDescribe().getChildRelationships()) {
localChildToRelationshipNames.put(childRelationship.getField(), childRelationship.getRelationshipName());
}
return localChildToRelationshipNames;
}
private String getSelectAndFrom() {
Set<String> localSelectFields = this.addSelectFields();
if (this.baseSelectUsed) {
localSelectFields.addAll(this.selectFields);
this.baseSelectUsed = false;
}
return 'SELECT ' + String.join(new List<String>(localSelectFields), ', ') + '\nFROM ' + this.repoType;
}
private String addWheres(List<Query> queries) {
List<String> wheres = new List<String>();
for (Query qry : queries) {
wheres.add(qry.toString());
this.bindVars.putAll(qry.getBindVars());
}
return wheres.isEmpty() ? '' : '\nWHERE ' + String.join(wheres, '\nAND ');
}
private List<SObject> performQuery(String finalQuery) {
System.debug('Query: \n' + finalQuery);
List<SObject> results = Database.queryWithBinds(finalQuery, this.bindVars, this.accessLevel);
System.debug('Number of results: ' + results.size() + '\nResults: \n' + results);
return results;
}
// DML
public SObject doInsert(SObject record) {
return this.dml.doInsert(record);
}
public List<SObject> doInsert(List<SObject> records) {
return this.dml.doInsert(records);
}
public SObject doUpdate(SObject record) {
return this.dml.doUpdate(record);
}
public List<SObject> doUpdate(List<SObject> records) {
return this.dml.doUpdate(records);
}
public SObject doUpsert(SObject record) {
return this.dml.doUpsert(record);
}
public List<SObject> doUpsert(List<SObject> records) {
return this.dml.doUpsert(records);
}
public List<SObject> doUpsert(List<SObject> records, Schema.SObjectField field) {
return this.dml.doUpsert(records, field);
}
public SObject doUndelete(SObject record) {
return this.dml.doUnDelete(record);
}
public List<SObject> doUndelete(List<SObject> records) {
return this.dml.doUndelete(records);
}
public void doDelete(SObject record) {
this.dml.doDelete(record);
}
public void doDelete(List<SObject> records) {
this.dml.doDelete(records);
}
public void doHardDelete(SObject record) {
this.dml.doHardDelete(record);
}
public void doHardDelete(List<SObject> records) {
this.dml.doHardDelete(records);
}
}