示例#1
0
        internal static DataRow?GetParentRow(DataKey parentKey, DataKey childKey, DataRow childRow, DataRowVersion version)
        {
            if (!childRow.HasVersion((version == DataRowVersion.Original) ? DataRowVersion.Original : DataRowVersion.Current))
            {
                if (childRow._tempRecord == -1)
                {
                    return(null);
                }
            }

            object[] values = childRow.GetKeyValues(childKey, version);
            if (IsKeyNull(values))
            {
                return(null);
            }

            Index index = parentKey.GetSortIndex((version == DataRowVersion.Original) ? DataViewRowState.OriginalRows : DataViewRowState.CurrentRows);
            Range range = index.FindRecords(values);

            if (range.IsNull)
            {
                return(null);
            }

            if (range.Count > 1)
            {
                throw ExceptionBuilder.MultipleParents();
            }

            return(parentKey.Table._recordManager[index.GetRecord(range.Min)]);
        }
示例#2
0
        internal void CascadeRollback(DataRow row)
        {
            Index sortIndex = this.childKey.GetSortIndex((row.RowState == DataRowState.Deleted) ? DataViewRowState.OriginalRows : DataViewRowState.CurrentRows);

            object[] keyValues = row.GetKeyValues(this.parentKey, (row.RowState == DataRowState.Modified) ? DataRowVersion.Current : DataRowVersion.Default);
            if (!this.IsKeyNull(keyValues))
            {
                Range range = sortIndex.FindRecords(keyValues);
                if (this.acceptRejectRule == System.Data.AcceptRejectRule.Cascade)
                {
                    if (!range.IsNull)
                    {
                        DataRow[] rows = sortIndex.GetRows(range);
                        for (int i = 0; i < rows.Length; i++)
                        {
                            if (!rows[i].inCascade)
                            {
                                rows[i].RejectChanges();
                            }
                        }
                    }
                }
                else if (((((row.RowState != DataRowState.Deleted) && row.Table.DataSet.EnforceConstraints) && !range.IsNull) && ((range.Count != 1) || (sortIndex.GetRow(range.Min) != row))) && row.HasKeyChanged(this.parentKey))
                {
                    throw ExceptionBuilder.FailedCascadeUpdate(this.ConstraintName);
                }
            }
        }
示例#3
0
        internal override bool IsConstraintViolated()
        {
            Index childIndex = childKey.GetSortIndex();

            object[] uniqueChildKeys = childIndex.GetUniqueKeyValues();
            bool     errors          = false;

            Index parentIndex = parentKey.GetSortIndex();

            for (int i = 0; i < uniqueChildKeys.Length; i++)
            {
                object[] childValues = (object[])uniqueChildKeys[i];

                if (!IsKeyNull(childValues))
                {
                    if (!parentIndex.IsKeyInIndex(childValues))
                    {
                        DataRow[] rows  = childIndex.GetRows(childIndex.FindRecords(childValues));
                        string    error = Res.GetString(Res.DataConstraint_ForeignKeyViolation, ConstraintName, ExceptionBuilder.KeysToString(childValues));
                        for (int j = 0; j < rows.Length; j++)
                        {
                            rows[j].RowError = error;
                        }
                        errors = true;
                    }
                }
            }
            return(errors);
        }
示例#4
0
        internal void CascadeCommit(DataRow row)
        {
            if (row.RowState == DataRowState.Detached)
            {
                return;
            }
            if (acceptRejectRule == AcceptRejectRule.Cascade)
            {
                Index    childIndex = childKey.GetSortIndex(row.RowState == DataRowState.Deleted ? DataViewRowState.Deleted : DataViewRowState.CurrentRows);
                object[] key        = row.GetKeyValues(parentKey, row.RowState == DataRowState.Deleted ? DataRowVersion.Original  : DataRowVersion.Default);
                if (IsKeyNull(key))
                {
                    return;
                }

                Range range = childIndex.FindRecords(key);
                if (!range.IsNull)
                {
                    for (int j = range.Min; j <= range.Max; j++)
                    {
                        DataRow childRow = childIndex.GetRow(j);
                        if (childRow.inCascade)
                        {
                            continue;
                        }
                        childRow.AcceptChanges();
                    }
                }
            }
        }
