Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data / System / Data / RelatedView.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="RelatedView.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 //------------------------------------------------------------------------------
8
9 namespace System.Data {
10     using System;
11     using System.Diagnostics;
12
13     internal sealed class RelatedView : DataView, IFilter {
14         private readonly Nullable<DataKey> parentKey;  
15         private readonly DataKey childKey;
16         private readonly DataRowView parentRowView;
17         private readonly object[] filterValues;
18
19         public RelatedView(DataColumn[] columns, object[] values)
20             : base(columns[0].Table, false) {
21             if (values == null) {
22                 throw ExceptionBuilder.ArgumentNull("values");
23             }
24             this.parentRowView = null;
25             this.parentKey = null;
26             this.childKey = new DataKey(columns, true);
27             this.filterValues = values;
28             Debug.Assert(this.Table == childKey.Table, "Key.Table Must be equal to Current Table");
29             base.ResetRowViewCache();
30         }
31
32
33         public RelatedView(DataRowView parentRowView, DataKey parentKey, DataColumn[] childKeyColumns) : base(childKeyColumns[0].Table, false) {
34             this.filterValues = null;
35             this.parentRowView = parentRowView;
36             this.parentKey = parentKey;
37             this.childKey = new DataKey(childKeyColumns, true);
38             Debug.Assert (this.Table == childKey.Table, "Key.Table Must be equal to Current Table");
39             base.ResetRowViewCache();
40         }
41
42         private object[] GetParentValues()
43         {
44             if (filterValues != null) {
45                 return filterValues;
46             }
47           
48             if (!parentRowView.HasRecord()) {
49                 return null;
50             }
51             return parentKey.Value.GetKeyValues(parentRowView.GetRecord());
52         }
53
54
55         public bool Invoke(DataRow row, DataRowVersion version) {
56             object[] parentValues = GetParentValues();
57             if (parentValues == null) {
58                 return false;
59             }
60
61             object[] childValues = row.GetKeyValues(childKey, version);
62 #if false
63             for (int i = 0; i < keyValues.Length; i++) {
64                 Debug.WriteLine("keyvalues[" + (i).ToString() + "] = " + Convert.ToString(keyValues[i]));
65             }
66             for (int i = 0; i < values.Length; i++) {
67                 Debug.WriteLine("values[" + (i).ToString() + "] = " + Convert.ToString(values[i]));
68             }
69 #endif
70             bool allow = true;
71             if (childValues.Length != parentValues.Length) {
72                 allow = false;
73             }
74             else {
75                 for (int i = 0; i < childValues.Length; i++) {
76                     if (!childValues[i].Equals(parentValues[i])) {
77                         allow = false;
78                         break;
79                     }
80                 }
81             }
82
83             IFilter baseFilter = base.GetFilter();
84             if (baseFilter != null) {
85                 allow &= baseFilter.Invoke(row, version);
86             }
87
88             return allow;
89         }
90
91         internal override IFilter GetFilter() {
92             return this;
93         }
94
95         // move to OnModeChanged
96         public override DataRowView AddNew() {
97             DataRowView addNewRowView = base.AddNew();
98             addNewRowView.Row.SetKeyValues(childKey, GetParentValues());
99             return addNewRowView;
100         }
101
102         internal override void SetIndex(string newSort, DataViewRowState newRowStates, IFilter newRowFilter) {
103             SetIndex2(newSort, newRowStates, newRowFilter, false);
104             Reset();
105         }
106
107         public override bool Equals( DataView dv) {
108             RelatedView other = dv as RelatedView;
109             if (other == null) {
110                 return false;
111             }
112             if (!base.Equals(dv)) {
113                 return false;
114             }
115             if (filterValues != null) {
116                 return (CompareArray(this.childKey.ColumnsReference, other.childKey.ColumnsReference) && CompareArray(this.filterValues, other.filterValues));
117             }
118             else {
119                 if (other.filterValues != null)
120                     return false;
121                 return (CompareArray(this.childKey.ColumnsReference, other.childKey.ColumnsReference) &&
122                         CompareArray(this.parentKey.Value.ColumnsReference, this.parentKey.Value.ColumnsReference) &&
123                         parentRowView.Equals(other.parentRowView));
124             }
125         }
126
127         private bool CompareArray(object[] value1, object[] value2) {
128             if (value1 == null || value2 == null) {
129                 return value1 == value2;
130             }
131             if (value1.Length != value2.Length) {
132                 return false;
133             }
134             for(int i = 0; i < value1.Length; i++) {
135                 if (value1[i] != value2[i])
136                     return false;
137             }
138             return true;
139         }
140     }
141 }