internal SyncConflict(long itemId, SyncStatus syncStatus, ISyncableItemInfo localItemInfo, ISyncableItemInfo remoteItemInfo) { _itemId = itemId; _syncStatus = syncStatus; _remoteItemInfo = remoteItemInfo; _localItemInfo = localItemInfo; }
private async Task SaveSyncData(IDbConnection connection, ISyncableItemInfo remoteSyncableItemInfo, SyncStatus status) { var data = JObject.Parse("{item:{itemRefs:[]}}"); if (!remoteSyncableItemInfo.Deleted) { var request = new JObject { { "sessionID", _remoteSessionId }, { "item", SyncUtil.SyncableItemInfoToJson(remoteSyncableItemInfo) } }; var response = await _transport.TransportAsync(SyncEndpoint.GetItemData, request); data = response; } SessionDbHelper.SaveItemData(connection, remoteSyncableItemInfo, status, data); var itemRefs = (JArray)data["item"]["itemRefs"]; foreach (var item in itemRefs) { ISyncableItemInfo itemRefInfo = SyncUtil.SyncableItemInfoFromJson(item); ISyncableItemInfo localItemRefInfo = _store.LocateCurrentItemInfo(itemRefInfo); if (localItemRefInfo != null && localItemRefInfo.Deleted) { await SaveSyncData(connection, itemRefInfo, SyncStatus.MayBeNeeded); } } }
public static JObject JsonItemFromSyncableItemInfo(ISyncableItemInfo syncItemInfo) { var item = SyncableItemInfoToJson(syncItemInfo); item.Add("itemRefs", new JArray()); return(item); }
public void SaveItemData(ISyncableItemInfo itemInfo, JObject itemData) { RemoveTombstone(itemInfo); HandlerForItemType(itemInfo.ItemType).SaveItemData(itemInfo, itemData); _pendingUpdates.Add(itemInfo); }
public static JToken GenerateItemRefAndIndex(JObject builder, ISyncableItemInfo syncableItemInfo) { var itemRef = new JObject { { "itemRefIndex", AddJsonItemRef(builder, syncableItemInfo) } }; return(itemRef); }
private void RemoveTombstone(ISyncableItemInfo itemInfo) { var handler = HandlerForItemType(itemInfo.ItemType); IDbCommand command = _connection.CreateCommand(); command.CommandText = "DELETE FROM Tombstones WHERE ItemType=@ItemType AND CreatedReplica=@CreatedReplica AND CreatedTickCount=@CreatedTickCount"; command.AddParameter("@ItemType", handler.TypeId); command.AddParameter("@CreatedReplica", GetLocalReplicaIdForGlobalReplicaId(itemInfo.Created.ReplicaId)); command.AddParameter("@CreatedTickCount", itemInfo.Created.ReplicaTickCount); command.ExecuteNonQuery(); }
public void DeleteItem(ISyncableItemInfo itemInfo) { InsertTombstone(itemInfo); if (HandlerForItemType(itemInfo.ItemType).DeleteItem(itemInfo)) { _pendingDeletes.Add(itemInfo); } else { _pendingUpdates.Add(itemInfo); } }
private void InsertTombstone(ISyncableItemInfo itemInfo) { var handler = HandlerForItemType(itemInfo.ItemType); IDbCommand command = _connection.CreateCommand(); command.CommandText = "INSERT INTO Tombstones(ItemType, CreatedReplica, CreatedTickCount, ModifiedReplica, ModifiedTickCount) VALUES (@ItemType,@CreatedReplica,@CreatedTick,@ModifiedReplica,@ModifiedTickCount)"; command.AddParameter("@ItemType", handler.TypeId); command.AddParameter("@CreatedReplica", GetLocalReplicaIdForGlobalReplicaId(itemInfo.Created.ReplicaId)); command.AddParameter("@CreatedTick", itemInfo.Created.ReplicaTickCount); command.AddParameter("@ModifiedReplica", GetLocalReplicaIdForGlobalReplicaId(itemInfo.Modified.ReplicaId)); command.AddParameter("@ModifiedTickCount", itemInfo.Modified.ReplicaTickCount); command.ExecuteNonQuery(); }
public JObject GetItemData(JObject request) { ISyncableItemInfo requestedItemInfo = SyncUtil.SyncableItemInfoFromJson(request["item"]); var json = new JObject(); JObject builder = SyncUtil.JsonItemFromSyncableItemInfo(requestedItemInfo); _store.BuildItemData(requestedItemInfo, builder); json.Add(new JProperty("item", builder)); return(json); }
private static JObject JsonItemRefFromSyncableItemInfo(ISyncableItemInfo syncItemInfo) { var item = new JObject { { "itemType", syncItemInfo.ItemType }, { "creationReplicaID", syncItemInfo.Created.ReplicaId }, { "creationReplicaTickCount", syncItemInfo.Created.ReplicaTickCount }, { "modificationReplicaID", syncItemInfo.Modified.ReplicaId }, { "modificationReplicaTickCount", syncItemInfo.Modified.ReplicaTickCount } }; return(item); }
public override void BuildItemData(ISyncableItemInfo itemInfo, JObject builder) { IBook book = Adapter.BookRepository.getBookByRowID(GetRowIdFromItemInfo(itemInfo)); builder.Add("title", book.Title); JArray authors = new JArray(); foreach (IPerson author in book.Authors) { ReplicaItemId id = ((Person)author).Id; authors.Add(SyncUtil.GenerateItemRefAndIndex(builder, getSyncableItemInfoFrom(id))); } builder.Add("authors", authors); }
public static JObject SyncableItemInfoToJson(ISyncableItemInfo syncItemInfo) { var item = new JObject { { "itemType", syncItemInfo.ItemType }, { "creationReplicaID", syncItemInfo.Created.ReplicaId }, { "creationReplicaTickCount", syncItemInfo.Created.ReplicaTickCount }, { "modificationReplicaID", syncItemInfo.Modified.ReplicaId }, { "modificationReplicaTickCount", syncItemInfo.Modified.ReplicaTickCount }, { "deleted", syncItemInfo.Deleted } }; return(item); }
public static void ResolveItemNoData(IDbConnection connection, ISyncableItemInfo itemInfo, SyncStatus resolvedStatus, IReplicaInfo modifiedReplica) { var command = connection.CreateCommand(); command.CommandText = "UPDATE SyncItems SET SyncStatus=@SyncStatus, GlobalModifiedReplica=@ModifiedReplica, ModifiedTickCount=@ModifiedTick WHERE GlobalCreatedReplica=@CreatedReplica AND CreatedTickCount=@CreatedTick AND ItemType=@ItemType"; command.AddParameter("@SyncStatus", resolvedStatus); command.AddParameter("@ItemType", itemInfo.ItemType); command.AddParameter("@CreatedReplica", itemInfo.Created.ReplicaId); command.AddParameter("@CreatedTick", itemInfo.Created.ReplicaTickCount); command.AddParameter("@ModifiedReplica", modifiedReplica.ReplicaId); command.AddParameter("@ModifiedTick", modifiedReplica.ReplicaTickCount); command.ExecuteNonQuery(); }
public long GetRowIdFromItemInfo(ISyncableItemInfo itemInfo) { IDbCommand command = Adapter.Connection.CreateCommand(); command.CommandText = String.Format("SELECT RowID FROM {0} WHERE CreatedReplica=@CreatedReplica AND CreatedTickCount=@CreatedTick", DbTable); command.AddParameter("@CreatedReplica", adapter.GetLocalReplicaIdForGlobalReplicaId(itemInfo.Created.ReplicaId)); command.AddParameter("@CreatedTick", itemInfo.Created.ReplicaTickCount); object o = command.ExecuteScalar(); if (o == null) { return(-1); } return(Convert.ToInt64(o)); }
public static void SaveItemData(IDbConnection connection, ISyncableItemInfo remoteSyncableItemInfo, SyncStatus status, JObject data) { var command = connection.CreateCommand(); command.CommandText = "INSERT INTO SyncItems(SyncStatus, ItemType, GlobalCreatedReplica, CreatedTickCount, GlobalModifiedReplica, ModifiedTickCount, ItemData) VALUES(@SyncStatus,@ItemType,@CreatedReplica,@CreatedTick,@ModifiedReplica,@ModifiedTick,@ItemData)"; command.AddParameter("@SyncStatus", status); command.AddParameter("@ItemType", remoteSyncableItemInfo.ItemType); command.AddParameter("@CreatedReplica", remoteSyncableItemInfo.Created.ReplicaId); command.AddParameter("@CreatedTick", remoteSyncableItemInfo.Created.ReplicaTickCount); command.AddParameter("@ModifiedReplica", remoteSyncableItemInfo.Modified.ReplicaId); command.AddParameter("@ModifiedTick", remoteSyncableItemInfo.Modified.ReplicaTickCount); command.AddParameter("@ItemData", data.ToString()); command.ExecuteNonQuery(); }
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(); } } } }
public override void SaveItemData(ISyncableItemInfo itemInfo, JObject itemData) { long rowId = GetRowIdFromItemInfo(itemInfo); IDbCommand command = Adapter.Connection.CreateCommand(); if (rowId == -1) { command.CommandText = "INSERT INTO Books(BookTitle, CreatedReplica, CreatedTickCount, ModifiedReplica, ModifiedTickCount ) VALUES(@BookTitle, @CreatedReplica, @CreatedTickCount, @ModifiedReplica, @ModifiedTickCount)"; command.AddParameter("@CreatedReplica", Adapter.GetLocalReplicaIdForGlobalReplicaId(itemInfo.Created.ReplicaId)); command.AddParameter("@CreatedTickCount", itemInfo.Created.ReplicaTickCount); } else { command.CommandText = "UPDATE Books SET BookTitle=@BookTitle,ModifiedReplica=@ModifiedReplica, ModifiedTickCount=@ModifiedTickCount WHERE BookID=@BookID"; command.AddParameter("@BookID", rowId); } command.AddParameter("@BookTitle", (string)itemData["item"]["title"]); command.AddParameter("@ModifiedReplica", Adapter.GetLocalReplicaIdForGlobalReplicaId(itemInfo.Modified.ReplicaId)); command.AddParameter("@ModifiedTickCount", itemInfo.Modified.ReplicaTickCount); command.ExecuteNonQuery(); command.Parameters.Clear(); if (rowId == -1) { rowId = GetRowIdFromItemInfo(itemInfo); } command.CommandText = "DELETE FROM BookAuthors WHERE BookID = @ID;"; command.AddParameter("@ID", rowId); command.ExecuteNonQuery(); command.Parameters.Clear(); int authorPriority = 0; foreach (var authors in itemData["item"]["authors"]) { ISyncableItemInfo authorItemInfo = SyncUtil.SyncableItemInfoFromJsonItemRef(itemData["item"], authors); long authorRowId = Adapter.HandlerForItemType(authorItemInfo.ItemType).GetRowIdFromItemInfo(authorItemInfo); authorPriority++; command.CommandText = String.Format("INSERT INTO BookAuthors(BookID, PersonID, AuthorPriority) VALUES ({0},{1},{2})", rowId, authorRowId, authorPriority); command.ExecuteNonQuery(); } }
public static int AddJsonItemRef(JObject json, ISyncableItemInfo item) { var itemRefs = (JArray)json["itemRefs"]; for (int i = 0; i < itemRefs.Count; i++) { var test = SyncableItemInfoFromJson(itemRefs[i]); if (test.ItemType == item.ItemType && test.Created.ReplicaId == item.Created.ReplicaId && test.Created.ReplicaTickCount == item.Created.ReplicaTickCount && test.Created.ReplicaId == item.Modified.ReplicaId && test.Created.ReplicaTickCount == item.Modified.ReplicaTickCount) { return(i); } } itemRefs.Add(JsonItemRefFromSyncableItemInfo(item)); return(itemRefs.Count - 1); }
private async Task <int> SaveChangesBatch(IDbConnection connection, IList <IReplicaInfo> localKnowledge, int startItem) { var request = new JObject { { "sessionID", _remoteSessionId }, { "startItem", startItem }, { "maxBatchCount", PullMaxBatchCount }, { "maxBatchSize", PullMaxBatchSize } }; JObject response = await _transport.TransportAsync(SyncEndpoint.GetItemDataBatch, request); var batch = (JArray)response["batch"]; foreach (var item in batch) { ISyncableItemInfo remoteSyncableItemInfo = SyncUtil.SyncableItemInfoFromJson(item["item"]); var itemData = new JObject { { "item", item["item"] } }; var status = SyncStatus.MayBeNeeded; if (!SyncUtil.KnowledgeContains(localKnowledge, remoteSyncableItemInfo.Modified)) { ISyncableItemInfo localSyncableItemInfo = _store.LocateCurrentItemInfo(remoteSyncableItemInfo); status = SyncUtil.CalculateSyncStatus(remoteSyncableItemInfo, localSyncableItemInfo, _remoteKnowledge); } SessionDbHelper.SaveItemData(connection, remoteSyncableItemInfo, status, itemData); var itemRefs = (JArray)itemData["item"]["itemRefs"]; foreach (var itemRef in itemRefs) { ISyncableItemInfo itemRefInfo = SyncUtil.SyncableItemInfoFromJson(itemRef); ISyncableItemInfo localItemRefInfo = _store.LocateCurrentItemInfo(itemRefInfo); if (localItemRefInfo != null && localItemRefInfo.Deleted) { await SaveSyncData(connection, itemRefInfo, SyncStatus.MayBeNeeded); } } } return(batch.Count); }
public JObject GetItemDataBatch(JObject request) { var startItem = (int)request["startItem"]; var maxBatchCount = (int)request["maxBatchCount"]; var maxBatchSize = (int)request["maxBatchSize"]; var batchArray = new JArray(); var getChangedItemsCommand = _connection.CreateCommand(); getChangedItemsCommand.CommandText = String.Format("SELECT ItemID, SyncStatus, ItemType, GlobalCreatedReplica, CreatedTickCount, GlobalModifiedReplica, ModifiedTickCount FROM SyncItems WHERE ItemID >= {0} ORDER BY ItemID", startItem); using (var reader = getChangedItemsCommand.ExecuteReader()) { var batchSize = 0; while (reader != null && reader.Read()) { ISyncableItemInfo requestedItemInfo = SessionDbHelper.SyncableItemInfoFromDataReader(reader); var singleItem = new JObject(); JObject builder = SyncUtil.JsonItemFromSyncableItemInfo(requestedItemInfo); if (!requestedItemInfo.Deleted) { _store.BuildItemData(requestedItemInfo, builder); } singleItem.Add(new JProperty("item", builder)); batchSize += singleItem.ToString().Length; batchArray.Add(singleItem); if (batchArray.Count >= maxBatchCount || batchSize >= maxBatchSize) { break; } } } var json = new JObject { { "batch", batchArray } }; return(json); }
public static SyncStatus CalculateSyncStatus(ISyncableItemInfo remoteSyncableItemInfo, ISyncableItemInfo localSyncableItemInfo, IEnumerable <IReplicaInfo> remoteKnowledge) { if (localSyncableItemInfo == null) // We have no knowledge of the remote item { if (remoteSyncableItemInfo.Deleted) { return(SyncStatus.DeleteNonExisting); } return(SyncStatus.Insert); } if (localSyncableItemInfo.Deleted && remoteSyncableItemInfo.Deleted) { return(SyncStatus.DeleteNonExisting); } if (KnowledgeContains(remoteKnowledge, localSyncableItemInfo.Modified)) { if (remoteSyncableItemInfo.Deleted) { return(SyncStatus.Delete); } if (localSyncableItemInfo.Deleted) { return(SyncStatus.Insert); // Should never happen } return(SyncStatus.Update); } if (localSyncableItemInfo.Deleted) { return(SyncStatus.DeleteConflict); } if (remoteSyncableItemInfo.Deleted) { return(SyncStatus.DeleteConflict); } return(SyncStatus.UpdateConflict); }
public void ResolveConflictMerge(SyncConflict conflict, JObject itemData) { if (_closed) { throw new InvalidOperationException(); } long tickCount = _store.IncrementLocalRepilcaTickCount(); IReplicaInfo modifiedReplica = new ReplicaInfo { ReplicaId = _store.GetLocalReplicaId(), ReplicaTickCount = tickCount }; ISyncableItemInfo itemInfo = conflict.RemoteItemInfo; using ( IDbConnection connection = _syncSessionDbConnectionProvider.GetSyncSessionDbConnection(_localSessionId)) { SessionDbHelper.ResolveItemWithData(connection, itemInfo, SyncStatus.Update, modifiedReplica, itemData); } }
public override void SaveItemData(ISyncableItemInfo itemInfo, JObject itemData) { long rowId = GetRowIdFromItemInfo(itemInfo); IDbCommand command = Adapter.Connection.CreateCommand(); if (rowId == -1) { command.CommandText = "INSERT INTO People(PersonName, CreatedReplica, CreatedTickCount, ModifiedReplica, ModifiedTickCount ) VALUES(@PersonName, @CreatedReplica, @CreatedTickCount, @ModifiedReplica, @ModifiedTickCount)"; command.AddParameter("@CreatedReplica", Adapter.GetLocalReplicaIdForGlobalReplicaId(itemInfo.Created.ReplicaId)); command.AddParameter("@CreatedTickCount", itemInfo.Created.ReplicaTickCount); } else { command.CommandText = "UPDATE People SET PersonName=@PersonName, ModifiedReplica=@ModifiedReplica, ModifiedTickCount=@ModifiedTickCount WHERE PersonID=@PersonID"; command.AddParameter("@PersonID", rowId); } command.AddParameter("@PersonName", (string)itemData["item"]["name"]); command.AddParameter("@ModifiedReplica", Adapter.GetLocalReplicaIdForGlobalReplicaId(itemInfo.Modified.ReplicaId)); command.AddParameter("@ModifiedTickCount", itemInfo.Modified.ReplicaTickCount); command.ExecuteNonQuery(); }
public override bool DeleteItem(ISyncableItemInfo itemInfo) { long rowId = GetRowIdFromItemInfo(itemInfo); if (rowId != -1) { string savepointName = "DeleteBook"; IDbCommand command = Adapter.Connection.CreateCommand(); command.CommandText = "SAVEPOINT " + savepointName; command.ExecuteNonQuery(); try { command.CommandText = "DELETE FROM BookAuthors WHERE BookID = @ID;"; command.AddParameter("@ID", rowId); command.ExecuteNonQuery(); command.Parameters.Clear(); if (base.DeleteItem(itemInfo)) { command.CommandText = "RELEASE " + savepointName; command.ExecuteNonQuery(); return(true); } else { command.CommandText = "ROLLBACK TO SAVEPOINT " + savepointName; command.ExecuteNonQuery(); return(false); } } catch (Exception) { command.CommandText = "ROLLBACK TO SAVEPOINT " + savepointName; command.ExecuteNonQuery(); throw; } } return(true); }
public ISyncableItemInfo LocateCurrentItemInfo(ISyncableItemInfo source) { var typeHandler = HandlerForItemType(source.ItemType); IDbCommand command = _connection.CreateCommand(); command.CommandText = String.Format("SELECT CreatedReplica, CreatedTickCount, ModifiedReplica, ModifiedTickCount FROM {0} WHERE CreatedReplica=@CreatedReplica AND CreatedTickCount=@CreatedTick", typeHandler.DbTable); command.AddParameter("@CreatedReplica", GetLocalReplicaIdForGlobalReplicaId(source.Created.ReplicaId)); command.AddParameter("@CreatedTick", source.Created.ReplicaTickCount); using (IDataReader reader = command.ExecuteReader()) { if (reader.Read()) { IReplicaInfo createdReplicaInfo = ReplicaInfoFromDataReader(reader, "Created"); IReplicaInfo modifiedReplicaInfo = ReplicaInfoFromDataReader(reader, "Modified"); return(new SyncableItemInfo { ItemType = typeHandler.TypeName, Created = createdReplicaInfo, Modified = modifiedReplicaInfo, Deleted = false }); } } command = _connection.CreateCommand(); command.CommandText = String.Format("SELECT CreatedReplica, CreatedTickCount, ModifiedReplica, ModifiedTickCount FROM {0} WHERE CreatedReplica=@CreatedReplica AND CreatedTickCount=@CreatedTick AND ItemType={1}", "Tombstones", typeHandler.TypeId); command.AddParameter("@CreatedReplica", GetLocalReplicaIdForGlobalReplicaId(source.Created.ReplicaId)); command.AddParameter("@CreatedTick", source.Created.ReplicaTickCount); using (IDataReader reader = command.ExecuteReader()) { if (reader.Read()) { IReplicaInfo createdReplicaInfo = ReplicaInfoFromDataReader(reader, "Created"); IReplicaInfo modifiedReplicaInfo = ReplicaInfoFromDataReader(reader, "Modified"); return(new SyncableItemInfo { ItemType = typeHandler.TypeName, Created = createdReplicaInfo, Modified = modifiedReplicaInfo, Deleted = true }); } } return(null); }
public override DuplicateStatus GetDuplicateStatus(JObject localItemData, JObject remoteItemData) { string localName = (string)localItemData["item"]["title"]; string remoteName = (string)remoteItemData["item"]["title"]; if (localName != remoteName) { return(DuplicateStatus.None); } JArray localAuthors = (JArray)localItemData["item"]["authors"]; JArray remoteAuthors = (JArray)remoteItemData["item"]["authors"]; if (localAuthors.Count != remoteAuthors.Count) { return(DuplicateStatus.None); } for (int i = 0; i < localAuthors.Count; i++) { ISyncableItemInfo localAuthorItemInfo = SyncUtil.SyncableItemInfoFromJsonItemRef(localItemData["item"], localAuthors[i]); ISyncableItemInfo remoteAuthorItemInfo = SyncUtil.SyncableItemInfoFromJsonItemRef(remoteItemData["item"], remoteAuthors[i]); if (localAuthorItemInfo.Created.ReplicaId != remoteAuthorItemInfo.Created.ReplicaId) { return(DuplicateStatus.None); } if (localAuthorItemInfo.Created.ReplicaTickCount != remoteAuthorItemInfo.Created.ReplicaTickCount) { return(DuplicateStatus.None); } } return(DuplicateStatus.Exact); }
public static void UpdateItemPlaceholderData(IDbConnection connection, int itemNumber, SyncStatus status, ISyncableItemInfo remoteSyncableItemInfo, JObject itemData) { var command = connection.CreateCommand(); command.CommandText = "UPDATE SyncItems SET SyncStatus=@SyncStatus, ItemType=@ItemType, GlobalCreatedReplica=@CreatedReplica, CreatedTickCount=@CreatedTick, GlobalModifiedReplica=@ModifiedReplica, ModifiedTickCount=@ModifiedTick, ItemData=@ItemData WHERE RowID=@RowID"; command.AddParameter("@RowID", itemNumber); command.AddParameter("@SyncStatus", status); command.AddParameter("@ItemType", remoteSyncableItemInfo.ItemType); command.AddParameter("@CreatedReplica", remoteSyncableItemInfo.Created.ReplicaId); command.AddParameter("@CreatedTick", remoteSyncableItemInfo.Created.ReplicaTickCount); command.AddParameter("@ModifiedReplica", remoteSyncableItemInfo.Modified.ReplicaId); command.AddParameter("@ModifiedTick", remoteSyncableItemInfo.Modified.ReplicaTickCount); if (status == SyncStatus.Delete || status == SyncStatus.DeleteNonExisting) { command.AddParameter("@ItemData", "{item:{itemRefs:[]}}"); } else { command.AddParameter("@ItemData", itemData.ToString()); } command.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); }
public override void RemoveFromReplica(ISyncableItemInfo itemInfo) { Adapter.BookRepository.removePerson(Adapter.GetLocalReplicaIdForGlobalReplicaId(itemInfo.Created.ReplicaId), itemInfo.Created.ReplicaTickCount); }
public override void UpdateInReplica(ISyncableItemInfo itemInfo) { long rowId = GetRowIdFromItemInfo(itemInfo); Adapter.BookRepository.updatePerson(Adapter.Connection, rowId); }