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 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 using System.Collections;
39 using System.ComponentModel;
40 using System.Runtime.InteropServices;
41 using System.Runtime.Serialization;
42 using System.Data.Common;
44 namespace System.Data {
46 internal delegate void DelegateConstraintNameChange (object sender, string newName);
48 [DefaultProperty ("ConstraintName")]
52 [TypeConverterAttribute (typeof (ConstraintConverter))]
53 public abstract class Constraint {
54 static readonly object beforeConstraintNameChange = new object ();
56 EventHandlerList events = new EventHandlerList ();
58 internal event DelegateConstraintNameChange BeforeConstraintNameChange {
59 add { events.AddHandler (beforeConstraintNameChange, value); }
60 remove { events.RemoveHandler (beforeConstraintNameChange, value); }
63 //if constraintName is not set then a name is
64 //created when it is added to
65 //the ConstraintCollection
66 //it can not be set to null, empty or duplicate
67 //once it has been added to the collection
68 private string _constraintName;
69 private PropertyCollection _properties;
73 //Used for membership checking
74 private ConstraintCollection _constraintCollection;
78 protected Constraint ()
81 _properties = new PropertyCollection ();
84 [CLSCompliant (false)]
85 protected internal virtual DataSet _DataSet {
86 get { return dataSet; }
89 [DataCategory ("Data")]
91 [DataSysDescription ("Indicates the name of this constraint.")]
94 public virtual string ConstraintName {
95 get { return _constraintName == null ? "" : _constraintName; }
97 //This should only throw an exception when it
98 //is a member of a ConstraintCollection which
99 //means we should let the ConstraintCollection
100 //handle exceptions when this value changes
101 _onConstraintNameChange (value);
102 _constraintName = value;
107 [DataCategory ("Data")]
109 [DataSysDescription ("The collection that holds custom user information.")]
111 public PropertyCollection ExtendedProperties {
112 get { return _properties; }
116 [DataSysDescription ("Indicates the table of this constraint.")]
118 public abstract DataTable Table {
122 internal ConstraintCollection ConstraintCollection {
123 get { return _constraintCollection; }
124 set { _constraintCollection = value; }
127 private void _onConstraintNameChange (string newName)
129 DelegateConstraintNameChange eh = events [beforeConstraintNameChange] as DelegateConstraintNameChange;
134 //call once before adding a constraint to a collection
135 //will throw an exception to prevent the add if a rule is broken
136 internal abstract void AddToConstraintCollectionSetup (ConstraintCollection collection);
138 internal abstract bool IsConstraintViolated ();
140 internal static void ThrowConstraintException ()
142 throw new ConstraintException("Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.");
145 bool initInProgress = false;
146 internal virtual bool InitInProgress {
147 get { return initInProgress; }
148 set { initInProgress = value; }
151 internal virtual void FinishInit (DataTable table)
155 internal void AssertConstraint ()
157 // The order is important.. IsConstraintViolated fills the RowErrors if it detects
159 if (!IsConstraintViolated ())
161 if (Table._duringDataLoad || (Table.DataSet != null && !Table.DataSet.EnforceConstraints))
163 ThrowConstraintException ();
166 internal abstract void AssertConstraint (DataRow row);
168 internal virtual void RollbackAssert (DataRow row)
172 //call once before removing a constraint to a collection
173 //can throw an exception to prevent the removal
174 internal abstract void RemoveFromConstraintCollectionCleanup (ConstraintCollection collection);
177 protected void CheckStateForProperty ()
179 throw new NotImplementedException ();
182 protected internal void SetDataSet (DataSet dataSet)
184 this.dataSet = dataSet;
187 internal void SetExtendedProperties (PropertyCollection properties)
189 _properties = properties;
192 internal Index Index {
193 get { return _index; }
195 if (_index != null) {
197 Table.DropIndex(_index);
207 internal abstract bool IsColumnContained (DataColumn column);
208 internal abstract bool CanRemoveFromCollection (ConstraintCollection col, bool shouldThrow);
211 /// Gets the ConstraintName, if there is one, as a string.
213 public override string ToString ()
215 return _constraintName == null ? "" : _constraintName;