-
Notifications
You must be signed in to change notification settings - Fork 10
/
RsapiDao.Update.cs
225 lines (186 loc) · 6.33 KB
/
RsapiDao.Update.cs
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
using kCura.Relativity.Client.DTOs;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Gravity.Base;
using Gravity.Exceptions;
using Gravity.Extensions;
namespace Gravity.DAL.RSAPI
{
public partial class RsapiDao
{
#region UPDATE Protected Stuff
protected void UpdateRdos(params RDO[] rdos)
{
InvokeProxyWithRetry(proxyToWorkspace => proxyToWorkspace.Repositories.RDO.Update(rdos)).GetResultData();
}
protected void UpdateRdo(RDO theRdo)
{
InvokeProxyWithRetry(proxyToWorkspace => proxyToWorkspace.Repositories.RDO.UpdateSingle(theRdo));
}
//inserts *child* lists of a parent artifact ID (not associated artifacts)
protected void UpdateChildListObjects<T>(IList<T> objectsToUpdate, int parentArtifactId)
where T : BaseDto, new()
{
var objectsToBeInsertedLookup = objectsToUpdate.ToLookup(x => x.ArtifactId == 0);
var objectsToBeInserted = objectsToBeInsertedLookup[true];
var objectsToBeUpdated = objectsToBeInsertedLookup[false];
//insert ones that do not exist
if (objectsToBeInserted.Any())
{
this.InvokeGenericMethod(typeof(T), nameof(InsertChildListObjects), objectsToBeInserted, parentArtifactId);
}
if (!objectsToBeUpdated.Any())
return;
var childObjectsInfo = BaseDto.GetRelativityObjectChildrenListInfos<T>();
//if do not have child objects in turn, we can take a shortcut
//and batch update all the items at once
if (childObjectsInfo.Count == 0)
{
//update RDOs in bulk
UpdateRdos(objectsToBeUpdated.Select(x => x.ToRdo()).ToArray());
//Cannot update files in bulk; do here
if (typeof(T).GetProperties().ToList()
.Any(c => c.DeclaringType.IsAssignableFrom(typeof(RelativityFile))))
{
foreach (var objectToBeUpdated in objectsToBeUpdated)
{
InsertUpdateFileFields(objectToBeUpdated, objectToBeUpdated.ArtifactId);
}
}
return;
}
//if have child lists, recurse (UpdateRelativityObject and UpdateChildListObjects form a recursion)
foreach (var objectToUpdate in objectsToBeUpdated)
{
UpdateRelativityObject(objectToUpdate, childObjectsInfo);
}
}
#endregion
public void UpdateRelativityObject<T>(BaseDto theObjectToUpdate)
where T : BaseDto , new()
{
var childObjectsInfo = BaseDto.GetRelativityObjectChildrenListInfos<T>();
UpdateRelativityObject(theObjectToUpdate, childObjectsInfo);
}
private void UpdateRelativityObject(
BaseDto theObjectToUpdate,
IEnumerable<KeyValuePair<PropertyInfo, RelativityObjectChildrenListAttribute>> childObjectsInfo)
{
//update root object
UpdateRdo(theObjectToUpdate.ToRdo());
//update files on object
InsertUpdateFileFields(theObjectToUpdate, theObjectToUpdate.ArtifactId);
//loop through each child object property
foreach (var childPropertyInfo in childObjectsInfo)
{
var childObjectsList = childPropertyInfo.Key.GetValue(theObjectToUpdate, null) as IList;
if (childObjectsList != null && childObjectsList.Count > 0)
{
Type childType = childPropertyInfo.Value.ChildType;
this.InvokeGenericMethod(childType, nameof(UpdateChildListObjects), childObjectsList, theObjectToUpdate.ArtifactId);
}
}
}
public void UpdateField<T>(int rdoID, Guid fieldGuid, object value)
where T : BaseDto, new()
{
PropertyInfo fieldProperty = typeof(T).GetProperties()
.Where(p => p.GetFieldGuidValueFromAttribute() == fieldGuid)
.FirstOrDefault();
if (fieldProperty == null)
throw new InvalidOperationException($"Field not on type {typeof(T)}");
object rdoValue;
if (!TryGetRelativityFieldValue<T>(fieldProperty, value, out rdoValue))
return;
var rdoValueFile = rdoValue as RelativityFile;
if (rdoValueFile != null)
{
InsertUpdateFileField(rdoValueFile, rdoID);
return;
}
RDO theRdo = new RDO(rdoID);
theRdo.ArtifactTypeGuids.Add(BaseDto.GetObjectTypeGuid<T>());
theRdo.Fields.Add(new FieldValue(fieldGuid, rdoValue));
UpdateRdo(theRdo);
}
private static bool TryGetRelativityFieldValue<T>(PropertyInfo fieldProperty, object value, out object rdoValue)
where T : BaseDto, new()
{
rdoValue = null;
Type fieldType = fieldProperty.PropertyType;
if (fieldType.IsGenericType)
{
if (fieldType.GetGenericTypeDefinition() == typeof(IList<>))
{
var valueList = value as IList;
if (valueList.HeuristicallyDetermineType().IsEnum)
{
var choices = valueList.Cast<Enum>()
.Select(x => new Choice(x.GetRelativityObjectAttributeGuidValue()))
.ToList();
rdoValue = choices; return true;
}
var genericArg = value.GetType().GetGenericArguments().FirstOrDefault();
if (genericArg?.IsSubclassOf(typeof(BaseDto)) == true)
{
rdoValue =
valueList.Cast<object>()
.Select(x => new Artifact((int)x.GetType().GetProperty(nameof(BaseDto.ArtifactId)).GetValue(x, null)))
.ToList();
return true;
}
if (genericArg?.IsEquivalentTo(typeof(int)) == true)
{
rdoValue = valueList.Cast<int>().Select(x => new Artifact(x)).ToList();
return true;
}
}
if (value == null)
{
return true;
}
if (value.GetType() == typeof(string) ||
value.GetType() == typeof(int) ||
value.GetType() == typeof(bool) ||
value.GetType() == typeof(decimal) ||
value.GetType() == typeof(DateTime))
{
rdoValue = value; return true;
}
return false;
}
RelativityObjectFieldAttribute fieldAttributeValue = fieldProperty.GetCustomAttribute<RelativityObjectFieldAttribute>();
if (fieldAttributeValue == null)
{
return false;
}
if ((fieldAttributeValue.FieldType == (int)RdoFieldType.File)
&& value.GetType().BaseType?.IsAssignableFrom(typeof(RelativityFile)) == true)
{
rdoValue = value; return true;
}
if ((fieldAttributeValue.FieldType == (int)RdoFieldType.User)
&& (value.GetType() == typeof(User)))
{
rdoValue = value; return true;
}
if (value.GetType().IsEnum)
{
rdoValue = new Choice(((Enum)value).GetRelativityObjectAttributeGuidValue());
return true;
}
if (value.GetType() == typeof(string) ||
value.GetType() == typeof(int) ||
value.GetType() == typeof(bool) ||
value.GetType() == typeof(decimal) ||
value.GetType() == typeof(DateTime))
{
rdoValue = value; return true;
}
return false;
}
}
}