示例#5
0
        internal override void CheckConstraint(DataRow row, DataRowAction action)
        {
            if (Table.EnforceConstraints &&
                (action == DataRowAction.Add ||
                 action == DataRowAction.Change ||
                 (action == DataRowAction.Rollback && row.tempRecord != -1)))
            {
                if (row.HaveValuesChanged(Columns))
                {
                    Index    index  = Key.GetSortIndex();
                    object[] values = row.GetColumnValues(Columns);
                    if (index.IsKeyInIndex(values))
                    {
#if DEBUG
                        if (CompModSwitches.Data_Constraints.TraceVerbose)
                        {
                            Debug.WriteLine("UniqueConstraint violation...");
                            string valuesText = "";
                            for (int i = 0; i < values.Length; i++)
                            {
                                valuesText = Convert.ToString(values[i]) + (i < values.Length - 1 ? ", " : "");
                            }
                            Debug.WriteLine("   constraint: " + this.GetDebugString());
                            Debug.WriteLine("   key values: " + valuesText);
                            Range range  = index.FindRecords(values);
                            int   record = index.GetRecord(range.Min);
                            Debug.WriteLine("   conflicting record: " + record.ToString());
                        }
#endif
                        throw ExceptionBuilder.ConstraintViolation(Columns, values);
                    }
                }
            }
        }
示例#6
0
        internal override bool IsConstraintViolated()
        {
            bool  result = false;
            Index index  = ConstraintIndex;

            if (index.HasDuplicates)
            {
                object[] uniqueKeys = index.GetUniqueKeyValues();

                for (int i = 0; i < uniqueKeys.Length; i++)
                {
                    Range r = index.FindRecords((object[])uniqueKeys[i]);
                    if (1 < r.Count)
                    {
                        DataRow[] rows  = index.GetRows(r);
                        string    error = ExceptionBuilder.UniqueConstraintViolationText(_key.ColumnsReference, (object[])uniqueKeys[i]);
                        for (int j = 0; j < rows.Length; j++)
                        {
                            rows[j].RowError = error;
                            foreach (DataColumn dataColumn in _key.ColumnsReference)
                            {
                                rows[j].SetColumnError(dataColumn, error);
                            }
                        }
                        result = true;
                    }
                }
            }
            return(result);
        }
        internal override bool IsConstraintViolated()
        {
            bool  flag            = false;
            Index constraintIndex = this.ConstraintIndex;

            if (constraintIndex.HasDuplicates)
            {
                object[] uniqueKeyValues = constraintIndex.GetUniqueKeyValues();
                for (int i = 0; i < uniqueKeyValues.Length; i++)
                {
                    Range range = constraintIndex.FindRecords((object[])uniqueKeyValues[i]);
                    if (1 < range.Count)
                    {
                        DataRow[] rows  = constraintIndex.GetRows(range);
                        string    error = ExceptionBuilder.UniqueConstraintViolationText(this.key.ColumnsReference, (object[])uniqueKeyValues[i]);
                        for (int j = 0; j < rows.Length; j++)
                        {
                            rows[j].RowError = error;
                            foreach (DataColumn column in this.key.ColumnsReference)
                            {
                                rows[j].SetColumnError(column, error);
                            }
                        }
                        flag = true;
                    }
                }
            }
            return(flag);
        }
