2010-07-23 Veerapuram Varadhan <v.varadhan@gmail.com>
[mono.git] / mcs / class / System.Data / System.Data / Constraint.cs
1 //
2 // System.Data.Constraint.cs
3 //
4 // Author:
5 //      Franklin Wise <gracenote@earthlink.net>
6 //      Daniel Morgan
7 //      Tim Coleman (tim@timcoleman.com)
8 //
9 //
10 // (C) Ximian, Inc. 2002
11 // Copyright (C) Tim Coleman, 2002
12 //
13
14 //
15 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 //
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:
24 //
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
27 //
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.
35 //
36
37 using System;
38 using System.Collections;
39 using System.ComponentModel;
40 using System.Runtime.InteropServices;
41 using System.Runtime.Serialization;
42 using System.Data.Common;
43
44 namespace System.Data {
45         [Serializable]
46         internal delegate void DelegateConstraintNameChange (object sender, string newName);
47
48         [DefaultProperty ("ConstraintName")]
49 #if !NET_2_0
50         [Serializable]
51 #endif
52         [TypeConverterAttribute (typeof (ConstraintConverter))]
53         public abstract class Constraint {
54                 static readonly object beforeConstraintNameChange = new object ();
55
56                 EventHandlerList events = new EventHandlerList ();
57
58                 internal event DelegateConstraintNameChange BeforeConstraintNameChange {
59                         add { events.AddHandler (beforeConstraintNameChange, value); }
60                         remove { events.RemoveHandler (beforeConstraintNameChange, value); }
61                 }
62
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;
70
71                 private Index _index;
72
73                 //Used for membership checking
74                 private ConstraintCollection _constraintCollection;
75
76                 DataSet dataSet;
77
78                 protected Constraint ()
79                 {
80                         dataSet = null;
81                         _properties = new PropertyCollection ();
82                 }
83
84                 [CLSCompliant (false)]
85                 protected internal virtual DataSet _DataSet {
86                         get { return dataSet; }
87                 }
88
89                 [DataCategory ("Data")]
90 #if !NET_2_0
91                 [DataSysDescription ("Indicates the name of this constraint.")]
92 #endif
93                 [DefaultValue ("")]
94                 public virtual string ConstraintName {
95                         get { return _constraintName == null ? "" : _constraintName; }
96                         set {
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;
103                         }
104                 }
105
106                 [Browsable (false)]
107                 [DataCategory ("Data")]
108 #if !NET_2_0
109                 [DataSysDescription ("The collection that holds custom user information.")]
110 #endif
111                 public PropertyCollection ExtendedProperties {
112                         get { return _properties; }
113                 }
114
115 #if !NET_2_0
116                 [DataSysDescription ("Indicates the table of this constraint.")]
117 #endif
118                 public abstract DataTable Table {
119                         get;
120                 }
121
122                 internal ConstraintCollection ConstraintCollection {
123                         get { return _constraintCollection; }
124                         set { _constraintCollection = value; }
125                 }
126
127                 private void _onConstraintNameChange (string newName)
128                 {
129                         DelegateConstraintNameChange eh = events [beforeConstraintNameChange] as DelegateConstraintNameChange;
130                         if (eh != null)
131                                 eh (this, newName);
132                 }
133
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);
137
138                 internal abstract bool IsConstraintViolated ();
139
140                 internal static void ThrowConstraintException ()
141                 {
142                         throw new ConstraintException("Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.");
143                 }
144
145                 bool initInProgress = false;
146                 internal virtual bool InitInProgress {
147                         get { return initInProgress; }
148                         set { initInProgress = value; }
149                 }
150
151                 internal virtual void FinishInit (DataTable table)
152                 {
153                 }
154
155                 internal void AssertConstraint ()
156                 {
157                         // The order is important.. IsConstraintViolated fills the RowErrors if it detects
158                         // a violation
159                         if (!IsConstraintViolated ())
160                                 return;
161                         if (Table._duringDataLoad || (Table.DataSet != null && !Table.DataSet.EnforceConstraints))
162                                 return;
163                         ThrowConstraintException ();
164                 }
165
166                 internal abstract void AssertConstraint (DataRow row);
167
168                 internal virtual void RollbackAssert (DataRow row)
169                 {
170                 }
171
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);
175
176                 [MonoTODO]
177                 protected void CheckStateForProperty ()
178                 {
179                         throw new NotImplementedException ();
180                 }
181
182                 protected internal void SetDataSet (DataSet dataSet)
183                 {
184                         this.dataSet = dataSet;
185                 }
186
187                 internal void SetExtendedProperties (PropertyCollection properties)
188                 {
189                         _properties = properties;
190                 }
191
192                 internal Index Index {
193                         get { return _index; }
194                         set {
195                                 if (_index != null) {
196                                         _index.RemoveRef();
197                                         Table.DropIndex(_index);
198                                 }
199
200                                 _index = value;
201
202                                 if (_index != null)
203                                         _index.AddRef();
204                         }
205                 }
206
207                 internal abstract bool IsColumnContained (DataColumn column);
208                 internal abstract bool CanRemoveFromCollection (ConstraintCollection col, bool shouldThrow);
209
210                 /// <summary>
211                 /// Gets the ConstraintName, if there is one, as a string.
212                 /// </summary>
213                 public override string ToString ()
214                 {
215                         return _constraintName == null ? "" : _constraintName;
216                 }
217         }
218 }