2 // System.Data.Constraint.cs
5 // Franklin Wise <gracenote@earthlink.net>
7 // Tim Coleman (tim@timcoleman.com)
10 // (C) Ximian, Inc. 2002
11 // Copyright (C) Tim Coleman, 2002
15 using System.Collections;
16 using System.ComponentModel;
17 using System.Runtime.InteropServices;
18 using System.Runtime.Serialization;
20 namespace System.Data {
22 internal delegate void DelegateConstraintNameChange (object sender, string newName);
24 [DefaultProperty ("ConstraintName")]
26 public abstract class Constraint
28 internal event DelegateConstraintNameChange BeforeConstraintNameChange;
30 //if constraintName is not set then a name is
31 //created when it is added to
32 //the ConstraintCollection
33 //it can not be set to null, empty or duplicate
34 //once it has been added to the collection
35 private string _constraintName;
36 private PropertyCollection _properties;
40 //Used for membership checking
41 private ConstraintCollection _constraintCollection;
45 protected Constraint ()
48 _properties = new PropertyCollection();
51 protected internal virtual DataSet _DataSet {
52 get { return dataSet; }
55 [DataCategory ("Data")]
56 [DataSysDescription ("Indicates the name of this constraint.")]
58 public virtual string ConstraintName {
59 get{ return "" + _constraintName; }
61 //This should only throw an exception when it
62 //is a member of a ConstraintCollection which
63 //means we should let the ConstraintCollection
64 //handle exceptions when this value changes
65 _onConstraintNameChange(value);
66 _constraintName = value;
71 [DataCategory ("Data")]
72 [DataSysDescription ("The collection that holds custom user information.")]
73 public PropertyCollection ExtendedProperties {
74 get { return _properties; }
77 [DataSysDescription ("Indicates the table of this constraint.")]
78 public abstract DataTable Table {
82 internal ConstraintCollection ConstraintCollection {
83 get{ return _constraintCollection; }
84 set{ _constraintCollection = value; }
87 private void _onConstraintNameChange (string newName)
89 if (null != BeforeConstraintNameChange)
91 BeforeConstraintNameChange (this, newName);
95 //call once before adding a constraint to a collection
96 //will throw an exception to prevent the add if a rule is broken
97 internal virtual void AddToConstraintCollectionSetup (ConstraintCollection collection)
101 internal virtual void AssertConstraint ()
105 internal virtual void AssertConstraint (DataRow row)
109 internal virtual void RollbackAssert (DataRow row)
113 //call once before removing a constraint to a collection
114 //can throw an exception to prevent the removal
115 internal virtual void RemoveFromConstraintCollectionCleanup (ConstraintCollection collection)
120 protected void CheckStateForProperty ()
122 throw new NotImplementedException ();
125 protected internal void SetDataSet (DataSet dataSet)
127 this.dataSet = dataSet;
140 protected internal void UpdateIndex (DataRow row)
142 if (row.RowState == DataRowState.Detached || row.RowState == DataRowState.Unchanged)
143 Index.Insert (new Node (row), DataRowVersion.Default);
144 else if ((row.RowState == DataRowState.Modified) || (row.RowState == DataRowState.Added)) {
145 // first we check if the values of the key changed.
146 bool keyChanged = false;
147 for (int i = 0; i < Index.Columns.Length; i++) {
148 if (row[Index.Columns[i], DataRowVersion.Default] != row[Index.Columns[i], DataRowVersion.Current]) {
152 // if key changed we first try to insert a new node
153 // and,if succeded, we delete the row's old node.
156 // insert new node for the row
157 // note : may throw if not succeded
158 Index.Insert (new Node (row), DataRowVersion.Default);
160 // delete the row's node
166 protected internal void RollbackIndex (DataRow row)
168 Node n = Index.Find(row, DataRowVersion.Default);
170 throw new ConstraintException("Row was not found in constraint index");
172 // first remove the node inserted as a result of last AssertConstraint on the row
175 // if the row is not detached we should add back to the index
176 // node corresponding to row value before AssertConstraint was called
177 if(row.RowState != DataRowState.Detached){
178 // since index before we updated index was ok, insert should always suceed
179 // maybe we still need to try/catch here
180 Index.Insert(new Node(row), DataRowVersion.Current);
186 /// Gets the ConstraintName, if there is one, as a string.
188 public override string ToString ()
190 return "" + _constraintName;