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