public static void ReplaceAllItemRefs(IDbConnection connection, ISyncableStore store, ISyncableItemInfo remoteItemInfo, ISyncableItemInfo changedItemInfo) { // update *all* the itemData.item refs in all rows from remoteItemInfo to changedItemInfo var selectItemDataCommand = connection.CreateCommand(); selectItemDataCommand.CommandText = String.Format("SELECT ItemID, ItemData FROM SyncItems"); using (var reader = selectItemDataCommand.ExecuteReader()) { while (reader != null && reader.Read()) { JObject itemData = JObject.Parse((string)reader["ItemData"]); bool needToUpdate = false; foreach (var itemRefJson in itemData["item"]["itemRefs"]) { ISyncableItemInfo referencedItemInfo = SyncUtil.SyncableItemInfoFromJson(itemRefJson); if (referencedItemInfo.ItemType == remoteItemInfo.ItemType && referencedItemInfo.Created.ReplicaId == remoteItemInfo.Created.ReplicaId && referencedItemInfo.Created.ReplicaTickCount == remoteItemInfo.Created.ReplicaTickCount && referencedItemInfo.Modified.ReplicaId == remoteItemInfo.Modified.ReplicaId && referencedItemInfo.Modified.ReplicaTickCount == remoteItemInfo.Modified.ReplicaTickCount ) { itemRefJson["creationReplicaID"] = changedItemInfo.Created.ReplicaId; itemRefJson["creationReplicaTickCount"] = changedItemInfo.Created.ReplicaTickCount; itemRefJson["modificationReplicaID"] = changedItemInfo.Modified.ReplicaId; itemRefJson["modificationReplicaTickCount"] = changedItemInfo.Modified.ReplicaTickCount; needToUpdate = true; } } if (needToUpdate) { IDbCommand updateCommand = connection.CreateCommand(); updateCommand.CommandText = "UPDATE SyncItems SET ItemData=@ItemData, GlobalModifiedReplica=@ModifiedReplica, ModifiedTickCount=@TickCount WHERE ItemID=@ItemID"; updateCommand.AddParameter("@ItemID", reader["ItemID"]); updateCommand.AddParameter("@ItemData", itemData.ToString()); updateCommand.AddParameter("@TickCount", store.IncrementLocalRepilcaTickCount()); updateCommand.AddParameter("@ModifiedReplica", store.GetLocalReplicaId()); updateCommand.ExecuteNonQuery(); } } } }
private IEnumerable <SyncConflict> LoadConflicts(IDbConnection connection) { var conflicts = new List <SyncConflict>(); IDbCommand getInsertedItemsCommand = connection.CreateCommand(); getInsertedItemsCommand.CommandText = String.Format( "SELECT ItemID, SyncStatus, ItemType, GlobalCreatedReplica, CreatedTickCount, GlobalModifiedReplica, ModifiedTickCount, ItemData FROM SyncItems WHERE SyncStatus NOT IN ({0},{1},{2},{3},{4},{5})", (int)SyncStatus.Insert, (int)SyncStatus.Update, (int)SyncStatus.Delete, (int)SyncStatus.DeleteNonExisting, (int)SyncStatus.MayBeNeeded, (int)SyncStatus.InsertConflict ); using (var reader = getInsertedItemsCommand.ExecuteReader()) { while (reader != null && reader.Read()) { var createdReplicaInfo = SessionDbHelper.ReplicaInfoFromDataReader(reader, "Created"); var modifiedReplicaInfo = SessionDbHelper.ReplicaInfoFromDataReader(reader, "Modified"); var itemType = (string)reader["ItemType"]; var remoteItemInfo = new SyncableItemInfo { ItemType = itemType, Created = createdReplicaInfo, Modified = modifiedReplicaInfo, Deleted = false }; var itemId = Convert.ToInt64(reader["ItemID"]); var status = (SyncStatus)reader["SyncStatus"]; ISyncableItemInfo localItemInfo = _store.LocateCurrentItemInfo(remoteItemInfo); if (status == SyncStatus.UpdateConflict) { // Check to see if the "conflict" is actually an exact same update var builder = SyncUtil.JsonItemFromSyncableItemInfo(localItemInfo); _store.BuildItemData(localItemInfo, builder); var localItemData = new JObject { { "item", builder } }; var remoteItemData = JObject.Parse((string)reader["ItemData"]); var dupStatus = _store.GetDuplicateStatus(remoteItemInfo.ItemType, localItemData, remoteItemData); if (dupStatus == DuplicateStatus.Exact) { var tickCount = _store.IncrementLocalRepilcaTickCount(); var modifiedReplica = new ReplicaInfo { ReplicaId = _store.GetLocalReplicaId(), ReplicaTickCount = tickCount }; SessionDbHelper.ResolveItemNoData(connection, remoteItemInfo, SyncStatus.Update, modifiedReplica); // TODO: Really should have an update status that just updates the modified repos without doing everything else, but this should work continue; } } conflicts.Add(new SyncConflict(itemId, status, localItemInfo, remoteItemInfo)); } } return(conflicts); }