Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / DataTableCollection.cs / 1305376 / DataTableCollection.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Diagnostics; using System.Collections; using System.ComponentModel; using System.Globalization; ////// [ DefaultEvent("CollectionChanged"), Editor("Microsoft.VSDesigner.Data.Design.TablesCollectionEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing), ListBindable(false), ] public sealed class DataTableCollection : InternalDataCollectionBase { private readonly DataSet dataSet = null; // private DataTable[] tables = new DataTable[2]; // private int tableCount = 0; private readonly ArrayList _list = new ArrayList(); private int defaultNameIndex = 1; private DataTable[] delayedAddRangeTables = null; private CollectionChangeEventHandler onCollectionChangedDelegate = null; private CollectionChangeEventHandler onCollectionChangingDelegate = null; private static int _objectTypeCount; // Bid counter private readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); ////// Represents the collection of tables for the ///. /// /// DataTableCollection constructor. Used only by DataSet. /// internal DataTableCollection(DataSet dataSet) { Bid.Trace("%d#, dataSet=%d\n", ObjectID, (dataSet != null) ? dataSet.ObjectID : 0); this.dataSet = dataSet; } /// /// protected override ArrayList List { get { return _list; } } internal int ObjectID { get { return _objectID; } } ////// Gets the tables /// in the collection as an object. /// ////// public DataTable this[int index] { get { try { // Perf: use the readonly _list field directly and let ArrayList check the range return(DataTable) _list[index]; } catch(ArgumentOutOfRangeException) { throw ExceptionBuilder.TableOutOfRange(index); } } } ///Gets the table specified by its index. ////// public DataTable this[string name] { get { int index = InternalIndexOf(name); if (index == -2) { throw ExceptionBuilder.CaseInsensitiveNameConflict(name); } if (index == -3) { throw ExceptionBuilder.NamespaceNameConflict(name); } return (index < 0) ? null : (DataTable)_list[index]; } } public DataTable this[string name, string tableNamespace] { get { if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); int index = InternalIndexOf(name, tableNamespace); if (index == -2) { throw ExceptionBuilder.CaseInsensitiveNameConflict(name); } return (index < 0) ? null : (DataTable)_list[index]; } } // Case-sensitive search in Schema, data and diffgram loading internal DataTable GetTable(string name, string ns) { for (int i = 0; i < _list.Count; i++) { DataTable table = (DataTable) _list[i]; if (table.TableName == name && table.Namespace == ns) return table; } return null; } // Case-sensitive smart search: it will look for a table using the ns only if required to // resolve a conflict internal DataTable GetTableSmart(string name, string ns){ int fCount = 0; DataTable fTable = null; for (int i = 0; i < _list.Count; i++) { DataTable table = (DataTable) _list[i]; if (table.TableName == name) { if (table.Namespace == ns) return table; fCount++; fTable = table; } } // if we get here we didn't match the namespace // so return the table only if fCount==1 (it's the only one) return (fCount == 1) ? fTable : null; } ///Gets the table in the collection with the given name (not case-sensitive). ////// public void Add(DataTable table) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Adds /// the specified table to the collection. /// ///%d#, table=%d\n", ObjectID, (table!= null) ? table.ObjectID : 0); try { OnCollectionChanging(new CollectionChangeEventArgs(CollectionChangeAction.Add, table)); BaseAdd(table); ArrayAdd(table); if (table.SetLocaleValue(dataSet.Locale, false, false) || table.SetCaseSensitiveValue(dataSet.CaseSensitive, false, false)) { table.ResetIndexes(); } OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, table)); } finally { Bid.ScopeLeave(ref hscp); } } /// /// public void AddRange(DataTable[] tables) { IntPtr hscp; Bid.ScopeEnter(out hscp, "[To be supplied.] ///%d#\n", ObjectID); try { if (dataSet.fInitInProgress) { delayedAddRangeTables = tables; return; } if (tables != null) { foreach(DataTable table in tables) { if (table != null) { Add(table); } } } } finally{ Bid.ScopeLeave(ref hscp); } } /// /// public DataTable Add(string name) { DataTable table = new DataTable(name); // fxcop: new DataTable should inherit the CaseSensitive, Locale, Namespace from DataSet Add(table); return table; } public DataTable Add(string name, string tableNamespace) { DataTable table = new DataTable(name, tableNamespace); // fxcop: new DataTable should inherit the CaseSensitive, Locale from DataSet Add(table); return table; } ////// Creates a table with the given name and adds it to the /// collection. /// ////// public DataTable Add() { DataTable table = new DataTable(); // fxcop: new DataTable should inherit the CaseSensitive, Locale, Namespace from DataSet Add(table); return table; } ////// Creates a new table with a default name and adds it to /// the collection. /// ////// [ResDescriptionAttribute(Res.collectionChangedEventDescr)] public event CollectionChangeEventHandler CollectionChanged { add { Bid.Trace("/// Occurs when the collection is changed. /// ///%d#\n", ObjectID); onCollectionChangedDelegate += value; } remove { Bid.Trace(" %d#\n", ObjectID); onCollectionChangedDelegate -= value; } } /// /// public event CollectionChangeEventHandler CollectionChanging { add { Bid.Trace("[To be supplied.] ///%d#\n", ObjectID); onCollectionChangingDelegate += value; } remove { Bid.Trace(" %d#\n", ObjectID); onCollectionChangingDelegate -= value; } } /// /// Adds the table to the tables array. /// private void ArrayAdd(DataTable table) { _list.Add(table); } ////// Creates a new default name. /// internal string AssignName() { string newName = null; // RAIDBUG: 91671 while(this.Contains( newName = MakeName(defaultNameIndex))) defaultNameIndex++; return newName; } ////// Does verification on the table and it's name, and points the table at the dataSet that owns this collection. /// An ArgumentNullException is thrown if this table is null. An ArgumentException is thrown if this table /// already belongs to this collection, belongs to another collection. /// A DuplicateNameException is thrown if this collection already has a table with the same /// name (case insensitive). /// private void BaseAdd(DataTable table) { if (table == null) throw ExceptionBuilder.ArgumentNull("table"); if (table.DataSet == dataSet) throw ExceptionBuilder.TableAlreadyInTheDataSet(); if (table.DataSet != null) throw ExceptionBuilder.TableAlreadyInOtherDataSet(); if (table.TableName.Length == 0) table.TableName = AssignName(); else { if (NamesEqual(table.TableName, dataSet.DataSetName, false, dataSet.Locale) != 0 && !table.fNestedInDataset) throw ExceptionBuilder.DatasetConflictingName(dataSet.DataSetName); RegisterName(table.TableName, table.Namespace); } table.SetDataSet(dataSet); //must run thru the document incorporating the addition of this data table //must make sure there is no other schema component which have the same // identity as this table (for example, there must not be a table with the // same identity as a column in this schema. } ////// BaseGroupSwitch will intelligently remove and add tables from the collection. /// private void BaseGroupSwitch(DataTable[] oldArray, int oldLength, DataTable[] newArray, int newLength) { // We're doing a smart diff of oldArray and newArray to find out what // should be removed. We'll pass through oldArray and see if it exists // in newArray, and if not, do remove work. newBase is an opt. in case // the arrays have similar prefixes. int newBase = 0; for (int oldCur = 0; oldCur < oldLength; oldCur++) { bool found = false; for (int newCur = newBase; newCur < newLength; newCur++) { if (oldArray[oldCur] == newArray[newCur]) { if (newBase == newCur) { newBase++; } found = true; break; } } if (!found) { // This means it's in oldArray and not newArray. Remove it. if (oldArray[oldCur].DataSet == dataSet) { BaseRemove(oldArray[oldCur]); } } } // Now, let's pass through news and those that don't belong, add them. for (int newCur = 0; newCur < newLength; newCur++) { if (newArray[newCur].DataSet != dataSet) { BaseAdd(newArray[newCur]); _list.Add(newArray[newCur]); } } } ////// Does verification on the table and it's name, and clears the table's dataSet pointer. /// An ArgumentNullException is thrown if this table is null. An ArgumentException is thrown /// if this table doesn't belong to this collection or if this table is part of a relationship. /// private void BaseRemove(DataTable table) { if (CanRemove(table, true)) { UnregisterName(table.TableName); table.SetDataSet(null); } _list.Remove(table); dataSet.OnRemovedTable(table); } ////// public bool CanRemove(DataTable table) { return CanRemove(table, false); } internal bool CanRemove(DataTable table, bool fThrowException) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Verifies if a given table can be removed from the collection. /// ///%d#, table=%d, fThrowException=%d{bool}\n", ObjectID, (table != null)? table.ObjectID : 0 , fThrowException); try { if (table == null) { if (!fThrowException) return false; else throw ExceptionBuilder.ArgumentNull("table"); } if (table.DataSet != dataSet) { if (!fThrowException) return false; else throw ExceptionBuilder.TableNotInTheDataSet(table.TableName); } // allow subclasses to throw. dataSet.OnRemoveTable(table); if (table.ChildRelations.Count != 0 || table.ParentRelations.Count != 0) { if (!fThrowException) return false; else throw ExceptionBuilder.TableInRelation(); } for (ParentForeignKeyConstraintEnumerator constraints = new ParentForeignKeyConstraintEnumerator(dataSet, table); constraints.GetNext();) { ForeignKeyConstraint constraint = constraints.GetForeignKeyConstraint(); if (constraint.Table == table && constraint.RelatedTable == table) // we can go with (constraint.Table == constraint.RelatedTable) continue; if (!fThrowException) return false; else throw ExceptionBuilder.TableInConstraint(table, constraint); } for (ChildForeignKeyConstraintEnumerator constraints = new ChildForeignKeyConstraintEnumerator(dataSet, table); constraints.GetNext();) { ForeignKeyConstraint constraint = constraints.GetForeignKeyConstraint(); if (constraint.Table == table && constraint.RelatedTable == table) // bug 97670 continue; if (!fThrowException) return false; else throw ExceptionBuilder.TableInConstraint(table, constraint); } return true; } finally{ Bid.ScopeLeave(ref hscp); } } /// /// public void Clear() { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Clears the collection of any tables. /// ///%d#\n", ObjectID); try { int oldLength = _list.Count; DataTable[] tables = new DataTable[_list.Count]; _list.CopyTo(tables, 0); OnCollectionChanging(RefreshEventArgs); if (dataSet.fInitInProgress && delayedAddRangeTables != null) { delayedAddRangeTables = null; } BaseGroupSwitch(tables, oldLength, null, 0); _list.Clear(); OnCollectionChanged(RefreshEventArgs); } finally { Bid.ScopeLeave(ref hscp); } } /// /// public bool Contains(string name) { return (InternalIndexOf(name) >= 0); } public bool Contains(string name, string tableNamespace) { if (name == null) throw ExceptionBuilder.ArgumentNull("name"); if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); return (InternalIndexOf(name, tableNamespace) >= 0); } internal bool Contains(string name, string tableNamespace, bool checkProperty, bool caseSensitive) { if (!caseSensitive) return (InternalIndexOf(name) >= 0); // Case-Sensitive compare int count = _list.Count; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; // this may be needed to check wether the cascading is creating some conflicts string ns = checkProperty ? table.Namespace : table.tableNamespace ; if (NamesEqual(table.TableName, name, true, dataSet.Locale) == 1 && (ns == tableNamespace)) return true; } return false; } internal bool Contains(string name, bool caseSensitive) { if (!caseSensitive) return (InternalIndexOf(name) >= 0); // Case-Sensitive compare int count = _list.Count; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; if (NamesEqual(table.TableName, name, true, dataSet.Locale) == 1 ) return true; } return false; } public void CopyTo(DataTable[] array, int index) { if (array==null) throw ExceptionBuilder.ArgumentNull("array"); if (index < 0) throw ExceptionBuilder.ArgumentOutOfRange("index"); if (array.Length - index < _list.Count) throw ExceptionBuilder.InvalidOffsetLength(); for(int i = 0; i < _list.Count; ++i) { array[index + i] = (DataTable)_list[i]; } } ////// Checks if a table, specified by name, exists in the collection. /// ////// public int IndexOf(DataTable table) { int tableCount = _list.Count; for (int i = 0; i < tableCount; ++i) { if (table == (DataTable) _list[i]) { return i; } } return -1; } ////// Returns the index of a specified ///. /// /// public int IndexOf(string tableName) { int index = InternalIndexOf(tableName); return (index < 0) ? -1 : index; } public int IndexOf(string tableName, string tableNamespace) { return IndexOf( tableName, tableNamespace, true); } internal int IndexOf(string tableName, string tableNamespace, bool chekforNull) { // this should be public! why it is missing? if (chekforNull) { if (tableName == null) throw ExceptionBuilder.ArgumentNull("tableName"); if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); } int index = InternalIndexOf(tableName, tableNamespace); return (index < 0) ? -1 : index; } internal void ReplaceFromInference(System.Collections.Generic.List/// Returns the index of the /// table with the given name (case insensitive), or -1 if the table /// doesn't exist in the collection. /// ///tableList) { Debug.Assert(_list.Count == tableList.Count, "Both lists should have equal numbers of tables"); _list.Clear(); _list.AddRange(tableList); } // Return value: // >= 0: find the match // -1: No match // -2: At least two matches with different cases // -3: At least two matches with different namespaces internal int InternalIndexOf(string tableName) { int cachedI = -1; if ((null != tableName) && (0 < tableName.Length)) { int count = _list.Count; int result = 0; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; result = NamesEqual(table.TableName, tableName, false, dataSet.Locale); if (result == 1) { // ok, we have found a table with the same name. // let's see if there are any others with the same name // if any let's return (-3) otherwise... for (int j=i+1;j = 0: find the match // -1: No match // -2: At least two matches with different cases internal int InternalIndexOf(string tableName, string tableNamespace) { int cachedI = -1; if ((null != tableName) && (0 < tableName.Length)) { int count = _list.Count; int result = 0; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; result = NamesEqual(table.TableName, tableName, false, dataSet.Locale); if ((result == 1) && (table.Namespace == tableNamespace)) return i; if ((result == -1) && (table.Namespace == tableNamespace)) cachedI = (cachedI == -1) ? i : -2; } } return cachedI; } internal void FinishInitCollection() { if (delayedAddRangeTables != null) { foreach(DataTable table in delayedAddRangeTables) { if (table != null) { Add(table); } } delayedAddRangeTables = null; } } /// /// Makes a default name with the given index. e.g. Table1, Table2, ... Tablei /// private string MakeName(int index) { if (1 == index) { return "Table1"; } return "Table" + index.ToString(System.Globalization.CultureInfo.InvariantCulture); } ////// private void OnCollectionChanged(CollectionChangeEventArgs ccevent) { if (onCollectionChangedDelegate != null) { Bid.Trace("/// Raises the ///event. /// %d#\n", ObjectID); onCollectionChangedDelegate(this, ccevent); } } /// /// private void OnCollectionChanging(CollectionChangeEventArgs ccevent) { if (onCollectionChangingDelegate != null) { Bid.Trace("[To be supplied.] ///%d#\n", ObjectID); onCollectionChangingDelegate(this, ccevent); } } /// /// Registers this name as being used in the collection. Will throw an ArgumentException /// if the name is already being used. Called by Add, All property, and Table.TableName property. /// if the name is equivalent to the next default name to hand out, we increment our defaultNameIndex. /// internal void RegisterName(string name, string tbNamespace) { Bid.Trace("%d#, name='%ls', tbNamespace='%ls'\n", ObjectID, name, tbNamespace); Debug.Assert (name != null); CultureInfo locale = dataSet.Locale; int tableCount = _list.Count; for (int i = 0; i < tableCount; i++) { DataTable table = (DataTable) _list[i]; if (NamesEqual(name, table.TableName, true, locale) != 0 && (tbNamespace == table.Namespace)) { throw ExceptionBuilder.DuplicateTableName(((DataTable) _list[i]).TableName); } } if (NamesEqual(name, MakeName(defaultNameIndex), true, locale) != 0) { defaultNameIndex++; } } /// /// public void Remove(DataTable table) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Removes the specified table from the collection. /// ///%d#, table=%d\n", ObjectID, (table != null) ? table.ObjectID : 0); try { OnCollectionChanging(new CollectionChangeEventArgs(CollectionChangeAction.Remove, table)); BaseRemove(table); OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, table)); } finally{ Bid.ScopeLeave(ref hscp); } } /// /// public void RemoveAt(int index) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Removes the /// table at the given index from the collection /// ///%d#, index=%d\n", ObjectID, index); try { DataTable dt = this[index]; if (dt == null) throw ExceptionBuilder.TableOutOfRange(index); Remove(dt); } finally { Bid.ScopeLeave(ref hscp); } } /// /// public void Remove(string name) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Removes the table with a specified name from the /// collection. /// ///%d#, name='%ls'\n", ObjectID, name); try { DataTable dt = this[name]; if (dt == null) throw ExceptionBuilder.TableNotInTheDataSet(name); Remove(dt); } finally{ Bid.ScopeLeave(ref hscp); } } public void Remove(string name, string tableNamespace) { if (name == null) throw ExceptionBuilder.ArgumentNull("name"); if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); DataTable dt = this[name, tableNamespace]; if (dt == null) throw ExceptionBuilder.TableNotInTheDataSet(name); Remove(dt); } /// /// Unregisters this name as no longer being used in the collection. Called by Remove, All property, and /// Table.TableName property. If the name is equivalent to the last proposed default namem, we walk backwards /// to find the next proper default name to hang out. /// internal void UnregisterName(string name) { Bid.Trace("%d#, name='%ls'\n", ObjectID, name); if (NamesEqual(name, MakeName(defaultNameIndex - 1), true, dataSet.Locale) != 0) { do { defaultNameIndex--; } while (defaultNameIndex > 1 && !Contains(MakeName(defaultNameIndex - 1))); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ // // Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //[....] //[....] //----------------------------------------------------------------------------- namespace System.Data { using System; using System.Diagnostics; using System.Collections; using System.ComponentModel; using System.Globalization; ////// [ DefaultEvent("CollectionChanged"), Editor("Microsoft.VSDesigner.Data.Design.TablesCollectionEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing), ListBindable(false), ] public sealed class DataTableCollection : InternalDataCollectionBase { private readonly DataSet dataSet = null; // private DataTable[] tables = new DataTable[2]; // private int tableCount = 0; private readonly ArrayList _list = new ArrayList(); private int defaultNameIndex = 1; private DataTable[] delayedAddRangeTables = null; private CollectionChangeEventHandler onCollectionChangedDelegate = null; private CollectionChangeEventHandler onCollectionChangingDelegate = null; private static int _objectTypeCount; // Bid counter private readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); ////// Represents the collection of tables for the ///. /// /// DataTableCollection constructor. Used only by DataSet. /// internal DataTableCollection(DataSet dataSet) { Bid.Trace("%d#, dataSet=%d\n", ObjectID, (dataSet != null) ? dataSet.ObjectID : 0); this.dataSet = dataSet; } /// /// protected override ArrayList List { get { return _list; } } internal int ObjectID { get { return _objectID; } } ////// Gets the tables /// in the collection as an object. /// ////// public DataTable this[int index] { get { try { // Perf: use the readonly _list field directly and let ArrayList check the range return(DataTable) _list[index]; } catch(ArgumentOutOfRangeException) { throw ExceptionBuilder.TableOutOfRange(index); } } } ///Gets the table specified by its index. ////// public DataTable this[string name] { get { int index = InternalIndexOf(name); if (index == -2) { throw ExceptionBuilder.CaseInsensitiveNameConflict(name); } if (index == -3) { throw ExceptionBuilder.NamespaceNameConflict(name); } return (index < 0) ? null : (DataTable)_list[index]; } } public DataTable this[string name, string tableNamespace] { get { if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); int index = InternalIndexOf(name, tableNamespace); if (index == -2) { throw ExceptionBuilder.CaseInsensitiveNameConflict(name); } return (index < 0) ? null : (DataTable)_list[index]; } } // Case-sensitive search in Schema, data and diffgram loading internal DataTable GetTable(string name, string ns) { for (int i = 0; i < _list.Count; i++) { DataTable table = (DataTable) _list[i]; if (table.TableName == name && table.Namespace == ns) return table; } return null; } // Case-sensitive smart search: it will look for a table using the ns only if required to // resolve a conflict internal DataTable GetTableSmart(string name, string ns){ int fCount = 0; DataTable fTable = null; for (int i = 0; i < _list.Count; i++) { DataTable table = (DataTable) _list[i]; if (table.TableName == name) { if (table.Namespace == ns) return table; fCount++; fTable = table; } } // if we get here we didn't match the namespace // so return the table only if fCount==1 (it's the only one) return (fCount == 1) ? fTable : null; } ///Gets the table in the collection with the given name (not case-sensitive). ////// public void Add(DataTable table) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Adds /// the specified table to the collection. /// ///%d#, table=%d\n", ObjectID, (table!= null) ? table.ObjectID : 0); try { OnCollectionChanging(new CollectionChangeEventArgs(CollectionChangeAction.Add, table)); BaseAdd(table); ArrayAdd(table); if (table.SetLocaleValue(dataSet.Locale, false, false) || table.SetCaseSensitiveValue(dataSet.CaseSensitive, false, false)) { table.ResetIndexes(); } OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Add, table)); } finally { Bid.ScopeLeave(ref hscp); } } /// /// public void AddRange(DataTable[] tables) { IntPtr hscp; Bid.ScopeEnter(out hscp, "[To be supplied.] ///%d#\n", ObjectID); try { if (dataSet.fInitInProgress) { delayedAddRangeTables = tables; return; } if (tables != null) { foreach(DataTable table in tables) { if (table != null) { Add(table); } } } } finally{ Bid.ScopeLeave(ref hscp); } } /// /// public DataTable Add(string name) { DataTable table = new DataTable(name); // fxcop: new DataTable should inherit the CaseSensitive, Locale, Namespace from DataSet Add(table); return table; } public DataTable Add(string name, string tableNamespace) { DataTable table = new DataTable(name, tableNamespace); // fxcop: new DataTable should inherit the CaseSensitive, Locale from DataSet Add(table); return table; } ////// Creates a table with the given name and adds it to the /// collection. /// ////// public DataTable Add() { DataTable table = new DataTable(); // fxcop: new DataTable should inherit the CaseSensitive, Locale, Namespace from DataSet Add(table); return table; } ////// Creates a new table with a default name and adds it to /// the collection. /// ////// [ResDescriptionAttribute(Res.collectionChangedEventDescr)] public event CollectionChangeEventHandler CollectionChanged { add { Bid.Trace("/// Occurs when the collection is changed. /// ///%d#\n", ObjectID); onCollectionChangedDelegate += value; } remove { Bid.Trace(" %d#\n", ObjectID); onCollectionChangedDelegate -= value; } } /// /// public event CollectionChangeEventHandler CollectionChanging { add { Bid.Trace("[To be supplied.] ///%d#\n", ObjectID); onCollectionChangingDelegate += value; } remove { Bid.Trace(" %d#\n", ObjectID); onCollectionChangingDelegate -= value; } } /// /// Adds the table to the tables array. /// private void ArrayAdd(DataTable table) { _list.Add(table); } ////// Creates a new default name. /// internal string AssignName() { string newName = null; // RAIDBUG: 91671 while(this.Contains( newName = MakeName(defaultNameIndex))) defaultNameIndex++; return newName; } ////// Does verification on the table and it's name, and points the table at the dataSet that owns this collection. /// An ArgumentNullException is thrown if this table is null. An ArgumentException is thrown if this table /// already belongs to this collection, belongs to another collection. /// A DuplicateNameException is thrown if this collection already has a table with the same /// name (case insensitive). /// private void BaseAdd(DataTable table) { if (table == null) throw ExceptionBuilder.ArgumentNull("table"); if (table.DataSet == dataSet) throw ExceptionBuilder.TableAlreadyInTheDataSet(); if (table.DataSet != null) throw ExceptionBuilder.TableAlreadyInOtherDataSet(); if (table.TableName.Length == 0) table.TableName = AssignName(); else { if (NamesEqual(table.TableName, dataSet.DataSetName, false, dataSet.Locale) != 0 && !table.fNestedInDataset) throw ExceptionBuilder.DatasetConflictingName(dataSet.DataSetName); RegisterName(table.TableName, table.Namespace); } table.SetDataSet(dataSet); //must run thru the document incorporating the addition of this data table //must make sure there is no other schema component which have the same // identity as this table (for example, there must not be a table with the // same identity as a column in this schema. } ////// BaseGroupSwitch will intelligently remove and add tables from the collection. /// private void BaseGroupSwitch(DataTable[] oldArray, int oldLength, DataTable[] newArray, int newLength) { // We're doing a smart diff of oldArray and newArray to find out what // should be removed. We'll pass through oldArray and see if it exists // in newArray, and if not, do remove work. newBase is an opt. in case // the arrays have similar prefixes. int newBase = 0; for (int oldCur = 0; oldCur < oldLength; oldCur++) { bool found = false; for (int newCur = newBase; newCur < newLength; newCur++) { if (oldArray[oldCur] == newArray[newCur]) { if (newBase == newCur) { newBase++; } found = true; break; } } if (!found) { // This means it's in oldArray and not newArray. Remove it. if (oldArray[oldCur].DataSet == dataSet) { BaseRemove(oldArray[oldCur]); } } } // Now, let's pass through news and those that don't belong, add them. for (int newCur = 0; newCur < newLength; newCur++) { if (newArray[newCur].DataSet != dataSet) { BaseAdd(newArray[newCur]); _list.Add(newArray[newCur]); } } } ////// Does verification on the table and it's name, and clears the table's dataSet pointer. /// An ArgumentNullException is thrown if this table is null. An ArgumentException is thrown /// if this table doesn't belong to this collection or if this table is part of a relationship. /// private void BaseRemove(DataTable table) { if (CanRemove(table, true)) { UnregisterName(table.TableName); table.SetDataSet(null); } _list.Remove(table); dataSet.OnRemovedTable(table); } ////// public bool CanRemove(DataTable table) { return CanRemove(table, false); } internal bool CanRemove(DataTable table, bool fThrowException) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Verifies if a given table can be removed from the collection. /// ///%d#, table=%d, fThrowException=%d{bool}\n", ObjectID, (table != null)? table.ObjectID : 0 , fThrowException); try { if (table == null) { if (!fThrowException) return false; else throw ExceptionBuilder.ArgumentNull("table"); } if (table.DataSet != dataSet) { if (!fThrowException) return false; else throw ExceptionBuilder.TableNotInTheDataSet(table.TableName); } // allow subclasses to throw. dataSet.OnRemoveTable(table); if (table.ChildRelations.Count != 0 || table.ParentRelations.Count != 0) { if (!fThrowException) return false; else throw ExceptionBuilder.TableInRelation(); } for (ParentForeignKeyConstraintEnumerator constraints = new ParentForeignKeyConstraintEnumerator(dataSet, table); constraints.GetNext();) { ForeignKeyConstraint constraint = constraints.GetForeignKeyConstraint(); if (constraint.Table == table && constraint.RelatedTable == table) // we can go with (constraint.Table == constraint.RelatedTable) continue; if (!fThrowException) return false; else throw ExceptionBuilder.TableInConstraint(table, constraint); } for (ChildForeignKeyConstraintEnumerator constraints = new ChildForeignKeyConstraintEnumerator(dataSet, table); constraints.GetNext();) { ForeignKeyConstraint constraint = constraints.GetForeignKeyConstraint(); if (constraint.Table == table && constraint.RelatedTable == table) // bug 97670 continue; if (!fThrowException) return false; else throw ExceptionBuilder.TableInConstraint(table, constraint); } return true; } finally{ Bid.ScopeLeave(ref hscp); } } /// /// public void Clear() { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Clears the collection of any tables. /// ///%d#\n", ObjectID); try { int oldLength = _list.Count; DataTable[] tables = new DataTable[_list.Count]; _list.CopyTo(tables, 0); OnCollectionChanging(RefreshEventArgs); if (dataSet.fInitInProgress && delayedAddRangeTables != null) { delayedAddRangeTables = null; } BaseGroupSwitch(tables, oldLength, null, 0); _list.Clear(); OnCollectionChanged(RefreshEventArgs); } finally { Bid.ScopeLeave(ref hscp); } } /// /// public bool Contains(string name) { return (InternalIndexOf(name) >= 0); } public bool Contains(string name, string tableNamespace) { if (name == null) throw ExceptionBuilder.ArgumentNull("name"); if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); return (InternalIndexOf(name, tableNamespace) >= 0); } internal bool Contains(string name, string tableNamespace, bool checkProperty, bool caseSensitive) { if (!caseSensitive) return (InternalIndexOf(name) >= 0); // Case-Sensitive compare int count = _list.Count; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; // this may be needed to check wether the cascading is creating some conflicts string ns = checkProperty ? table.Namespace : table.tableNamespace ; if (NamesEqual(table.TableName, name, true, dataSet.Locale) == 1 && (ns == tableNamespace)) return true; } return false; } internal bool Contains(string name, bool caseSensitive) { if (!caseSensitive) return (InternalIndexOf(name) >= 0); // Case-Sensitive compare int count = _list.Count; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; if (NamesEqual(table.TableName, name, true, dataSet.Locale) == 1 ) return true; } return false; } public void CopyTo(DataTable[] array, int index) { if (array==null) throw ExceptionBuilder.ArgumentNull("array"); if (index < 0) throw ExceptionBuilder.ArgumentOutOfRange("index"); if (array.Length - index < _list.Count) throw ExceptionBuilder.InvalidOffsetLength(); for(int i = 0; i < _list.Count; ++i) { array[index + i] = (DataTable)_list[i]; } } ////// Checks if a table, specified by name, exists in the collection. /// ////// public int IndexOf(DataTable table) { int tableCount = _list.Count; for (int i = 0; i < tableCount; ++i) { if (table == (DataTable) _list[i]) { return i; } } return -1; } ////// Returns the index of a specified ///. /// /// public int IndexOf(string tableName) { int index = InternalIndexOf(tableName); return (index < 0) ? -1 : index; } public int IndexOf(string tableName, string tableNamespace) { return IndexOf( tableName, tableNamespace, true); } internal int IndexOf(string tableName, string tableNamespace, bool chekforNull) { // this should be public! why it is missing? if (chekforNull) { if (tableName == null) throw ExceptionBuilder.ArgumentNull("tableName"); if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); } int index = InternalIndexOf(tableName, tableNamespace); return (index < 0) ? -1 : index; } internal void ReplaceFromInference(System.Collections.Generic.List/// Returns the index of the /// table with the given name (case insensitive), or -1 if the table /// doesn't exist in the collection. /// ///tableList) { Debug.Assert(_list.Count == tableList.Count, "Both lists should have equal numbers of tables"); _list.Clear(); _list.AddRange(tableList); } // Return value: // >= 0: find the match // -1: No match // -2: At least two matches with different cases // -3: At least two matches with different namespaces internal int InternalIndexOf(string tableName) { int cachedI = -1; if ((null != tableName) && (0 < tableName.Length)) { int count = _list.Count; int result = 0; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; result = NamesEqual(table.TableName, tableName, false, dataSet.Locale); if (result == 1) { // ok, we have found a table with the same name. // let's see if there are any others with the same name // if any let's return (-3) otherwise... for (int j=i+1;j = 0: find the match // -1: No match // -2: At least two matches with different cases internal int InternalIndexOf(string tableName, string tableNamespace) { int cachedI = -1; if ((null != tableName) && (0 < tableName.Length)) { int count = _list.Count; int result = 0; for (int i = 0; i < count; i++) { DataTable table = (DataTable) _list[i]; result = NamesEqual(table.TableName, tableName, false, dataSet.Locale); if ((result == 1) && (table.Namespace == tableNamespace)) return i; if ((result == -1) && (table.Namespace == tableNamespace)) cachedI = (cachedI == -1) ? i : -2; } } return cachedI; } internal void FinishInitCollection() { if (delayedAddRangeTables != null) { foreach(DataTable table in delayedAddRangeTables) { if (table != null) { Add(table); } } delayedAddRangeTables = null; } } /// /// Makes a default name with the given index. e.g. Table1, Table2, ... Tablei /// private string MakeName(int index) { if (1 == index) { return "Table1"; } return "Table" + index.ToString(System.Globalization.CultureInfo.InvariantCulture); } ////// private void OnCollectionChanged(CollectionChangeEventArgs ccevent) { if (onCollectionChangedDelegate != null) { Bid.Trace("/// Raises the ///event. /// %d#\n", ObjectID); onCollectionChangedDelegate(this, ccevent); } } /// /// private void OnCollectionChanging(CollectionChangeEventArgs ccevent) { if (onCollectionChangingDelegate != null) { Bid.Trace("[To be supplied.] ///%d#\n", ObjectID); onCollectionChangingDelegate(this, ccevent); } } /// /// Registers this name as being used in the collection. Will throw an ArgumentException /// if the name is already being used. Called by Add, All property, and Table.TableName property. /// if the name is equivalent to the next default name to hand out, we increment our defaultNameIndex. /// internal void RegisterName(string name, string tbNamespace) { Bid.Trace("%d#, name='%ls', tbNamespace='%ls'\n", ObjectID, name, tbNamespace); Debug.Assert (name != null); CultureInfo locale = dataSet.Locale; int tableCount = _list.Count; for (int i = 0; i < tableCount; i++) { DataTable table = (DataTable) _list[i]; if (NamesEqual(name, table.TableName, true, locale) != 0 && (tbNamespace == table.Namespace)) { throw ExceptionBuilder.DuplicateTableName(((DataTable) _list[i]).TableName); } } if (NamesEqual(name, MakeName(defaultNameIndex), true, locale) != 0) { defaultNameIndex++; } } /// /// public void Remove(DataTable table) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Removes the specified table from the collection. /// ///%d#, table=%d\n", ObjectID, (table != null) ? table.ObjectID : 0); try { OnCollectionChanging(new CollectionChangeEventArgs(CollectionChangeAction.Remove, table)); BaseRemove(table); OnCollectionChanged(new CollectionChangeEventArgs(CollectionChangeAction.Remove, table)); } finally{ Bid.ScopeLeave(ref hscp); } } /// /// public void RemoveAt(int index) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Removes the /// table at the given index from the collection /// ///%d#, index=%d\n", ObjectID, index); try { DataTable dt = this[index]; if (dt == null) throw ExceptionBuilder.TableOutOfRange(index); Remove(dt); } finally { Bid.ScopeLeave(ref hscp); } } /// /// public void Remove(string name) { IntPtr hscp; Bid.ScopeEnter(out hscp, "/// Removes the table with a specified name from the /// collection. /// ///%d#, name='%ls'\n", ObjectID, name); try { DataTable dt = this[name]; if (dt == null) throw ExceptionBuilder.TableNotInTheDataSet(name); Remove(dt); } finally{ Bid.ScopeLeave(ref hscp); } } public void Remove(string name, string tableNamespace) { if (name == null) throw ExceptionBuilder.ArgumentNull("name"); if (tableNamespace == null) throw ExceptionBuilder.ArgumentNull("tableNamespace"); DataTable dt = this[name, tableNamespace]; if (dt == null) throw ExceptionBuilder.TableNotInTheDataSet(name); Remove(dt); } /// /// Unregisters this name as no longer being used in the collection. Called by Remove, All property, and /// Table.TableName property. If the name is equivalent to the last proposed default namem, we walk backwards /// to find the next proper default name to hang out. /// internal void UnregisterName(string name) { Bid.Trace("%d#, name='%ls'\n", ObjectID, name); if (NamesEqual(name, MakeName(defaultNameIndex - 1), true, dataSet.Locale) != 0) { do { defaultNameIndex--; } while (defaultNameIndex > 1 && !Contains(MakeName(defaultNameIndex - 1))); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ApplicationSecurityInfo.cs
- PropertyTabAttribute.cs
- XmlNavigatorFilter.cs
- CheckedPointers.cs
- COM2Properties.cs
- ControlBindingsCollection.cs
- UnmanagedMemoryStream.cs
- SqlNode.cs
- BulletedListDesigner.cs
- Floater.cs
- MailBnfHelper.cs
- ApplicationSecurityInfo.cs
- UserInitiatedNavigationPermission.cs
- ConfigXmlSignificantWhitespace.cs
- DbConnectionPool.cs
- AssemblyLoader.cs
- SimpleWorkerRequest.cs
- OdbcCommandBuilder.cs
- WindowsStatic.cs
- LazyLoadBehavior.cs
- XmlUtf8RawTextWriter.cs
- SortDescription.cs
- BindingContext.cs
- StaticExtensionConverter.cs
- SpoolingTask.cs
- ButtonField.cs
- SynchronizationValidator.cs
- ItemsControlAutomationPeer.cs
- HMAC.cs
- _LocalDataStoreMgr.cs
- dbdatarecord.cs
- FileUtil.cs
- CatalogPart.cs
- CompareValidator.cs
- XPathQueryGenerator.cs
- ReverseComparer.cs
- SafeRegistryHandle.cs
- HyperLinkField.cs
- ImageAnimator.cs
- MemoryStream.cs
- VectorAnimationBase.cs
- ValidationSummary.cs
- LayoutInformation.cs
- HwndSourceParameters.cs
- SharedStream.cs
- TextRange.cs
- ManagementOptions.cs
- DataGridView.cs
- TypeConverterHelper.cs
- StatusBarItem.cs
- ListViewItem.cs
- RtfToken.cs
- TextFormatterImp.cs
- AddInController.cs
- DataGridViewCellValueEventArgs.cs
- XmlObjectSerializerWriteContextComplexJson.cs
- DiscoveryClientProtocol.cs
- RegexRunner.cs
- DateTimeStorage.cs
- RootBrowserWindowAutomationPeer.cs
- EnumConverter.cs
- DomainConstraint.cs
- OleDbPropertySetGuid.cs
- BinaryReader.cs
- Image.cs
- EnumUnknown.cs
- DrawingDrawingContext.cs
- HtmlInputRadioButton.cs
- GeneratedContractType.cs
- XmlDataSource.cs
- ConnectionPointCookie.cs
- ReaderContextStackData.cs
- ToolStripSplitStackLayout.cs
- CapabilitiesRule.cs
- TextRangeBase.cs
- WebScriptEnablingElement.cs
- GridViewColumnHeaderAutomationPeer.cs
- SchemaAttDef.cs
- ProtocolReflector.cs
- SqlCharStream.cs
- ApplicationServiceHelper.cs
- XamlPointCollectionSerializer.cs
- ToolStripItemCollection.cs
- SqlPersistenceProviderFactory.cs
- Stack.cs
- InternalBufferOverflowException.cs
- LicenseException.cs
- QueryCacheKey.cs
- TransportContext.cs
- AccessDataSourceView.cs
- _ListenerAsyncResult.cs
- _LocalDataStoreMgr.cs
- OrderedDictionary.cs
- TreeViewCancelEvent.cs
- Stylesheet.cs
- InputLanguageEventArgs.cs
- SystemPens.cs
- HttpListenerException.cs
- Viewport2DVisual3D.cs
- CreateUserWizard.cs