private DocumentChange[] determineChanges(UpdateBatch batch) { var types = _operations.Select(x => x.Key).TopologicalSort(GetTypeDependencies); foreach (var type in types) { if (!_operations.ContainsKey(type)) { continue; } foreach (var operation in _operations[type]) { // No Virginia, I do not approve of this but I'm pulling all my hair // out as is trying to make this work if (operation is DocumentStorageOperation) { operation.As <DocumentStorageOperation>().Persist(batch, _tenant); } else { batch.Add(operation); } } } writeEvents(batch); batch.Add(_ancillaryOperations); var changes = detectTrackerChanges(); changes.GroupBy(x => x.DocumentType).Each(group => { var upsert = _tenant.StorageFor(group.Key); group.Each(c => { upsert.RegisterUpdate(null, UpdateStyle.Upsert, batch, c.Document, c.Json); }); }); return(changes); }
/// <summary> /// /// </summary> /// <param name="inserts"></param> /// <param name="updates"></param> /// <param name="deletes"></param> /// <param name="connection"></param> /// #UPLOAD 3 public void Update(DataTable changes, SpConnection connection, out Collection <SyncConflict> errors) { errors = new Collection <SyncConflict>(); if (changes == null) { throw new ArgumentNullException("changes"); } if (connection == null) { throw new ArgumentNullException("connection"); } int _batchSize = 25; int segmentsCount = (int)Math.Round(Math.Ceiling((double)changes.Rows.Count / _batchSize), 0); if (IgnoreColumnsOnUpdate != null) { // case to be handled // cannot remove Sharepoint ID. // cannot remove Primary Key of DataTable? foreach (string ignoredColumn in IgnoreColumnsOnUpdate) { string clientColumn = GetClientColumnFromServerColumn(ignoredColumn); if (clientColumn != null && changes.Columns.Contains(clientColumn)) { changes.Columns.Remove(clientColumn); } } } DataTable changesTotal = changes.Copy(); for (int i = 0; i < segmentsCount; i++) { changes.Rows.Clear(); CopyRows(changesTotal, changes, i * _batchSize, _batchSize); //SEND SEGMENT UpdateBatch batch = new UpdateBatch(); string clientIdColumn = GetClientColumnFromServerColumn("ID"); if (!changes.Columns.Contains(clientIdColumn)) { throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Messages.ColumnIDNotContained, clientIdColumn)); } IDictionary <int, DataRow> IdMapping = new Dictionary <int, DataRow>(); foreach (DataRow row in changes.Rows) { UpdateItem u = batch.CreateNewItem(); switch (row.RowState) { case DataRowState.Added: u.Command = UpdateCommands.Insert; break; case DataRowState.Deleted: u.Command = UpdateCommands.Delete; break; case DataRowState.Modified: u.Command = UpdateCommands.Update; break; case DataRowState.Unchanged: continue; } if (u.Command == UpdateCommands.Delete) { row.RejectChanges(); } if (u.Command != UpdateCommands.Insert) { if (!(row[clientIdColumn] is DBNull)) { u.ListItemID = (int)row[clientIdColumn]; } else { continue; } } if (u.Command != UpdateCommands.Delete) { ListItem item = new ListItem(); Exception e; MapDataRowToListItem(row, item, out e); u.ChangedItemData = item; if (e != null && SyncTracer.IsErrorEnabled()) { SyncTracer.Error(e.ToString()); } } batch.Add(u); IdMapping[u.ID] = row; if (u.Command == UpdateCommands.Delete) { row.Delete(); } } if (batch.Count != 0) { //try //{ UpdateResults results = connection.UpdateListItems(this.ListName, batch); // FIX: errors must be handled appropriately foreach (UpdateResult r in results) { if (!r.IsSuccess()) { if (!IdMapping.ContainsKey(r.UpdateItemID)) { throw new InvalidOperationException( String.Format(CultureInfo.CurrentCulture, Messages.NoIDMapping, r.UpdateItemID)); } DataRow clientRow = IdMapping[r.UpdateItemID]; errors.Add(CreateSyncError(r, clientRow)); } } //} //catch (Exception ex) //{ ////usually connection error // foreach (UpdateItem item in batch) // { // if (!IdMapping.ContainsKey(item.ID)) // throw new InvalidOperationException( // String.Format(CultureInfo.CurrentCulture, Messages.NoIDMapping, r.UpdateItemID)); // DataRow clientRow = IdMapping[item.ID]; // errors.Add(CreateSyncError(new UpdateResult(, clientRow)); // } //} } //END SEND SEGMENT } if (errors.Count == 0) { errors = null; } }
/// <summary> /// /// </summary> /// <param name="inserts"></param> /// <param name="updates"></param> /// <param name="deletes"></param> /// <param name="connection"></param> /// #UPLOAD 3 public void Update(DataTable changes, SpConnection connection, out Collection<SyncConflict> errors) { errors = new Collection<SyncConflict>(); if (changes == null) throw new ArgumentNullException("changes"); if (connection == null) throw new ArgumentNullException("connection"); int _batchSize = 25; int segmentsCount = (int)Math.Round( Math.Ceiling((double)changes.Rows.Count/ _batchSize),0); if (IgnoreColumnsOnUpdate != null) { // case to be handled // cannot remove Sharepoint ID. // cannot remove Primary Key of DataTable? foreach (string ignoredColumn in IgnoreColumnsOnUpdate) { string clientColumn = GetClientColumnFromServerColumn(ignoredColumn); if (clientColumn != null && changes.Columns.Contains(clientColumn)) { changes.Columns.Remove(clientColumn); } } } DataTable changesTotal = changes.Copy(); for (int i = 0; i < segmentsCount; i++) { changes.Rows.Clear(); CopyRows(changesTotal, changes, i * _batchSize, _batchSize); //SEND SEGMENT UpdateBatch batch = new UpdateBatch(); string clientIdColumn = GetClientColumnFromServerColumn("ID"); if (!changes.Columns.Contains(clientIdColumn)) throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Messages.ColumnIDNotContained, clientIdColumn)); IDictionary<int, DataRow> IdMapping = new Dictionary<int, DataRow>(); foreach (DataRow row in changes.Rows) { UpdateItem u = batch.CreateNewItem(); switch (row.RowState) { case DataRowState.Added: u.Command = UpdateCommands.Insert; break; case DataRowState.Deleted: u.Command = UpdateCommands.Delete; break; case DataRowState.Modified: u.Command = UpdateCommands.Update; break; case DataRowState.Unchanged: continue; } if (u.Command == UpdateCommands.Delete) row.RejectChanges(); if (u.Command != UpdateCommands.Insert) { if (!(row[clientIdColumn] is DBNull)) { u.ListItemID = (int)row[clientIdColumn]; } else { continue; } } if (u.Command != UpdateCommands.Delete) { ListItem item = new ListItem(); Exception e; MapDataRowToListItem(row, item, out e); u.ChangedItemData = item; if (e != null && SyncTracer.IsErrorEnabled()) SyncTracer.Error(e.ToString()); } batch.Add(u); IdMapping[u.ID] = row; if (u.Command == UpdateCommands.Delete) row.Delete(); } if (batch.Count != 0) { //try //{ UpdateResults results = connection.UpdateListItems(this.ListName, batch); // FIX: errors must be handled appropriately foreach (UpdateResult r in results) { if (!r.IsSuccess()) { if (!IdMapping.ContainsKey(r.UpdateItemID)) throw new InvalidOperationException( String.Format(CultureInfo.CurrentCulture, Messages.NoIDMapping, r.UpdateItemID)); DataRow clientRow = IdMapping[r.UpdateItemID]; errors.Add(CreateSyncError(r, clientRow)); } } //} //catch (Exception ex) //{ ////usually connection error // foreach (UpdateItem item in batch) // { // if (!IdMapping.ContainsKey(item.ID)) // throw new InvalidOperationException( // String.Format(CultureInfo.CurrentCulture, Messages.NoIDMapping, r.UpdateItemID)); // DataRow clientRow = IdMapping[item.ID]; // errors.Add(CreateSyncError(new UpdateResult(, clientRow)); // } //} } //END SEND SEGMENT } if (errors.Count == 0) errors = null; }