Beispiel #1
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));
                }
            }
        }
        /// <summary>
        /// Creates a Range set build and pre calculates the effective
        /// tables ranges for use later when building a BatchRangeSet.
        /// </summary>
        /// <param name="idFormat">
        /// The id format for the SyncIds
        /// </param>
        /// <param name="tableNames">
        /// All the table names in that will be in the sum of the
        /// batches. Order does not matter.
        /// </param>
        public BatchRangeSetBuilder(SyncIdFormat idFormat, List <string> tableNames)
        {
            _tableRanges = new Dictionary <string, BatchRange>(tableNames.Count);
            _idFormat    = idFormat;

            int numTables = tableNames.Count;
            SortedList <SyncId, string> tablesSortedBySyncId
                = new SortedList <SyncId, string>(numTables);

            List <object> emptyPkVals = new List <object>(0);

            foreach (string curTable in tableNames)
            {
                SyncId idBeforeTable = SyncUtil.InitRowId(curTable, emptyPkVals);
                tablesSortedBySyncId.Add(idBeforeTable, curTable);
            }

            // for each table we need to determine the:
            // - starting SyncId (zero or first id in table)
            // - ending SyncId (just before next table or infinity)
            BatchRange prevTableRange = null;

            foreach (KeyValuePair <SyncId, string> curElem in tablesSortedBySyncId)
            {
                BatchRange curTableRange = new BatchRange();
                curTableRange.TableName = curElem.Value;
                // assume this is the last table and then fix this if
                // there is another table
                curTableRange.End = _idFormat.Infinity;
                if (prevTableRange == null)
                {
                    // first table starts at zero
                    curTableRange.Start = _idFormat.Zero;
                }
                else
                {
                    // fix up prev end to be correct
                    // set it's end to be one before current tables
                    // starting SyncId
                    prevTableRange.End  = curElem.Key;
                    curTableRange.Start = IdPlusOne(_idFormat, curElem.Key);
                }
                prevTableRange = curTableRange;
                _tableRanges.Add(curTableRange.TableName, curTableRange);
            }
        }