More patches from Eran Domb <erand@mainsoft.com>.
[mono.git] / mcs / class / System.Data / System.Data / DataRelation.cs
1 //
2 // System.Data.DataRelation.cs
3 //
4 // Author:
5 //   Daniel Morgan <danmorg@sc.rr.com>
6 //   Alan Tam Siu Lung <Tam@SiuLung.com>
7 //
8 // (C) 2002 Daniel Morgan
9 // (C) 2002 Ximian, Inc.
10 //
11
12 using System;
13 using System.ComponentModel;
14 using System.Runtime.Serialization;
15
16 namespace System.Data
17 {
18         /// <summary>
19         /// DataRelation is used for a parent/child relationship 
20         /// between two DataTable objects
21         /// </summary>
22         [Editor]
23         [DefaultProperty ("RelationName")]
24         [Serializable]
25         public class DataRelation {
26                 private DataSet dataSet;
27                 private string relationName;
28                 private UniqueConstraint parentKeyConstraint;
29                 private ForeignKeyConstraint childKeyConstraint;
30                 private DataColumn[] parentColumns;
31                 private DataColumn[] childColumns;
32                 private bool nested;
33                 internal bool createConstraints;
34                 private PropertyCollection extendedProperties;
35                 private PropertyChangedEventHandler onPropertyChangingDelegate;
36
37                 #region Constructors
38
39                 public DataRelation (string relationName, DataColumn parentColumn, DataColumn childColumn) 
40                 : this(relationName, parentColumn, childColumn, true)
41                 {
42                 }
43
44                 public DataRelation (string relationName, DataColumn[] parentColumns, DataColumn[] childColumns) 
45                 : this(relationName, parentColumns, childColumns, true)
46                 {
47                 }
48
49                 public DataRelation (string relationName, DataColumn parentColumn, DataColumn childColumn, bool createConstraints)
50                 : this(relationName, new DataColumn[] { parentColumn }, new DataColumn[] { childColumn }, createConstraints)
51                 {
52                 }
53
54                 public DataRelation (string relationName, DataColumn[] parentColumns, DataColumn[] childColumns, bool createConstraints) 
55                 {
56                         this.extendedProperties = new PropertyCollection();
57                         if (relationName == null) relationName = string.Empty;
58                         this.relationName = relationName;
59                         if (parentColumns == null) throw new ArgumentNullException ();
60                         this.parentColumns = parentColumns;
61                         if (childColumns == null) throw new ArgumentNullException ();
62                         this.childColumns = childColumns;
63                         this.createConstraints = createConstraints;
64                         if (parentColumns.Length != childColumns.Length)
65                                 throw new InvalidConstraintException ();
66                         DataTable parentTable = parentColumns[0].Table;
67                         DataTable childTable = childColumns[0].Table;
68                         if (parentTable.DataSet != childTable.DataSet)
69                                 throw new InvalidConstraintException ();
70                         foreach (DataColumn column in parentColumns)
71                                 if (column.Table != parentTable)
72                                         throw new InvalidConstraintException ();
73                         foreach (DataColumn column in childColumns)
74                                 if (column.Table != childTable)
75                                         throw new InvalidConstraintException ();
76                 }
77
78                 [MonoTODO]
79                 [Browsable (false)]
80                 public DataRelation (string relationName, string parentTableName, string childTableName, string[] parentColumnNames, string[] childColumnNames, bool nested) 
81                 {
82                         throw new NotImplementedException ();
83                 }
84
85                 #endregion // Constructors
86
87                 #region Properties
88
89                 [DataCategory ("Data")]
90                 [DataSysDescription ("Indicates the child columns of this relation.")]
91                 public virtual DataColumn[] ChildColumns {
92                         get {
93                                 return childColumns;
94                         }
95                 }
96
97                 public virtual ForeignKeyConstraint ChildKeyConstraint {
98                         get {
99                                 return childKeyConstraint;
100                         }
101                 }
102
103                 internal void SetChildKeyConstraint(ForeignKeyConstraint foreignKeyConstraint) {
104                         childKeyConstraint = foreignKeyConstraint;
105                 }
106
107                 public virtual DataTable ChildTable {
108                         get {
109                                 return childColumns[0].Table;
110                         }
111                 }
112
113                 [Browsable (false)]
114                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
115                 public virtual DataSet DataSet {
116                         get {
117                                 return childColumns[0].Table.DataSet;
118                         }
119                 }
120
121                 [Browsable (false)]
122                 [DataCategory ("Data")]
123                 [DataSysDescription ("The collection that holds custom user information.")]
124                 public PropertyCollection ExtendedProperties {
125                         get {
126                                 if (extendedProperties == null)
127                                         extendedProperties = new PropertyCollection();
128                                 return extendedProperties;
129                         }
130                 }
131
132                 [DataCategory ("Data")]
133                 [DataSysDescription ("Indicates whether relations are nested.")]
134                 [DefaultValue (false)]
135                 public virtual bool Nested {
136                         get {
137                                 return nested;
138                         } 
139                         
140                         set {
141                                 nested = value;
142                         }
143                 }
144
145                 [DataCategory ("Data")]
146                 [DataSysDescription ("Indicates the parent columns of this relation.")]
147                 public virtual DataColumn[] ParentColumns {
148                         get {
149                                 return parentColumns;
150                         }
151                 }
152
153                 public virtual UniqueConstraint ParentKeyConstraint {
154                         get {
155                                 return parentKeyConstraint;
156                         }
157                 }
158
159                 internal void SetParentKeyConstraint(UniqueConstraint uniqueConstraint) {
160                         parentKeyConstraint = uniqueConstraint;
161                 }
162
163                 internal void SetDataSet(DataSet ds) {
164                         dataSet = ds;
165                 }
166
167                 public virtual DataTable ParentTable {
168                         get {
169                                 return parentColumns[0].Table;
170                         }
171                 }
172
173                 [DataCategory ("Data")]
174                 [DataSysDescription ("The name used to look up this relation in the Relations collection of a DataSet.")]
175                 [DefaultValue ("")]
176                 public virtual string RelationName {
177                         get {
178                                 return relationName;
179                         }
180                         
181                         set {
182                                 relationName = value;
183                         }
184                 }
185
186                 #endregion // Properties
187
188                 #region Methods
189
190                 protected void CheckStateForProperty () 
191                 {
192                         // TODO: check consistency of constraints
193                         DataTable parentTable = parentColumns[0].Table;
194                         DataTable childTable = parentColumns[0].Table;
195                         if (parentTable.DataSet != childTable.DataSet)
196                                 throw new DataException ();
197                         bool allColumnsEqual = false;
198                         for (int colCnt = 0; colCnt < parentColumns.Length; ++colCnt) {
199                                 if (!parentColumns [colCnt].DataType.Equals (childColumns [colCnt].DataType))
200                                         throw new DataException ();
201                                 if (parentColumns [colCnt] != childColumns [colCnt]) allColumnsEqual = false;
202                         }
203                         if (allColumnsEqual) throw new DataException ();
204                 }
205
206                 protected internal void OnPropertyChanging (PropertyChangedEventArgs pcevent)
207                 {
208                         if (onPropertyChangingDelegate != null)
209                                 onPropertyChangingDelegate (this, pcevent);
210                 }
211
212                 protected internal void RaisePropertyChanging (string name)
213                 {
214                         OnPropertyChanging(new PropertyChangedEventArgs(name));
215                 }
216
217                 public override string ToString () 
218                 {
219                         return relationName;
220                 }
221
222                 #endregion // Methods
223         }
224 }