//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) { ulong timeStamp = 0; ItemMetadata item = null; ItemData data = null; 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; } }
public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { ItemMetadata item = null; T data = default(T); try { switch (saveChangeAction) { case SaveChangeAction.Create: try { //Do duplicate detection here item = _metaData.FindItemMetadataById(change.ItemId); if (item != null) { throw new SyncProviderException("SaveItemChange must not have Create action for existing items."); } item = _metaData.CreateItemMetadata(change.ItemId, change.CreationVersion); item.ChangeVersion = change.ChangeVersion; data = ConvertFromTransferData(context.ChangeData); CreateDataItem(change, item, data); SaveItemMetadata(item); } catch (Exception e) { throw new SyncProviderException(e, SaveChangeAction.Create); } break; case SaveChangeAction.UpdateVersionAndData: case SaveChangeAction.UpdateVersionOnly: try { item = _metaData.FindItemMetadataById(change.ItemId); if (null == item) { throw new SyncProviderException("Item Not Found in Store!?"); } item.ChangeVersion = change.ChangeVersion; if (saveChangeAction == SaveChangeAction.UpdateVersionOnly) { SaveItemMetadata(item); } else //Also update the data. { data = ConvertFromTransferData(context.ChangeData); UpdateDataItem(change, item, data); SaveItemMetadata(item); } } catch (Exception e) { throw new SyncProviderException(e, SaveChangeAction.UpdateVersionAndData); } break; case SaveChangeAction.DeleteAndStoreTombstone: try { 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 SyncProviderException("Invalid ChangeType"); } item.ChangeVersion = change.ChangeVersion; SaveItemMetadata(item); DeleteDataItem(change, item, data); //item.GlobalId.GetGuidId()); } catch (Exception e) { throw new SyncProviderException(e, SaveChangeAction.DeleteAndStoreTombstone); } 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: try { item = _metaData.FindItemMetadataById(change.ItemId); if (null == item) { throw new SyncProviderException("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... T dataItem = GetDataItem(item); if (dataItem == null) { throw new SyncProviderException("data item not found for merge"); } data = ConvertFromTransferData(context.ChangeData); data = MergeDataItem(dataItem, data); UpdateDataItem(change, item, data); SaveItemMetadata(item); } } catch (Exception e) { throw new SyncProviderException(e, SaveChangeAction.UpdateVersionAndMergeData); } break; case SaveChangeAction.DeleteAndRemoveTombstone: try { item = _metaData.FindItemMetadataById(change.ItemId); if (item != null) { _metaData.RemoveItemMetadata(new SyncId[] { item.GlobalId }); } data = ConvertFromTransferData(context.ChangeData); DeleteDataItem(change, item, data); } catch (Exception e) { throw new SyncProviderException(e, SaveChangeAction.DeleteAndRemoveTombstone); } break; } } catch (SyncProviderException e) { Exception exception = e.InnerException != null ? e.InnerException : e; string itemDescr = e.SaveChangeAction.ToString(); string errDescr = e.Message + "[" + e.InnerException != null?e.InnerException.ToString() : string.Empty + "]"; RecoverableErrorData recoverableError = new RecoverableErrorData(exception, itemDescr, errDescr); context.RecordRecoverableErrorForItem(recoverableError); } }
public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { try { UInt64 timeStamp = 0; ItemMetadata item = null; ISyncDataObject data = null; switch (saveChangeAction) { case SaveChangeAction.Create: //Do duplicate detection here item = _metadata.FindItemMetadataById(change.ItemId); if (null != item) { throw new SyncException("SaveItemChange must not have Create action for existing items."); } item = _metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); item.ChangeVersion = change.ChangeVersion; data = (ISyncDataObject)context.ChangeData; //We are using the same id for both the local and global item id. var version = _syncContext.CreateItem(data, change.ItemId.GetGuidId(), CompanyId, StoreId); if (version != null) { timeStamp = BitConverter.ToUInt64(version, 0); SaveItemMetadata(item, timeStamp); } break; case SaveChangeAction.UpdateVersionAndData: case SaveChangeAction.UpdateVersionOnly: item = _metadata.FindItemMetadataById(change.ItemId); if (null == item) { throw new SyncException("Item Not Found in Store!?"); } item.ChangeVersion = change.ChangeVersion; if (saveChangeAction == SaveChangeAction.UpdateVersionOnly) { SaveItemMetadata(item); } else //Also update the data and the timestamp. { data = (ISyncDataObject)context.ChangeData; timeStamp = BitConverter.ToUInt64(_syncContext.UpdateItem(item.GlobalId.GetGuidId(), data, CompanyId, StoreId), 0); SaveItemMetadata(item, timeStamp); } break; case SaveChangeAction.DeleteAndStoreTombstone: item = _metadata.FindItemMetadataById(change.ItemId); if (null == item) { // item = _metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); return; } if (change.ChangeKind == ChangeKind.Deleted) { item.MarkAsDeleted(change.ChangeVersion); } else { // This should never happen in Sync Framework V1.0 throw new SyncException("Invalid ChangeType"); } item.ChangeVersion = change.ChangeVersion; SaveItemMetadata(item, timeStamp); // set timestamp to 0 for tombstones _syncContext.DeleteItem(item.GlobalId.GetGuidId(), CompanyId, StoreId); 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 SyncException("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... ISyncDataObject mergedData = _syncContext.Merge(_syncContext.GetItem(item.GlobalId.GetGuidId(), CompanyId, StoreId), (ISyncDataObject)context.ChangeData, CompanyId, StoreId); timeStamp = BitConverter.ToUInt64(_syncContext.UpdateItem(item.GlobalId.GetGuidId(), mergedData, CompanyId, StoreId), 0); 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); } _syncContext.DeleteItem(change.ItemId.GetGuidId(), CompanyId, StoreId); break; } } catch (SyncException ex) { ILog logger = LogManager.GetLogger(Assembly.GetExecutingAssembly().GetName().Name); logger.Error(ex.Message, ex); //do Log } catch (DbEntityValidationException ex) { ILog logger = LogManager.GetLogger(Assembly.GetExecutingAssembly().GetName().Name); logger.Error(ex.Message, ex); //do Log } catch (Exception ex) { ILog logger = LogManager.GetLogger(Assembly.GetExecutingAssembly().GetName().Name); logger.Error(ex.Message, ex); //do Log } }