Ejemplo n.º 1
0
        internal DataRow MergeRow(DataRow row, DataRow targetRow, bool preserveChanges, Index idxSearch) {
             if (targetRow == null) {
                targetRow = this.NewEmptyRow();
                targetRow.oldRecord = recordManager.ImportRecord(row.Table, row.oldRecord);
                targetRow.newRecord = targetRow.oldRecord;
                if(row.oldRecord != row.newRecord) {
                    targetRow.newRecord = recordManager.ImportRecord(row.Table, row.newRecord);
                }
                InsertRow(targetRow, -1);
            }
            else {
                // SQLBU 500789: Record Manager corruption during Merge when target row in edit state
                // the newRecord would be freed and overwrite tempRecord (which became the newRecord)
                // this would leave the DataRow referencing a freed record and leaking memory for the now lost record
                int proposedRecord = targetRow.tempRecord; // by saving off the tempRecord, EndEdit won't free newRecord
                targetRow.tempRecord = -1;
                try {
                    DataRowState saveRowState = targetRow.RowState;
                    int saveIdxRecord = (saveRowState == DataRowState.Added) ? targetRow.newRecord : saveIdxRecord = targetRow.oldRecord;
                     int newRecord;
                     int oldRecord;
                    if (targetRow.RowState == DataRowState.Unchanged && row.RowState == DataRowState.Unchanged) {
                        // unchanged row merging with unchanged row
                        oldRecord = targetRow.oldRecord;
                        newRecord = (preserveChanges) ? recordManager.CopyRecord(this, oldRecord, -1) : targetRow.newRecord;
                        oldRecord = recordManager.CopyRecord(row.Table, row.oldRecord, targetRow.oldRecord);
                        SetMergeRecords(targetRow, newRecord, oldRecord, DataRowAction.Change);
                    }
                    else if (row.newRecord == -1) {
                        // Incoming row is deleted
                        oldRecord = targetRow.oldRecord;
                        if (preserveChanges) {
                          newRecord = (targetRow.RowState == DataRowState.Unchanged)? recordManager.CopyRecord(this, oldRecord, -1) : targetRow.newRecord;
                        }
                        else
                            newRecord = -1;
                        oldRecord = recordManager.CopyRecord(row.Table, row.oldRecord, oldRecord);

                        // Change index record, need to update index
                        if (saveIdxRecord != ((saveRowState == DataRowState.Added) ? newRecord : oldRecord)) {
                            SetMergeRecords(targetRow, newRecord, oldRecord, (newRecord == -1) ? DataRowAction.Delete : DataRowAction.Change);
                            idxSearch.Reset();
                            saveIdxRecord = ((saveRowState == DataRowState.Added) ? newRecord : oldRecord);
                        } else {
                            SetMergeRecords(targetRow, newRecord, oldRecord, (newRecord == -1) ? DataRowAction.Delete : DataRowAction.Change);
                        }
                    }
                    else {
                        // incoming row is added, modified or unchanged (targetRow is not unchanged)
                        oldRecord = targetRow.oldRecord;
                        newRecord = targetRow.newRecord;
                        if (targetRow.RowState == DataRowState.Unchanged) {
                            newRecord = recordManager.CopyRecord(this, oldRecord, -1);
                        }
                        oldRecord = recordManager.CopyRecord(row.Table, row.oldRecord, oldRecord);

                        if (!preserveChanges) {
                            newRecord = recordManager.CopyRecord(row.Table, row.newRecord, newRecord);
                        }
                        SetMergeRecords(targetRow, newRecord, oldRecord, DataRowAction.Change);
                    }

                    if (saveRowState == DataRowState.Added && targetRow.oldRecord != -1)
                        idxSearch.Reset();
                    Debug.Assert(saveIdxRecord == ((saveRowState == DataRowState.Added) ? targetRow.newRecord : targetRow.oldRecord), "oops, you change index record without noticing it");
                }
                finally {
                    targetRow.tempRecord = proposedRecord;
                }
            }

            // Merge all errors
            if (row.HasErrors) {
                if (targetRow.RowError.Length == 0) {
                    targetRow.RowError = row.RowError;
                } else {
                    targetRow.RowError += " ]:[ " + row.RowError;
                }
                DataColumn[] cols = row.GetColumnsInError();

                for (int i = 0; i < cols.Length; i++) {
                    DataColumn col = targetRow.Table.Columns[cols[i].ColumnName];
                    targetRow.SetColumnError(col, row.GetColumnError(cols[i]));
                }
            }else {
                if (!preserveChanges) {
                    targetRow.ClearErrors();
                }
            }

            return targetRow;
        }
 internal DataRow MergeRow(DataRow row, DataRow targetRow, bool preserveChanges, Index idxSearch)
 {
     if (targetRow == null)
     {
         targetRow = this.NewEmptyRow();
         targetRow.oldRecord = this.recordManager.ImportRecord(row.Table, row.oldRecord);
         targetRow.newRecord = targetRow.oldRecord;
         if (row.oldRecord != row.newRecord)
         {
             targetRow.newRecord = this.recordManager.ImportRecord(row.Table, row.newRecord);
         }
         this.InsertRow(targetRow, -1L);
     }
     else
     {
         int tempRecord = targetRow.tempRecord;
         targetRow.tempRecord = -1;
         try
         {
             int oldRecord;
             int newRecord;
             int num4;
             DataRowState rowState = targetRow.RowState;
             num4 = (rowState == DataRowState.Added) ? targetRow.newRecord : (num4 = targetRow.oldRecord);
             if ((targetRow.RowState == DataRowState.Unchanged) && (row.RowState == DataRowState.Unchanged))
             {
                 oldRecord = targetRow.oldRecord;
                 newRecord = preserveChanges ? this.recordManager.CopyRecord(this, oldRecord, -1) : targetRow.newRecord;
                 oldRecord = this.recordManager.CopyRecord(row.Table, row.oldRecord, targetRow.oldRecord);
                 this.SetMergeRecords(targetRow, newRecord, oldRecord, DataRowAction.Change);
             }
             else if (row.newRecord == -1)
             {
                 oldRecord = targetRow.oldRecord;
                 if (preserveChanges)
                 {
                     newRecord = (targetRow.RowState == DataRowState.Unchanged) ? this.recordManager.CopyRecord(this, oldRecord, -1) : targetRow.newRecord;
                 }
                 else
                 {
                     newRecord = -1;
                 }
                 oldRecord = this.recordManager.CopyRecord(row.Table, row.oldRecord, oldRecord);
                 if (num4 != ((rowState == DataRowState.Added) ? newRecord : oldRecord))
                 {
                     this.SetMergeRecords(targetRow, newRecord, oldRecord, (newRecord == -1) ? DataRowAction.Delete : DataRowAction.Change);
                     idxSearch.Reset();
                     num4 = (rowState == DataRowState.Added) ? newRecord : oldRecord;
                 }
                 else
                 {
                     this.SetMergeRecords(targetRow, newRecord, oldRecord, (newRecord == -1) ? DataRowAction.Delete : DataRowAction.Change);
                 }
             }
             else
             {
                 oldRecord = targetRow.oldRecord;
                 newRecord = targetRow.newRecord;
                 if (targetRow.RowState == DataRowState.Unchanged)
                 {
                     newRecord = this.recordManager.CopyRecord(this, oldRecord, -1);
                 }
                 oldRecord = this.recordManager.CopyRecord(row.Table, row.oldRecord, oldRecord);
                 if (!preserveChanges)
                 {
                     newRecord = this.recordManager.CopyRecord(row.Table, row.newRecord, newRecord);
                 }
                 this.SetMergeRecords(targetRow, newRecord, oldRecord, DataRowAction.Change);
             }
             if ((rowState == DataRowState.Added) && (targetRow.oldRecord != -1))
             {
                 idxSearch.Reset();
             }
         }
         finally
         {
             targetRow.tempRecord = tempRecord;
         }
     }
     if (row.HasErrors)
     {
         if (targetRow.RowError.Length == 0)
         {
             targetRow.RowError = row.RowError;
         }
         else
         {
             targetRow.RowError = targetRow.RowError + " ]:[ " + row.RowError;
         }
         DataColumn[] columnsInError = row.GetColumnsInError();
         for (int i = 0; i < columnsInError.Length; i++)
         {
             DataColumn column = targetRow.Table.Columns[columnsInError[i].ColumnName];
             targetRow.SetColumnError(column, row.GetColumnError(columnsInError[i]));
         }
         return targetRow;
     }
     if (!preserveChanges)
     {
         targetRow.ClearErrors();
     }
     return targetRow;
 }