Ejemplo n.º 1
0
        /// <devdoc>
        ///    <para>Finds and updates a specific row. If no matching
        ///       row is found, a new row is created using the given values.</para>
        /// </devdoc>
        public DataRow LoadDataRow(object[] values, LoadOption loadOption) {
            IntPtr hscp;
            Bid.ScopeEnter(out hscp, "<ds.DataTable.LoadDataRow|API> %d#, loadOption=%d{ds.LoadOption}\n", ObjectID,  (int)loadOption);
            try {
                Index indextoUse = null;
                if (this.primaryKey != null) {
                    if (loadOption == LoadOption.Upsert) { // CurrentVersion, and Deleted
                        if (loadIndexwithCurrentDeleted == null) {
                            loadIndexwithCurrentDeleted = this.primaryKey.Key.GetSortIndex(DataViewRowState.CurrentRows |DataViewRowState.Deleted);
                            Debug.Assert(loadIndexwithCurrentDeleted != null, "loadIndexwithCurrentDeleted should not be null" );
                            if (loadIndexwithCurrentDeleted != null) {
                                loadIndexwithCurrentDeleted.AddRef();
                            }
                        }
                        indextoUse = loadIndexwithCurrentDeleted;
                    }
                    else {// CurrentVersion, and Deleted : OverwriteRow, PreserveCurrentValues
                        if (loadIndexwithOriginalAdded == null) {
                            loadIndexwithOriginalAdded  = this.primaryKey.Key.GetSortIndex(DataViewRowState.OriginalRows |DataViewRowState.Added);
                            Debug.Assert(loadIndexwithOriginalAdded != null, "loadIndexwithOriginalAdded should not be null");
                            if (loadIndexwithOriginalAdded != null) {
                                loadIndexwithOriginalAdded.AddRef();
                            }
                        }
                        indextoUse = loadIndexwithOriginalAdded;
                    }
                    // not expecting LiveIndexes to clear the index we use between calls to LoadDataRow
                    Debug.Assert(2 <= indextoUse.RefCount, "bad indextoUse.RefCount");
                }
                if(inDataLoad && !AreIndexEventsSuspended) { // we do not want to fire any listchanged in new Load/Fill
                    SuspendIndexEvents();// so suspend events here(not suspended == table already has some rows initially)
                }

                DataRow dataRow = LoadRow(values, loadOption, indextoUse);// if indextoUse == null, it means we dont have PK,
                                                                          // so LoadRow will take care of just adding the row to end

                return dataRow;
            }
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        }
Ejemplo n.º 2
0
        // 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;
                    int candidatesNotInIndex = nCandidates - 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(this.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(this.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(this.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 (this.linearExpression != this.expression) {
                            IndexField[] fields = index.IndexFields;
                            while (matchedCandidates < j) { // [....] : j = index.IndexDesc.Length
                                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 
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
 internal Index GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter rowFilter) {
     indexesLock.AcquireReaderLock(-1);
     try {
         for (int i = 0; i < indexes.Count; i++) {
             Index index = indexes[i];
             if (index != null) {
                 if (index.Equal(indexDesc, recordStates, rowFilter)) {
                     return index;
                 }
             }
         }
     }
     finally {
         indexesLock.ReleaseReaderLock();
     }
     Index ndx = new Index(this, indexDesc, recordStates, rowFilter);
     ndx.AddRef();
     return ndx;
 }
Ejemplo n.º 4
0
 internal Index GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter rowFilter)
 {
     _indexesLock.EnterUpgradeableReadLock();
     try
     {
         for (int i = 0; i < _indexes.Count; i++)
         {
             Index index = _indexes[i];
             if (index != null)
             {
                 if (index.Equal(indexDesc, recordStates, rowFilter))
                 {
                     return index;
                 }
             }
         }
     }
     finally
     {
         _indexesLock.ExitUpgradeableReadLock();
     }
     Index ndx = new Index(this, indexDesc, recordStates, rowFilter);
     ndx.AddRef();
     return ndx;
 }