//*** Post merge ***// public static void MergeProperties(IDictionary <string, object> newProperties, IDictionary <string, object> oldProperties) { // Iterates on each old properties var oldPropertiesEnumerator = oldProperties.GetEnumerator(); while (oldPropertiesEnumerator.MoveNext()) { // Gets old document key and value var oldProperty = oldPropertiesEnumerator.Current; var oldPropertyKey = oldProperty.Key; var oldPropertyValue = oldProperty.Value; // Checks if there is a new value to merge with the old one (if the new document contains the same key) Object newPropertyValue; if (newProperties.TryGetValue(oldPropertyKey, out newPropertyValue)) { if (newPropertyValue is IDictionary <string, object> ) { if (oldPropertyValue is JObject) { oldPropertyValue = (oldPropertyValue as JObject).ToObject <IDictionary <string, object> >(); } if (oldPropertyValue is IDictionary <string, object> ) { FullSyncUtils.MergeProperties(newPropertyValue as IDictionary <string, object>, oldPropertyValue as IDictionary <string, object>); } } else if (newPropertyValue is JObject && oldPropertyValue is JObject) { FullSyncUtils.MergeProperties(newPropertyValue as JObject, oldPropertyValue as JObject); } else if (newPropertyValue is JArray && oldPropertyValue is JArray) { FullSyncUtils.MergeArrayProperties(newPropertyValue as JArray, oldPropertyValue as JArray); } else { // If the new document has the same key but its value is not the same type than the old one or if their type are "simple" // Does nothing cause the right value is the new one } } else { // If the new document does not contain the key then adds it newProperties.Add(oldPropertyKey, oldPropertyValue); } } }
private static void MergeArrayProperties(JArray newArray, JArray oldArray) { int newArraySize = newArray.Count; int oldArraySize = oldArray.Count; // Iterates on old values for (int i = 0; i < oldArraySize; i++) { // Gets new and old values at this index JToken newArrayValue = null; if (i < newArraySize) { newArrayValue = newArray[i]; } JToken oldArrayValue = oldArray[i]; // If there is a new value to merge with the old one if (newArrayValue != null) { if (newArrayValue is JObject && oldArrayValue is JObject) { FullSyncUtils.MergeProperties(newArrayValue as JObject, oldArrayValue as JObject); } else if (newArrayValue is JArray && oldArrayValue is JArray) { FullSyncUtils.MergeArrayProperties(newArrayValue as JArray, oldArrayValue as JArray); } else { // If the new document has the same key but its value is not the same type than the old one or if their type are "simple" // Does nothing cause the right value is the new one } } else { newArray.Insert(i, oldArrayValue); } } }
private static void MergeProperties(JObject newProperties, JObject oldProperties) { // Iterates on each old properties var oldPropertiesEnumerable = oldProperties.Properties(); foreach (var oldProperty in oldPropertiesEnumerable) { // Gets old document key and value string oldPropertyKey = oldProperty.Name; var oldPropertyValue = oldProperty.Value; // Checks if there is a new value to merge with the old one (if the new document contains the same key) JToken newPropertyValue; if (newProperties.TryGetValue(oldPropertyKey, out newPropertyValue)) { // Get the new document value //Object newPropertyValue; // newProperties.TryGetValue(oldPropertyKey, out newPropertyValue); if (newPropertyValue is JObject && oldPropertyValue is JObject) { FullSyncUtils.MergeProperties(newPropertyValue as JObject, oldPropertyValue as JObject); } else if (newPropertyValue is JArray && oldPropertyValue is JArray) { FullSyncUtils.MergeArrayProperties(newPropertyValue as JArray, oldPropertyValue as JArray); } else { // If the new document has the same key but its value is not the same type than the old one or if their type are "simple" // Does nothing cause the right value is the new one } } else { // If the new document does not contain the key then adds it newProperties.Add(oldPropertyKey, oldPropertyValue); } } }
//*** PostDocument ***// public async override Task <object> HandlePostDocumentRequest(string databaseName, FullSyncPolicy fullSyncPolicy, IDictionary <string, object> parameters) { var fullSyncDatabase = await GetOrCreateFullSyncDatabase(databaseName); // Gets the subkey separator parameter string subkeySeparatorParameterValue = C8oUtils.GetParameterStringValue(parameters, FullSyncPostDocumentParameter.SUBKEY_SEPARATOR.name, false); if (subkeySeparatorParameterValue == null) { subkeySeparatorParameterValue = "."; } // Filters and modifies wrong properties var newProperties = new Dictionary <string, object>(); foreach (var parameter in parameters) { string parameterName = parameter.Key; if (parameterName.Equals(C8oFullSync.FULL_SYNC__REV)) { newProperties[parameterName] = parameter.Value; } else if (!parameterName.StartsWith("__") && !parameterName.StartsWith("_use_")) { // Retrieves ??? var objectParameterValue = C8oUtils.GetParameterJsonValue(parameter); //Manager.SharedInstance. ow = null; if (objectParameterValue is JObject) { objectParameterValue = (objectParameterValue as JObject).ToObject <Dictionary <string, object> > (); } // Checks if the parameter name is splittable var paths = parameterName.Split(new String[] { subkeySeparatorParameterValue }, StringSplitOptions.None); // Regex.Split(parameterName, subkeySeparatorParameterValue); if (paths.Length > 1) { // The first substring becomes the key parameterName = paths[0]; // Next substrings create a hierarchy which will becomes json subkeys int count = paths.Length - 1; while (count > 0) { var tmpObject = new Dictionary <string, object>(); tmpObject[paths[count]] = objectParameterValue; objectParameterValue = tmpObject; count--; } if (newProperties.ContainsKey(parameterName) && newProperties[parameterName] is IDictionary <string, object> ) { FullSyncUtils.MergeProperties(objectParameterValue as IDictionary <string, object>, newProperties[parameterName] as IDictionary <string, object>); } } newProperties[parameterName] = objectParameterValue; } } var createdDocument = C8oFullSyncCblEnum.PostDocument(fullSyncPolicy, fullSyncDatabase.Database, newProperties); string documentId = createdDocument.Id; string currentRevision = createdDocument.CurrentRevisionId; return(new FullSyncDocumentOperationResponse(documentId, currentRevision, true)); }
//*** FullSyncPolicies ***// private static void InitFullSyncPolicies() { fullSyncPolicies = new Dictionary <FullSyncPolicy, Func <Database, IDictionary <string, object>, Document> >(); FullSyncPolicy policy; Func <Database, IDictionary <string, object>, Document> func; // NONE policy = FullSyncPolicy.NONE; func = (database, newProperties) => { Document createdDocument; try { string documentId = C8oUtils.GetParameterStringValue(newProperties, C8oFullSync.FULL_SYNC__ID, false); // removes special properties newProperties.Remove(C8oFullSync.FULL_SYNC__ID); // Creates a new document or get an existing one (if the ID is specified) createdDocument = (documentId == null) ? database.CreateDocument() : database.GetDocument(documentId); createdDocument.PutProperties(newProperties); } catch (CouchbaseLiteException e) { throw new C8oCouchbaseLiteException(C8oExceptionMessage.FullSyncPutProperties(newProperties), e); } return(createdDocument); }; fullSyncPolicies.Add(policy, func); // CREATE policy = FullSyncPolicy.CREATE; func = (database, newProperties) => { Document createdDocument; try { // Removes specials properties in order to create a new document newProperties.Remove(C8oFullSync.FULL_SYNC__ID); newProperties.Remove(C8oFullSync.FULL_SYNC__REV); createdDocument = database.CreateDocument(); createdDocument.PutProperties(newProperties); } catch (CouchbaseLiteException e) { throw new C8oCouchbaseLiteException(C8oExceptionMessage.FullSyncPutProperties(newProperties), e); } return(createdDocument); }; fullSyncPolicies.Add(policy, func); // OVERRIDE policy = FullSyncPolicy.OVERRIDE; func = (database, newProperties) => { Document createdDocument; try { // Gets the document ID string documentId = C8oUtils.GetParameterStringValue(newProperties, C8oFullSync.FULL_SYNC__ID, false); // Removes special properties in order to create a new document newProperties.Remove(C8oFullSync.FULL_SYNC__ID); newProperties.Remove(C8oFullSync.FULL_SYNC__REV); // Creates a new document or get an existing one (if the ID is specified) if (documentId == null) { createdDocument = database.CreateDocument(); } else { createdDocument = database.GetDocument(documentId); // Must add the current revision to the properties var currentRevision = createdDocument.CurrentRevision; if (currentRevision != null) { newProperties[C8oFullSync.FULL_SYNC__REV] = currentRevision.Id; } } createdDocument.PutProperties(newProperties); } catch (CouchbaseLiteException e) { throw new C8oCouchbaseLiteException(C8oExceptionMessage.FullSyncPutProperties(newProperties), e); } return(createdDocument); }; fullSyncPolicies.Add(policy, func); // MERGE policy = FullSyncPolicy.MERGE; func = (database, newProperties) => { Document createdDocument; try { // Gets the document ID string documentId = C8oUtils.GetParameterStringValue(newProperties, C8oFullSync.FULL_SYNC__ID, false); // Removes special properties in order to create a new document newProperties.Remove(C8oFullSync.FULL_SYNC__ID); newProperties.Remove(C8oFullSync.FULL_SYNC__REV); // Creates a new document or get an existing one (if the ID is specified) if (documentId == null) { createdDocument = database.CreateDocument(); } else { createdDocument = database.GetDocument(documentId); } // Merges old properties with the new ones var oldProperties = createdDocument.Properties; if (oldProperties != null) { FullSyncUtils.MergeProperties(newProperties, oldProperties); } createdDocument.PutProperties(newProperties); } catch (CouchbaseLiteException e) { throw new C8oCouchbaseLiteException(C8oExceptionMessage.FullSyncPutProperties(newProperties), e); } return(createdDocument); }; fullSyncPolicies.Add(policy, func); }