public ColumnData[] GetColumnMetaData() { int columnCount = GetResultColumns(); if (columnCount == 0) { return(null); } ColumnData[] columns = new ColumnData[columnCount]; MemoryHandle name = new MemoryHandle((CLI.SQL_MAX_COLUMN_NAME_LEN + 1) * Platform.WideCharSize); try { for (int i = 0; i < columnCount; i++) { CLI.ReturnCode rc; short length, dataType, decimalDigits, nullable; uint columnSize; IntPtr iVal; ColumnData column = new ColumnData(); columns[i] = column; rc = (CLI.ReturnCode)CLI.SQLDescribeCol( hstmt, (ushort)(i + 1), name.Handle, (short)name.Length, out length, out dataType, out columnSize, out decimalDigits, out nullable); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } length = (short)(length * Platform.WideCharSize); column.columnName = Platform.WideCharsToString(name.Handle, length); //System.Console.WriteLine ("name.Length: {0}, length: {1}, columnName: {2}", name.Length, length, column.columnName); Debug.WriteLineIf(SqlXml.Switch.TraceVerbose, String.Format("SQLColAttribute col={0} data_type={1}", column.columnName, dataType)); column.columnType = DataTypeInfo.MapSqlType((CLI.SqlType)dataType); if (((CLI.SqlType)dataType) == CLI.SqlType.SQL_WLONGVARCHAR) { MemoryHandle bcolt = new MemoryHandle( (CLI.SQL_MAX_COLUMN_NAME_LEN + 1) * Platform.WideCharSize); short blength; IntPtr biVal; Debug.WriteLineIf(SqlXml.Switch.TraceVerbose, String.Format("Calling SQLColAttribute for col {0}", column.columnName)); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.DescriptorField.SQL_DESC_LOCAL_TYPE_NAME, bcolt.Handle, (short)bcolt.Length, out blength, out biVal); Debug.WriteLineIf(SqlXml.Switch.TraceInfo, String.Format( "Calling SQLColAttribute for col {0} returned rc={1}", column.columnName, rc)); if (rc == CLI.ReturnCode.SQL_SUCCESS) { String baseColumnType = Platform.WideCharsToString( bcolt.Handle, blength); Debug.WriteLineIf(SqlXml.Switch.TraceInfo, String.Format( "Calling SQLColAttribute for col {0} returned type={1}", column.columnName, baseColumnType)); if (baseColumnType == "XMLType") { column.columnType = DataTypeInfo.Xml; } } } if (column.columnType == null) { throw new SystemException("Unknown data type"); } column.bufferType = column.columnType.bufferType; column.columnSize = column.columnType.GetFieldSize((int)columnSize); column.precision = (short)column.columnSize; column.scale = decimalDigits; column.IsLong = column.columnType.isLong; column.IsNullable = nullable == 0 ? false : true; rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.ColumnAttribute.SQL_COLUMN_UPDATABLE, IntPtr.Zero, (short)0, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } CLI.Updatable updatable = (CLI.Updatable)(int) iVal; column.IsReadOnly = (updatable == CLI.Updatable.SQL_ATTR_READONLY); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.ColumnAttribute.SQL_COLUMN_KEY, IntPtr.Zero, (short)0, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.IsKey = (((int)iVal) != 0); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.ColumnAttribute.SQL_COLUMN_HIDDEN, IntPtr.Zero, (short)0, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.IsHidden = (((int)iVal) != 0); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.ColumnAttribute.SQL_COLUMN_AUTO_INCREMENT, IntPtr.Zero, (short)0, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.IsAutoIncrement = (((int)iVal) != 0); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.DescriptorField.SQL_DESC_ROWVER, IntPtr.Zero, (short)0, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.IsRowVersion = (((int)iVal) != 0); // TODO: check for unique columns as well. column.IsUnique = false; rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.DescriptorField.SQL_DESC_BASE_COLUMN_NAME, name.Handle, (short)name.Length, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.baseColumnName = Platform.WideCharsToString(name.Handle, length); //System.Console.WriteLine ("name.Length: {0}, length: {1}, baseColumnName: {2}", name.Length, length, column.baseColumnName); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.DescriptorField.SQL_DESC_BASE_TABLE_NAME, name.Handle, (short)name.Length, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.baseTableName = Platform.WideCharsToString(name.Handle, length); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.DescriptorField.SQL_DESC_SCHEMA_NAME, name.Handle, (short)name.Length, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.baseSchemaName = Platform.WideCharsToString(name.Handle, length); rc = (CLI.ReturnCode)CLI.SQLColAttribute( hstmt, (ushort)(i + 1), (ushort)CLI.DescriptorField.SQL_DESC_CATALOG_NAME, name.Handle, (short)name.Length, out length, out iVal); if (rc != CLI.ReturnCode.SQL_SUCCESS) { Diagnostics.HandleResult(rc, this, outerCommand.Connection); } column.baseCatalogName = Platform.WideCharsToString(name.Handle, length); if (column.baseTableName == null || column.baseTableName == "") { column.IsExpression = true; } else { column.IsExpression = false; } } GC.KeepAlive(this); } finally { name.Dispose(); } return(columns); }
public static void DeriveParameters(VirtuosoCommand command) { if (command == null) { throw new ArgumentNullException("command"); } if (command.CommandType != CommandType.StoredProcedure) { throw new InvalidOperationException("DeriveParameters supports only stored procedures."); } VirtuosoConnection connection = (VirtuosoConnection)command.Connection; if (connection == null) { throw new InvalidOperationException("The Connection property is not set."); } if (connection.State == ConnectionState.Closed) { throw new InvalidOperationException("The connection is closed."); } IInnerCommand innerCommand = null; VirtuosoDataReader reader = null; try { innerCommand = connection.innerConnection.CreateInnerCommand(null); innerCommand.GetProcedureColumns(command.CommandText); reader = new VirtuosoDataReader(connection, innerCommand, null, CommandBehavior.Default, false); command.Parameters.Clear(); while (reader.Read()) { CLI.InOutType iotype = (CLI.InOutType)reader.GetInt16(reader.GetOrdinal("COLUMN_TYPE")); ParameterDirection direction; switch (iotype) { case CLI.InOutType.SQL_PARAM_INPUT: direction = ParameterDirection.Input; break; case CLI.InOutType.SQL_PARAM_OUTPUT: direction = ParameterDirection.Output; break; case CLI.InOutType.SQL_PARAM_INPUT_OUTPUT: direction = ParameterDirection.InputOutput; break; case CLI.InOutType.SQL_PARAM_RETURN_VALUE: direction = ParameterDirection.ReturnValue; break; default: #if MONO direction = ParameterDirection.Input; #endif continue; } string name = reader.GetString(reader.GetOrdinal("COLUMN_NAME")); if (name == "" && iotype == CLI.InOutType.SQL_PARAM_RETURN_VALUE) { name = "ReturnValue"; } CLI.SqlType sqlType = (CLI.SqlType)reader.GetInt16(reader.GetOrdinal("DATA_TYPE")); DataType type = DataTypeInfo.MapSqlType(sqlType); if (type == null) { throw new SystemException("Unknown data type"); } int sizeOrdinal = reader.GetOrdinal("COLUMN_SIZE"); if (sizeOrdinal < 0) { sizeOrdinal = reader.GetOrdinal("PRECISION"); } int size = reader.IsDBNull(sizeOrdinal) ? 0 : reader.GetInt32(sizeOrdinal); int scaleOrdinal = reader.GetOrdinal("DECIMAL_DIGITS"); if (scaleOrdinal < 0) { scaleOrdinal = reader.GetOrdinal("SCALE"); } short scale = reader.IsDBNull(scaleOrdinal) ? (short)0 : reader.GetInt16(scaleOrdinal); int nullableOrdinal = reader.GetOrdinal("NULLABLE"); CLI.Nullable nullable = (CLI.Nullable)reader.GetInt16(nullableOrdinal); bool isNullable = (nullable != CLI.Nullable.SQL_NO_NULLS); VirtuosoParameter parameter = (VirtuosoParameter)command.CreateParameter(); parameter.ParameterName = name; parameter.Direction = direction; parameter.VirtDbType = type.vdbType; parameter.Size = type.GetFieldSize(size); parameter.Precision = type.GetPrecision(size); parameter.Scale = (byte)scale; parameter.IsNullable = isNullable; command.Parameters.Add(parameter); } } finally { if (reader != null) { reader.Close(); } if (innerCommand != null) { innerCommand.Dispose(); } } }