public override void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { // Extract the data from the change TransferMechanism data = context.ChangeData as TransferMechanism; // Now apply the change if (!(saveChangeAction == SaveChangeAction.UpdateVersionOnly) && ((change.ChangeKind & ChangeKind.Deleted) == 0)) { ItemMetadata item = new ItemMetadata(); item.ItemId = change.ItemId; item.ChangeVersion = change.ChangeVersion; item.CreationVersion = change.CreationVersion; item.Uri = data.Uri; RemoteFileInfo fileInfo = new RemoteFileInfo(); fileInfo.FolderPath = Path; fileInfo.Length = data.DataStream.Length; fileInfo.Metadata = item; fileInfo.FileByteStream = data.DataStream; Proxy.UploadFile(fileInfo); // Close input stream data.DataStream.Close(); } else { Proxy.DeleteFile(Path, change.ItemId, _filters); } // If we made it here, the change was successfully applied locally // (or it is a version only change), so we can update our knowledge with the // learned knowledge from the change context.GetUpdatedDestinationKnowledge(out _syncKnowledge, out _forgottenKnowledge); }
public override void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { // Extract the data from the change TransferMechanism data = context.ChangeData as TransferMechanism; // Item metadata ItemMetadata item = _sync.GetItemMetaData(saveChangeAction, change, data); // Now apply the change if (!(saveChangeAction == SaveChangeAction.UpdateVersionOnly) && ((change.ChangeKind & ChangeKind.Deleted) == 0)) { // Only copy if destination file name is known // (May have been lost if loser of name collision) if (item.Uri != String.Empty) { FileInfo fi = new FileInfo(System.IO.Path.Combine(Path, item.Uri)); if (!fi.Directory.Exists) { fi.Directory.Create(); } // Change should have stream data, so copy the file data to the local store using (FileStream outputStream = new FileStream(System.IO.Path.Combine(Path, item.Uri), FileMode.OpenOrCreate)) { const int copyBlockSize = 4096; byte[] buffer = new byte[copyBlockSize]; int bytesRead; // Simple block-by-block copy while ((bytesRead = data.DataStream.Read(buffer, 0, copyBlockSize)) > 0) { outputStream.Write(buffer, 0, bytesRead); } // Truncate if needed outputStream.SetLength(outputStream.Position); } // Update the last write time from the updated file to the metadata entry item.LastWriteTimeUtc = fi.LastWriteTimeUtc; } // Close input stream data.DataStream.Close(); } else { // Not an update/create, so must be a delete or version only change // Is it a delete?... if (item.IsTombstone && item.Uri != String.Empty) { // Change is a delete File.Delete(System.IO.Path.Combine(Path, item.Uri)); } } // If we made it here, the change was successfully applied locally // (or it is a version only change), so we can update our knowledge with the // learned knowledge from the change _sync.GetUpdatedKnowledge(context); }
//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; switch (saveChangeAction) { case SaveChangeAction.Create: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); if (item != null) { // doubtful solution _metadataStore.Metadata.RemoveItemMetadata(new List<SyncId> { item.GlobalId }); item = null; } CreateItem(change, context); break; case SaveChangeAction.UpdateVersionAndData: case SaveChangeAction.UpdateVersionOnly: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); if (item == null) { CreateItem(change, context); break; } if (saveChangeAction == SaveChangeAction.UpdateVersionOnly) { item.ChangeVersion = change.ChangeVersion; _metadataStore.SaveItemMetadata(item); } else { UpdateItem(item, change, context); } break; case SaveChangeAction.DeleteAndStoreTombstone: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); // didn't know about this item if (item == null) { item = _metadataStore.Metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); item.MarkAsDeleted(change.ChangeVersion); item.ChangeVersion = change.ChangeVersion; _metadataStore.SaveItemMetadata(item); } else { DeleteItem(item, change, context); } break; case SaveChangeAction.UpdateVersionAndMergeData: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); ResolveConflict(item, change, context, null); break; case SaveChangeAction.DeleteAndRemoveTombstone: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); if (item != null) { DeleteItem(item, change, context, true); } break; } }
/// <summary> /// Called when [sync item change skiped]. /// </summary> /// <param name="sender">The sender.</param> /// <param name="args">The <see cref="Microsoft.Synchronization.ItemChangeSkippedEventArgs"/> instance containing the event data.</param> protected virtual void OnSyncItemChangeSkiped(object sender, ItemChangeSkippedEventArgs args) { if (_syncApp.CurrentProcessedSyncType == null) { throw new NullReferenceException("CurrentProcessedSyncType"); } SaveChangeAction changeAction = (SaveChangeAction)Enum.Parse(typeof(SaveChangeAction), args.ItemRecoverableErrorData.ItemDisplayName); string debugStr = string.Format("Item change skiped: {0} in stage - {1} provider position - {2} for action {3} error detail {4}", args.ItemRecoverableErrorData.ItemDisplayName, args.Stage.ToString(), args.ReportingProvider.ToString(), changeAction.ToString(), args.ItemRecoverableErrorData.ErrorDescription); DebugAssistant.Log(debugStr); }
//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; } }
public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { DataTransfer data = context.ChangeData as DataTransfer; switch (saveChangeAction) { case SaveChangeAction.Create: { ItemMetadata item = new ItemMetadata(); item.ItemId = change.ItemId; item.ChangeVersion = change.ChangeVersion; item.CreationVersion = change.CreationVersion; item.Uri = data.Uri; data.DataStream.Position = 0; System.Diagnostics.Debug.WriteLine("Uploading File:" + item.Uri); service.UploadFile(data.DataStream.Length, item, data.DataStream); data.DataStream.Close(); sync.UpdateItemItem(item); break; } case SaveChangeAction.DeleteAndStoreTombstone: { ItemMetadata item = sync.GetItemMetaData(saveChangeAction, change, data); sync.DeleteItem(change.ItemId); service.DeleteFile(change.ItemId, item.Uri); break; } default: { throw new NotImplementedException(saveChangeAction + " ChangeAction is not implemented!"); } } context.GetUpdatedDestinationKnowledge(out myKnowledge, out myForgottenKnowledge); }
public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { // anyone know how to implement ??? throw new NotImplementedException(); }
public SyncProviderException(string message, Exception innerException, SaveChangeAction saveChangeAction) : this(message, innerException) { SaveChangeAction = saveChangeAction; }
public SyncProviderException(string message, SaveChangeAction saveChangeAction) : base(message) { SaveChangeAction = saveChangeAction; }
//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; } }
public SyncProviderException(Exception innerException, SaveChangeAction saveChangeAction) : base(saveChangeAction.ToString(), innerException) { SaveChangeAction = saveChangeAction; }
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 abstract void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context);
public ItemMetadata GetItemMetaData(SaveChangeAction saveChangeAction, ItemChange change, TransferMechanism data) { ItemMetadata item; // Populate the URI field of the updated item metadata if (saveChangeAction == SaveChangeAction.UpdateVersionOnly || ((change.ChangeKind & ChangeKind.Deleted) == ChangeKind.Deleted)) { // Version only changes and deletions will not contain data, // so we cannot get the item URI from the change data // // So, we attempt to look up the item metadata instead (by item id) // to populate the URI field if (!metadataStore.TryGetItem(change.ItemId, out item)) { // Not found, must mean we've never seen this item locally // Can safely use an empty URI item = new ItemMetadata(); item.Uri = String.Empty; } } else { // Since this isn't a version-only change or a delete, context should contain // change data item = new ItemMetadata(); // Used for storing updated item metadata // Populate the Uri field item.Uri = data.Uri; } // Now copy the rest of the metadata for the item from the change item.ItemId = change.ItemId; item.CreationVersion = change.CreationVersion; item.ChangeVersion = change.ChangeVersion; // If deletion change, mark it as a tombstone if ((change.ChangeKind & ChangeKind.Deleted) == ChangeKind.Deleted) { item.IsTombstone = true; } // Is this a new item? if (!metadataStore.Has(item.ItemId)) { ItemMetadata oldItem; // Not found // Need to check for duplicates (by URI) if (metadataStore.TryGetItem(item.Uri, out oldItem)) { // Duplicate item (same Uri), so we deterministically choose a winner // by comparing the guid part of the item ids if (item.ItemId.CompareTo(oldItem.ItemId) > 0) { // New item is the winner // Record old item as a loser oldItem.IsTombstone = true; oldItem.Uri = String.Empty; oldItem.ChangeVersion = new SyncVersion(0, tickCount); } else { // Old item is the winner // Record new item as a loser item.IsTombstone = true; item.Uri = String.Empty; item.ChangeVersion = new SyncVersion(0, tickCount); } // Record the updated item metadata metadataStore.SetItemInfo(item); metadataStore.SetItemInfo(oldItem); } } // Save the updated item metadata metadataStore.SetItemInfo(item); return(item); }
//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; switch (saveChangeAction) { case SaveChangeAction.Create: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); if (item != null) { // doubtful solution _metadataStore.Metadata.RemoveItemMetadata(new List <SyncId> { item.GlobalId }); item = null; } CreateItem(change, context); break; case SaveChangeAction.UpdateVersionAndData: case SaveChangeAction.UpdateVersionOnly: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); if (item == null) { CreateItem(change, context); break; } if (saveChangeAction == SaveChangeAction.UpdateVersionOnly) { item.ChangeVersion = change.ChangeVersion; _metadataStore.SaveItemMetadata(item); } else { UpdateItem(item, change, context); } break; case SaveChangeAction.DeleteAndStoreTombstone: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); // didn't know about this item if (item == null) { item = _metadataStore.Metadata.CreateItemMetadata(change.ItemId, change.CreationVersion); item.MarkAsDeleted(change.ChangeVersion); item.ChangeVersion = change.ChangeVersion; _metadataStore.SaveItemMetadata(item); } else { DeleteItem(item, change, context); } break; case SaveChangeAction.UpdateVersionAndMergeData: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); ResolveConflict(item, change, context, null); break; case SaveChangeAction.DeleteAndRemoveTombstone: item = _metadataStore.Metadata.FindItemMetadataById(change.ItemId); if (item != null) { DeleteItem(item, change, context, true); } break; } }
/// <summary> /// Download Mechanism /// </summary> /// <param name="saveChangeAction"></param> /// <param name="change"></param> /// <param name="context"></param> public void SaveItemChange(SaveChangeAction saveChangeAction, ItemChange change, SaveChangeContext context) { DataTransfer data = context.ChangeData as DataTransfer; ItemMetadata item = sync.GetItemMetaData(saveChangeAction, change, data); switch (saveChangeAction) { case SaveChangeAction.Create: { System.Diagnostics.Debug.WriteLine("Create File: " + item.Uri); UpdateOrCreateFile(data, item); break; } case SaveChangeAction.UpdateVersionAndData: { System.Diagnostics.Debug.WriteLine("UpdateVersion And Data File: " + item.Uri); UpdateOrCreateFile(data, item); break; } case SaveChangeAction.DeleteAndStoreTombstone: { System.Diagnostics.Debug.WriteLine(" Delete File: " + item.Uri); File.Delete(Path.Combine(folderPath, item.Uri)); break; } default: { throw new NotImplementedException(saveChangeAction + " ChangeAction is not implemented!"); } } sync.GetUpdatedKnowledge(context); }
public ItemMetadata GetItemMetaData(SaveChangeAction saveChangeAction, ItemChange change, DataTransfer data) { ItemMetadata item; if (saveChangeAction == SaveChangeAction.UpdateVersionOnly || ((change.ChangeKind & ChangeKind.Deleted) == ChangeKind.Deleted)) { if (!metadataStore.TryGetItem(change.ItemId, out item)) { item = new ItemMetadata(); item.Uri = String.Empty; } } else { item = new ItemMetadata(); item.Uri = data.Uri; } item.ItemId = change.ItemId; item.CreationVersion = change.CreationVersion; item.ChangeVersion = change.ChangeVersion; if ((change.ChangeKind & ChangeKind.Deleted) == ChangeKind.Deleted) item.IsTombstone = true; if (!metadataStore.Has(item.ItemId)) { ItemMetadata oldItem; if (metadataStore.TryGetItem(item.Uri, out oldItem)) { if (item.ItemId.CompareTo(oldItem.ItemId) > 0) { oldItem.IsTombstone = true; oldItem.Uri = String.Empty; oldItem.ChangeVersion = new SyncVersion(0, tickCount); } else { item.IsTombstone = true; item.Uri = String.Empty; item.ChangeVersion = new SyncVersion(0, tickCount); } metadataStore.SetItemInfo(item); metadataStore.SetItemInfo(oldItem); } } metadataStore.SetItemInfo(item); return item; }
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 } }