DataTableMappingCollection.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. //------------------------------------------------------------------------------
  2. // <copyright file="DataTableMappingCollection.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. namespace System.Data.Common {
  9. using System;
  10. using System.Collections;
  11. using System.Collections.Generic;
  12. using System.ComponentModel;
  13. using System.Data;
  14. using System.Diagnostics;
  15. [
  16. Editor("Microsoft.VSDesigner.Data.Design.DataTableMappingCollectionEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
  17. ListBindable(false)
  18. ]
  19. public sealed class DataTableMappingCollection : MarshalByRefObject, ITableMappingCollection {
  20. private List<DataTableMapping> items; // delay creation until AddWithoutEvents, Insert, CopyTo, GetEnumerator
  21. public DataTableMappingCollection() {
  22. }
  23. // explicit ICollection implementation
  24. bool System.Collections.ICollection.IsSynchronized {
  25. get { return false;}
  26. }
  27. object System.Collections.ICollection.SyncRoot {
  28. get { return this;}
  29. }
  30. // explicit IList implementation
  31. bool System.Collections.IList.IsReadOnly {
  32. get { return false;}
  33. }
  34. bool System.Collections.IList.IsFixedSize {
  35. get { return false;}
  36. }
  37. object System.Collections.IList.this[int index] {
  38. get {
  39. return this[index];
  40. }
  41. set {
  42. ValidateType(value);
  43. this[index] = (DataTableMapping) value;
  44. }
  45. }
  46. object ITableMappingCollection.this[string index] {
  47. get {
  48. return this[index];
  49. }
  50. set {
  51. ValidateType(value);
  52. this[index] = (DataTableMapping) value;
  53. }
  54. }
  55. ITableMapping ITableMappingCollection.Add(string sourceTableName, string dataSetTableName) {
  56. return Add(sourceTableName, dataSetTableName);
  57. }
  58. ITableMapping ITableMappingCollection.GetByDataSetTable(string dataSetTableName) {
  59. return GetByDataSetTable(dataSetTableName);
  60. }
  61. [
  62. Browsable(false),
  63. DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  64. ResDescriptionAttribute(Res.DataTableMappings_Count),
  65. ]
  66. public int Count {
  67. get {
  68. return ((null != items) ? items.Count : 0);
  69. }
  70. }
  71. private Type ItemType {
  72. get { return typeof(DataTableMapping); }
  73. }
  74. [
  75. Browsable(false),
  76. DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  77. ResDescriptionAttribute(Res.DataTableMappings_Item),
  78. ]
  79. public DataTableMapping this[int index] {
  80. get {
  81. RangeCheck(index);
  82. return items[index];
  83. }
  84. set {
  85. RangeCheck(index);
  86. Replace(index, value);
  87. }
  88. }
  89. [
  90. Browsable(false),
  91. DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
  92. ResDescriptionAttribute(Res.DataTableMappings_Item),
  93. ]
  94. public DataTableMapping this[string sourceTable] {
  95. get {
  96. int index = RangeCheck(sourceTable);
  97. return items[index];
  98. }
  99. set {
  100. int index = RangeCheck(sourceTable);
  101. Replace(index, value);
  102. }
  103. }
  104. public int Add(object value) {
  105. ValidateType(value);
  106. Add((DataTableMapping) value);
  107. return Count-1;
  108. }
  109. private DataTableMapping Add(DataTableMapping value) {
  110. AddWithoutEvents(value);
  111. return value;
  112. }
  113. public void AddRange(DataTableMapping[] values) { // V1.0.3300
  114. AddEnumerableRange(values, false);
  115. }
  116. public void AddRange(System.Array values) { // V1.2.3300
  117. AddEnumerableRange(values, false);
  118. }
  119. private void AddEnumerableRange(IEnumerable values, bool doClone) {
  120. if (null == values) {
  121. throw ADP.ArgumentNull("values");
  122. }
  123. foreach(object value in values) {
  124. ValidateType(value);
  125. }
  126. if (doClone) {
  127. foreach(ICloneable value in values) {
  128. AddWithoutEvents(value.Clone() as DataTableMapping);
  129. }
  130. }
  131. else {
  132. foreach(DataTableMapping value in values) {
  133. AddWithoutEvents(value);
  134. }
  135. }
  136. }
  137. /*/// <include file='doc\DataTableMappingCollection.uex' path='docs/doc[@for="DataTableMappingCollection.AddCloneOfRange"]/*' />
  138. public void AddCloneOfRange(IEnumerable values) {
  139. AddEnumerableRange(values, true);
  140. }*/
  141. public DataTableMapping Add(string sourceTable, string dataSetTable) {
  142. return Add(new DataTableMapping(sourceTable, dataSetTable));
  143. }
  144. private void AddWithoutEvents(DataTableMapping value) {
  145. Validate(-1, value);
  146. value.Parent = this;
  147. ArrayList().Add(value);
  148. }
  149. // implemented as a method, not as a property because the VS7 debugger
  150. // object browser calls properties to display their value, and we want this delayed
  151. private List<DataTableMapping> ArrayList() {
  152. if (null == this.items) {
  153. this.items = new List<DataTableMapping>();
  154. }
  155. return this.items;
  156. }
  157. public void Clear() {
  158. if (0 < Count) {
  159. ClearWithoutEvents();
  160. }
  161. }
  162. private void ClearWithoutEvents() {
  163. if (null != items) {
  164. foreach(DataTableMapping item in items) {
  165. item.Parent = null;
  166. }
  167. items.Clear();
  168. }
  169. }
  170. public bool Contains(string value) {
  171. return (-1 != IndexOf(value));
  172. }
  173. public bool Contains(object value) {
  174. return (-1 != IndexOf(value));
  175. }
  176. public void CopyTo(Array array, int index) {
  177. ((ICollection)ArrayList()).CopyTo(array, index);
  178. }
  179. public void CopyTo(DataTableMapping[] array, int index) {
  180. ArrayList().CopyTo(array, index);
  181. }
  182. public DataTableMapping GetByDataSetTable(string dataSetTable) {
  183. int index = IndexOfDataSetTable(dataSetTable);
  184. if (0 > index) {
  185. throw ADP.TablesDataSetTable(dataSetTable);
  186. }
  187. return items[index];
  188. }
  189. public IEnumerator GetEnumerator() {
  190. return ArrayList().GetEnumerator();
  191. }
  192. public int IndexOf(object value) {
  193. if (null != value) {
  194. ValidateType(value);
  195. for (int i = 0; i < Count; ++i) {
  196. if (items[i] == value) {
  197. return i;
  198. }
  199. }
  200. }
  201. return -1;
  202. }
  203. public int IndexOf(string sourceTable) {
  204. if (!ADP.IsEmpty(sourceTable)) {
  205. for (int i = 0; i < Count; ++i) {
  206. string value = items[i].SourceTable;
  207. if ((null != value) && (0 == ADP.SrcCompare(sourceTable, value))) {
  208. return i;
  209. }
  210. }
  211. }
  212. return -1;
  213. }
  214. public int IndexOfDataSetTable(string dataSetTable) {
  215. if (!ADP.IsEmpty(dataSetTable)) {
  216. for (int i = 0; i < Count; ++i) {
  217. string value = items[i].DataSetTable;
  218. if ((null != value) && (0 == ADP.DstCompare(dataSetTable, value))) {
  219. return i;
  220. }
  221. }
  222. }
  223. return -1;
  224. }
  225. public void Insert(int index, Object value) {
  226. ValidateType(value);
  227. Insert(index, (DataTableMapping) value);
  228. }
  229. public void Insert(int index, DataTableMapping value) {
  230. if (null == value) {
  231. throw ADP.TablesAddNullAttempt("value");
  232. }
  233. Validate(-1, value);
  234. value.Parent = this;
  235. ArrayList().Insert(index, value);
  236. }
  237. private void RangeCheck(int index) {
  238. if ((index < 0) || (Count <= index)) {
  239. throw ADP.TablesIndexInt32(index, this);
  240. }
  241. }
  242. private int RangeCheck(string sourceTable) {
  243. int index = IndexOf(sourceTable);
  244. if (index < 0) {
  245. throw ADP.TablesSourceIndex(sourceTable);
  246. }
  247. return index;
  248. }
  249. public void RemoveAt(int index) {
  250. RangeCheck(index);
  251. RemoveIndex(index);
  252. }
  253. public void RemoveAt(string sourceTable) {
  254. int index = RangeCheck(sourceTable);
  255. RemoveIndex(index);
  256. }
  257. private void RemoveIndex(int index) {
  258. Debug.Assert((null != items) && (0 <= index) && (index < Count), "RemoveIndex, invalid");
  259. items[index].Parent = null;
  260. items.RemoveAt(index);
  261. }
  262. public void Remove(object value) {
  263. ValidateType(value);
  264. Remove((DataTableMapping) value);
  265. }
  266. public void Remove (DataTableMapping value) {
  267. if (null == value) {
  268. throw ADP.TablesAddNullAttempt ("value");
  269. }
  270. int index = IndexOf (value);
  271. if (-1 != index) {
  272. RemoveIndex (index);
  273. }
  274. else {
  275. throw ADP.CollectionRemoveInvalidObject (ItemType, this);
  276. }
  277. }
  278. private void Replace (int index, DataTableMapping newValue) {
  279. Validate(index, newValue);
  280. items[index].Parent = null;
  281. newValue.Parent = this;
  282. items[index] = newValue;
  283. }
  284. private void ValidateType(object value) {
  285. if (null == value) {
  286. throw ADP.TablesAddNullAttempt("value");
  287. }
  288. else if (!ItemType.IsInstanceOfType(value)) {
  289. throw ADP.NotADataTableMapping(value);
  290. }
  291. }
  292. private void Validate(int index, DataTableMapping value) {
  293. if (null == value) {
  294. throw ADP.TablesAddNullAttempt("value");
  295. }
  296. if (null != value.Parent) {
  297. if (this != value.Parent) {
  298. throw ADP.TablesIsNotParent(this);
  299. }
  300. else if (index != IndexOf(value)) {
  301. throw ADP.TablesIsParent(this);
  302. }
  303. }
  304. String name = value.SourceTable;
  305. if (ADP.IsEmpty(name)) {
  306. index = 1;
  307. do {
  308. name = ADP.SourceTable + index.ToString(System.Globalization.CultureInfo.InvariantCulture);
  309. index++;
  310. } while (-1 != IndexOf(name));
  311. value.SourceTable = name;
  312. }
  313. else {
  314. ValidateSourceTable(index, name);
  315. }
  316. }
  317. internal void ValidateSourceTable(int index, string value) {
  318. int pindex = IndexOf(value);
  319. if ((-1 != pindex) && (index != pindex)) { // must be non-null and unique
  320. throw ADP.TablesUniqueSourceTable(value);
  321. }
  322. }
  323. [ EditorBrowsableAttribute(EditorBrowsableState.Advanced) ] // MDAC 69508
  324. static public DataTableMapping GetTableMappingBySchemaAction(DataTableMappingCollection tableMappings, string sourceTable, string dataSetTable, MissingMappingAction mappingAction) {
  325. if (null != tableMappings) {
  326. int index = tableMappings.IndexOf(sourceTable);
  327. if (-1 != index) {
  328. #if DEBUG
  329. if (AdapterSwitches.DataSchema.TraceWarning) {
  330. Debug.WriteLine("mapping match on SourceTable \"" + sourceTable + "\"");
  331. }
  332. #endif
  333. return tableMappings.items[index];
  334. }
  335. }
  336. if (ADP.IsEmpty(sourceTable)) {
  337. throw ADP.InvalidSourceTable("sourceTable");
  338. }
  339. switch (mappingAction) {
  340. case MissingMappingAction.Passthrough:
  341. #if DEBUG
  342. if (AdapterSwitches.DataSchema.TraceInfo) {
  343. Debug.WriteLine("mapping passthrough of SourceTable \"" + sourceTable + "\" -> \"" + dataSetTable + "\"");
  344. }
  345. #endif
  346. return new DataTableMapping(sourceTable, dataSetTable);
  347. case MissingMappingAction.Ignore:
  348. #if DEBUG
  349. if (AdapterSwitches.DataSchema.TraceWarning) {
  350. Debug.WriteLine("mapping filter of SourceTable \"" + sourceTable + "\"");
  351. }
  352. #endif
  353. return null;
  354. case MissingMappingAction.Error:
  355. #if DEBUG
  356. if (AdapterSwitches.DataSchema.TraceError) {
  357. Debug.WriteLine("mapping error on SourceTable \"" + sourceTable + "\"");
  358. }
  359. #endif
  360. throw ADP.MissingTableMapping(sourceTable);
  361. default:
  362. throw ADP.InvalidMissingMappingAction(mappingAction);
  363. }
  364. }
  365. }
  366. }