private void LoguearNivelDeTracingConfigurador() { if (SyncTracer.IsErrorEnabled() || SyncTracer.IsWarningEnabled() || SyncTracer.IsInfoEnabled() || SyncTracer.IsVerboseEnabled()) { Loguear("Tracing activado! revisar en config cual es el archivo."); } else { Loguear("Tracing desactivado, activar en el config."); } if (SyncTracer.IsErrorEnabled()) { Loguear("Tracing de errores Activado"); } if (SyncTracer.IsWarningEnabled()) { Loguear("Tracing de advertencias Activado"); } if (SyncTracer.IsInfoEnabled()) { Loguear("Tracing de información Activado"); } if (SyncTracer.IsVerboseEnabled()) { Loguear("Tracing de todo Activado"); } }
/// #DOWNLOAD (not in batches) public SpSyncAnchor SelectAll(SpSyncAnchor anchor, int rowLimit, DataTable dataTable, SpConnection connection) { if (anchor == null) { throw new ArgumentNullException("anchor"); } if (connection == null) { throw new ArgumentNullException("connection"); } if (dataTable == null) { throw new ArgumentNullException("dataTable"); } QueryOptions queryOptions = new QueryOptions() { PagingToken = anchor.PagingToken, DateInUtc = false }; IEnumerable <string> viewFields = GetViewFields(); ListItemCollection listItems = connection.GetListItems( this.ListName, this.ViewName, this.FilterClause, viewFields, IncludeProperties, rowLimit, queryOptions); if (dataTable != null) { foreach (ListItem item in listItems) { DataRow row = dataTable.NewRow(); Exception e; MapListItemToDataRow(item, row, out e); if (e != null) { if (SyncTracer.IsErrorEnabled()) { SyncTracer.Error(e.ToString()); } } dataTable.Rows.Add(row); } } dataTable.AcceptChanges(); return(CalculateNextAnchor(anchor, listItems.NextPage)); }
/// <summary> /// Gets a SyncSchema object created by consulting the database, namely by filling the datatables from the SyncAdapters /// </summary> /// <param name="tableNames">the names of the tables to be included in the schema</param> /// <param name="missingTables">the names of the missing tables not found in the set of the SyncAdapters</param> /// <returns>the SyncSchema object</returns> protected virtual SyncSchema GetSchemaFromDatabase(Collection <string> tableNames, out Collection <string> missingTables) { SyncSchema schema = new SyncSchema(); schema.SchemaDataSet = new DataSet(); schema.SchemaDataSet.Locale = CultureInfo.InvariantCulture; missingTables = new Collection <string>(); Connection.Open(); foreach (string tableName in tableNames) { SpSyncAdapter adapter = null; if (SyncAdapters.Contains(tableName)) { adapter = SyncAdapters[tableName]; } if (adapter != null) { DataTable dataTable = null; try { dataTable = adapter.FillSchema(dataTable, Connection); dataTable.TableName = tableName; schema.SchemaDataSet.Tables.Add(dataTable); } catch (Exception e) { missingTables.Add(tableName); if (SyncTracer.IsErrorEnabled()) { SyncTracer.Error(e.ToString()); } } } else { missingTables.Add(tableName); } } Connection.Close(); if (missingTables.Count == 0) { missingTables = null; } return(schema); }
/// <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; } }
/// #DOWNLOAD public SpSyncAnchor SelectIncremental(SpSyncAnchor anchor, int rowLimit, SpConnection connection, DataTable changeTable) {//#DOWNLOAD in batches - step 3 if (anchor == null) { throw new ArgumentNullException("anchor"); } if (connection == null) { throw new ArgumentNullException("connection"); } QueryOptions queryOptions = new QueryOptions() { PagingToken = anchor.PagingToken, DateInUtc = false }; IEnumerable <string> viewFields = GetViewFields(); ChangeBatch changes = connection.GetListItemChangesSinceToken( this.ListName, this.ViewName, FilterClause, viewFields, IncludeProperties, rowLimit, queryOptions, anchor.NextChangesToken); foreach (ListItem item in changes.ChangedItems) { DataRow row = changeTable.NewRow(); Exception e; MapListItemToDataRow(item, row, out e); if (e != null) { if (SyncTracer.IsErrorEnabled()) { SyncTracer.Error(e.ToString()); } } changeTable.Rows.Add(row); row.AcceptChanges(); row.SetModified(); } foreach (ChangeItem item in changes.ChangeLog) { string clientColumnName = GetClientColumnFromServerColumn("ID"); if (ChangeCommands.IsDelete(item.Command)) { DataRow row = changeTable.NewRow(); // FIX: Probably the ID is not mapped at all to the client table row[clientColumnName] = item.ListItemID; changeTable.Rows.Add(row); row.AcceptChanges(); row.Delete(); } } return(CalculateNextAnchor(anchor, changes)); }
/// <summary> /// Fills the tables insertTbl, updateTbl, deleteTbl with the changes fetch by the sharepoint server /// since a change token /// </summary> /// <param name="anchor">the anchor to specify the change token</param> /// <param name="rowLimit">the maximum number of rows to fetch </param> /// <param name="connection">the connection to the sharepoint server</param> /// <param name="insertTbl">the DataTable to append the rows that have been inserted</param> /// <param name="updateTbl">the DataTable to append the rows that have been updated</param> /// <param name="deleteTbl">the DataTable to append the rows that have been deleted</param> /// <remarks> /// Because of the response of the sharepoint changelog we cannot identify the updates from the inserts. /// So, no record will be added to the updateTbl. /// </remarks> /// <returns>the new SpSyncAnchor object to be used in subsequent calls</returns> /// #DOWNLOAD public SpSyncAnchor SelectIncremental(SpSyncAnchor anchor, int rowLimit, SpConnection connection, DataTable insertTbl, DataTable updateTbl, DataTable deleteTbl) { if (anchor == null) { throw new ArgumentNullException("anchor"); } if (connection == null) { throw new ArgumentNullException("connection"); } QueryOptions queryOptions = new QueryOptions() { PagingToken = anchor.PagingToken, DateInUtc = false }; IEnumerable <string> viewFields = GetViewFields(); ChangeBatch changes = connection.GetListItemChangesSinceToken( this.ListName, this.ViewName, FilterClause, viewFields, IncludeProperties, rowLimit, queryOptions, anchor.NextChangesToken); if (insertTbl != null) { foreach (ListItem item in changes.ChangedItems) { DataRow row = insertTbl.NewRow(); Exception e; MapListItemToDataRow(item, row, out e); if (e != null) { if (SyncTracer.IsErrorEnabled()) { SyncTracer.Error(e.ToString()); } } insertTbl.Rows.Add(row); } } // FIX: Cannot identify the updates from the inserts. if (deleteTbl != null) { foreach (ChangeItem item in changes.ChangeLog) { if (ChangeCommands.IsDelete(item.Command)) { DataRow row = deleteTbl.NewRow(); // FIX: Probably the ID is not mapped at all to the client table row[deleteTbl.PrimaryKey[0]] = item.ListItemID; deleteTbl.Rows.Add(row); } } } insertTbl.AcceptChanges(); // COMMITCHANGES updateTbl.AcceptChanges(); deleteTbl.AcceptChanges(); return(CalculateNextAnchor(anchor, changes)); }
/// #UPLOAD 2 private void ApplyChangesInternal(SyncGroupMetadata groupMetadata, DataSet dataSet, SyncSession syncSession, SyncContext syncContext) { SyncStage syncStage = SyncStage.UploadingChanges; foreach (SyncTableMetadata tableMetadata in groupMetadata.TablesMetadata) { SpSyncAdapter adapter = null; if (this.SyncAdapters.Contains(tableMetadata.TableName)) { adapter = this.SyncAdapters[tableMetadata.TableName]; } if (adapter == null) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Messages.InvalidTableName, tableMetadata.TableName)); } // SpSyncAnchor anchor if (!dataSet.Tables.Contains(tableMetadata.TableName)) { throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Messages.TableNotInSchema, tableMetadata.TableName)); } SyncTableProgress tableProgress = syncContext.GroupProgress.FindTableProgress(tableMetadata.TableName); DataTable dataTable = dataSet.Tables[tableMetadata.TableName]; try { Collection <SyncConflict> conflicts; int changesCount = dataTable.Rows.Count; adapter.Update(dataTable, Connection, out conflicts); if (conflicts != null) { foreach (SyncConflict conflict in conflicts) { ApplyChangeFailedEventArgs failureArgs = new ApplyChangeFailedEventArgs(tableMetadata, conflict, null, syncSession, syncContext, Connection, null); OnApplyChangeFailed(failureArgs); if (failureArgs.Action == ApplyAction.Continue) { if (conflict != null) { tableProgress.ChangesFailed++; tableProgress.Conflicts.Add(conflict); } } } } tableProgress.ChangesApplied = changesCount - tableProgress.ChangesFailed; } catch (Exception e) { SyncConflict conflict = new SyncConflict(ConflictType.ErrorsOccurred, SyncStage.UploadingChanges) { ErrorMessage = e.Message + ", InnerException:" + e.InnerException.ToString(), ServerChange = dataTable, ClientChange = dataTable }; ApplyChangeFailedEventArgs failureArgs = new ApplyChangeFailedEventArgs(tableMetadata, conflict, null, syncSession, syncContext, Connection, null); OnApplyChangeFailed(failureArgs); // handle errors? if (SyncTracer.IsErrorEnabled()) { SyncTracer.Error(e.ToString()); } } SyncProgressEventArgs args = new SyncProgressEventArgs(tableMetadata, tableProgress, groupMetadata, syncContext.GroupProgress, syncStage); OnSyncProgress(args); } }
static void Main(string[] args) { //The Utility class handles all functionality that is not //directly related to synchronization, such as holding connection //string information and making changes to the server database. Utility util = new Utility(); //The SampleStats class handles information from the SyncStatistics //object that the Synchronize method returns. SampleStats sampleStats = new SampleStats(); //Delete and re-create the database. The client synchronization //provider also enables you to create the client database //if it does not exist. util.SetClientPassword(); util.RecreateClientDatabase(); //Write to the console which tracing levels are enabled. The app.config //file specifies a value of 3 for the SyncTracer switch, which corresponds //to Info. Therefore, Error, Warning, and Info return True, and Verbose //returns False. Console.WriteLine(""); //<snippetOCS_CS_Tracing_LevelsEnabled> Console.WriteLine("** Tracing Levels Enabled for this Application **"); Console.WriteLine("Error: " + SyncTracer.IsErrorEnabled().ToString()); Console.WriteLine("Warning: " + SyncTracer.IsWarningEnabled().ToString()); Console.WriteLine("Info: " + SyncTracer.IsInfoEnabled().ToString()); Console.WriteLine("Verbose: " + SyncTracer.IsVerboseEnabled().ToString()); //</snippetOCS_CS_Tracing_LevelsEnabled> //Initial synchronization. Instantiate the SyncAgent //and call Synchronize. //<snippetOCS_CS_Tracing_Synchronize> SampleSyncAgent sampleSyncAgent = new SampleSyncAgent(); SyncStatistics syncStatistics = sampleSyncAgent.Synchronize(); //</snippetOCS_CS_Tracing_Synchronize> sampleStats.DisplayStats(syncStatistics, "initial"); //Make a change at the client that fails when it is //applied at the server. The constraint violation //is automatically written to the trace file as a warning. util.MakeFailingChangesOnClient(); //Make changes at the client and server that conflict //when they are synchronized. The conflicts are written //to the trace file in the SampleServerSyncProvider_ApplyChangeFailed //event handler. util.MakeConflictingChangesOnClientAndServer(); //Subsequent synchronization. syncStatistics = sampleSyncAgent.Synchronize(); sampleStats.DisplayStats(syncStatistics, "subsequent"); //Return server data back to its original state. util.CleanUpServer(); //Exit. Console.Write("\nPress Enter to close the window."); Console.ReadLine(); }