public void EqualsAndHashCode() { UniqueConstraint cst = new UniqueConstraint(new DataColumn [] { _table.Columns[0], _table.Columns[1] }); UniqueConstraint cst2 = new UniqueConstraint(new DataColumn [] { _table.Columns[1], _table.Columns[0] }); UniqueConstraint cst3 = new UniqueConstraint(_table.Columns [0]); UniqueConstraint cst4 = new UniqueConstraint(_table.Columns [2]); //true Assert.That(cst.Equals(cst2), Is.True, "A0"); //false Assert.That(cst.Equals(23), Is.False, "A1"); Assert.That(cst.Equals(cst3), Is.False, "A2"); Assert.That(cst3.Equals(cst), Is.False, "A3"); Assert.That(cst.Equals(cst4), Is.False, "A4"); //false... but it should be true (FXDG violation) //Assert.That (cst.GetHashCode (), Is.Not.EqualTo (cst2.GetHashCode ()), "HashEquals"); //false Assert.That(cst.GetHashCode(), Is.Not.EqualTo(cst3.GetHashCode()), "Hash Not Equals"); }
//Activate This Construntor to log All To Standard output //public TestClass():base(true){} //Activate this constructor to log Failures to a log file //public TestClass(System.IO.TextWriter tw):base(tw, false){} //Activate this constructor to log All to a log file //public TestClass(System.IO.TextWriter tw):base(tw, true){} //BY DEFAULT LOGGING IS DONE TO THE STANDARD OUTPUT ONLY FOR FAILURES public void run() { Exception exp = null; DataSet ds = new DataSet(); DataTable dtParent = GHTUtils.DataProvider.CreateParentDataTable(); ds.Tables.Add(dtParent); UniqueConstraint uc1, uc2; uc1 = new UniqueConstraint(dtParent.Columns[0]); uc2 = new UniqueConstraint(dtParent.Columns[1]); try { BeginCase("different columnn"); Compare(uc1.Equals(uc2), false); } catch (Exception ex) { exp = ex; } finally { EndCase(exp); exp = null; } //Two System.Data.ForeignKeyConstraint are equal if they constrain the same columns. try { BeginCase("same column"); uc2 = new UniqueConstraint(dtParent.Columns[0]); Compare(uc1.Equals(uc2), true); } catch (Exception ex) { exp = ex; } finally { EndCase(exp); exp = null; } }
public void EqualsAndHashCode() { UniqueConstraint cst = new UniqueConstraint(new DataColumn [] { _table.Columns[0], _table.Columns[1] }); UniqueConstraint cst2 = new UniqueConstraint(new DataColumn [] { _table.Columns[1], _table.Columns[0] }); UniqueConstraint cst3 = new UniqueConstraint(_table.Columns[0]); UniqueConstraint cst4 = new UniqueConstraint(_table.Columns[2]); //true Assert(cst.Equals(cst2) == true); //false Assert("A1", cst.Equals(23) == false); Assert("A2", cst.Equals(cst3) == false); Assert("A3", cst3.Equals(cst) == false); Assert("A4", cst.Equals(cst4) == false); //true Assert("HashEquals", cst.GetHashCode() == cst2.GetHashCode()); //false Assert("Hash Not Equals", (cst.GetHashCode() == cst3.GetHashCode()) == false); }
public void Equals_O() { var ds = new DataSet(); DataTable dtParent = DataProvider.CreateParentDataTable(); ds.Tables.Add(dtParent); UniqueConstraint uc1, uc2; uc1 = new UniqueConstraint(dtParent.Columns[0]); uc2 = new UniqueConstraint(dtParent.Columns[1]); // different columnn Assert.Equal(false, uc1.Equals(uc2)); //Two System.Data.ForeignKeyConstraint are equal if they constrain the same columns. // same column uc2 = new UniqueConstraint(dtParent.Columns[0]); Assert.Equal(true, uc1.Equals(uc2)); }
[Test] public void Equals_O() { DataSet ds = new DataSet(); DataTable dtParent = DataProvider.CreateParentDataTable(); ds.Tables.Add(dtParent); UniqueConstraint uc1, uc2; uc1 = new UniqueConstraint(dtParent.Columns[0]); uc2 = new UniqueConstraint(dtParent.Columns[1]); // different columnn Assert.AreEqual(false, uc1.Equals(uc2), "UC3"); //Two System.Data.ForeignKeyConstraint are equal if they constrain the same columns. // same column uc2 = new UniqueConstraint(dtParent.Columns[0]); Assert.AreEqual(true, uc1.Equals(uc2), "UC4"); }
public void EqualsAndHashCode() { UniqueConstraint cst = new UniqueConstraint(new DataColumn[] { _table.Columns[0], _table.Columns[1] }); UniqueConstraint cst2 = new UniqueConstraint(new DataColumn[] { _table.Columns[1], _table.Columns[0] }); UniqueConstraint cst3 = new UniqueConstraint(_table.Columns[0]); UniqueConstraint cst4 = new UniqueConstraint(_table.Columns[2]); //true Assert.True(cst.Equals(cst2)); //false Assert.False(cst.Equals(23)); Assert.False(cst.Equals(cst3)); Assert.False(cst3.Equals(cst)); Assert.False(cst.Equals(cst4)); Assert.NotEqual(cst3.GetHashCode(), cst.GetHashCode()); }
private object[] SetupSchemaWithKeyInfo(MissingMappingAction mappingAction, MissingSchemaAction schemaAction, bool gettingData, DataColumn parentChapterColumn, object chapterValue) { // must sort rows from schema table by ordinal because Jet is sorted by coumn name DbSchemaRow[] schemaRows = DbSchemaRow.GetSortedSchemaRows(_schemaTable, _dataReader.ReturnProviderSpecificTypes); Debug.Assert(null != schemaRows, "SchemaSetup - null DbSchemaRow[]"); Debug.Assert(_dataReader.FieldCount <= schemaRows.Length, "unexpected fewer rows in Schema than FieldCount"); if (0 == schemaRows.Length) { _dataTable = null; return null; } // Everett behavior, always add a primary key if a primary key didn't exist before // Whidbey behavior, same as Everett unless using LoadOption then add primary key only if no columns previously existed bool addPrimaryKeys = (((0 == _dataTable.PrimaryKey.Length) && ((4 <= (int)_loadOption) || (0 == _dataTable.Rows.Count))) || (0 == _dataTable.Columns.Count)); DataColumn[] keys = null; int keyCount = 0; bool isPrimary = true; // assume key info (if any) is about a primary key string keyBaseTable = null; string commonBaseTable = null; bool keyFromMultiTable = false; bool commonFromMultiTable = false; int[] columnIndexMap = null; bool[] chapterIndexMap = null; int mappingCount = 0; object[] dataValues = null; List<object> addedItems = null; DataColumnCollection columnCollection = _dataTable.Columns; try { for (int sortedIndex = 0; sortedIndex < schemaRows.Length; ++sortedIndex) { DbSchemaRow schemaRow = schemaRows[sortedIndex]; int unsortedIndex = schemaRow.UnsortedIndex; bool ischapter = false; Type fieldType = schemaRow.DataType; if (null == fieldType) { fieldType = _dataReader.GetFieldType(sortedIndex); } if (null == fieldType) { throw ADP.MissingDataReaderFieldType(sortedIndex); } // if IDataReader, hierarchy exists and we will use an Int32,AutoIncrementColumn in this table if (typeof(IDataReader).IsAssignableFrom(fieldType)) { if (null == chapterIndexMap) { chapterIndexMap = new bool[schemaRows.Length]; } chapterIndexMap[unsortedIndex] = ischapter = true; fieldType = typeof(int); } else if (typeof(System.Data.SqlTypes.SqlXml).IsAssignableFrom(fieldType)) { if (null == _xmlMap) { _xmlMap = new int[schemaRows.Length]; } _xmlMap[sortedIndex] = SqlXml; } else if (typeof(System.Xml.XmlReader).IsAssignableFrom(fieldType)) { fieldType = typeof(string); if (null == _xmlMap) { _xmlMap = new int[schemaRows.Length]; } _xmlMap[sortedIndex] = XmlDocument; } DataColumn dataColumn = null; if (!schemaRow.IsHidden) { dataColumn = _tableMapping.GetDataColumn(_fieldNames[sortedIndex], fieldType, _dataTable, mappingAction, schemaAction); } string basetable = /*schemaRow.BaseServerName+schemaRow.BaseCatalogName+schemaRow.BaseSchemaName+*/ schemaRow.BaseTableName; if (null == dataColumn) { if (null == columnIndexMap) { columnIndexMap = CreateIndexMap(schemaRows.Length, unsortedIndex); } columnIndexMap[unsortedIndex] = -1; // if the column is not mapped and it is a key, then don't add any key information if (schemaRow.IsKey) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: partial primary key detected"); } #endif // if the hidden key comes from a different table - don't throw away the primary key // example SELECT [T2].[ID], [T2].[ProdID], [T2].[VendorName] FROM [Vendor] AS [T2], [Prod] AS [T1] WHERE (([T1].[ProdID] = [T2].[ProdID])) if (keyFromMultiTable || (schemaRow.BaseTableName == keyBaseTable)) { addPrimaryKeys = false; // don't add any future keys now keys = null; // get rid of any keys we've seen } } continue; // null means ignore (mapped to nothing) } else if ((null != _xmlMap) && (0 != _xmlMap[sortedIndex])) { if (typeof(System.Data.SqlTypes.SqlXml) == dataColumn.DataType) { _xmlMap[sortedIndex] = SqlXml; } else if (typeof(System.Xml.XmlDocument) == dataColumn.DataType) { _xmlMap[sortedIndex] = XmlDocument; } else { _xmlMap[sortedIndex] = 0; // datacolumn is not a specific Xml dataType, i.e. string int total = 0; for (int x = 0; x < _xmlMap.Length; ++x) { total += _xmlMap[x]; } if (0 == total) { // not mapping to a specific Xml datatype, get rid of the map _xmlMap = null; } } } if (schemaRow.IsKey) { if (basetable != keyBaseTable) { if (null == keyBaseTable) { keyBaseTable = basetable; } else keyFromMultiTable = true; } } if (ischapter) { if (null == dataColumn.Table) { dataColumn.AllowDBNull = false; dataColumn.AutoIncrement = true; dataColumn.ReadOnly = true; } else if (!dataColumn.AutoIncrement) { throw ADP.FillChapterAutoIncrement(); } } else { if (!commonFromMultiTable) { if ((basetable != commonBaseTable) && (!string.IsNullOrEmpty(basetable))) { if (null == commonBaseTable) { commonBaseTable = basetable; } else { commonFromMultiTable = true; } } } if (4 <= (int)_loadOption) { if (schemaRow.IsAutoIncrement && DataColumn.IsAutoIncrementType(fieldType)) { // CONSIDER: use T-SQL "IDENT_INCR('table_or_view')" and "IDENT_SEED('table_or_view')" // functions to obtain the actual increment and seed values dataColumn.AutoIncrement = true; if (!schemaRow.AllowDBNull) { dataColumn.AllowDBNull = false; } } // setup maxLength, only for string columns since this is all the DataSet supports if (fieldType == typeof(string)) { // schemaRow.Size is count of characters for string columns, count of bytes otherwise dataColumn.MaxLength = schemaRow.Size > 0 ? schemaRow.Size : -1; } if (schemaRow.IsReadOnly) { dataColumn.ReadOnly = true; } if (!schemaRow.AllowDBNull && (!schemaRow.IsReadOnly || schemaRow.IsKey)) { dataColumn.AllowDBNull = false; } if (schemaRow.IsUnique && !schemaRow.IsKey && !fieldType.IsArray) { // note, arrays are not comparable so only mark non-arrays as unique, ie timestamp columns // are unique, but not comparable dataColumn.Unique = true; if (!schemaRow.AllowDBNull) { dataColumn.AllowDBNull = false; } } } else if (null == dataColumn.Table) { dataColumn.AutoIncrement = schemaRow.IsAutoIncrement; dataColumn.AllowDBNull = schemaRow.AllowDBNull; dataColumn.ReadOnly = schemaRow.IsReadOnly; dataColumn.Unique = schemaRow.IsUnique; if (fieldType == typeof(string) || (fieldType == typeof(SqlTypes.SqlString))) { // schemaRow.Size is count of characters for string columns, count of bytes otherwise dataColumn.MaxLength = schemaRow.Size; } } } if (null == dataColumn.Table) { if (4 > (int)_loadOption) { AddAdditionalProperties(dataColumn, schemaRow.DataRow); } AddItemToAllowRollback(ref addedItems, dataColumn); columnCollection.Add(dataColumn); } // The server sends us one key per table according to these rules. // // 1. If the table has a primary key, the server sends us this key. // 2. If the table has a primary key and a unique key, it sends us the primary key // 3. if the table has no primary key but has a unique key, it sends us the unique key // // In case 3, we will promote a unique key to a primary key IFF all the columns that compose // that key are not nullable since no columns in a primary key can be null. If one or more // of the keys is nullable, then we will add a unique constraint. // if (addPrimaryKeys && schemaRow.IsKey) { if (keys == null) { keys = new DataColumn[schemaRows.Length]; } keys[keyCount++] = dataColumn; #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: building list of " + ((isPrimary) ? "PrimaryKey" : "UniqueConstraint")); } #endif // see case 3 above, we do want dataColumn.AllowDBNull not schemaRow.AllowDBNull // otherwise adding PrimaryKey will change AllowDBNull to false if (isPrimary && dataColumn.AllowDBNull) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: changing PrimaryKey into UniqueContraint"); } #endif isPrimary = false; } } if (null != columnIndexMap) { columnIndexMap[unsortedIndex] = dataColumn.Ordinal; } else if (unsortedIndex != dataColumn.Ordinal) { columnIndexMap = CreateIndexMap(schemaRows.Length, unsortedIndex); columnIndexMap[unsortedIndex] = dataColumn.Ordinal; } mappingCount++; } bool addDataRelation = false; DataColumn chapterColumn = null; if (null != chapterValue) { // add the extra column in the child table Type fieldType = chapterValue.GetType(); chapterColumn = _tableMapping.GetDataColumn(_tableMapping.SourceTable, fieldType, _dataTable, mappingAction, schemaAction); if (null != chapterColumn) { if (null == chapterColumn.Table) { chapterColumn.ReadOnly = true; chapterColumn.AllowDBNull = false; AddItemToAllowRollback(ref addedItems, chapterColumn); columnCollection.Add(chapterColumn); addDataRelation = (null != parentChapterColumn); } mappingCount++; } } if (0 < mappingCount) { if ((null != _dataSet) && null == _dataTable.DataSet) { AddItemToAllowRollback(ref addedItems, _dataTable); _dataSet.Tables.Add(_dataTable); } // setup the key if (addPrimaryKeys && (null != keys)) { if (keyCount < keys.Length) { keys = ResizeColumnArray(keys, keyCount); } if (isPrimary) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: set_PrimaryKey"); } #endif _dataTable.PrimaryKey = keys; } else { UniqueConstraint unique = new UniqueConstraint("", keys); ConstraintCollection constraints = _dataTable.Constraints; int constraintCount = constraints.Count; for (int i = 0; i < constraintCount; ++i) { if (unique.Equals(constraints[i])) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: duplicate Contraint detected"); } #endif unique = null; break; } } if (null != unique) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: adding new UniqueConstraint"); } #endif constraints.Add(unique); } } } if (!commonFromMultiTable && !string.IsNullOrEmpty(commonBaseTable) && string.IsNullOrEmpty(_dataTable.TableName)) { _dataTable.TableName = commonBaseTable; } if (gettingData) { _indexMap = columnIndexMap; _chapterMap = chapterIndexMap; dataValues = SetupMapping(schemaRows.Length, columnCollection, chapterColumn, chapterValue); } else { // debug only, but for retail debug ability _mappedMode = -1; } } else { _dataTable = null; } if (addDataRelation) { AddRelation(parentChapterColumn, chapterColumn); } } catch (Exception e) when (ADP.IsCatchableOrSecurityExceptionType(e)) { RollbackAddedItems(addedItems); throw; } return dataValues; }
private object[] SetupSchemaWithKeyInfo(MissingMappingAction mappingAction, MissingSchemaAction schemaAction, bool gettingData, DataColumn parentChapterColumn, object chapterValue) { DbSchemaRow[] sortedSchemaRows = DbSchemaRow.GetSortedSchemaRows(this._schemaTable, this._dataReader.ReturnProviderSpecificTypes); if (sortedSchemaRows.Length == 0) { this._dataTable = null; return(null); } bool flag3 = ((this._dataTable.PrimaryKey.Length == 0) && ((((LoadOption)4) <= this._loadOption) || (this._dataTable.Rows.Count == 0))) || (0 == this._dataTable.Columns.Count); DataColumn[] rgcol = null; int len = 0; bool flag2 = true; string str3 = null; string str2 = null; bool flag6 = false; bool flag = false; int[] numArray = null; bool[] flagArray = null; int num3 = 0; object[] objArray = null; List <object> items = null; DataColumnCollection columnCollection = this._dataTable.Columns; try { for (int i = 0; i < sortedSchemaRows.Length; i++) { DbSchemaRow row = sortedSchemaRows[i]; int unsortedIndex = row.UnsortedIndex; bool flag5 = false; Type dataType = row.DataType; if (null == dataType) { dataType = this._dataReader.GetFieldType(i); } if (null == dataType) { throw ADP.MissingDataReaderFieldType(i); } if (typeof(IDataReader).IsAssignableFrom(dataType)) { if (flagArray == null) { flagArray = new bool[sortedSchemaRows.Length]; } flagArray[unsortedIndex] = flag5 = true; dataType = typeof(int); } else if (typeof(System.Data.SqlTypes.SqlXml).IsAssignableFrom(dataType)) { if (this._xmlMap == null) { this._xmlMap = new int[sortedSchemaRows.Length]; } this._xmlMap[i] = 1; } else if (typeof(XmlReader).IsAssignableFrom(dataType)) { dataType = typeof(string); if (this._xmlMap == null) { this._xmlMap = new int[sortedSchemaRows.Length]; } this._xmlMap[i] = 2; } DataColumn targetColumn = null; if (!row.IsHidden) { targetColumn = this._tableMapping.GetDataColumn(this._fieldNames[i], dataType, this._dataTable, mappingAction, schemaAction); } string baseTableName = row.BaseTableName; if (targetColumn == null) { if (numArray == null) { numArray = this.CreateIndexMap(sortedSchemaRows.Length, unsortedIndex); } numArray[unsortedIndex] = -1; if (row.IsKey && (flag6 || (row.BaseTableName == str3))) { flag3 = false; rgcol = null; } } else { if ((this._xmlMap != null) && (this._xmlMap[i] != 0)) { if (typeof(System.Data.SqlTypes.SqlXml) == targetColumn.DataType) { this._xmlMap[i] = 1; } else if (typeof(System.Xml.XmlDocument) == targetColumn.DataType) { this._xmlMap[i] = 2; } else { this._xmlMap[i] = 0; int num7 = 0; for (int j = 0; j < this._xmlMap.Length; j++) { num7 += this._xmlMap[j]; } if (num7 == 0) { this._xmlMap = null; } } } if (row.IsKey && (baseTableName != str3)) { if (str3 == null) { str3 = baseTableName; } else { flag6 = true; } } if (flag5) { if (targetColumn.Table != null) { if (!targetColumn.AutoIncrement) { throw ADP.FillChapterAutoIncrement(); } } else { targetColumn.AllowDBNull = false; targetColumn.AutoIncrement = true; targetColumn.ReadOnly = true; } } else { if ((!flag && (baseTableName != str2)) && !ADP.IsEmpty(baseTableName)) { if (str2 == null) { str2 = baseTableName; } else { flag = true; } } if (((LoadOption)4) <= this._loadOption) { if (row.IsAutoIncrement && DataColumn.IsAutoIncrementType(dataType)) { targetColumn.AutoIncrement = true; if (!row.AllowDBNull) { targetColumn.AllowDBNull = false; } } if (dataType == typeof(string)) { targetColumn.MaxLength = (row.Size > 0) ? row.Size : -1; } if (row.IsReadOnly) { targetColumn.ReadOnly = true; } if (!row.AllowDBNull && (!row.IsReadOnly || row.IsKey)) { targetColumn.AllowDBNull = false; } if ((row.IsUnique && !row.IsKey) && !dataType.IsArray) { targetColumn.Unique = true; if (!row.AllowDBNull) { targetColumn.AllowDBNull = false; } } } else if (targetColumn.Table == null) { targetColumn.AutoIncrement = row.IsAutoIncrement; targetColumn.AllowDBNull = row.AllowDBNull; targetColumn.ReadOnly = row.IsReadOnly; targetColumn.Unique = row.IsUnique; if ((dataType == typeof(string)) || (dataType == typeof(SqlString))) { targetColumn.MaxLength = row.Size; } } } if (targetColumn.Table == null) { if (((LoadOption)4) > this._loadOption) { this.AddAdditionalProperties(targetColumn, row.DataRow); } this.AddItemToAllowRollback(ref items, targetColumn); columnCollection.Add(targetColumn); } if (flag3 && row.IsKey) { if (rgcol == null) { rgcol = new DataColumn[sortedSchemaRows.Length]; } rgcol[len++] = targetColumn; if (flag2 && targetColumn.AllowDBNull) { flag2 = false; } } if (numArray != null) { numArray[unsortedIndex] = targetColumn.Ordinal; } else if (unsortedIndex != targetColumn.Ordinal) { numArray = this.CreateIndexMap(sortedSchemaRows.Length, unsortedIndex); numArray[unsortedIndex] = targetColumn.Ordinal; } num3++; } } bool flag4 = false; DataColumn column2 = null; if (chapterValue != null) { Type type = chapterValue.GetType(); column2 = this._tableMapping.GetDataColumn(this._tableMapping.SourceTable, type, this._dataTable, mappingAction, schemaAction); if (column2 != null) { if (column2.Table == null) { column2.ReadOnly = true; column2.AllowDBNull = false; this.AddItemToAllowRollback(ref items, column2); columnCollection.Add(column2); flag4 = null != parentChapterColumn; } num3++; } } if (0 < num3) { if ((this._dataSet != null) && (this._dataTable.DataSet == null)) { this.AddItemToAllowRollback(ref items, this._dataTable); this._dataSet.Tables.Add(this._dataTable); } if (flag3 && (rgcol != null)) { if (len < rgcol.Length) { rgcol = this.ResizeColumnArray(rgcol, len); } if (flag2) { this._dataTable.PrimaryKey = rgcol; } else { UniqueConstraint constraint = new UniqueConstraint("", rgcol); ConstraintCollection constraints = this._dataTable.Constraints; int count = constraints.Count; for (int k = 0; k < count; k++) { if (constraint.Equals(constraints[k])) { constraint = null; break; } } if (constraint != null) { constraints.Add(constraint); } } } if ((!flag && !ADP.IsEmpty(str2)) && ADP.IsEmpty(this._dataTable.TableName)) { this._dataTable.TableName = str2; } if (gettingData) { this._indexMap = numArray; this._chapterMap = flagArray; objArray = this.SetupMapping(sortedSchemaRows.Length, columnCollection, column2, chapterValue); } else { this._mappedMode = -1; } } else { this._dataTable = null; } if (flag4) { this.AddRelation(parentChapterColumn, column2); } } catch (Exception exception) { if (ADP.IsCatchableOrSecurityExceptionType(exception)) { this.RollbackAddedItems(items); } throw; } return(objArray); }
public void EqualsAndHashCode() { UniqueConstraint cst = new UniqueConstraint(new DataColumn[] { _table.Columns[0], _table.Columns[1]}); UniqueConstraint cst2 = new UniqueConstraint(new DataColumn[] { _table.Columns[1], _table.Columns[0]}); UniqueConstraint cst3 = new UniqueConstraint(_table.Columns[0]); UniqueConstraint cst4 = new UniqueConstraint(_table.Columns[2]); //true Assert.True(cst.Equals(cst2)); //false Assert.False(cst.Equals(23)); Assert.False(cst.Equals(cst3)); Assert.False(cst3.Equals(cst)); Assert.False(cst.Equals(cst4)); Assert.NotEqual(cst3.GetHashCode(), cst.GetHashCode()); }
private void SetupSchemaWithKeyInfo(MissingMappingAction mappingAction, MissingSchemaAction schemaAction, bool gettingData, DataColumn parentChapterColumn, object chapterValue) { #if DEBUG Debug.Assert(null != schemaTable, "null schematable"); if (AdapterSwitches.DataSchema.TraceVerbose) { ADP.TraceDataTable("SetupSchema", schemaTable); } #endif DBSchemaRow[] schemaRows = DBSchemaRow.GetSortedSchemaRows(schemaTable); // MDAC 60609 Debug.Assert(null != schemaRows, "SchemaSetup - null DBSchemaRow[]"); int count = schemaRows.Length; if (0 == count) { this.dataTable = null; return; } bool addPrimaryKeys = (0 == this.dataTable.PrimaryKey.Length); // MDAC 67033 DataColumn[] keys = null; int keyCount = 0; bool isPrimary = true; // assume key info (if any) is about a primary key int[] columnIndexMap = null; bool[] chapterIndexMap = null; int mappingCount = 0; GenerateFieldNames(count); DataColumnCollection columnCollection = null; for (int sortedIndex = 0; sortedIndex < count; ++sortedIndex) { DBSchemaRow schemaRow = schemaRows[sortedIndex]; int unsortedIndex = schemaRow.UnsortedIndex; // MDAC 67050 DataColumnMapping columnMapping = null; Type fieldType = schemaRow.DataType; DataColumn dataColumn = null; if (!schemaRow.IsHidden) { columnMapping = tableMapping.GetColumnMappingBySchemaAction(fieldNames[sortedIndex], mappingAction); } bool ischapter = false; if ((null != columnMapping) && typeof(IDataReader).IsAssignableFrom(fieldType)) { if (null == chapterIndexMap) { chapterIndexMap = new bool[count]; } chapterIndexMap[unsortedIndex] = ischapter = true; fieldType = typeof(Int32); } if (columnMapping != null) { dataColumn = columnMapping.GetDataColumnBySchemaAction(this.dataTable, fieldType, schemaAction); } if (null == dataColumn) { if (null == columnIndexMap) { columnIndexMap = CreateIndexMap(count, unsortedIndex); } columnIndexMap[unsortedIndex] = -1; // if the column is not mapped and it is a key, then don't add any key information if (schemaRow.IsKey) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: partial primary key detected"); } #endif addPrimaryKeys = false; // don't add any future keys now keys = null; // get rid of any keys we've seen } continue; // null means ignore (mapped to nothing) } if (ischapter) { if (null == dataColumn.Table) { dataColumn.AllowDBNull = false; dataColumn.AutoIncrement = true; dataColumn.ReadOnly = true; } else if (!dataColumn.AutoIncrement) { throw ADP.FillChapterAutoIncrement(); } } else // MDAC 67033 { if (schemaRow.IsAutoIncrement && IsAutoIncrementType(fieldType)) { // CONSIDER: use T-SQL "IDENT_INCR('table_or_view')" and "IDENT_SEED('table_or_view')" // functions to obtain the actual increment and seed values dataColumn.AutoIncrement = true; if (!schemaRow.AllowDBNull) // MDAC 71060 { dataColumn.AllowDBNull = false; } } // setup maxLength, only for string columns since this is all the DataSet supports if (fieldType == typeof(string)) { //@devnote: schemaRow.Size is count of characters for string columns, count of bytes otherwise dataColumn.MaxLength = schemaRow.Size; } if (schemaRow.IsReadOnly) { dataColumn.ReadOnly = true; } if (!schemaRow.AllowDBNull && (!schemaRow.IsReadOnly || schemaRow.IsKey)) // MDAC 71060, 72252 { dataColumn.AllowDBNull = false; } if (schemaRow.IsUnique && !schemaRow.IsKey && !fieldType.IsArray) { // note, arrays are not comparable so only mark non-arrays as unique, ie timestamp columns // are unique, but not comparable dataColumn.Unique = true; if (!schemaRow.AllowDBNull) // MDAC 71060 { dataColumn.AllowDBNull = false; } } } if (null == dataColumn.Table) { if (null == columnCollection) { columnCollection = dataTable.Columns; } columnCollection.Add(dataColumn); } // The server sends us one key per table according to these rules. // // 1. If the table has a primary key, the server sends us this key. // 2. If the table has a primary key and a unique key, it sends us the primary key // 3. if the table has no primary key but has a unique key, it sends us the unique key // // In case 3, we will promote a unique key to a primary key IFF all the columns that compose // that key are not nullable since no columns in a primary key can be null. If one or more // of the keys is nullable, then we will add a unique constraint. // if (addPrimaryKeys && schemaRow.IsKey) // MDAC 67033 { if (keys == null) { keys = new DataColumn[count]; } keys[keyCount++] = dataColumn; #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: building list of " + ((isPrimary) ? "PrimaryKey" : "UniqueConstraint")); } #endif // see case 3 above, we do want dataColumn.AllowDBNull not schemaRow.AllowDBNull // otherwise adding PrimaryKey will change AllowDBNull to false if (isPrimary && dataColumn.AllowDBNull) // MDAC 72241 { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: changing PrimaryKey into UniqueContraint"); } #endif isPrimary = false; } } if (null != columnIndexMap) { columnIndexMap[unsortedIndex] = dataColumn.Ordinal; } else if (unsortedIndex != dataColumn.Ordinal) { columnIndexMap = CreateIndexMap(count, unsortedIndex); columnIndexMap[unsortedIndex] = dataColumn.Ordinal; } mappingCount++; } bool addDataRelation = false; DataColumn chapterColumn = null; if (null != chapterValue) // add the extra column in the child table { DataColumnMapping columnMapping = tableMapping.GetColumnMappingBySchemaAction(tableMapping.SourceTable, mappingAction); if (null != columnMapping) { Type fieldType = chapterValue.GetType(); chapterColumn = columnMapping.GetDataColumnBySchemaAction(this.dataTable, fieldType, schemaAction); if (null != chapterColumn) { if (null == chapterColumn.Table) { chapterColumn.ReadOnly = true; // MDAC 71878 chapterColumn.AllowDBNull = false; if (null == columnCollection) { columnCollection = dataTable.Columns; } columnCollection.Add(chapterColumn); addDataRelation = (null != parentChapterColumn); } mappingCount++; } } } object[] dataValues = null; if (0 < mappingCount) { if ((null != this.dataSet) && null == this.dataTable.DataSet) { this.dataSet.Tables.Add(this.dataTable); } // setup the key if (addPrimaryKeys && (null != keys)) // MDAC 67033 { if (keyCount < keys.Length) { keys = ResizeColumnArray(keys, keyCount); } // MDAC 66188 if (isPrimary) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: set_PrimaryKey"); } #endif this.dataTable.PrimaryKey = keys; } else { UniqueConstraint unique = new UniqueConstraint("", keys); ConstraintCollection constraints = this.dataTable.Constraints; int constraintCount = constraints.Count; for (int i = 0; i < constraintCount; ++i) { if (unique.Equals(constraints[i])) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: duplicate Contraint detected"); } #endif unique = null; break; } } if (null != unique) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("SetupSchema: adding new UniqueConstraint"); } #endif constraints.Add(unique); } } } if (gettingData) { if (null == columnCollection) { columnCollection = dataTable.Columns; } _indexMap = columnIndexMap; _chapterMap = chapterIndexMap; dataValues = SetupMapping(count, columnCollection, chapterColumn, chapterValue); } #if DEBUG else { this.mappedMode = -1; } #endif } else { this.dataTable = null; } if (addDataRelation) { AddRelation(parentChapterColumn, chapterColumn); } _readerDataValues = dataValues; }