internal void RegisterListChangedEvent(Index index) { // TODO: do we realy need this lock? See considerations in the bug 55221 lock (index) { this.index = index; index.AddRef(); index.ListChanged += new ListChangedEventHandler(IndexListChanged); } }
internal void ConstraintIndexInitialize() { if (null == _constraintIndex) { _constraintIndex = _key.GetSortIndex(); _constraintIndex.AddRef(); } AssertConstraintAndKeyIndexes(); }
internal void ConstraintIndexInitialize() { //Debug.Assert(null == _constraintIndex, "non-null UniqueConstraint index"); if (null == _constraintIndex) { _constraintIndex = key.GetSortIndex(); _constraintIndex.AddRef(); } AssertConstraintAndKeyIndexes(); }
internal void RegisterListChangedEvent(Index index) { Debug.Assert(null == _index, "DataviewListener already registered index"); _index = index; if (null != index) { lock (index) { index.AddRef(); index.ListChangedAdd(this); } } }
internal void RegisterListChangedEvent(Index index) { this._index = index; if (index != null) { lock (index) { index.AddRef(); index.ListChangedAdd(this); } } }
internal void MergeRows(DataRow[] rows) { DataTable dst = null; DataTable src = null; DataKey srcKey = new DataKey(); Index ndx = null; bool enforceConstraints = this.dataSet.EnforceConstraints; this.dataSet.EnforceConstraints = false; for (int i = 0; i < rows.Length; i++) { DataRow row = rows[i]; if (row == null) { throw ExceptionBuilder.ArgumentNull("rows[" + i + "]"); } if (row.Table == null) { throw ExceptionBuilder.ArgumentNull("rows[" + i + "].Table"); } if (row.Table.DataSet != this.dataSet) { if (src != row.Table) { src = row.Table; dst = this.MergeSchema(row.Table); if (dst == null) { this.dataSet.EnforceConstraints = enforceConstraints; return; } if (dst.primaryKey != null) { srcKey = this.GetSrcKey(src, dst); } if (srcKey.HasValue) { if (ndx != null) { ndx.RemoveRef(); ndx = null; } ndx = new Index(dst, dst.primaryKey.Key.GetIndexDesc(), DataViewRowState.OriginalRows | DataViewRowState.Added, null); ndx.AddRef(); ndx.AddRef(); } } if ((row.newRecord != -1) || (row.oldRecord != -1)) { DataRow targetRow = null; if ((0 < dst.Rows.Count) && (ndx != null)) { targetRow = dst.FindMergeTarget(row, srcKey, ndx); } targetRow = dst.MergeRow(row, targetRow, this.preserveChanges, ndx); if ((targetRow.Table.dependentColumns != null) && (targetRow.Table.dependentColumns.Count > 0)) { targetRow.Table.EvaluateExpressions(targetRow, DataRowAction.Change, null); } } } } if (ndx != null) { ndx.RemoveRef(); ndx = null; } this.dataSet.EnforceConstraints = enforceConstraints; }
internal void MergeRows(DataRow[] rows) { DataTable src = null; DataTable dst = null; DataKey key = default(DataKey); Index ndxSearch = null; bool fEnforce = dataSet.EnforceConstraints; dataSet.EnforceConstraints = false; for (int i = 0; i < rows.Length; i++) { DataRow row = rows[i]; if (row == null) { throw ExceptionBuilder.ArgumentNull("rows[" + i + "]"); } if (row.Table == null) { throw ExceptionBuilder.ArgumentNull("rows[" + i + "].Table"); } //somebody is doing an 'automerge' if (row.Table.DataSet == dataSet) { continue; } if (src != row.Table) // row.Table changed from prev. row. { src = row.Table; dst = MergeSchema(row.Table); if (dst == null) { Debug.Assert(MissingSchemaAction.Ignore == missingSchemaAction, "MergeSchema failed"); dataSet.EnforceConstraints = fEnforce; return; } if (dst.primaryKey != null) { key = GetSrcKey(src, dst); } if (key.HasValue) { // Getting our own copy instead. ndxSearch = dst.primaryKey.Key.GetSortIndex(); // IMO, Better would be to reuse index // ndxSearch = dst.primaryKey.Key.GetSortIndex(DataViewRowState.OriginalRows | DataViewRowState.Added ); if (null != ndxSearch) { ndxSearch.RemoveRef(); ndxSearch = null; } ndxSearch = new Index(dst, dst.primaryKey.Key.GetIndexDesc(), DataViewRowState.OriginalRows | DataViewRowState.Added, (IFilter)null); ndxSearch.AddRef(); // need to addref twice, otherwise it will be collected ndxSearch.AddRef(); // in past first adref was done in const } } if (row.newRecord == -1 && row.oldRecord == -1) { continue; } DataRow targetRow = null; if (0 < dst.Rows.Count && ndxSearch != null) { targetRow = dst.FindMergeTarget(row, key, ndxSearch); } targetRow = dst.MergeRow(row, targetRow, preserveChanges, ndxSearch); if (targetRow.Table.dependentColumns != null && targetRow.Table.dependentColumns.Count > 0) { targetRow.Table.EvaluateExpressions(targetRow, DataRowAction.Change, null); } } if (null != ndxSearch) { ndxSearch.RemoveRef(); ndxSearch = null; } dataSet.EnforceConstraints = fEnforce; }
// Based on the required sorting and candidate columns settings, create a new index; Should be called only when there is no existing index to be reused private void CreateIndex() { if (_index == null) { if (_nCandidates == 0) { _index = new Index(_table, _indexFields, _recordStates, null); _index.AddRef(); } else { int i; int lenCanColumns = _candidateColumns.Length; int lenIndexDesc = _indexFields.Length; bool equalsOperator = true; for (i = 0; i < lenCanColumns; i++) { if (_candidateColumns[i] != null) { if (!_candidateColumns[i].equalsOperator) { equalsOperator = false; break; } } } int j = 0; for (i = 0; i < lenIndexDesc; i++) { ColumnInfo candidateColumn = _candidateColumns[_indexFields[i].Column.Ordinal]; if (candidateColumn != null) { candidateColumn.flag = true; j++; } } int indexNotInCandidates = lenIndexDesc - j; IndexField[] ndxFields = new IndexField[_nCandidates + indexNotInCandidates]; if (equalsOperator) { j = 0; for (i = 0; i < lenCanColumns; i++) { if (_candidateColumns[i] != null) { ndxFields[j++] = new IndexField(_table.Columns[i], isDescending: false); _candidateColumns[i].flag = false;// this means it is processed } } for (i = 0; i < lenIndexDesc; i++) { ColumnInfo canColumn = _candidateColumns[_indexFields[i].Column.Ordinal]; if (canColumn == null || canColumn.flag) { // if sort column is not a filter col , or not processed ndxFields[j++] = _indexFields[i]; if (canColumn != null) { canColumn.flag = false; } } } for (i = 0; i < _candidateColumns.Length; i++) { if (_candidateColumns[i] != null) { _candidateColumns[i].flag = false;// same as before, it is false when it returns } } // Debug.Assert(j == candidatesNotInIndex, "Whole ndxDesc should be filled!"); _index = new Index(_table, ndxFields, _recordStates, null); if (!IsOperatorIn(_expression)) { // if the expression contains an 'IN' operator, the index will not be shared // therefore we do not need to index.AddRef, also table would track index consuming more memory until first write _index.AddRef(); } _matchedCandidates = _nCandidates; } else { for (i = 0; i < lenIndexDesc; i++) { ndxFields[i] = _indexFields[i]; ColumnInfo canColumn = _candidateColumns[_indexFields[i].Column.Ordinal]; if (canColumn != null) { canColumn.flag = true; } } j = i; for (i = 0; i < lenCanColumns; i++) { if (_candidateColumns[i] != null) { if (!_candidateColumns[i].flag) { ndxFields[j++] = new IndexField(_table.Columns[i], isDescending: false); } else { _candidateColumns[i].flag = false; } } } // Debug.Assert(j == nCandidates+indexNotInCandidates, "Whole ndxDesc should be filled!"); _index = new Index(_table, ndxFields, _recordStates, null); _matchedCandidates = 0; if (_linearExpression != _expression) { IndexField[] fields = _index._indexFields; while (_matchedCandidates < j) { ColumnInfo canColumn = _candidateColumns[fields[_matchedCandidates].Column.Ordinal]; if (canColumn == null || canColumn.expr == null) { break; } _matchedCandidates++; if (!canColumn.equalsOperator) { break; } } } for (i = 0; i < _candidateColumns.Length; i++) { if (_candidateColumns[i] != null) { _candidateColumns[i].flag = false;// same as before, it is false when it returns } } } } } }