Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Data / System / Data / Common / DataColumnMapping.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="DataColumnMapping.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.Common {
10
11     using System;
12     using System.ComponentModel;
13     using System.ComponentModel.Design.Serialization;
14     using System.Data;
15     using System.Diagnostics;
16     using System.Globalization;
17     using System.Reflection;
18
19     [
20     System.ComponentModel.TypeConverterAttribute(typeof(System.Data.Common.DataColumnMapping.DataColumnMappingConverter))
21     ]
22     public sealed class DataColumnMapping : MarshalByRefObject, IColumnMapping, ICloneable {
23         private DataColumnMappingCollection parent;
24         private string _dataSetColumnName;
25         private string _sourceColumnName;
26
27         public DataColumnMapping() {
28         }
29
30         public DataColumnMapping(string sourceColumn, string dataSetColumn) {
31             SourceColumn = sourceColumn;
32             DataSetColumn = dataSetColumn;
33         }
34
35         [
36         DefaultValue(""),
37         ResCategoryAttribute(Res.DataCategory_Mapping),
38         ResDescriptionAttribute(Res.DataColumnMapping_DataSetColumn),
39         ]
40         public string DataSetColumn {
41             get {
42                 string dataSetColumnName = _dataSetColumnName;
43                 return ((null != dataSetColumnName) ? dataSetColumnName : ADP.StrEmpty);
44             }
45             set {
46                 _dataSetColumnName = value;
47             }
48         }
49
50         internal DataColumnMappingCollection Parent {
51             get {
52                 return parent;
53             }
54             set {
55                 parent = value;
56             }
57         }
58
59         [
60         DefaultValue(""),
61         ResCategoryAttribute(Res.DataCategory_Mapping),
62         ResDescriptionAttribute(Res.DataColumnMapping_SourceColumn),
63         ]
64         public string SourceColumn {
65             get {
66                 string sourceColumnName = _sourceColumnName;
67                 return ((null != sourceColumnName) ? sourceColumnName : ADP.StrEmpty);
68             }
69             set {
70                 if ((null != Parent) && (0 != ADP.SrcCompare(_sourceColumnName, value))) {
71                     Parent.ValidateSourceColumn(-1, value);
72                 }
73                 _sourceColumnName = value;
74             }
75         }
76
77         object ICloneable.Clone() {
78             DataColumnMapping clone = new DataColumnMapping(); // MDAC 81448
79             clone._sourceColumnName = _sourceColumnName;
80             clone._dataSetColumnName = _dataSetColumnName;
81             return clone;
82         }
83
84         [ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
85         public DataColumn GetDataColumnBySchemaAction(DataTable dataTable, Type dataType, MissingSchemaAction schemaAction) {
86             return GetDataColumnBySchemaAction(SourceColumn, DataSetColumn, dataTable, dataType, schemaAction);
87         }
88
89         [ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
90         static public DataColumn GetDataColumnBySchemaAction(string sourceColumn, string dataSetColumn, DataTable dataTable, Type dataType, MissingSchemaAction schemaAction) {
91             if (null == dataTable) {
92                 throw ADP.ArgumentNull("dataTable");
93             }
94             if (ADP.IsEmpty(dataSetColumn)) {
95 #if DEBUG
96                 if (AdapterSwitches.DataSchema.TraceWarning) {
97                     Debug.WriteLine("explicit filtering of SourceColumn \"" + sourceColumn + "\"");
98                 }
99 #endif
100                 return null;
101             }
102             DataColumnCollection columns = dataTable.Columns;
103             Debug.Assert(null != columns, "GetDataColumnBySchemaAction: unexpected null DataColumnCollection");
104
105             int index = columns.IndexOf(dataSetColumn);
106             if ((0 <= index) && (index < columns.Count)) {
107                 DataColumn dataColumn = columns[index];
108                 Debug.Assert(null != dataColumn, "GetDataColumnBySchemaAction: unexpected null dataColumn");
109
110                 if (!ADP.IsEmpty(dataColumn.Expression)) {
111 #if DEBUG
112                     if (AdapterSwitches.DataSchema.TraceError) {
113                         Debug.WriteLine("schema mismatch on DataColumn \"" + dataSetColumn + "\" which is a computed column");
114                     }
115 #endif
116                     throw ADP.ColumnSchemaExpression(sourceColumn, dataSetColumn);
117                 }
118                 if ((null == dataType) || (dataType.IsArray == dataColumn.DataType.IsArray)) {
119 #if DEBUG
120                     if (AdapterSwitches.DataSchema.TraceInfo) {
121                         Debug.WriteLine("schema match on DataColumn \"" + dataSetColumn + "\"");
122                     }
123 #endif
124                     return dataColumn;
125                 }
126 #if DEBUG
127                 if (AdapterSwitches.DataSchema.TraceWarning) {
128                     Debug.WriteLine("schema mismatch on DataColumn \"" + dataSetColumn + "\" " + dataType.Name + " != " + dataColumn.DataType.Name);
129                 }
130 #endif
131                 throw ADP.ColumnSchemaMismatch(sourceColumn, dataType, dataColumn);
132             }
133
134             return CreateDataColumnBySchemaAction(sourceColumn, dataSetColumn, dataTable, dataType, schemaAction);
135         }
136
137         static internal DataColumn CreateDataColumnBySchemaAction(string sourceColumn, string dataSetColumn, DataTable dataTable, Type dataType, MissingSchemaAction schemaAction) {
138             Debug.Assert(dataTable != null, "Should not call with a null DataTable");
139             if (ADP.IsEmpty(dataSetColumn)) {
140                 return null;
141             }
142             
143             switch (schemaAction) {
144                 case MissingSchemaAction.Add:
145                 case MissingSchemaAction.AddWithKey:
146 #if DEBUG
147                     if (AdapterSwitches.DataSchema.TraceInfo) {
148                         Debug.WriteLine("schema add of DataColumn \"" + dataSetColumn + "\" <" + Convert.ToString(dataType, CultureInfo.InvariantCulture) +">");
149                     }
150 #endif
151                     return new DataColumn(dataSetColumn, dataType);
152
153                 case MissingSchemaAction.Ignore:
154 #if DEBUG
155                     if (AdapterSwitches.DataSchema.TraceWarning) {
156                         Debug.WriteLine("schema filter of DataColumn \"" + dataSetColumn + "\" <" + Convert.ToString(dataType, CultureInfo.InvariantCulture) +">");
157                     }
158 #endif
159                     return null;
160
161                 case MissingSchemaAction.Error:
162 #if DEBUG
163                     if (AdapterSwitches.DataSchema.TraceError) {
164                         Debug.WriteLine("schema error on DataColumn \"" + dataSetColumn + "\" <" + Convert.ToString(dataType, CultureInfo.InvariantCulture) +">");
165                     }
166 #endif
167                     throw ADP.ColumnSchemaMissing(dataSetColumn, dataTable.TableName, sourceColumn);
168             }
169             throw ADP.InvalidMissingSchemaAction(schemaAction);
170         }
171
172         public override String ToString() {
173             return SourceColumn;
174         }
175
176         sealed internal class DataColumnMappingConverter : System.ComponentModel.ExpandableObjectConverter {
177
178             // converter classes should have public ctor
179             public DataColumnMappingConverter() {
180             }
181
182             override public bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
183                 if (typeof(InstanceDescriptor) == destinationType) {
184                     return true;
185                 }
186                 return base.CanConvertTo(context, destinationType);
187             }
188
189             override public object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
190                 if (null == destinationType) {
191                     throw ADP.ArgumentNull("destinationType");
192                 }
193
194                 if ((typeof(InstanceDescriptor) == destinationType) && (value is DataColumnMapping)) {
195                     DataColumnMapping mapping = (DataColumnMapping)value;
196
197                     object[] values = new object[] { mapping.SourceColumn, mapping.DataSetColumn };
198                     Type[] types = new Type[] { typeof(string), typeof(string) };
199
200                     ConstructorInfo ctor = typeof(DataColumnMapping).GetConstructor(types);
201                     return new InstanceDescriptor(ctor, values);
202                 }            
203                 return base.ConvertTo(context, culture, value, destinationType);
204             }
205         }
206     }
207 }