private ColumnBinding GetValueBinding(MetaData info) { ColumnBinding binding = info.columnBinding; Debug.Assert(null != binding, "null binding"); // do we need to jump to the next accessor for (int i = _nextAccessorForRetrieval; i <= binding.IndexForAccessor; ++i) { Debug.Assert(_nextAccessorForRetrieval <= binding.IndexForAccessor, "backwards index for accessor"); Debug.Assert(_nextAccessorForRetrieval == i, "failed to increment"); if (_sequentialAccess) { if (_nextValueForRetrieval != binding.Index) { // release old value _metadata[_nextValueForRetrieval].columnBinding.ResetValue(); } _nextAccessorForRetrieval = binding.IndexForAccessor; } if (null != _irowset) { GetRowDataFromHandle(); // will increment _nextAccessorForRetrieval } else if (null != _irow) { GetRowValue(); // will increment _nextAccessorForRetrieval } else { throw ADP.DataReaderNoData(); } } // to enforce sequential access _nextValueForRetrieval = binding.Index; return binding; }
private DataTable BuildSchemaTable(MetaData[] metadata) { Debug.Assert(null == _dbSchemaTable, "BuildSchemaTable: schema table already exists"); Debug.Assert(null != metadata, "BuildSchemaTable: no _metadata"); DataTable schemaTable = new DataTable("SchemaTable"); schemaTable.Locale = CultureInfo.InvariantCulture; schemaTable.MinimumCapacity = metadata.Length; DataColumn name = new DataColumn("ColumnName", typeof(System.String)); DataColumn ordinal = new DataColumn("ColumnOrdinal", typeof(System.Int32)); DataColumn size = new DataColumn("ColumnSize", typeof(System.Int32)); DataColumn precision = new DataColumn("NumericPrecision", typeof(System.Int16)); DataColumn scale = new DataColumn("NumericScale", typeof(System.Int16)); DataColumn dataType = new DataColumn("DataType", typeof(System.Type)); DataColumn providerType = new DataColumn("ProviderType", typeof(System.Int32)); DataColumn isLong = new DataColumn("IsLong", typeof(System.Boolean)); DataColumn allowDBNull = new DataColumn("AllowDBNull", typeof(System.Boolean)); DataColumn isReadOnly = new DataColumn("IsReadOnly", typeof(System.Boolean)); DataColumn isRowVersion = new DataColumn("IsRowVersion", typeof(System.Boolean)); DataColumn isUnique = new DataColumn("IsUnique", typeof(System.Boolean)); DataColumn isKey = new DataColumn("IsKey", typeof(System.Boolean)); DataColumn isAutoIncrement = new DataColumn("IsAutoIncrement", typeof(System.Boolean)); DataColumn isHidden = new DataColumn("IsHidden", typeof(System.Boolean)); DataColumn baseSchemaName = new DataColumn("BaseSchemaName", typeof(System.String)); DataColumn baseCatalogName = new DataColumn("BaseCatalogName", typeof(System.String)); DataColumn baseTableName = new DataColumn("BaseTableName", typeof(System.String)); DataColumn baseColumnName = new DataColumn("BaseColumnName", typeof(System.String)); ordinal.DefaultValue = 0; isLong.DefaultValue = false; DataColumnCollection columns = schemaTable.Columns; columns.Add(name); columns.Add(ordinal); columns.Add(size); columns.Add(precision); columns.Add(scale); columns.Add(dataType); columns.Add(providerType); columns.Add(isLong); columns.Add(allowDBNull); columns.Add(isReadOnly); columns.Add(isRowVersion); columns.Add(isUnique); columns.Add(isKey); columns.Add(isAutoIncrement); if (_visibleFieldCount < metadata.Length) { columns.Add(isHidden); } columns.Add(baseSchemaName); columns.Add(baseCatalogName); columns.Add(baseTableName); columns.Add(baseColumnName); for (int i = 0; i < metadata.Length; ++i) { MetaData info = metadata[i]; DataRow newRow = schemaTable.NewRow(); newRow[name] = info.columnName; newRow[ordinal] = i; // MDAC 68319 // @devnote: size is count of characters for WSTR or STR, bytes otherwise // @devnote: see OLEDB spec under IColumnsInfo::GetColumnInfo newRow[size] = ((info.type.enumOleDbType != OleDbType.BSTR) ? info.size : -1); // MDAC 72653 newRow[precision] = info.precision; // MDAC 72800 newRow[scale] = info.scale; newRow[dataType] = info.type.dataType; newRow[providerType] = info.type.enumOleDbType; newRow[isLong] = OleDbDataReader.IsLong(info.flags); if (info.isKeyColumn) { newRow[allowDBNull] = OleDbDataReader.AllowDBNull(info.flags); } else { newRow[allowDBNull] = OleDbDataReader.AllowDBNullMaybeNull(info.flags); } newRow[isReadOnly] = OleDbDataReader.IsReadOnly(info.flags); newRow[isRowVersion] = OleDbDataReader.IsRowVersion(info.flags); newRow[isUnique] = info.isUnique; newRow[isKey] = info.isKeyColumn; newRow[isAutoIncrement] = info.isAutoIncrement; if (_visibleFieldCount < metadata.Length) { newRow[isHidden] = info.isHidden; } if (null != info.baseSchemaName) { newRow[baseSchemaName] = info.baseSchemaName; } if (null != info.baseCatalogName) { newRow[baseCatalogName] = info.baseCatalogName; } if (null != info.baseTableName) { newRow[baseTableName] = info.baseTableName; } if (null != info.baseColumnName) { newRow[baseColumnName] = info.baseColumnName; } schemaTable.Rows.Add(newRow); newRow.AcceptChanges(); } // mark all columns as readonly int count = columns.Count; for (int i=0; i < count; i++) { columns[i].ReadOnly = true; // MDAC 70943 } _dbSchemaTable = schemaTable; return schemaTable; }
// create DataColumns // add DataColumns to DataTable // add schema information to DataTable // generate unique column names private void BuildSchemaTableInfoTable(int columnCount, IntPtr columnInfos, bool filterITypeInfo, bool filterChapters) { Debug.Assert(0 < columnCount, "BuildSchemaTableInfoTable - no column"); int rowCount = 0; MetaData[] metainfo = new MetaData[columnCount]; // for every column, build an equivalent to tagDBCOLUMNINFO tagDBCOLUMNINFO dbColumnInfo = new tagDBCOLUMNINFO(); for (int i = 0, offset = 0; i < columnCount; ++i, offset += ODB.SizeOf_tagDBCOLUMNINFO) { Marshal.PtrToStructure(ADP.IntPtrOffset(columnInfos, offset), dbColumnInfo); #if WIN32 if (0 >= (int) dbColumnInfo.iOrdinal) { #else if (0 >= (long) dbColumnInfo.iOrdinal) { #endif continue; } if (OleDbDataReader.DoColumnDropFilter(dbColumnInfo.dwFlags)) { continue; } if (null == dbColumnInfo.pwszName) { dbColumnInfo.pwszName = ""; } if (filterITypeInfo && (ODB.DBCOLUMN_TYPEINFO == dbColumnInfo.pwszName)) { // MDAC 65306 continue; } if (filterChapters && (NativeDBType.HCHAPTER == dbColumnInfo.wType)) { continue; // filter chapters in IRowset from IDBSchemaRowset for DumpToTable } bool islong = OleDbDataReader.IsLong(dbColumnInfo.dwFlags); bool isfixed = OleDbDataReader.IsFixed(dbColumnInfo.dwFlags); NativeDBType dbType = NativeDBType.FromDBType(dbColumnInfo.wType, islong, isfixed); MetaData info = new MetaData(); info.columnName = dbColumnInfo.pwszName; info.type = dbType; info.ordinal = dbColumnInfo.iOrdinal; #if WIN32 info.size = (int)dbColumnInfo.ulColumnSize; #else long maxsize = (long) dbColumnInfo.ulColumnSize; info.size = (((maxsize < 0) || (Int32.MaxValue < maxsize)) ? Int32.MaxValue : (int)maxsize); #endif info.flags = dbColumnInfo.dwFlags; info.precision = dbColumnInfo.bPrecision; info.scale = dbColumnInfo.bScale; info.kind = dbColumnInfo.columnid.eKind; switch(dbColumnInfo.columnid.eKind) { case ODB.DBKIND_GUID_NAME: case ODB.DBKIND_GUID_PROPID: case ODB.DBKIND_GUID: info.guid = dbColumnInfo.columnid.uGuid; break; default: Debug.Assert(ODB.DBKIND_PGUID_NAME != dbColumnInfo.columnid.eKind, "OLE DB providers never return pGuid-style bindings."); Debug.Assert(ODB.DBKIND_PGUID_PROPID != dbColumnInfo.columnid.eKind, "OLE DB providers never return pGuid-style bindings."); info.guid = Guid.Empty; break; } switch(dbColumnInfo.columnid.eKind) { case ODB.DBKIND_GUID_PROPID: case ODB.DBKIND_PROPID: info.propid = dbColumnInfo.columnid.ulPropid; break; case ODB.DBKIND_GUID_NAME: case ODB.DBKIND_NAME: if (ADP.PtrZero != dbColumnInfo.columnid.ulPropid) { info.idname = Marshal.PtrToStringUni(dbColumnInfo.columnid.ulPropid); } else { info.idname = null; } break; default: info.propid = ADP.PtrZero; break; } metainfo[rowCount] = info; #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("OleDbDataReader[" + info.ordinal.ToInt64().ToString(CultureInfo.InvariantCulture) + ", " + dbColumnInfo.pwszName + "]=" + dbType.enumOleDbType.ToString() + "," + dbType.dataSourceType + ", " + dbType.wType); } #endif rowCount++; } if (rowCount < columnCount) { // shorten names array appropriately MetaData[] tmpinfo = new MetaData[rowCount]; for (int i = 0; i < rowCount; ++i) { tmpinfo[i] = metainfo[i]; } metainfo = tmpinfo; } _visibleFieldCount = rowCount; _metadata = metainfo; }
internal void DumpToSchemaTable(UnsafeNativeMethods.IRowset rowset) { List<MetaData> metainfo = new List<MetaData>(); object hiddenColumns = null; using (OleDbDataReader dataReader = new OleDbDataReader(_connection, _command, Int32.MinValue, 0)) { dataReader.InitializeIRowset(rowset, ChapterHandle.DB_NULL_HCHAPTER, IntPtr.Zero); dataReader.BuildSchemaTableInfo(rowset, true, false); hiddenColumns = GetPropertyValue(ODB.DBPROP_HIDDENCOLUMNS); // MDAC 55611, 72106 if (0 == dataReader.FieldCount) { return; } Debug.Assert(null == dataReader._fieldNameLookup, "lookup already exists"); FieldNameLookup lookup = new FieldNameLookup(dataReader, -1); dataReader._fieldNameLookup = lookup; // This column, together with the DBCOLUMN_GUID and DBCOLUMN_PROPID // columns, forms the ID of the column. One or more (but not all) of these columns // will be NULL, depending on which elements of the DBID structure the provider uses. MetaData columnidname = dataReader.FindMetaData(ODB.DBCOLUMN_IDNAME); MetaData columnguid = dataReader.FindMetaData(ODB.DBCOLUMN_GUID); MetaData columnpropid = dataReader.FindMetaData(ODB.DBCOLUMN_PROPID); MetaData columnname = dataReader.FindMetaData(ODB.DBCOLUMN_NAME); MetaData columnordinal = dataReader.FindMetaData(ODB.DBCOLUMN_NUMBER); MetaData dbtype = dataReader.FindMetaData(ODB.DBCOLUMN_TYPE); MetaData columnsize = dataReader.FindMetaData(ODB.DBCOLUMN_COLUMNSIZE); MetaData numericprecision = dataReader.FindMetaData(ODB.DBCOLUMN_PRECISION); MetaData numericscale = dataReader.FindMetaData(ODB.DBCOLUMN_SCALE); MetaData columnflags = dataReader.FindMetaData(ODB.DBCOLUMN_FLAGS); MetaData baseschemaname = dataReader.FindMetaData(ODB.DBCOLUMN_BASESCHEMANAME); MetaData basecatalogname = dataReader.FindMetaData(ODB.DBCOLUMN_BASECATALOGNAME); MetaData basetablename = dataReader.FindMetaData(ODB.DBCOLUMN_BASETABLENAME); MetaData basecolumnname = dataReader.FindMetaData(ODB.DBCOLUMN_BASECOLUMNNAME); MetaData isautoincrement = dataReader.FindMetaData(ODB.DBCOLUMN_ISAUTOINCREMENT); MetaData isunique = dataReader.FindMetaData(ODB.DBCOLUMN_ISUNIQUE); MetaData iskeycolumn = dataReader.FindMetaData(ODB.DBCOLUMN_KEYCOLUMN); // @devnote: because we want to use the DBACCESSOR_OPTIMIZED bit, // we are required to create the accessor before fetching any rows dataReader.CreateAccessors(false); ColumnBinding binding; while (dataReader.ReadRowset()) { dataReader.GetRowDataFromHandle(); MetaData info = new MetaData(); binding = columnidname.columnBinding; // MDAC 72627 if (!binding.IsValueNull()) { info.idname = (string)binding.Value(); info.kind = ODB.DBKIND_NAME; } binding = columnguid.columnBinding; if (!binding.IsValueNull()) { info.guid = binding.Value_GUID(); info.kind = ((ODB.DBKIND_NAME == info.kind) ? ODB.DBKIND_GUID_NAME : ODB.DBKIND_GUID); } binding = columnpropid.columnBinding; if (!binding.IsValueNull()) { info.propid = new IntPtr(binding.Value_UI4()); info.kind = ((ODB.DBKIND_GUID == info.kind) ? ODB.DBKIND_GUID_PROPID : ODB.DBKIND_PROPID); } binding = columnname.columnBinding; if (!binding.IsValueNull()) { info.columnName = (string)binding.Value(); } else { info.columnName = ""; } if (4 == ADP.PtrSize) { info.ordinal = (IntPtr)columnordinal.columnBinding.Value_UI4(); } else { info.ordinal = (IntPtr)columnordinal.columnBinding.Value_UI8(); } short wType = unchecked((short) dbtype.columnBinding.Value_UI2()); if (4 == ADP.PtrSize) { info.size = unchecked((int) columnsize.columnBinding.Value_UI4()); // WebData 99298 } else { info.size = ADP.IntPtrToInt32((IntPtr)unchecked((long)columnsize.columnBinding.Value_UI8())); } binding = numericprecision.columnBinding; if (!binding.IsValueNull()) { info.precision = (byte)binding.Value_UI2(); } binding = numericscale.columnBinding; if (!binding.IsValueNull()) { info.scale = (byte)binding.Value_I2(); } info.flags = unchecked((int) columnflags.columnBinding.Value_UI4()); bool islong = OleDbDataReader.IsLong(info.flags); bool isfixed = OleDbDataReader.IsFixed(info.flags); NativeDBType dbType = NativeDBType.FromDBType(wType, islong, isfixed); info.type = dbType; if (null != isautoincrement) { binding = isautoincrement.columnBinding; if (!binding.IsValueNull()) { info.isAutoIncrement = binding.Value_BOOL(); } } if (null != isunique) { binding = isunique.columnBinding; if (!binding.IsValueNull()) { info.isUnique = binding.Value_BOOL(); } } if (null != iskeycolumn) { binding = iskeycolumn.columnBinding; if (!binding.IsValueNull()) { info.isKeyColumn = binding.Value_BOOL(); } } if (null != baseschemaname) { binding = baseschemaname.columnBinding; if (!binding.IsValueNull()) { info.baseSchemaName = binding.ValueString(); } } if (null != basecatalogname) { binding = basecatalogname.columnBinding; if (!binding.IsValueNull()) { info.baseCatalogName = binding.ValueString(); } } if (null != basetablename) { binding = basetablename.columnBinding; if (!binding.IsValueNull()) { info.baseTableName = binding.ValueString(); } } if (null != basecolumnname) { binding = basecolumnname.columnBinding; if (!binding.IsValueNull()) { info.baseColumnName = binding.ValueString(); } } metainfo.Add(info); } } int visibleCount = metainfo.Count; if (hiddenColumns is Int32) { visibleCount -= (int)hiddenColumns; } // VSTFDevDiv 479578: // if one key column is invalidated, they all need to be invalidated. The SET is the key, // and subsets likely are not accurate keys. Note the assumption that the two loops below // will traverse the entire set of columns. bool disallowKeyColumns = false; for (int index = metainfo.Count - 1; visibleCount <= index; --index) { MetaData info = metainfo[index]; info.isHidden = true; if (disallowKeyColumns) { info.isKeyColumn = false; } else if (info.guid.Equals(ODB.DBCOL_SPECIALCOL)) { // MDAC 90827 info.isKeyColumn = false; // This is the first key column to be invalidated, scan back through the // columns we already processed to make sure none of those are marked as keys. disallowKeyColumns = true; for (int index2 = metainfo.Count-1; index < index2; --index2) { metainfo[index2].isKeyColumn = false; } } } for (int index = visibleCount - 1; 0 <= index; --index) { MetaData info = metainfo[index]; if (disallowKeyColumns) { info.isKeyColumn = false; } if (info.guid.Equals(ODB.DBCOL_SPECIALCOL)) { // MDAC 72390 #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("Filtered Column: DBCOLUMN_GUID=DBCOL_SPECIALCOL DBCOLUMN_NAME=" + info.columnName + " DBCOLUMN_KEYCOLUMN=" + info.isKeyColumn); } #endif info.isHidden = true; visibleCount--; } #if WIN32 else if (0 >= (int)info.ordinal) { #else else if (0 >= (long)info.ordinal) { #endif #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("Filtered Column: DBCOLUMN_NUMBER=" + info.ordinal.ToInt64().ToString(CultureInfo.InvariantCulture) + " DBCOLUMN_NAME=" + info.columnName); } #endif info.isHidden = true; visibleCount--; } else if (OleDbDataReader.DoColumnDropFilter(info.flags)) { #if DEBUG if (AdapterSwitches.DataSchema.TraceVerbose) { Debug.WriteLine("Filtered Column: DBCOLUMN_FLAGS=" + info.flags.ToString("X8", (System.IFormatProvider)null) + " DBCOLUMN_NAME=" + info.columnName); } #endif info.isHidden = true; visibleCount--; } } // metainfo.Sort(); // MDAC 68319 _visibleFieldCount = visibleCount; _metadata = metainfo.ToArray(); }