Exemple #1
0
        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);
        }
Exemple #2
0
        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();
                }
            }
        }