public DatabaseCollector(IDatabase database)
        {
            MaintainObjectModel = true;
            Database            = database;

            // 1. Build a Collector for each Table
            _tableCollectors = new Dictionary <string, TableCollector>();
            foreach (var table in database.Tables)
            {
                _tableCollectors[table.Key] = new TableCollector(this, table.Value, table.Key);
            }

            // 2. Hook up ref columns between the source and target table collectors
            foreach (var table in database.Tables)
            {
                string         tableName       = table.Key;
                TableCollector sourceCollector = _tableCollectors[tableName];

                foreach (var column in table.Value.Columns)
                {
                    IRefColumn refColumn = column.Value as IRefColumn;
                    if (refColumn != null)
                    {
                        sourceCollector.AddRefColumn(column.Key, refColumn, _tableCollectors[refColumn.ReferencedTableName]);
                    }
                }
            }
        }
        public void AddRefColumn(string columnName, IRefColumn column, TableCollector target)
        {
            if (_refsFromTable == null)
            {
                _refsFromTable = new List <ColumnCollector>();
            }
            if (target._refsToTable == null)
            {
                target._refsToTable = new List <ColumnCollector>();
            }

            ColumnCollector collector = new ColumnCollector(columnName, column, target);

            // Add column to 'RefsTo' in the target (for remapping indices)
            target._refsToTable.Add(collector);

            // Add column to 'RefsFrom' in the source (for walking reachable indices)
            _refsFromTable.Add(collector);
        }
        public void CopyUnreachableGraphToTemp()
        {
            if (_unreachableCount == 0)
            {
                return;
            }

            _tempTable = _databaseCollector.TempDatabase.Tables[_tableName];

            // Copy every row in the unreachable graph to the temp table *non-recursively*
            foreach (string columnName in _table.Columns.Keys)
            {
                IColumn source = _table.Columns[columnName];
                IColumn temp   = _tempTable.Columns[columnName];

                for (int tempIndex = 0; tempIndex < _tempIndexToRowIndex.Length; ++tempIndex)
                {
                    int sourceIndex = _tempIndexToRowIndex[tempIndex];
                    temp.CopyItem(tempIndex, source, sourceIndex);
                }
            }

            // Update every Ref and RefList in the temp copy of *this* table to use the re-assigned temp indices from the corresponding referenced temp table
            if (_refsFromTable != null)
            {
                foreach (var refCollector in _refsFromTable)
                {
                    IRefColumn     tempTableColumn          = (IRefColumn)_tempTable.Columns[refCollector.ColumnName];
                    TableCollector referencedTableCollector = refCollector.ReferencedTableCollector;
                    tempTableColumn.ForEach((slice) => IntRemapper.Instance.Remap(slice, referencedTableCollector._rowIndexToTempIndex));
                }
            }

            // Ensure temp table count correct
            _tempTable.SetCount(_tempIndexToRowIndex.Length);
        }
 public ColumnCollector(string columnName, IRefColumn column, TableCollector referencedTableCollector)
 {
     ColumnName = columnName;
     Column     = column;
     ReferencedTableCollector = referencedTableCollector;
 }