示例#8
0
        internal void CascadeRollback(DataRow row)
        {
            Debug.Assert(row.Table.DataSet != null);

            Index childIndex = _childKey.GetSortIndex(row.RowState == DataRowState.Deleted ? DataViewRowState.OriginalRows : DataViewRowState.CurrentRows);

            object[] key = row.GetKeyValues(_parentKey, row.RowState == DataRowState.Modified ? DataRowVersion.Current : DataRowVersion.Default);

            if (IsKeyNull(key))
            {
                return;
            }

            Range range = childIndex.FindRecords(key);

            if (_acceptRejectRule == AcceptRejectRule.Cascade)
            {
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        if (rows[j]._inCascade)
                        {
                            continue;
                        }
                        rows[j].RejectChanges();
                    }
                }
            }
            else
            {
                // AcceptRejectRule.None
                if (row.RowState != DataRowState.Deleted && row.Table.DataSet.EnforceConstraints)
                {
                    if (!range.IsNull)
                    {
                        if (range.Count == 1 && childIndex.GetRow(range.Min) == row)
                        {
                            return;
                        }

                        if (row.HasKeyChanged(_parentKey))
                        {// if key is not changed, this will not cause child to be stranded
                            throw ExceptionBuilder.FailedCascadeUpdate(ConstraintName);
                        }
                    }
                }
            }
        }
示例#9
0
        internal void CascadeRollback(DataRow row)
        {
            Index childIndex = childKey.GetSortIndex(row.RowState == DataRowState.Deleted  ? DataViewRowState.OriginalRows : DataViewRowState.CurrentRows);

            object[] key = row.GetKeyValues(parentKey, row.RowState == DataRowState.Modified ? DataRowVersion.Current        : DataRowVersion.Default);

            // Bug : This is definitely not a proper fix. (Ref. MDAC Bug 73592)
            if (IsKeyNull(key))
            {
                return;
            }

            Range range = childIndex.FindRecords(key);

            if (acceptRejectRule == AcceptRejectRule.Cascade)
            {
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        if (rows[j].inCascade)
                        {
                            continue;
                        }
                        rows[j].RejectChanges();
                    }
                }
            }
            else
            {
                // AcceptRejectRule.None
                if (row.RowState != DataRowState.Deleted && row.Table.DataSet.EnforceConstraints)
                {
                    if (!range.IsNull)
                    {
                        if (range.Count == 1 && childIndex.GetRow(range.Min) == row)
                        {
                            return;
                        }

                        throw ExceptionBuilder.FailedCascadeUpdate(ConstraintName);
                    }
                }
            }
        }
示例#10
0
 internal void CascadeCommit(DataRow row)
 {
     if ((row.RowState != DataRowState.Detached) && (this.acceptRejectRule == System.Data.AcceptRejectRule.Cascade))
     {
         Index    sortIndex = this.childKey.GetSortIndex((row.RowState == DataRowState.Deleted) ? DataViewRowState.Deleted : DataViewRowState.CurrentRows);
         object[] keyValues = row.GetKeyValues(this.parentKey, (row.RowState == DataRowState.Deleted) ? DataRowVersion.Original : DataRowVersion.Default);
         if (!this.IsKeyNull(keyValues))
         {
             Range range = sortIndex.FindRecords(keyValues);
             if (!range.IsNull)
             {
                 foreach (DataRow row2 in sortIndex.GetRows(range))
                 {
                     if ((DataRowState.Detached != row2.RowState) && !row2.inCascade)
                     {
                         row2.AcceptChanges();
                     }
                 }
             }
         }
     }
 }
示例#11
0
        internal override bool IsConstraintViolated()
        {
            Index index = key.GetSortIndex();

            object[] uniqueKeys = index.GetUniqueKeyValues();
            bool     errors     = false;

            for (int i = 0; i < uniqueKeys.Length; i++)
            {
                Range     r    = index.FindRecords((object[])uniqueKeys[i]);
                DataRow[] rows = index.GetRows(r);
                if (rows.Length > 1)
                {
                    string error = ExceptionBuilder.UniqueConstraintViolationText(key.Columns, (object[])uniqueKeys[i]);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        rows[j].RowError = error;
                        errors           = true;
                    }
                }
            }
            return(errors);
        }
