public ItemData Merge(ItemData other) { ItemData result = new ItemData(); foreach (string key in other._data.Keys) { if (this._data.ContainsKey(key)) { // merge the value if it exists in both objects result._data[key] = string.Concat(this._data[key], other._data[key]); } else { //Just add the value since it only exists inone. result._data[key] = other._data[key]; } } foreach (string key in this._data.Keys) { if (!other._data.ContainsKey(key)) { //Just add the value since it only exists inone. result._data[key] = this._data[key]; } } return result; }
public ItemData(ItemData src) { //Deep copy the data, but create a new timestamp value. _data = new Dictionary<string, string>(src._data); _timestamp = (ulong)DateTime.Now.Ticks; }
public ulong UpdateItem(Guid id, ItemData value) { ulong timeStamp = (ulong)DateTime.Now.Ticks; value.TimeStamp = timeStamp; _store[id] = value; // Assume value passed in is already copied instance return timeStamp; }
public Guid CreateItem(ItemData value, Guid id) { value.TimeStamp = (ulong)DateTime.Now.Ticks; _store[id] = value; // Assume value passed in is already copied instance return id; }
public Guid CreateItem(ItemData value) { Guid id = Guid.NewGuid(); return CreateItem(value, id); }
//Save the item, taking the appropriate action for the 'change' and the data from the item (in 'context') public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { Thread.Sleep(1000); ulong timeStamp = 0; ItemMetadata item = null; ItemData data = null; change.WorkEstimate = 1; switch (saveChangeAction) { case SaveChangeAction.Create: //Do duplicate detection here item = _metadata.FindItemMetadataById(change.ItemId); if (null != item) { throw new Exception("SaveItemChange must not have Create action for existing items."); } item = _metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); item.ChangeVersion = change.ChangeVersion; data = new ItemData( (ItemData)context.ChangeData); //We are using the same id for both the local and global item id. _store.CreateItem( data, change.ItemId.GetGuidId()); SaveItemMetadata(item, _store.Get(change.ItemId.GetGuidId()).TimeStamp); break; case SaveChangeAction.UpdateVersionAndData: case SaveChangeAction.UpdateVersionOnly: item = _metadata.FindItemMetadataById(change.ItemId); if (null == item) { throw new Exception("Item Not Found in Store!?"); } item.ChangeVersion = change.ChangeVersion; if (saveChangeAction == SaveChangeAction.UpdateVersionOnly) { SaveItemMetadata(item); } else //Also update the data and the timestamp. { data = new ItemData((ItemData)context.ChangeData); timeStamp = _store.UpdateItem(item.GlobalId.GetGuidId(), data); SaveItemMetadata(item, timeStamp); } break; case SaveChangeAction.DeleteAndStoreTombstone: item = _metadata.FindItemMetadataById(change.ItemId); if (null == item) { item = _metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); } if (change.ChangeKind == ChangeKind.Deleted) { item.MarkAsDeleted(change.ChangeVersion); } else { // This should never happen in Sync Framework V1.0 throw new Exception("Invalid ChangeType"); } item.ChangeVersion = change.ChangeVersion; SaveItemMetadata(item, 0); // set timestamp to 0 for tombstones _store.DeleteItem(item.GlobalId.GetGuidId()); break; //Merge the changes! (Take the data from the local item + the remote item),noting to update the tick count to propagate the resolution! case SaveChangeAction.UpdateVersionAndMergeData: item = _metadata.FindItemMetadataById(change.ItemId); if (null == item) { throw new Exception("Item Not Found in Store!?"); } if (item.IsDeleted != true) { //Note - you must update the change version to propagate the resolution! item.ChangeVersion = new SyncVersion(0, _metadata.GetNextTickCount()); //Combine the conflicting data... ItemData mergedData = (_store.Get(item.GlobalId.GetGuidId())).Merge( (ItemData)context.ChangeData); timeStamp = _store.UpdateItem(item.GlobalId.GetGuidId(), mergedData); SaveItemMetadata(item, timeStamp); } break; case SaveChangeAction.DeleteAndRemoveTombstone: item = _metadata.FindItemMetadataById(change.ItemId); if (item != null) { List<SyncId> ids = new List<SyncId>(); ids.Add(item.GlobalId); _metadata.RemoveItemMetadata(ids); } _store.DeleteItem(change.ItemId.GetGuidId()); break; } }