Ejemplo n.º 1
0
        internal static void CheckForAdapterRowIds(DbSyncAdapterCollection adapters)
        {
            List <string> list = new List <string>();

            foreach (DbSyncAdapter dbSyncAdapter in (Collection <DbSyncAdapter>)adapters)
            {
                if (dbSyncAdapter.RowIdColumns.Count == 0)
                {
                    list.Add(dbSyncAdapter.TableName);
                }
            }
            if (list.Count <= 0)
            {
                return;
            }
            StringBuilder stringBuilder = new StringBuilder();
            string        str1          = string.Empty;

            foreach (string str2 in list)
            {
                stringBuilder.Append(str1 + str2);
                str1 = ", ";
            }
            SyncTracer.Error(SyncResource.FormatString("MissingAdapterRowIdColumns", new object[0]), new object[1]
            {
                (object)((object)stringBuilder).ToString()
            });
            throw new DbSyncException(SyncResource.FormatString("MissingAdapterRowIdColumns", new object[1]
            {
                (object)((object)stringBuilder).ToString()
            }));
        }
Ejemplo n.º 2
0
        //
        // ****** Methods for adding unsorted data
        //
        public void AddUnsortedDataSet(DataSet dataSet)
        {
            // for each table in the DataSet
            foreach (DataTable curTable in dataSet.Tables)
            {
                int numColumns = curTable.Columns.Count;
                // this table should already be in the list of added
                // tables
                SortedTable sortedTable;
                if (!_sortedTables.TryGetValue(curTable.TableName, out sortedTable))
                {
                    SyncTracer.Error("Cannot Apply Changes since Adapters are missing for the following tables: {0}.  " +
                                     "Please ensure that the local and global names on the Adapters are set properly.", curTable);

                    throw new DbSyncException("MissingProviderAdapter");
                }
                if (sortedTable._schema == null)
                {
                    // add a new row storage dictionary and schema if we
                    // need one
                    sortedTable._schema = curTable.Clone();
                    Debug.Assert(sortedTable._schema.DataSet == null);
                    sortedTable._rows = new SortedDictionary <SyncId, SortedRow>(_syncIdComparer);
                }
                if (curTable.Rows.Count == 0)
                {
                    continue;
                }
                object[] idColVals = new object[sortedTable._idCols.Count];
                // for each row
                foreach (DataRow curRow in curTable.Rows)
                {
                    DataRowVersion viewVersion =
                        (curRow.RowState == DataRowState.Deleted)
                        ? DataRowVersion.Original
                        : DataRowVersion.Current;
                    for (int idx = 0; idx < idColVals.Length; idx += 1)
                    {
                        idColVals[idx] = curRow[sortedTable._idCols[idx], viewVersion];
                    }

                    // Add the row to this tables row storage dictionary
                    SyncId curRowId = SyncUtil.InitRowId(curTable.TableName, idColVals);

                    // Note: There is an issue with batching in the provider which causes the same primary key to be repeated across files.
                    // This crashes the .Add call below. To work-around this problem, we need to check if the key already exists.
                    // If it does, then remove it and add it again so that the latest record is always used.

                    if (sortedTable._rows.ContainsKey(curRowId))
                    {
                        sortedTable._rows.Remove(curRowId);
                    }

                    sortedTable._rows.Add(curRowId, new SortedRow(curRow, numColumns));
                }
            }
        }
Ejemplo n.º 3
0
        /// #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));
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
 internal static void TryOpenConnection(IDbConnection connection)
 {
     for (int index = 0; index < 6; ++index)
     {
         try
         {
             if (index > 0)
             {
                 SyncTracer.Info("Retrying opening connection, attempt {0} of {1}.", new object[2]
                 {
                     (object)index,
                     (object)5
                 });
             }
             connection.Open();
             SqlConnection connection1 = connection as SqlConnection;
             if (connection1 == null)
             {
                 break;
             }
             using (SqlCommand sqlCommand = new SqlCommand("Select 1", connection1))
             {
                 sqlCommand.ExecuteScalar();
                 break;
             }
         }
         catch (SqlException ex)
         {
             if (index == 5)
             {
                 SyncTracer.Error("Open connection failed after max retry attempts, due to exception: {0}", new object[1]
                 {
                     (object)ex.Message
                 });
                 throw;
             }
             else if (!SyncUtil.RetryLitmus(ex))
             {
                 SyncTracer.Error("Open connection failed on attempt {0} of {1}, due to unretryable exception: {2}", (object)(index + 1), (object)5, (object)ex.Message);
                 throw;
             }
             else
             {
                 SyncTracer.Warning("Open connection failed on attempt {0} of {1}, due to retryable exception: {2}", (object)(index + 1), (object)5, (object)ex.Message);
                 Thread.Sleep(100 * (int)Math.Pow(2.0, (double)index));
             }
         }
     }
 }
Ejemplo n.º 6
0
 internal static void ExecuteNonQueryWithNewTransaction(IDbCommand command)
 {
     for (int index = 0; index < 6; ++index)
     {
         try
         {
             if (index > 0)
             {
                 SyncTracer.Info("Retrying SyncUtil.ExecuteNonQueryWithNewTransaction, attempt {0} of {1}.", new object[2]
                 {
                     (object)index,
                     (object)5
                 });
                 SyncUtil.OpenConnection(command.Connection);
             }
             using (IDbTransaction dbTransaction = command.Connection.BeginTransaction())
             {
                 command.Transaction = dbTransaction;
                 command.ExecuteNonQuery();
                 dbTransaction.Commit();
                 break;
             }
         }
         catch (DbException ex)
         {
             if (index == 5)
             {
                 SyncTracer.Error("SyncUtil.ExecuteNonQueryWithNewTransaction failed after max retry attempts, due to exception: {0}", new object[1]
                 {
                     (object)ex.Message
                 });
                 throw;
             }
             else
             {
                 SyncTracer.Warning("SyncUtil.ExecuteNonQueryWithNewTransaction failed on attempt {0} of {1}, due to retryable exception: {2}", (object)index, (object)5, (object)ex.Message);
                 Thread.Sleep(100 * (int)Math.Pow(2.0, (double)index));
             }
         }
     }
 }
Ejemplo n.º 7
0
        /// <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;
            }
        }
Ejemplo n.º 8
0
        /// #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));
        }
Ejemplo n.º 9
0
        /// <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));
        }
Ejemplo n.º 10
0
        /// #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);
            }
        }