示例#12
0
        internal override bool IsConstraintViolated()
        {
            Index sortIndex = this.childKey.GetSortIndex();

            object[] uniqueKeyValues = sortIndex.GetUniqueKeyValues();
            bool     flag            = false;
            Index    index2          = this.parentKey.GetSortIndex();

            for (int i = 0; i < uniqueKeyValues.Length; i++)
            {
                object[] values = (object[])uniqueKeyValues[i];
                if (!this.IsKeyNull(values) && !index2.IsKeyInIndex(values))
                {
                    DataRow[] rows = sortIndex.GetRows(sortIndex.FindRecords(values));
                    string    str  = Res.GetString("DataConstraint_ForeignKeyViolation", new object[] { this.ConstraintName, ExceptionBuilder.KeysToString(values) });
                    for (int j = 0; j < rows.Length; j++)
                    {
                        rows[j].RowError = str;
                    }
                    flag = true;
                }
            }
            return(flag);
        }
示例#13
0
        internal void CascadeCommit(DataRow row)
        {
            if (row.RowState == DataRowState.Detached)
            {
                return;
            }

            if (_acceptRejectRule == AcceptRejectRule.Cascade)
            {
                Index    childIndex = _childKey.GetSortIndex(row.RowState == DataRowState.Deleted ? DataViewRowState.Deleted : DataViewRowState.CurrentRows);
                object[] key        = row.GetKeyValues(_parentKey, row.RowState == DataRowState.Deleted ? DataRowVersion.Original : DataRowVersion.Default);
                if (IsKeyNull(key))
                {
                    return;
                }

                Range range = childIndex.FindRecords(key);
                if (!range.IsNull)
                {
                    // Self-referencing table has suspendIndexEvents, in the multi-table scenario the child table hasn't
                    // this allows the self-ref table to maintain the index while in the child-table doesn't
                    DataRow[] rows = childIndex.GetRows(range);
                    foreach (DataRow childRow in rows)
                    {
                        if (DataRowState.Detached != childRow.RowState)
                        {
                            if (childRow._inCascade)
                            {
                                continue;
                            }
                            childRow.AcceptChanges();
                        }
                    }
                }
            }
        }
示例#14
0
        internal void CascadeUpdate(DataRow row)
        {
            if (-1 == row.newRecord)
            {
                return;
            }

            object[] currentKey = row.GetKeyValues(parentKey, DataRowVersion.Current);
            if (!Table.DataSet.fInReadXml && IsKeyNull(currentKey))
            {
                return;
            }

            Index childIndex = childKey.GetSortIndex();

            switch (UpdateRule)
            {
            case Rule.None: {
                if (row.Table.DataSet.EnforceConstraints)
                {
                    // if we're not cascading deletes, we should throw if we're going to strand a child row under enforceConstraints.
                    Range range = childIndex.FindRecords(currentKey);
                    if (!range.IsNull)
                    {
                        throw ExceptionBuilder.FailedCascadeUpdate(ConstraintName);
                    }
                }
                break;
            }

            case Rule.Cascade: {
                Range range = childIndex.FindRecords(currentKey);
                if (!range.IsNull)
                {
                    object[]  proposedKey = row.GetKeyValues(parentKey, DataRowVersion.Proposed);
                    DataRow[] rows        = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        // if (rows[j].inCascade)
                        //    continue;
                        rows[j].SetKeyValues(childKey, proposedKey);
                    }
                }
                break;
            }

            case Rule.SetNull: {
                object[] proposedKey = new object[childKey.Columns.Length];
                for (int i = 0; i < childKey.Columns.Length; i++)
                {
                    proposedKey[i] = DBNull.Value;
                }
                Range range = childIndex.FindRecords(currentKey);
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        // if (rows[j].inCascade)
                        //    continue;
                        rows[j].SetKeyValues(childKey, proposedKey);
                    }
                }
                break;
            }

            case Rule.SetDefault: {
                object[] proposedKey = new object[childKey.Columns.Length];
                for (int i = 0; i < childKey.Columns.Length; i++)
                {
                    proposedKey[i] = childKey.Columns[i].DefaultValue;
                }
                Range range = childIndex.FindRecords(currentKey);
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        // if (rows[j].inCascade)
                        //    continue;
                        rows[j].SetKeyValues(childKey, proposedKey);
                    }
                }
                break;
            }

            default: {
                Debug.Assert(false, "Unknown Rule value");
                break;
            }
            }
        }
