1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections;
6 using System.Diagnostics;
7 
8 namespace System.Data.SqlClient
9 {
10     public sealed class SqlBulkCopyColumnMappingCollection : CollectionBase
11     {
12         private enum MappingSchema
13         {
14             Undefined = 0,
15             NamesNames = 1,
16             NemesOrdinals = 2,
17             OrdinalsNames = 3,
18             OrdinalsOrdinals = 4,
19         }
20 
21         private MappingSchema _mappingSchema = MappingSchema.Undefined;
22 
SqlBulkCopyColumnMappingCollection()23         internal SqlBulkCopyColumnMappingCollection()
24         {
25         }
26 
27         internal bool ReadOnly { get; set; }
28 
29         public SqlBulkCopyColumnMapping this[int index] => (SqlBulkCopyColumnMapping)this.List[index];
30 
Add(SqlBulkCopyColumnMapping bulkCopyColumnMapping)31         public SqlBulkCopyColumnMapping Add(SqlBulkCopyColumnMapping bulkCopyColumnMapping)
32         {
33             AssertWriteAccess();
34             Debug.Assert(string.IsNullOrEmpty(bulkCopyColumnMapping.SourceColumn) || bulkCopyColumnMapping._internalSourceColumnOrdinal == -1, "BulkLoadAmbiguousSourceColumn");
35             if (((string.IsNullOrEmpty(bulkCopyColumnMapping.SourceColumn)) && (bulkCopyColumnMapping.SourceOrdinal == -1))
36                 || ((string.IsNullOrEmpty(bulkCopyColumnMapping.DestinationColumn)) && (bulkCopyColumnMapping.DestinationOrdinal == -1)))
37             {
38                 throw SQL.BulkLoadNonMatchingColumnMapping();
39             }
40             InnerList.Add(bulkCopyColumnMapping);
41             return bulkCopyColumnMapping;
42         }
43 
Add(string sourceColumn, string destinationColumn)44         public SqlBulkCopyColumnMapping Add(string sourceColumn, string destinationColumn)
45         {
46             AssertWriteAccess();
47             return Add(new SqlBulkCopyColumnMapping(sourceColumn, destinationColumn));
48         }
49 
Add(int sourceColumnIndex, string destinationColumn)50         public SqlBulkCopyColumnMapping Add(int sourceColumnIndex, string destinationColumn)
51         {
52             AssertWriteAccess();
53             return Add(new SqlBulkCopyColumnMapping(sourceColumnIndex, destinationColumn));
54         }
55 
Add(string sourceColumn, int destinationColumnIndex)56         public SqlBulkCopyColumnMapping Add(string sourceColumn, int destinationColumnIndex)
57         {
58             AssertWriteAccess();
59             return Add(new SqlBulkCopyColumnMapping(sourceColumn, destinationColumnIndex));
60         }
Add(int sourceColumnIndex, int destinationColumnIndex)61         public SqlBulkCopyColumnMapping Add(int sourceColumnIndex, int destinationColumnIndex)
62         {
63             AssertWriteAccess();
64             return Add(new SqlBulkCopyColumnMapping(sourceColumnIndex, destinationColumnIndex));
65         }
66 
AssertWriteAccess()67         private void AssertWriteAccess()
68         {
69             if (ReadOnly)
70             {
71                 throw SQL.BulkLoadMappingInaccessible();
72             }
73         }
74 
Clear()75         public new void Clear()
76         {
77             AssertWriteAccess();
78             base.Clear();
79         }
80 
81         public bool Contains(SqlBulkCopyColumnMapping value) => InnerList.Contains(value);
82 
CopyTo(SqlBulkCopyColumnMapping[] array, int index)83         public void CopyTo(SqlBulkCopyColumnMapping[] array, int index) => InnerList.CopyTo(array, index);
84 
CreateDefaultMapping(int columnCount)85         internal void CreateDefaultMapping(int columnCount)
86         {
87             for (int i = 0; i < columnCount; i++)
88             {
89                 InnerList.Add(new SqlBulkCopyColumnMapping(i, i));
90             }
91         }
92 
93         public int IndexOf(SqlBulkCopyColumnMapping value) => InnerList.IndexOf(value);
94 
Insert(int index, SqlBulkCopyColumnMapping value)95         public void Insert(int index, SqlBulkCopyColumnMapping value)
96         {
97             AssertWriteAccess();
98             InnerList.Insert(index, value);
99         }
100 
Remove(SqlBulkCopyColumnMapping value)101         public void Remove(SqlBulkCopyColumnMapping value)
102         {
103             AssertWriteAccess();
104             InnerList.Remove(value);
105         }
106 
RemoveAt(int index)107         public new void RemoveAt(int index)
108         {
109             AssertWriteAccess();
110             base.RemoveAt(index);
111         }
112 
ValidateCollection()113         internal void ValidateCollection()
114         {
115             MappingSchema mappingSchema;
116             foreach (SqlBulkCopyColumnMapping a in InnerList)
117             {
118                 mappingSchema = a.SourceOrdinal != -1 ?
119                     (a.DestinationOrdinal != -1 ? MappingSchema.OrdinalsOrdinals : MappingSchema.OrdinalsNames) :
120                     (a.DestinationOrdinal != -1 ? MappingSchema.NemesOrdinals : MappingSchema.NamesNames);
121 
122                 if (_mappingSchema == MappingSchema.Undefined)
123                 {
124                     _mappingSchema = mappingSchema;
125                 }
126                 else
127                 {
128                     if (_mappingSchema != mappingSchema)
129                     {
130                         throw SQL.BulkLoadMappingsNamesOrOrdinalsOnly();
131                     }
132                 }
133             }
134         }
135     }
136 }
137