示例#15
0
        internal void CascadeDelete(DataRow row)
        {
            if (-1 != row.newRecord)
            {
                object[] keyValues = row.GetKeyValues(this.parentKey, DataRowVersion.Current);
                if (!this.IsKeyNull(keyValues))
                {
                    Index sortIndex = this.childKey.GetSortIndex();
                    switch (this.DeleteRule)
                    {
                    case Rule.None:
                        if (row.Table.DataSet.EnforceConstraints)
                        {
                            Range range4 = sortIndex.FindRecords(keyValues);
                            if (range4.IsNull)
                            {
                                return;
                            }
                            if ((range4.Count != 1) || (sortIndex.GetRow(range4.Min) != row))
                            {
                                throw ExceptionBuilder.FailedCascadeDelete(this.ConstraintName);
                            }
                        }
                        return;

                    case Rule.Cascade:
                    {
                        object[] key    = row.GetKeyValues(this.parentKey, DataRowVersion.Default);
                        Range    range3 = sortIndex.FindRecords(key);
                        if (!range3.IsNull)
                        {
                            foreach (DataRow row2 in sortIndex.GetRows(range3))
                            {
                                if (!row2.inCascade)
                                {
                                    row2.Table.DeleteRow(row2);
                                }
                            }
                        }
                        return;
                    }

                    case Rule.SetNull:
                    {
                        object[] objArray3 = new object[this.childKey.ColumnsReference.Length];
                        for (int i = 0; i < this.childKey.ColumnsReference.Length; i++)
                        {
                            objArray3[i] = DBNull.Value;
                        }
                        Range range2 = sortIndex.FindRecords(keyValues);
                        if (!range2.IsNull)
                        {
                            DataRow[] rows = sortIndex.GetRows(range2);
                            for (int j = 0; j < rows.Length; j++)
                            {
                                if (row != rows[j])
                                {
                                    rows[j].SetKeyValues(this.childKey, objArray3);
                                }
                            }
                        }
                        return;
                    }

                    case Rule.SetDefault:
                    {
                        object[] objArray2 = new object[this.childKey.ColumnsReference.Length];
                        for (int k = 0; k < this.childKey.ColumnsReference.Length; k++)
                        {
                            objArray2[k] = this.childKey.ColumnsReference[k].DefaultValue;
                        }
                        Range range = sortIndex.FindRecords(keyValues);
                        if (!range.IsNull)
                        {
                            DataRow[] rowArray = sortIndex.GetRows(range);
                            for (int m = 0; m < rowArray.Length; m++)
                            {
                                if (row != rowArray[m])
                                {
                                    rowArray[m].SetKeyValues(this.childKey, objArray2);
                                }
                            }
                        }
                        return;
                    }
                    }
                }
            }
        }
示例#16
0
        internal void CascadeUpdate(DataRow row)
        {
            if (-1 != row.newRecord)
            {
                object[] keyValues = row.GetKeyValues(this.parentKey, DataRowVersion.Current);
                if (this.Table.DataSet.fInReadXml || !this.IsKeyNull(keyValues))
                {
                    Index sortIndex = this.childKey.GetSortIndex();
                    switch (this.UpdateRule)
                    {
                    case Rule.None:
                        if (row.Table.DataSet.EnforceConstraints && !sortIndex.FindRecords(keyValues).IsNull)
                        {
                            throw ExceptionBuilder.FailedCascadeUpdate(this.ConstraintName);
                        }
                        return;

                    case Rule.Cascade:
                    {
                        Range range3 = sortIndex.FindRecords(keyValues);
                        if (!range3.IsNull)
                        {
                            object[]  objArray4 = row.GetKeyValues(this.parentKey, DataRowVersion.Proposed);
                            DataRow[] rows      = sortIndex.GetRows(range3);
                            for (int i = 0; i < rows.Length; i++)
                            {
                                rows[i].SetKeyValues(this.childKey, objArray4);
                            }
                        }
                        return;
                    }

                    case Rule.SetNull:
                    {
                        object[] objArray3 = new object[this.childKey.ColumnsReference.Length];
                        for (int j = 0; j < this.childKey.ColumnsReference.Length; j++)
                        {
                            objArray3[j] = DBNull.Value;
                        }
                        Range range2 = sortIndex.FindRecords(keyValues);
                        if (!range2.IsNull)
                        {
                            DataRow[] rowArray2 = sortIndex.GetRows(range2);
                            for (int k = 0; k < rowArray2.Length; k++)
                            {
                                rowArray2[k].SetKeyValues(this.childKey, objArray3);
                            }
                        }
                        return;
                    }

                    case Rule.SetDefault:
                    {
                        object[] objArray2 = new object[this.childKey.ColumnsReference.Length];
                        for (int m = 0; m < this.childKey.ColumnsReference.Length; m++)
                        {
                            objArray2[m] = this.childKey.ColumnsReference[m].DefaultValue;
                        }
                        Range range = sortIndex.FindRecords(keyValues);
                        if (!range.IsNull)
                        {
                            DataRow[] rowArray = sortIndex.GetRows(range);
                            for (int n = 0; n < rowArray.Length; n++)
                            {
                                rowArray[n].SetKeyValues(this.childKey, objArray2);
                            }
                        }
                        return;
                    }
                    }
                }
            }
        }
示例#17
0
        internal void CascadeDelete(DataRow row)
        {
            if (-1 == row._newRecord)
            {
                return;
            }

            object[] currentKey = row.GetKeyValues(_parentKey, DataRowVersion.Current);
            if (IsKeyNull(currentKey))
            {
                return;
            }

            Index childIndex = _childKey.GetSortIndex();

            switch (DeleteRule)
            {
            case Rule.None:
            {
                if (row.Table.DataSet.EnforceConstraints)
                {
                    // if we're not cascading deletes, we should throw if we're going to strand a child row under enforceConstraints.
                    Range range = childIndex.FindRecords(currentKey);
                    if (!range.IsNull)
                    {
                        if (range.Count == 1 && childIndex.GetRow(range.Min) == row)
                        {
                            return;
                        }

                        throw ExceptionBuilder.FailedCascadeDelete(ConstraintName);
                    }
                }
                break;
            }

            case Rule.Cascade:
            {
                object[] key   = row.GetKeyValues(_parentKey, DataRowVersion.Default);
                Range    range = childIndex.FindRecords(key);
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);

                    for (int j = 0; j < rows.Length; j++)
                    {
                        DataRow r = rows[j];
                        if (r._inCascade)
                        {
                            continue;
                        }
                        r.Table.DeleteRow(r);
                    }
                }
                break;
            }

            case Rule.SetNull:
            {
                object[] proposedKey = new object[_childKey.ColumnsReference.Length];
                for (int i = 0; i < _childKey.ColumnsReference.Length; i++)
                {
                    proposedKey[i] = DBNull.Value;
                }
                Range range = childIndex.FindRecords(currentKey);
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        // if (rows[j].inCascade)
                        //    continue;
                        if (row != rows[j])
                        {
                            rows[j].SetKeyValues(_childKey, proposedKey);
                        }
                    }
                }
                break;
            }

            case Rule.SetDefault:
            {
                object[] proposedKey = new object[_childKey.ColumnsReference.Length];
                for (int i = 0; i < _childKey.ColumnsReference.Length; i++)
                {
                    proposedKey[i] = _childKey.ColumnsReference[i].DefaultValue;
                }
                Range range = childIndex.FindRecords(currentKey);
                if (!range.IsNull)
                {
                    DataRow[] rows = childIndex.GetRows(range);
                    for (int j = 0; j < rows.Length; j++)
                    {
                        // if (rows[j].inCascade)
                        //    continue;
                        if (row != rows[j])
                        {
                            rows[j].SetKeyValues(_childKey, proposedKey);
                        }
                    }
                }
                break;
            }

            default:
            {
                Debug.Fail("Unknown Rule value");
                break;
            }
            }
        }