Odbc32.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / Odbc / Odbc32.cs / 1305376 / Odbc32.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 

namespace System.Data.Odbc { 

    using System;
    using System.Data;
    using System.Data.Common; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.InteropServices; 
    using System.Runtime.ConstrainedExecution;
    using System.Text; 

    internal static class ODBC {

        static internal Exception UnknownSQLType(ODBC32.SQL_TYPE sqltype) { 
            return ADP.Argument(Res.GetString(Res.Odbc_UnknownSQLType, sqltype.ToString()));
        } 
        static internal Exception ConnectionStringTooLong() { 
            return ADP.Argument(Res.GetString(Res.OdbcConnection_ConnectionStringTooLong,  ODBC32.MAX_CONNECTION_STRING_LENGTH));
        } 
        static internal ArgumentException GetSchemaRestrictionRequired() {
            return ADP.Argument(Res.GetString(Res.ODBC_GetSchemaRestrictionRequired));
        }
        static internal ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, int value) { 
            return ADP.ArgumentOutOfRange(Res.GetString(Res.ODBC_NotSupportedEnumerationValue, type.Name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)), type.Name);
        } 
        static internal ArgumentOutOfRangeException NotSupportedCommandType(CommandType value) { 
#if DEBUG
            switch(value) { 
            case CommandType.Text:
            case CommandType.StoredProcedure:
                Debug.Assert(false, "valid CommandType " + value.ToString());
                break; 
            case CommandType.TableDirect:
                break; 
            default: 
                Debug.Assert(false, "invalid CommandType " + value.ToString());
                break; 
            }
#endif
            return ODBC.NotSupportedEnumerationValue(typeof(CommandType), (int)value);
        } 
        static internal ArgumentOutOfRangeException NotSupportedIsolationLevel(IsolationLevel value) {
#if DEBUG 
            switch(value) { 
            case IsolationLevel.Unspecified:
            case IsolationLevel.ReadUncommitted: 
            case IsolationLevel.ReadCommitted:
            case IsolationLevel.RepeatableRead:
            case IsolationLevel.Serializable:
            case IsolationLevel.Snapshot: 
                Debug.Assert(false, "valid IsolationLevel " + value.ToString());
                break; 
            case IsolationLevel.Chaos: 
                break;
            default: 
                Debug.Assert(false, "invalid IsolationLevel " + value.ToString());
                break;
            }
#endif 
            return ODBC.NotSupportedEnumerationValue(typeof(IsolationLevel), (int)value);
        } 
 
        static internal InvalidOperationException NoMappingForSqlTransactionLevel(int value) {
            return ADP.DataAdapter(Res.GetString(Res.Odbc_NoMappingForSqlTransactionLevel, value.ToString(CultureInfo.InvariantCulture))); 
        }

        static internal Exception NegativeArgument() {
            return ADP.Argument(Res.GetString(Res.Odbc_NegativeArgument)); 
        }
        static internal Exception CantSetPropertyOnOpenConnection() { 
            return ADP.InvalidOperation(Res.GetString(Res.Odbc_CantSetPropertyOnOpenConnection)); 
        }
        static internal Exception CantEnableConnectionpooling(ODBC32.RetCode retcode) { 
            return ADP.DataAdapter(Res.GetString(Res.Odbc_CantEnableConnectionpooling, ODBC32.RetcodeToString(retcode)));
        }
        static internal Exception CantAllocateEnvironmentHandle(ODBC32.RetCode retcode) {
            return ADP.DataAdapter(Res.GetString(Res.Odbc_CantAllocateEnvironmentHandle, ODBC32.RetcodeToString(retcode))); 
        }
        static internal Exception FailedToGetDescriptorHandle(ODBC32.RetCode retcode) { 
            return ADP.DataAdapter(Res.GetString(Res.Odbc_FailedToGetDescriptorHandle, ODBC32.RetcodeToString(retcode))); 
        }
        static internal Exception NotInTransaction() { 
            return ADP.InvalidOperation(Res.GetString(Res.Odbc_NotInTransaction));
        }
        static internal Exception UnknownOdbcType(OdbcType odbctype) {
            return ADP.InvalidEnumerationValue(typeof(OdbcType), (int) odbctype); 
        }
        internal const string Pwd = "pwd"; 
 
        static internal void TraceODBC(int level, string method, ODBC32.RetCode retcode) {
            Bid.TraceSqlReturn(" %08X{SQLRETURN}, method=%ls\n", retcode, method); 
        }

        internal static short ShortStringLength(string inputString) {
            return checked((short)ADP.StringLength(inputString)); 
        }
    } 
 

    internal static class ODBC32 { 

        internal enum SQL_HANDLE : short {
            ENV                 = 1,
            DBC                 = 2, 
            STMT                = 3,
            DESC                = 4, 
        } 

        // from .\public\sdk\inc\sqlext.h: and .\public\sdk\inc\sql.h 
        // must be public because it is serialized by OdbcException
        [Serializable]
        public enum RETCODE : int { // must be int instead of short for Everett OdbcException Serializablity.
            SUCCESS             = 0, 
            SUCCESS_WITH_INFO   = 1,
            ERROR               = -1, 
            INVALID_HANDLE      = -2, 
            NO_DATA             = 100,
        } 

        // must be public because it is serialized by OdbcException
        internal enum RetCode : short {
            SUCCESS             = 0, 
            SUCCESS_WITH_INFO   = 1,
            ERROR               = -1, 
            INVALID_HANDLE      = -2, 
            NO_DATA             = 100,
        } 

        internal static string RetcodeToString(RetCode retcode) {
            switch (retcode) {
                case RetCode.SUCCESS:           return "SUCCESS"; 
                case RetCode.SUCCESS_WITH_INFO: return "SUCCESS_WITH_INFO";
                case RetCode.ERROR:             return "ERROR"; 
                case RetCode.INVALID_HANDLE:    return "INVALID_HANDLE"; 
                case RetCode.NO_DATA:           return "NO_DATA";
                default: 
                    Debug.Assert(false, "Unknown enumerator passed to RetcodeToString method");
                    goto case RetCode.ERROR;
            }
        } 

 
 
        internal enum SQL_CONVERT : ushort {
            BIGINT              = 53, 
            BINARY              = 54,
            BIT                 = 55,
            CHAR                = 56,
            DATE                = 57, 
            DECIMAL             = 58,
            DOUBLE              = 59, 
            FLOAT               = 60, 
            INTEGER             = 61,
            LONGVARCHAR         = 62, 
            NUMERIC             = 63,
            REAL                = 64,
            SMALLINT            = 65,
            TIME                = 66, 
            TIMESTAMP           = 67,
            TINYINT             = 68, 
            VARBINARY           = 69, 
            VARCHAR             = 70,
            LONGVARBINARY       = 71, 
        }

        [Flags]
        internal enum SQL_CVT { 
            CHAR                = 0x00000001,
            NUMERIC             = 0x00000002, 
            DECIMAL             = 0x00000004, 
            INTEGER             = 0x00000008,
            SMALLINT            = 0x00000010, 
            FLOAT               = 0x00000020,
            REAL                = 0x00000040,
            DOUBLE              = 0x00000080,
            VARCHAR             = 0x00000100, 
            LONGVARCHAR         = 0x00000200,
            BINARY              = 0x00000400, 
            VARBINARY           = 0x00000800, 
            BIT                 = 0x00001000,
            TINYINT             = 0x00002000, 
            BIGINT              = 0x00004000,
            DATE                = 0x00008000,
            TIME                = 0x00010000,
            TIMESTAMP           = 0x00020000, 
            LONGVARBINARY       = 0x00040000,
            INTERVAL_YEAR_MONTH = 0x00080000, 
            INTERVAL_DAY_TIME   = 0x00100000, 
            WCHAR               = 0x00200000,
            WLONGVARCHAR        = 0x00400000, 
            WVARCHAR            = 0x00800000,
            GUID                = 0x01000000,
        }
 
        internal enum STMT : short {
            CLOSE               =  0, 
            DROP                =  1, 
            UNBIND              =  2,
            RESET_PARAMS        =  3, 
        }

        internal enum SQL_MAX{
            NUMERIC_LEN     =   16, 
        }
 
        internal enum SQL_IS{ 
            POINTER         =   -4,
            INTEGER         =   -6, 
            UINTEGER        =   -5,
            SMALLINT        =   -8,
        }
 

        //SQL Server specific defines 
        // 
        internal enum SQL_HC                          // from Odbcss.h
        { 
            OFF                 = 0,                //  FOR BROWSE columns are hidden
            ON                  = 1,                //  FOR BROWSE columns are exposed
        }
 
        internal enum SQL_NB                          // from Odbcss.h
        { 
            OFF                 = 0,                //  NO_BROWSETABLE is off 
            ON                  = 1,                //  NO_BROWSETABLE is on
        } 

        //  SQLColAttributes driver specific defines.
        //  SQLSet/GetDescField driver specific defines.
        //  Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server driver usage. 
        //
        internal enum SQL_CA_SS                       // from Odbcss.h 
        { 
            BASE                =   1200,           // SQL_CA_SS_BASE
 
            COLUMN_HIDDEN       =   BASE + 11,      //  Column is hidden (FOR BROWSE)
            COLUMN_KEY          =   BASE + 12,      //  Column is key column (FOR BROWSE)
            VARIANT_TYPE        =   BASE + 15,
            VARIANT_SQL_TYPE    =   BASE + 16, 
            VARIANT_SERVER_TYPE =   BASE + 17,
 
        } 
        internal enum SQL_SOPT_SS                     // from Odbcss.h
        { 
            BASE                =   1225,           // SQL_SOPT_SS_BASE
            HIDDEN_COLUMNS      =   BASE + 2,       // Expose FOR BROWSE hidden columns
            NOBROWSETABLE       =   BASE + 3,       // Set NOBROWSETABLE option
        } 

        internal const Int16 SQL_COMMIT              =   0;      //Commit 
        internal const Int16 SQL_ROLLBACK            =   1;      //Abort 

        static internal readonly IntPtr SQL_AUTOCOMMIT_OFF = ADP.PtrZero; 
        static internal readonly IntPtr SQL_AUTOCOMMIT_ON = new IntPtr(1);

        internal enum SQL_TRANSACTION
        { 
            READ_UNCOMMITTED    =   0x00000001,
            READ_COMMITTED      =   0x00000002, 
            REPEATABLE_READ     =   0x00000004, 
            SERIALIZABLE        =   0x00000008,
            SNAPSHOT            =   0x00000020, // VSDD 414121: SQL_TXN_SS_SNAPSHOT == 0x20 (sqlncli.h) 
        }

        internal enum SQL_PARAM
        { 
// unused   TYPE_UNKNOWN        =   0,          // SQL_PARAM_TYPE_UNKNOWN
            INPUT               =   1,          // SQL_PARAM_INPUT 
            INPUT_OUTPUT        =   2,          // SQL_PARAM_INPUT_OUTPUT 
// unused   RESULT_COL          =   3,          // SQL_RESULT_COL
            OUTPUT              =   4,          // SQL_PARAM_OUTPUT 
            RETURN_VALUE        =   5,          // SQL_RETURN_VALUE
        }

        // SQL_API_* values 
        // there are a gillion of these I am only defining the ones currently needed
        // others can be added as needed 
        internal enum SQL_API : ushort 
        {
            SQLCOLUMNS          = 40, 
            SQLEXECDIRECT       = 11,
            SQLGETTYPEINFO      = 47,
            SQLPROCEDURECOLUMNS = 66,
            SQLPROCEDURES       = 67, 
            SQLSTATISTICS       = 53,
            SQLTABLES           = 54, 
        } 

 
        internal enum SQL_DESC : short
        {
            // from sql.h (ODBCVER >= 3.0)
            // 
            COUNT                  = 1001,
            TYPE                   = 1002, 
            LENGTH                 = 1003, 
            OCTET_LENGTH_PTR       = 1004,
            PRECISION              = 1005, 
            SCALE                  = 1006,
            DATETIME_INTERVAL_CODE = 1007,
            NULLABLE               = 1008,
            INDICATOR_PTR          = 1009, 
            DATA_PTR               = 1010,
            NAME                   = 1011, 
            UNNAMED                = 1012, 
            OCTET_LENGTH           = 1013,
            ALLOC_TYPE             = 1099, 

            // from sqlext.h (ODBCVER >= 3.0)
            //
            CONCISE_TYPE           = SQL_COLUMN.TYPE, 
            DISPLAY_SIZE           = SQL_COLUMN.DISPLAY_SIZE,
            UNSIGNED               = SQL_COLUMN.UNSIGNED, 
            UPDATABLE              = SQL_COLUMN.UPDATABLE, 
            AUTO_UNIQUE_VALUE      = SQL_COLUMN.AUTO_INCREMENT,
 
            TYPE_NAME              = SQL_COLUMN.TYPE_NAME,
            TABLE_NAME             = SQL_COLUMN.TABLE_NAME,
            SCHEMA_NAME            = SQL_COLUMN.OWNER_NAME,
            CATALOG_NAME           = SQL_COLUMN.QUALIFIER_NAME, 

            BASE_COLUMN_NAME       = 22, 
            BASE_TABLE_NAME        = 23, 
        }
 
        // ODBC version 2.0 style attributes
        // All IdentifierValues are ODBC 1.0 unless marked differently
        //
        internal enum SQL_COLUMN 
        {
            COUNT                  = 0, 
            NAME                   = 1, 
            TYPE                   = 2,
            LENGTH                 = 3, 
            PRECISION              = 4,
            SCALE                  = 5,
            DISPLAY_SIZE           = 6,
            NULLABLE               = 7, 
            UNSIGNED               = 8,
            MONEY                  = 9, 
            UPDATABLE              = 10, 
            AUTO_INCREMENT         = 11,
            CASE_SENSITIVE         = 12, 
            SEARCHABLE             = 13,
            TYPE_NAME              = 14,
            TABLE_NAME             = 15,    // (ODBC 2.0)
            OWNER_NAME             = 16,    // (ODBC 2.0) 
            QUALIFIER_NAME         = 17,    // (ODBC 2.0)
            LABEL                  = 18, 
        } 

        internal enum SQL_GROUP_BY 
        {
            NOT_SUPPORTED               = 0,    // SQL_GB_NOT_SUPPORTED
            GROUP_BY_EQUALS_SELECT      = 1,    // SQL_GB_GROUP_BY_EQUALS_SELECT
            GROUP_BY_CONTAINS_SELECT    = 2,    // SQL_GB_GROUP_BY_CONTAINS_SELECT 
            NO_RELATION                 = 3,    // SQL_GB_NO_RELATION
            COLLATE                     = 4,    // SQL_GB_COLLATE - added in ODBC 3.0 
        } 

        // values from sqlext.h 
        internal enum SQL_SQL92_RELATIONAL_JOIN_OPERATORS
        {
            CORRESPONDING_CLAUSE   = 0x00000001,    // SQL_SRJO_CORRESPONDING_CLAUSE
            CROSS_JOIN             = 0x00000002,    // SQL_SRJO_CROSS_JOIN 
            EXCEPT_JOIN            = 0x00000004,    // SQL_SRJO_EXCEPT_JOIN
            FULL_OUTER_JOIN        = 0x00000008,    // SQL_SRJO_FULL_OUTER_JOIN 
            INNER_JOIN             = 0x00000010,    // SQL_SRJO_INNER_JOIN 
            INTERSECT_JOIN         = 0x00000020,    // SQL_SRJO_INTERSECT_JOIN
            LEFT_OUTER_JOIN        = 0x00000040,    // SQL_SRJO_LEFT_OUTER_JOIN 
            NATURAL_JOIN           = 0x00000080,    // SQL_SRJO_NATURAL_JOIN
            RIGHT_OUTER_JOIN       = 0x00000100,    // SQL_SRJO_RIGHT_OUTER_JOIN
            UNION_JOIN             = 0x00000200,    // SQL_SRJO_UNION_JOIN
        } 

        // values from sql.h 
        internal enum SQL_OJ_CAPABILITIES 
        {
            LEFT   = 0x00000001,    // SQL_OJ_LEFT 
            RIGHT = 0x00000002,    // SQL_OJ_RIGHT
            FULL  = 0x00000004,    // SQL_OJ_FULL
            NESTED  = 0x00000008,    // SQL_OJ_NESTED
            NOT_ORDERED  = 0x00000010,    // SQL_OJ_NOT_ORDERED 
            INNER  = 0x00000020,    // SQL_OJ_INNER
            ALL_COMPARISON_OPS = 0x00000040,  //SQL_OJ_ALLCOMPARISION+OPS 
        } 

        internal enum SQL_UPDATABLE 
        {
            READONLY                = 0,    // SQL_ATTR_READ_ONLY
            WRITE                   = 1,    // SQL_ATTR_WRITE
            READWRITE_UNKNOWN       = 2,    // SQL_ATTR_READWRITE_UNKNOWN 
        }
 
        internal enum SQL_IDENTIFIER_CASE 
        {
            UPPER       = 1,    // SQL_IC_UPPER 
            LOWER       = 2,    // SQL_IC_LOWER
            SENSITIVE   = 3,    // SQL_IC_SENSITIVE
            MIXED       = 4,    // SQL_IC_MIXED
        } 

        // Uniqueness parameter in the SQLStatistics function 
        internal enum SQL_INDEX : short 
        {
            UNIQUE      = 0, 
            ALL          = 1,
        }

        // Reserved parameter in the SQLStatistics function 
        internal enum SQL_STATISTICS_RESERVED : short
        { 
            QUICK       = 0,                // SQL_QUICK 
            ENSURE      = 1,                // SQL_ENSURE
        } 

        // Identifier type parameter in the SQLSpecialColumns function
        internal enum SQL_SPECIALCOLS : ushort
        { 
            BEST_ROWID      = 1,            // SQL_BEST_ROWID
            ROWVER          = 2,            // SQL_ROWVER 
        } 

        // Scope parameter in the SQLSpecialColumns function 
        internal enum SQL_SCOPE : ushort
        {
            CURROW          = 0,            // SQL_SCOPE_CURROW
            TRANSACTION      = 1,           // SQL_SCOPE_TRANSACTION 
            SESSION          = 2,           // SQL_SCOPE_SESSION
        } 
 
        internal enum SQL_NULLABILITY : ushort
        { 
            NO_NULLS    = 0,                // SQL_NO_NULLS
            NULLABLE    = 1,                // SQL_NULLABLE
            UNKNOWN     = 2,                // SQL_NULLABLE_UNKNOWN
        } 

        internal enum SQL_SEARCHABLE 
        { 
            UNSEARCHABLE        = 0,        // SQL_UNSEARCHABLE
            LIKE_ONLY           = 1,        // SQL_LIKE_ONLY 
            ALL_EXCEPT_LIKE     = 2,        // SQL_ALL_EXCEPT_LIKE
            SEARCHABLE          = 3,        // SQL_SEARCHABLE
        }
 
        internal enum SQL_UNNAMED
        { 
            NAMED    = 0,                   // SQL_NAMED 
            UNNAMED    = 1,                 // SQL_UNNAMED
        } 
// todo:move
// internal constants
// not odbc specific
// 
        internal enum HANDLER
        { 
            IGNORE                  = 0x00000000, 
            THROW                   = 0x00000001,
        } 

        // values for SQLStatistics TYPE column
        internal enum SQL_STATISTICSTYPE
        { 
            TABLE_STAT          = 0,                    // TABLE Statistics
            INDEX_CLUSTERED     = 1,                    // CLUSTERED index statistics 
            INDEX_HASHED        = 2,                    // HASHED index statistics 
            INDEX_OTHER         = 3,                    // OTHER index statistics
        } 

        // values for SQLProcedures PROCEDURE_TYPE column
        internal enum SQL_PROCEDURETYPE
        { 
            UNKNOWN         = 0,                    // procedure is of unknow type
            PROCEDURE       = 1,                    // procedure is a procedure 
            FUNCTION        = 2,                    // procedure is a function 
        }
 
// private constants
// to define data types (see below)
//
        private const Int32 SIGNED_OFFSET   =    -20;    // SQL_SIGNED_OFFSET 
        private const Int32 UNSIGNED_OFFSET =    -22;    // SQL_UNSIGNED_OFFSET
 
        //C Data Types - used when getting data (SQLGetData) 
        internal enum SQL_C : short
        { 
            CHAR            =    1,                     //SQL_C_CHAR
            WCHAR           =   -8,                     //SQL_C_WCHAR
            SLONG           =    4 + SIGNED_OFFSET,     //SQL_C_LONG+SQL_SIGNED_OFFSET
//          ULONG           =    4 + UNSIGNED_OFFSET,   //SQL_C_LONG+SQL_UNSIGNED_OFFSET 
            SSHORT          =    5 + SIGNED_OFFSET,     //SQL_C_SSHORT+SQL_SIGNED_OFFSET
//          USHORT          =    5 + UNSIGNED_OFFSET,   //SQL_C_USHORT+SQL_UNSIGNED_OFFSET 
            REAL            =    7,                     //SQL_C_REAL 
            DOUBLE          =    8,                     //SQL_C_DOUBLE
            BIT             =   -7,                     //SQL_C_BIT 
//          STINYINT        =   -6 + SIGNED_OFFSET,     //SQL_C_STINYINT+SQL_SIGNED_OFFSET
            UTINYINT        =   -6 + UNSIGNED_OFFSET,   //SQL_C_UTINYINT+SQL_UNSIGNED_OFFSET
            SBIGINT         =   -5 + SIGNED_OFFSET,     //SQL_C_SBIGINT+SQL_SIGNED_OFFSET
            UBIGINT         =   -5 + UNSIGNED_OFFSET,   //SQL_C_UBIGINT+SQL_UNSIGNED_OFFSET 
            BINARY          =   -2,                     //SQL_C_BINARY
            TIMESTAMP       =   11,                     //SQL_C_TIMESTAMP 
 
            TYPE_DATE       =   91,                     //SQL_C_TYPE_DATE
            TYPE_TIME       =   92,                     //SQL_C_TYPE_TIME 
            TYPE_TIMESTAMP  =   93,                     //SQL_C_TYPE_TIMESTAMP

            NUMERIC         =    2,                     //SQL_C_NUMERIC
            GUID            =   -11,                    //SQL_C_GUID 
            DEFAULT         =   99,                     //SQL_C_DEFAULT
            ARD_TYPE        =   -99,                    //SQL_ARD_TYPE 
        } 

        //SQL Data Types - returned as column types (SQLColAttribute) 
        internal enum SQL_TYPE : short
        {
            CHAR            =   SQL_C.CHAR,             //SQL_CHAR
            VARCHAR         =   12,                     //SQL_VARCHAR 
            LONGVARCHAR     =   -1,                     //SQL_LONGVARCHAR
            WCHAR           =   SQL_C.WCHAR,            //SQL_WCHAR 
            WVARCHAR        =   -9,                     //SQL_WVARCHAR 
            WLONGVARCHAR    =   -10,                    //SQL_WLONGVARCHAR
            DECIMAL         =   3,                      //SQL_DECIMAL 
            NUMERIC         =   SQL_C.NUMERIC,          //SQL_NUMERIC
            SMALLINT        =   5,                      //SQL_SMALLINT
            INTEGER         =   4,                      //SQL_INTEGER
            REAL            =   SQL_C.REAL,             //SQL_REAL 
            FLOAT           =   6,                      //SQL_FLOAT
            DOUBLE          =   SQL_C.DOUBLE,           //SQL_DOUBLE 
            BIT             =   SQL_C.BIT,              //SQL_BIT 
            TINYINT         =   -6,                     //SQL_TINYINT
            BIGINT          =   -5,                     //SQL_BIGINT 
            BINARY          =   SQL_C.BINARY,           //SQL_BINARY
            VARBINARY       =   -3,                     //SQL_VARBINARY
            LONGVARBINARY   =   -4,                     //SQL_LONGVARBINARY
 
//          DATE            =   9,                      //SQL_DATE
            TYPE_DATE       =   SQL_C.TYPE_DATE,        //SQL_TYPE_DATE 
            TYPE_TIME       =   SQL_C.TYPE_TIME,        //SQL_TYPE_TIME 
            TIMESTAMP       =   SQL_C.TIMESTAMP,        //SQL_TIMESTAMP
            TYPE_TIMESTAMP  =   SQL_C.TYPE_TIMESTAMP,   //SQL_TYPE_TIMESTAMP 


            GUID            =   SQL_C.GUID,             //SQL_GUID
 
        //  from odbcss.h in mdac 9.0 sources!
        //  Driver specific SQL type defines. 
        //  Microsoft has -150 thru -199 reserved for Microsoft SQL Server driver usage. 
        //
            SS_VARIANT =                     -150, 
            SS_UDT =                         -151,
            SS_XML =                         -152,
            SS_UTCDATETIME =                 -153,
            SS_TIME_EX =                     -154, 
        }
 
        internal const Int16 SQL_ALL_TYPES = 0; 
        static internal readonly IntPtr  SQL_HANDLE_NULL  = ADP.PtrZero;
        internal const Int32  SQL_NULL_DATA     = -1;   // sql.h 
        internal const Int32  SQL_NO_TOTAL      = -4;   // sqlext.h

        internal const Int32  SQL_DEFAULT_PARAM= -5;
//      internal const Int32  SQL_IGNORE         = -6; 

// column ordinals for SQLProcedureColumns result set 
// this column ordinals are not defined in any c/c++ header but in the ODBC Programmer's Reference under SQLProcedureColumns 
//
        internal const Int32  COLUMN_NAME = 4; 
        internal const Int32  COLUMN_TYPE = 5;
        internal const Int32  DATA_TYPE = 6;
        internal const Int32  COLUMN_SIZE = 8;
        internal const Int32  DECIMAL_DIGITS = 10; 
        internal const Int32  NUM_PREC_RADIX = 11;
 
        internal enum SQL_ATTR 
        {
            APP_ROW_DESC        =   10010,              // (ODBC 3.0) 
            APP_PARAM_DESC      =   10011,              // (ODBC 3.0)
            IMP_ROW_DESC        =   10012,              // (ODBC 3.0)
            IMP_PARAM_DESC      =   10013,              // (ODBC 3.0)
            METADATA_ID         =   10014,              // (ODBC 3.0) 
            ODBC_VERSION        =   200,
            CONNECTION_POOLING  =   201, 
            AUTOCOMMIT          =   102, 
            TXN_ISOLATION       =   108,
            CURRENT_CATALOG     =   109, 
            LOGIN_TIMEOUT       =   103,
            QUERY_TIMEOUT       =   0,                  // from sqlext.h
            CONNECTION_DEAD     =   1209,               // from sqlext.h
 
            // from sqlncli.h
            SQL_COPT_SS_BASE          = 1200, 
            SQL_COPT_SS_ENLIST_IN_DTC = (SQL_COPT_SS_BASE + 7), 
            SQL_COPT_SS_TXN_ISOLATION = (SQL_COPT_SS_BASE + 27), // Used to set/get any driver-specific or ODBC-defined TXN iso level
        } 

        //SQLGetInfo
        internal enum SQL_INFO : ushort
        { 
            DATA_SOURCE_NAME            = 2,    // SQL_DATA_SOURCE_NAME in sql.h
            SERVER_NAME                 = 13,   // SQL_SERVER_NAME in sql.h 
            DRIVER_NAME                 = 6,    // SQL_DRIVER_NAME as defined in sqlext.h 
            DRIVER_VER                  = 7,    // SQL_DRIVER_VER as defined in sqlext.h
            ODBC_VER                    = 10,   // SQL_ODBC_VER as defined in sqlext.h 
            SEARCH_PATTERN_ESCAPE       = 14,   // SQL_SEARCH_PATTERN_ESCAPE from sql.h
            DBMS_VER                    = 18,
            DBMS_NAME                   = 17,   // SQL_DBMS_NAME as defined in sqlext.h
            IDENTIFIER_CASE             = 28,   // SQL_IDENTIFIER_CASE from sql.h 
            IDENTIFIER_QUOTE_CHAR       = 29,   // SQL_IDENTIFIER_QUOTE_CHAR from sql.h
            CATALOG_NAME_SEPARATOR      = 41,   // SQL_CATALOG_NAME_SEPARATOR 
            DRIVER_ODBC_VER             = 77,   // SQL_DRIVER_ODBC_VER as defined in sqlext.h 
            GROUP_BY                    = 88,   // SQL_GROUP_BY as defined in  sqlext.h
            KEYWORDS                    = 89,   // SQL_KEYWORDS as defined in sqlext.h 
            ORDER_BY_COLUMNS_IN_SELECT  = 90,   // SQL_ORDER_BY_COLUNS_IN_SELECT in sql.h
            QUOTED_IDENTIFIER_CASE      = 93,   // SQL_QUOTED_IDENTIFIER_CASE in sqlext.h
            SQL_OJ_CAPABILITIES_30 = 115, //SQL_OJ_CAPABILITIES from sql.h
            SQL_OJ_CAPABILITIES_20 = 65003, //SQL_OJ_CAPABILITIES from sqlext.h 
            SQL_SQL92_RELATIONAL_JOIN_OPERATORS = 161, //SQL_SQL92_RELATIONAL_JOIN_OPERATORS from sqlext.h
 
        } 

        static internal readonly IntPtr  SQL_OV_ODBC3      =  new IntPtr(3); 
        internal const Int32  SQL_NTS                 = -3;       //flags for null-terminated string

        //Pooling
        static internal readonly IntPtr  SQL_CP_OFF                        =  new IntPtr(0);       //Connection Pooling disabled 
        static internal readonly IntPtr  SQL_CP_ONE_PER_DRIVER  =  new IntPtr(1);       //One pool per driver
        static internal readonly IntPtr  SQL_CP_ONE_PER_HENV     =  new IntPtr(2);       //One pool per environment 
 
        /* values for SQL_ATTR_CONNECTION_DEAD */
        internal const Int32  SQL_CD_TRUE             = 1; 
        internal const Int32  SQL_CD_FALSE            = 0;

        internal const Int32 SQL_DTC_DONE = 0;
        internal const Int32 SQL_IS_POINTER = -4; 
        internal const Int32 SQL_IS_PTR = 1;
 
        internal enum SQL_DRIVER 
        {
            NOPROMPT            = 0, 
            COMPLETE            = 1,
            PROMPT              = 2,
            COMPLETE_REQUIRED   = 3,
        } 

// todo:move 
// internal const. not odbc specific 
//
        // Connection string max length 
        internal const Int32 MAX_CONNECTION_STRING_LENGTH    = 1024;

        // Column set for SQLPrimaryKeys
        internal enum SQL_PRIMARYKEYS : short 
        {
/* 
            CATALOGNAME         = 1,                    // TABLE_CAT 
            SCHEMANAME          = 2,                    // TABLE_SCHEM
            TABLENAME           = 3,                    // TABLE_NAME 
*/
            COLUMNNAME          = 4,                    // COLUMN_NAME
/*
            KEY_SEQ             = 5,                    // KEY_SEQ 
            PKNAME              = 6,                    // PK_NAME
*/ 
        } 

        // Column set for SQLStatistics 
        internal enum SQL_STATISTICS : short
        {
/*
            CATALOGNAME         = 1,                    // TABLE_CAT 
            SCHEMANAME          = 2,                    // TABLE_SCHEM
            TABLENAME           = 3,                    // TABLE_NAME 
            NONUNIQUE           = 4,                    // NON_UNIQUE 
            INDEXQUALIFIER      = 5,                    // INDEX_QUALIFIER
*/ 
            INDEXNAME           = 6,                    // INDEX_NAME
/*
            TYPE                = 7,                    // TYPE
*/ 
            ORDINAL_POSITION    = 8,                    // ORDINAL_POSITION
            COLUMN_NAME         = 9,                    // COLUMN_NAME 
/* 
            ASC_OR_DESC         = 10,                   // ASC_OR_DESC
            CARDINALITY         = 11,                   // CARDINALITY 
            PAGES               = 12,                   // PAGES
            FILTER_CONDITION    = 13,                   // FILTER_CONDITION
*/
        } 

        // Column set for SQLSpecialColumns 
        internal enum SQL_SPECIALCOLUMNSET : short 
        {
/* 
            SCOPE               = 1,                    // SCOPE
*/
            COLUMN_NAME         = 2,                    // COLUMN_NAME
/* 
            DATA_TYPE           = 3,                    // DATA_TYPE
            TYPE_NAME           = 4,                    // TYPE_NAME 
            COLUMN_SIZE         = 5,                    // COLUMN_SIZE 
            BUFFER_LENGTH       = 6,                    // BUFFER_LENGTH
            DECIMAL_DIGITS      = 7,                    // DECIMAL_DIGITS 
            PSEUDO_COLUMN       = 8,                    // PSEUDO_COLUMN
*/
        }
 
        internal const short SQL_DIAG_SQLSTATE = 4;
        internal const short SQL_RESULT_COL = 3; 
 
        // Helpers
        static internal OdbcErrorCollection GetDiagErrors(string source, OdbcHandle hrHandle, RetCode retcode) { 
            OdbcErrorCollection errors = new OdbcErrorCollection();
            GetDiagErrors(errors, source, hrHandle, retcode);
            return errors;
        } 

        static internal void GetDiagErrors(OdbcErrorCollection errors, string source, OdbcHandle hrHandle, RetCode retcode) { 
            Debug.Assert(retcode!=ODBC32.RetCode.INVALID_HANDLE, "retcode must never be ODBC32.RetCode.INVALID_HANDLE"); 
            if (RetCode.SUCCESS != retcode) {
                Int32       NativeError; 
                Int16       iRec            = 0;
                Int16       cchActual       = 0;

                StringBuilder message = new StringBuilder(1024); 
                string sqlState;
                bool moreerrors = true; 
                while(moreerrors) { 

                    ++iRec; 

                    retcode = hrHandle.GetDiagnosticRecord(iRec, out sqlState, message, out NativeError, out cchActual);
                    if ((RetCode.SUCCESS_WITH_INFO == retcode) && (message.Capacity-1 < cchActual)) {
                        message.Capacity = cchActual+1; 
                        retcode = hrHandle.GetDiagnosticRecord(iRec, out sqlState, message, out NativeError, out cchActual);
                    } 
 
                    //Note: SUCCESS_WITH_INFO from SQLGetDiagRec would be because
                    //the buffer is not large enough for the error string. 
                    moreerrors = (retcode == RetCode.SUCCESS || retcode == RetCode.SUCCESS_WITH_INFO);
                    if(moreerrors) {
                        //Sets up the InnerException as well...
                        errors.Add(new OdbcError( 
                            source,
                            message.ToString(), 
                            sqlState, 
                            NativeError
                            ) 
                        );
                    }
                }
            } 
        }
    } 
 
   sealed internal class TypeMap { // MDAC 68988
//      private TypeMap                                           (OdbcType odbcType,         DbType dbType,                Type type,        ODBC32.SQL_TYPE sql_type,       ODBC32.SQL_C sql_c,          ODBC32.SQL_C param_sql_c,   int bsize, int csize, bool signType) 
//      ---------------                                            ------------------         --------------                ----------        -------------------------       -------------------          -------------------------   -----------------------
        static private  readonly TypeMap _BigInt     = new TypeMap(OdbcType.BigInt,           DbType.Int64,                 typeof(Int64),    ODBC32.SQL_TYPE.BIGINT,         ODBC32.SQL_C.SBIGINT,        ODBC32.SQL_C.SBIGINT,         8, 20, true);
        static private  readonly TypeMap _Binary     = new TypeMap(OdbcType.Binary,           DbType.Binary,                typeof(byte[]),   ODBC32.SQL_TYPE.BINARY,         ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _Bit        = new TypeMap(OdbcType.Bit,              DbType.Boolean,               typeof(Boolean),  ODBC32.SQL_TYPE.BIT,            ODBC32.SQL_C.BIT,            ODBC32.SQL_C.BIT,             1,  1, false); 
        static internal readonly TypeMap _Char       = new TypeMap(OdbcType.Char,             DbType.AnsiStringFixedLength, typeof(String),   ODBC32.SQL_TYPE.CHAR,           ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false);
        static private  readonly TypeMap _DateTime   = new TypeMap(OdbcType.DateTime,         DbType.DateTime,              typeof(DateTime), ODBC32.SQL_TYPE.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, 16, 23, false); 
        static private  readonly TypeMap _Date       = new TypeMap(OdbcType.Date,             DbType.Date,                  typeof(DateTime), ODBC32.SQL_TYPE.TYPE_DATE,      ODBC32.SQL_C.TYPE_DATE,      ODBC32.SQL_C.TYPE_DATE,       6, 10, false); 
        static private  readonly TypeMap _Time       = new TypeMap(OdbcType.Time,             DbType.Time,                  typeof(TimeSpan), ODBC32.SQL_TYPE.TYPE_TIME,      ODBC32.SQL_C.TYPE_TIME,      ODBC32.SQL_C.TYPE_TIME,       6, 12, false);
        static private  readonly TypeMap _Decimal    = new TypeMap(OdbcType.Decimal,          DbType.Decimal,               typeof(Decimal),  ODBC32.SQL_TYPE.DECIMAL,        ODBC32.SQL_C.NUMERIC,        ODBC32.SQL_C.NUMERIC,        19, ADP.DecimalMaxPrecision28, false); 
//        static private  readonly TypeMap _Currency   = new TypeMap(OdbcType.Decimal,          DbType.Currency,              typeof(Decimal),  ODBC32.SQL_TYPE.DECIMAL,        ODBC32.SQL_C.NUMERIC,        ODBC32.SQL_C.NUMERIC,        19, ADP.DecimalMaxPrecision28, false);
        static private  readonly TypeMap _Double     = new TypeMap(OdbcType.Double,           DbType.Double,                typeof(Double),   ODBC32.SQL_TYPE.DOUBLE,         ODBC32.SQL_C.DOUBLE,         ODBC32.SQL_C.DOUBLE,          8, 15, false);
        static internal readonly TypeMap _Image      = new TypeMap(OdbcType.Image,            DbType.Binary,                typeof(Byte[]),   ODBC32.SQL_TYPE.LONGVARBINARY,  ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _Int        = new TypeMap(OdbcType.Int,              DbType.Int32,                 typeof(Int32),    ODBC32.SQL_TYPE.INTEGER,        ODBC32.SQL_C.SLONG,          ODBC32.SQL_C.SLONG,           4, 10, true); 
        static private  readonly TypeMap _NChar      = new TypeMap(OdbcType.NChar,            DbType.StringFixedLength,     typeof(String),   ODBC32.SQL_TYPE.WCHAR,          ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.WCHAR,          -1, -1, false);
        static internal readonly TypeMap _NText      = new TypeMap(OdbcType.NText,            DbType.String,                typeof(String),   ODBC32.SQL_TYPE.WLONGVARCHAR,   ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.WCHAR,          -1, -1, false); 
        static private  readonly TypeMap _Numeric    = new TypeMap(OdbcType.Numeric,          DbType.Decimal,               typeof(Decimal),  ODBC32.SQL_TYPE.NUMERIC,        ODBC32.SQL_C.NUMERIC,        ODBC32.SQL_C.NUMERIC,        19, ADP.DecimalMaxPrecision28, false); 
        static internal readonly TypeMap _NVarChar   = new TypeMap(OdbcType.NVarChar,         DbType.String,                typeof(String),   ODBC32.SQL_TYPE.WVARCHAR,       ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.WCHAR,          -1, -1, false);
        static private  readonly TypeMap _Real       = new TypeMap(OdbcType.Real,             DbType.Single,                typeof(Single),   ODBC32.SQL_TYPE.REAL,           ODBC32.SQL_C.REAL,           ODBC32.SQL_C.REAL,            4,  7, false); 
        static private  readonly TypeMap _UniqueId   = new TypeMap(OdbcType.UniqueIdentifier, DbType.Guid,                  typeof(Guid),     ODBC32.SQL_TYPE.GUID,           ODBC32.SQL_C.GUID,           ODBC32.SQL_C.GUID,           16, 36, false);
        static private  readonly TypeMap _SmallDT    = new TypeMap(OdbcType.SmallDateTime,    DbType.DateTime,              typeof(DateTime), ODBC32.SQL_TYPE.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, 16, 23, false);
        static private  readonly TypeMap _SmallInt   = new TypeMap(OdbcType.SmallInt,         DbType.Int16,                 typeof(Int16),    ODBC32.SQL_TYPE.SMALLINT,       ODBC32.SQL_C.SSHORT,         ODBC32.SQL_C.SSHORT,          2,  5, true);
        static internal readonly TypeMap _Text       = new TypeMap(OdbcType.Text,             DbType.AnsiString,            typeof(String),   ODBC32.SQL_TYPE.LONGVARCHAR,    ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false); 
        static private  readonly TypeMap _Timestamp  = new TypeMap(OdbcType.Timestamp,        DbType.Binary,                typeof(Byte[]),   ODBC32.SQL_TYPE.BINARY,         ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _TinyInt    = new TypeMap(OdbcType.TinyInt,          DbType.Byte,                  typeof(Byte),     ODBC32.SQL_TYPE.TINYINT,        ODBC32.SQL_C.UTINYINT,       ODBC32.SQL_C.UTINYINT,        1,  3, true); 
        static private  readonly TypeMap _VarBinary  = new TypeMap(OdbcType.VarBinary,        DbType.Binary,                typeof(Byte[]),   ODBC32.SQL_TYPE.VARBINARY,      ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false); 
        static internal readonly TypeMap _VarChar    = new TypeMap(OdbcType.VarChar,          DbType.AnsiString,            typeof(String),   ODBC32.SQL_TYPE.VARCHAR,        ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false);
        static private  readonly TypeMap _Variant    = new TypeMap(OdbcType.Binary,           DbType.Binary,                typeof(object),   ODBC32.SQL_TYPE.SS_VARIANT,     ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false); 
        static private  readonly TypeMap _UDT        = new TypeMap(OdbcType.Binary,           DbType.Binary,                typeof(object),   ODBC32.SQL_TYPE.SS_UDT,         ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _XML        = new TypeMap(OdbcType.Text,             DbType.AnsiString,            typeof(String),   ODBC32.SQL_TYPE.LONGVARCHAR,    ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false);

        internal readonly OdbcType _odbcType; 
        internal readonly DbType   _dbType;
        internal readonly Type     _type; 
 
        internal readonly ODBC32.SQL_TYPE _sql_type;
        internal readonly ODBC32.SQL_C    _sql_c; 
        internal readonly ODBC32.SQL_C    _param_sql_c;


        internal readonly int _bufferSize;  // fixed length byte size to reserve for buffer 
        internal readonly int _columnSize;  // column size passed to SQLBindParameter
        internal readonly bool _signType;   // this type may be has signature information 
 
        private TypeMap(OdbcType odbcType, DbType dbType, Type type, ODBC32.SQL_TYPE sql_type, ODBC32.SQL_C sql_c, ODBC32.SQL_C param_sql_c, int bsize, int csize, bool signType) {
            _odbcType = odbcType; 
            _dbType = dbType;
            _type = type;

            _sql_type = sql_type; 
            _sql_c = sql_c;
            _param_sql_c = param_sql_c; // alternative sql_c type for parameters 
 
            _bufferSize = bsize;
            _columnSize = csize; 
            _signType = signType;
        }

        static internal TypeMap FromOdbcType(OdbcType odbcType) { 
            switch(odbcType) {
            case OdbcType.BigInt: return _BigInt; 
            case OdbcType.Binary: return _Binary; 
            case OdbcType.Bit: return _Bit;
            case OdbcType.Char: return _Char; 
            case OdbcType.DateTime: return _DateTime;
            case OdbcType.Date: return _Date;
            case OdbcType.Time: return _Time;
            case OdbcType.Double: return _Double; 
            case OdbcType.Decimal: return _Decimal;
            case OdbcType.Image: return _Image; 
            case OdbcType.Int: return _Int; 
            case OdbcType.NChar: return _NChar;
            case OdbcType.NText: return _NText; 
            case OdbcType.Numeric: return _Numeric;
            case OdbcType.NVarChar: return _NVarChar;
            case OdbcType.Real: return _Real;
            case OdbcType.UniqueIdentifier: return _UniqueId; 
            case OdbcType.SmallDateTime: return _SmallDT;
            case OdbcType.SmallInt: return _SmallInt; 
            case OdbcType.Text: return _Text; 
            case OdbcType.Timestamp: return _Timestamp;
            case OdbcType.TinyInt: return _TinyInt; 
            case OdbcType.VarBinary: return _VarBinary;
            case OdbcType.VarChar: return _VarChar;
            default: throw ODBC.UnknownOdbcType(odbcType);
            } 
        }
 
        static internal TypeMap FromDbType(DbType dbType) { 
            switch(dbType) {
            case DbType.AnsiString: return _VarChar; 
            case DbType.AnsiStringFixedLength: return _Char;
            case DbType.Binary:     return _VarBinary;
            case DbType.Byte:       return _TinyInt;
            case DbType.Boolean:    return _Bit; 
            case DbType.Currency:   return _Decimal;
//            case DbType.Currency:   return _Currency; 
            case DbType.Date:       return _Date; 
            case DbType.Time:       return _Time;
            case DbType.DateTime:   return _DateTime; 
            case DbType.Decimal:    return _Decimal;
            case DbType.Double:     return _Double;
            case DbType.Guid:       return _UniqueId;
            case DbType.Int16:      return _SmallInt; 
            case DbType.Int32:      return _Int;
            case DbType.Int64:      return _BigInt; 
            case DbType.Single:     return _Real; 
            case DbType.String:     return _NVarChar;
            case DbType.StringFixedLength: return _NChar; 
            case DbType.Object:
            case DbType.SByte:
            case DbType.UInt16:
            case DbType.UInt32: 
            case DbType.UInt64:
            case DbType.VarNumeric: 
            default: throw ADP.DbTypeNotSupported(dbType, typeof(OdbcType)); 
            }
        } 

        static internal TypeMap FromSystemType(Type dataType) {
            switch(Type.GetTypeCode(dataType)) {
            case TypeCode.Empty:     throw ADP.InvalidDataType(TypeCode.Empty); 
            case TypeCode.Object:
                if (dataType == typeof(System.Byte[])) { 
                    return _VarBinary; 
                }
                else if (dataType == typeof(System.Guid)) { 
                    return _UniqueId;
                }
                else if (dataType == typeof(System.TimeSpan)) {
                    return _Time; 
                }
                else if (dataType == typeof(System.Char[])) { 
                    return _NVarChar; 
                }
                throw ADP.UnknownDataType(dataType); 

            case TypeCode.DBNull:    throw ADP.InvalidDataType(TypeCode.DBNull);
            case TypeCode.Boolean:   return _Bit;
 
// devnote: Char is actually not supported. Our _Char type is actually a fixed length string, not a single character
//            case TypeCode.Char:      return _Char; 
            case TypeCode.SByte:     return _SmallInt; 
            case TypeCode.Byte:      return _TinyInt;
            case TypeCode.Int16:     return _SmallInt; 
            case TypeCode.UInt16:    return _Int;
            case TypeCode.Int32:     return _Int;
            case TypeCode.UInt32:    return _BigInt;
            case TypeCode.Int64:     return _BigInt; 
            case TypeCode.UInt64:    return _Numeric;
            case TypeCode.Single:    return _Real; 
            case TypeCode.Double:    return _Double; 
            case TypeCode.Decimal:   return _Numeric;
            case TypeCode.DateTime:  return _DateTime; 

            case TypeCode.Char:
            case TypeCode.String:    return _NVarChar;
 
            default:                 throw ADP.UnknownDataTypeCode(dataType, Type.GetTypeCode(dataType));
            } 
        } 

        static internal TypeMap FromSqlType(ODBC32.SQL_TYPE sqltype) { 
            switch(sqltype) {
            case ODBC32.SQL_TYPE.CHAR: return _Char;
            case ODBC32.SQL_TYPE.VARCHAR: return _VarChar;
            case ODBC32.SQL_TYPE.LONGVARCHAR: return _Text; 
            case ODBC32.SQL_TYPE.WCHAR: return _NChar;
            case ODBC32.SQL_TYPE.WVARCHAR: return _NVarChar; 
            case ODBC32.SQL_TYPE.WLONGVARCHAR: return _NText; 
            case ODBC32.SQL_TYPE.DECIMAL: return _Decimal;
            case ODBC32.SQL_TYPE.NUMERIC: return _Numeric; 
            case ODBC32.SQL_TYPE.SMALLINT: return _SmallInt;
            case ODBC32.SQL_TYPE.INTEGER: return _Int;
            case ODBC32.SQL_TYPE.REAL: return _Real;
            case ODBC32.SQL_TYPE.FLOAT: return _Double; 
            case ODBC32.SQL_TYPE.DOUBLE: return _Double;
            case ODBC32.SQL_TYPE.BIT: return _Bit; 
            case ODBC32.SQL_TYPE.TINYINT: return _TinyInt; 
            case ODBC32.SQL_TYPE.BIGINT: return _BigInt;
            case ODBC32.SQL_TYPE.BINARY: return _Binary; 
            case ODBC32.SQL_TYPE.VARBINARY: return _VarBinary;
            case ODBC32.SQL_TYPE.LONGVARBINARY: return _Image;
            case ODBC32.SQL_TYPE.TYPE_DATE: return _Date;
            case ODBC32.SQL_TYPE.TYPE_TIME: return _Time; 
            case ODBC32.SQL_TYPE.TIMESTAMP:
            case ODBC32.SQL_TYPE.TYPE_TIMESTAMP: return _DateTime; 
            case ODBC32.SQL_TYPE.GUID: return _UniqueId; 
            case ODBC32.SQL_TYPE.SS_VARIANT: return _Variant;
            case ODBC32.SQL_TYPE.SS_UDT: return _UDT; 
            case ODBC32.SQL_TYPE.SS_XML: return _XML;

            case ODBC32.SQL_TYPE.SS_UTCDATETIME:
            case ODBC32.SQL_TYPE.SS_TIME_EX: 
                Debug.Assert(false, "Extended SqlServer Type that is not supported");
                throw ODBC.UnknownSQLType(sqltype); 
            default: 
                throw ODBC.UnknownSQLType(sqltype);
            } 
        }

        // Upgrade integer datatypes to missinterpretaion of the highest bit
        // (e.g. 0xff could be 255 if unsigned but is -1 if signed) 
        //
        static internal TypeMap UpgradeSignedType(TypeMap typeMap, bool unsigned) { 
            // upgrade unsigned types to be able to hold data that has the highest bit set 
            //
            if (unsigned == true) { 
                switch (typeMap._dbType) {
                    case DbType.Int64:
                        return _Decimal;        // upgrade to decimal
                    case DbType.Int32: 
                        return _BigInt;         // upgrade to 64 bit
                    case DbType.Int16: 
                        return _Int;            // upgrade to 32 bit 
                    default:
                        return typeMap; 
                } // end switch
            }
            else {
                switch (typeMap._dbType) { 
                    case DbType.Byte:
                        return _SmallInt;       // upgrade to 16 bit 
                    default: 
                        return typeMap;
                } // end switch 
            }
        } // end UpgradeSignedType
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 

namespace System.Data.Odbc { 

    using System;
    using System.Data;
    using System.Data.Common; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.InteropServices; 
    using System.Runtime.ConstrainedExecution;
    using System.Text; 

    internal static class ODBC {

        static internal Exception UnknownSQLType(ODBC32.SQL_TYPE sqltype) { 
            return ADP.Argument(Res.GetString(Res.Odbc_UnknownSQLType, sqltype.ToString()));
        } 
        static internal Exception ConnectionStringTooLong() { 
            return ADP.Argument(Res.GetString(Res.OdbcConnection_ConnectionStringTooLong,  ODBC32.MAX_CONNECTION_STRING_LENGTH));
        } 
        static internal ArgumentException GetSchemaRestrictionRequired() {
            return ADP.Argument(Res.GetString(Res.ODBC_GetSchemaRestrictionRequired));
        }
        static internal ArgumentOutOfRangeException NotSupportedEnumerationValue(Type type, int value) { 
            return ADP.ArgumentOutOfRange(Res.GetString(Res.ODBC_NotSupportedEnumerationValue, type.Name, value.ToString(System.Globalization.CultureInfo.InvariantCulture)), type.Name);
        } 
        static internal ArgumentOutOfRangeException NotSupportedCommandType(CommandType value) { 
#if DEBUG
            switch(value) { 
            case CommandType.Text:
            case CommandType.StoredProcedure:
                Debug.Assert(false, "valid CommandType " + value.ToString());
                break; 
            case CommandType.TableDirect:
                break; 
            default: 
                Debug.Assert(false, "invalid CommandType " + value.ToString());
                break; 
            }
#endif
            return ODBC.NotSupportedEnumerationValue(typeof(CommandType), (int)value);
        } 
        static internal ArgumentOutOfRangeException NotSupportedIsolationLevel(IsolationLevel value) {
#if DEBUG 
            switch(value) { 
            case IsolationLevel.Unspecified:
            case IsolationLevel.ReadUncommitted: 
            case IsolationLevel.ReadCommitted:
            case IsolationLevel.RepeatableRead:
            case IsolationLevel.Serializable:
            case IsolationLevel.Snapshot: 
                Debug.Assert(false, "valid IsolationLevel " + value.ToString());
                break; 
            case IsolationLevel.Chaos: 
                break;
            default: 
                Debug.Assert(false, "invalid IsolationLevel " + value.ToString());
                break;
            }
#endif 
            return ODBC.NotSupportedEnumerationValue(typeof(IsolationLevel), (int)value);
        } 
 
        static internal InvalidOperationException NoMappingForSqlTransactionLevel(int value) {
            return ADP.DataAdapter(Res.GetString(Res.Odbc_NoMappingForSqlTransactionLevel, value.ToString(CultureInfo.InvariantCulture))); 
        }

        static internal Exception NegativeArgument() {
            return ADP.Argument(Res.GetString(Res.Odbc_NegativeArgument)); 
        }
        static internal Exception CantSetPropertyOnOpenConnection() { 
            return ADP.InvalidOperation(Res.GetString(Res.Odbc_CantSetPropertyOnOpenConnection)); 
        }
        static internal Exception CantEnableConnectionpooling(ODBC32.RetCode retcode) { 
            return ADP.DataAdapter(Res.GetString(Res.Odbc_CantEnableConnectionpooling, ODBC32.RetcodeToString(retcode)));
        }
        static internal Exception CantAllocateEnvironmentHandle(ODBC32.RetCode retcode) {
            return ADP.DataAdapter(Res.GetString(Res.Odbc_CantAllocateEnvironmentHandle, ODBC32.RetcodeToString(retcode))); 
        }
        static internal Exception FailedToGetDescriptorHandle(ODBC32.RetCode retcode) { 
            return ADP.DataAdapter(Res.GetString(Res.Odbc_FailedToGetDescriptorHandle, ODBC32.RetcodeToString(retcode))); 
        }
        static internal Exception NotInTransaction() { 
            return ADP.InvalidOperation(Res.GetString(Res.Odbc_NotInTransaction));
        }
        static internal Exception UnknownOdbcType(OdbcType odbctype) {
            return ADP.InvalidEnumerationValue(typeof(OdbcType), (int) odbctype); 
        }
        internal const string Pwd = "pwd"; 
 
        static internal void TraceODBC(int level, string method, ODBC32.RetCode retcode) {
            Bid.TraceSqlReturn(" %08X{SQLRETURN}, method=%ls\n", retcode, method); 
        }

        internal static short ShortStringLength(string inputString) {
            return checked((short)ADP.StringLength(inputString)); 
        }
    } 
 

    internal static class ODBC32 { 

        internal enum SQL_HANDLE : short {
            ENV                 = 1,
            DBC                 = 2, 
            STMT                = 3,
            DESC                = 4, 
        } 

        // from .\public\sdk\inc\sqlext.h: and .\public\sdk\inc\sql.h 
        // must be public because it is serialized by OdbcException
        [Serializable]
        public enum RETCODE : int { // must be int instead of short for Everett OdbcException Serializablity.
            SUCCESS             = 0, 
            SUCCESS_WITH_INFO   = 1,
            ERROR               = -1, 
            INVALID_HANDLE      = -2, 
            NO_DATA             = 100,
        } 

        // must be public because it is serialized by OdbcException
        internal enum RetCode : short {
            SUCCESS             = 0, 
            SUCCESS_WITH_INFO   = 1,
            ERROR               = -1, 
            INVALID_HANDLE      = -2, 
            NO_DATA             = 100,
        } 

        internal static string RetcodeToString(RetCode retcode) {
            switch (retcode) {
                case RetCode.SUCCESS:           return "SUCCESS"; 
                case RetCode.SUCCESS_WITH_INFO: return "SUCCESS_WITH_INFO";
                case RetCode.ERROR:             return "ERROR"; 
                case RetCode.INVALID_HANDLE:    return "INVALID_HANDLE"; 
                case RetCode.NO_DATA:           return "NO_DATA";
                default: 
                    Debug.Assert(false, "Unknown enumerator passed to RetcodeToString method");
                    goto case RetCode.ERROR;
            }
        } 

 
 
        internal enum SQL_CONVERT : ushort {
            BIGINT              = 53, 
            BINARY              = 54,
            BIT                 = 55,
            CHAR                = 56,
            DATE                = 57, 
            DECIMAL             = 58,
            DOUBLE              = 59, 
            FLOAT               = 60, 
            INTEGER             = 61,
            LONGVARCHAR         = 62, 
            NUMERIC             = 63,
            REAL                = 64,
            SMALLINT            = 65,
            TIME                = 66, 
            TIMESTAMP           = 67,
            TINYINT             = 68, 
            VARBINARY           = 69, 
            VARCHAR             = 70,
            LONGVARBINARY       = 71, 
        }

        [Flags]
        internal enum SQL_CVT { 
            CHAR                = 0x00000001,
            NUMERIC             = 0x00000002, 
            DECIMAL             = 0x00000004, 
            INTEGER             = 0x00000008,
            SMALLINT            = 0x00000010, 
            FLOAT               = 0x00000020,
            REAL                = 0x00000040,
            DOUBLE              = 0x00000080,
            VARCHAR             = 0x00000100, 
            LONGVARCHAR         = 0x00000200,
            BINARY              = 0x00000400, 
            VARBINARY           = 0x00000800, 
            BIT                 = 0x00001000,
            TINYINT             = 0x00002000, 
            BIGINT              = 0x00004000,
            DATE                = 0x00008000,
            TIME                = 0x00010000,
            TIMESTAMP           = 0x00020000, 
            LONGVARBINARY       = 0x00040000,
            INTERVAL_YEAR_MONTH = 0x00080000, 
            INTERVAL_DAY_TIME   = 0x00100000, 
            WCHAR               = 0x00200000,
            WLONGVARCHAR        = 0x00400000, 
            WVARCHAR            = 0x00800000,
            GUID                = 0x01000000,
        }
 
        internal enum STMT : short {
            CLOSE               =  0, 
            DROP                =  1, 
            UNBIND              =  2,
            RESET_PARAMS        =  3, 
        }

        internal enum SQL_MAX{
            NUMERIC_LEN     =   16, 
        }
 
        internal enum SQL_IS{ 
            POINTER         =   -4,
            INTEGER         =   -6, 
            UINTEGER        =   -5,
            SMALLINT        =   -8,
        }
 

        //SQL Server specific defines 
        // 
        internal enum SQL_HC                          // from Odbcss.h
        { 
            OFF                 = 0,                //  FOR BROWSE columns are hidden
            ON                  = 1,                //  FOR BROWSE columns are exposed
        }
 
        internal enum SQL_NB                          // from Odbcss.h
        { 
            OFF                 = 0,                //  NO_BROWSETABLE is off 
            ON                  = 1,                //  NO_BROWSETABLE is on
        } 

        //  SQLColAttributes driver specific defines.
        //  SQLSet/GetDescField driver specific defines.
        //  Microsoft has 1200 thru 1249 reserved for Microsoft SQL Server driver usage. 
        //
        internal enum SQL_CA_SS                       // from Odbcss.h 
        { 
            BASE                =   1200,           // SQL_CA_SS_BASE
 
            COLUMN_HIDDEN       =   BASE + 11,      //  Column is hidden (FOR BROWSE)
            COLUMN_KEY          =   BASE + 12,      //  Column is key column (FOR BROWSE)
            VARIANT_TYPE        =   BASE + 15,
            VARIANT_SQL_TYPE    =   BASE + 16, 
            VARIANT_SERVER_TYPE =   BASE + 17,
 
        } 
        internal enum SQL_SOPT_SS                     // from Odbcss.h
        { 
            BASE                =   1225,           // SQL_SOPT_SS_BASE
            HIDDEN_COLUMNS      =   BASE + 2,       // Expose FOR BROWSE hidden columns
            NOBROWSETABLE       =   BASE + 3,       // Set NOBROWSETABLE option
        } 

        internal const Int16 SQL_COMMIT              =   0;      //Commit 
        internal const Int16 SQL_ROLLBACK            =   1;      //Abort 

        static internal readonly IntPtr SQL_AUTOCOMMIT_OFF = ADP.PtrZero; 
        static internal readonly IntPtr SQL_AUTOCOMMIT_ON = new IntPtr(1);

        internal enum SQL_TRANSACTION
        { 
            READ_UNCOMMITTED    =   0x00000001,
            READ_COMMITTED      =   0x00000002, 
            REPEATABLE_READ     =   0x00000004, 
            SERIALIZABLE        =   0x00000008,
            SNAPSHOT            =   0x00000020, // VSDD 414121: SQL_TXN_SS_SNAPSHOT == 0x20 (sqlncli.h) 
        }

        internal enum SQL_PARAM
        { 
// unused   TYPE_UNKNOWN        =   0,          // SQL_PARAM_TYPE_UNKNOWN
            INPUT               =   1,          // SQL_PARAM_INPUT 
            INPUT_OUTPUT        =   2,          // SQL_PARAM_INPUT_OUTPUT 
// unused   RESULT_COL          =   3,          // SQL_RESULT_COL
            OUTPUT              =   4,          // SQL_PARAM_OUTPUT 
            RETURN_VALUE        =   5,          // SQL_RETURN_VALUE
        }

        // SQL_API_* values 
        // there are a gillion of these I am only defining the ones currently needed
        // others can be added as needed 
        internal enum SQL_API : ushort 
        {
            SQLCOLUMNS          = 40, 
            SQLEXECDIRECT       = 11,
            SQLGETTYPEINFO      = 47,
            SQLPROCEDURECOLUMNS = 66,
            SQLPROCEDURES       = 67, 
            SQLSTATISTICS       = 53,
            SQLTABLES           = 54, 
        } 

 
        internal enum SQL_DESC : short
        {
            // from sql.h (ODBCVER >= 3.0)
            // 
            COUNT                  = 1001,
            TYPE                   = 1002, 
            LENGTH                 = 1003, 
            OCTET_LENGTH_PTR       = 1004,
            PRECISION              = 1005, 
            SCALE                  = 1006,
            DATETIME_INTERVAL_CODE = 1007,
            NULLABLE               = 1008,
            INDICATOR_PTR          = 1009, 
            DATA_PTR               = 1010,
            NAME                   = 1011, 
            UNNAMED                = 1012, 
            OCTET_LENGTH           = 1013,
            ALLOC_TYPE             = 1099, 

            // from sqlext.h (ODBCVER >= 3.0)
            //
            CONCISE_TYPE           = SQL_COLUMN.TYPE, 
            DISPLAY_SIZE           = SQL_COLUMN.DISPLAY_SIZE,
            UNSIGNED               = SQL_COLUMN.UNSIGNED, 
            UPDATABLE              = SQL_COLUMN.UPDATABLE, 
            AUTO_UNIQUE_VALUE      = SQL_COLUMN.AUTO_INCREMENT,
 
            TYPE_NAME              = SQL_COLUMN.TYPE_NAME,
            TABLE_NAME             = SQL_COLUMN.TABLE_NAME,
            SCHEMA_NAME            = SQL_COLUMN.OWNER_NAME,
            CATALOG_NAME           = SQL_COLUMN.QUALIFIER_NAME, 

            BASE_COLUMN_NAME       = 22, 
            BASE_TABLE_NAME        = 23, 
        }
 
        // ODBC version 2.0 style attributes
        // All IdentifierValues are ODBC 1.0 unless marked differently
        //
        internal enum SQL_COLUMN 
        {
            COUNT                  = 0, 
            NAME                   = 1, 
            TYPE                   = 2,
            LENGTH                 = 3, 
            PRECISION              = 4,
            SCALE                  = 5,
            DISPLAY_SIZE           = 6,
            NULLABLE               = 7, 
            UNSIGNED               = 8,
            MONEY                  = 9, 
            UPDATABLE              = 10, 
            AUTO_INCREMENT         = 11,
            CASE_SENSITIVE         = 12, 
            SEARCHABLE             = 13,
            TYPE_NAME              = 14,
            TABLE_NAME             = 15,    // (ODBC 2.0)
            OWNER_NAME             = 16,    // (ODBC 2.0) 
            QUALIFIER_NAME         = 17,    // (ODBC 2.0)
            LABEL                  = 18, 
        } 

        internal enum SQL_GROUP_BY 
        {
            NOT_SUPPORTED               = 0,    // SQL_GB_NOT_SUPPORTED
            GROUP_BY_EQUALS_SELECT      = 1,    // SQL_GB_GROUP_BY_EQUALS_SELECT
            GROUP_BY_CONTAINS_SELECT    = 2,    // SQL_GB_GROUP_BY_CONTAINS_SELECT 
            NO_RELATION                 = 3,    // SQL_GB_NO_RELATION
            COLLATE                     = 4,    // SQL_GB_COLLATE - added in ODBC 3.0 
        } 

        // values from sqlext.h 
        internal enum SQL_SQL92_RELATIONAL_JOIN_OPERATORS
        {
            CORRESPONDING_CLAUSE   = 0x00000001,    // SQL_SRJO_CORRESPONDING_CLAUSE
            CROSS_JOIN             = 0x00000002,    // SQL_SRJO_CROSS_JOIN 
            EXCEPT_JOIN            = 0x00000004,    // SQL_SRJO_EXCEPT_JOIN
            FULL_OUTER_JOIN        = 0x00000008,    // SQL_SRJO_FULL_OUTER_JOIN 
            INNER_JOIN             = 0x00000010,    // SQL_SRJO_INNER_JOIN 
            INTERSECT_JOIN         = 0x00000020,    // SQL_SRJO_INTERSECT_JOIN
            LEFT_OUTER_JOIN        = 0x00000040,    // SQL_SRJO_LEFT_OUTER_JOIN 
            NATURAL_JOIN           = 0x00000080,    // SQL_SRJO_NATURAL_JOIN
            RIGHT_OUTER_JOIN       = 0x00000100,    // SQL_SRJO_RIGHT_OUTER_JOIN
            UNION_JOIN             = 0x00000200,    // SQL_SRJO_UNION_JOIN
        } 

        // values from sql.h 
        internal enum SQL_OJ_CAPABILITIES 
        {
            LEFT   = 0x00000001,    // SQL_OJ_LEFT 
            RIGHT = 0x00000002,    // SQL_OJ_RIGHT
            FULL  = 0x00000004,    // SQL_OJ_FULL
            NESTED  = 0x00000008,    // SQL_OJ_NESTED
            NOT_ORDERED  = 0x00000010,    // SQL_OJ_NOT_ORDERED 
            INNER  = 0x00000020,    // SQL_OJ_INNER
            ALL_COMPARISON_OPS = 0x00000040,  //SQL_OJ_ALLCOMPARISION+OPS 
        } 

        internal enum SQL_UPDATABLE 
        {
            READONLY                = 0,    // SQL_ATTR_READ_ONLY
            WRITE                   = 1,    // SQL_ATTR_WRITE
            READWRITE_UNKNOWN       = 2,    // SQL_ATTR_READWRITE_UNKNOWN 
        }
 
        internal enum SQL_IDENTIFIER_CASE 
        {
            UPPER       = 1,    // SQL_IC_UPPER 
            LOWER       = 2,    // SQL_IC_LOWER
            SENSITIVE   = 3,    // SQL_IC_SENSITIVE
            MIXED       = 4,    // SQL_IC_MIXED
        } 

        // Uniqueness parameter in the SQLStatistics function 
        internal enum SQL_INDEX : short 
        {
            UNIQUE      = 0, 
            ALL          = 1,
        }

        // Reserved parameter in the SQLStatistics function 
        internal enum SQL_STATISTICS_RESERVED : short
        { 
            QUICK       = 0,                // SQL_QUICK 
            ENSURE      = 1,                // SQL_ENSURE
        } 

        // Identifier type parameter in the SQLSpecialColumns function
        internal enum SQL_SPECIALCOLS : ushort
        { 
            BEST_ROWID      = 1,            // SQL_BEST_ROWID
            ROWVER          = 2,            // SQL_ROWVER 
        } 

        // Scope parameter in the SQLSpecialColumns function 
        internal enum SQL_SCOPE : ushort
        {
            CURROW          = 0,            // SQL_SCOPE_CURROW
            TRANSACTION      = 1,           // SQL_SCOPE_TRANSACTION 
            SESSION          = 2,           // SQL_SCOPE_SESSION
        } 
 
        internal enum SQL_NULLABILITY : ushort
        { 
            NO_NULLS    = 0,                // SQL_NO_NULLS
            NULLABLE    = 1,                // SQL_NULLABLE
            UNKNOWN     = 2,                // SQL_NULLABLE_UNKNOWN
        } 

        internal enum SQL_SEARCHABLE 
        { 
            UNSEARCHABLE        = 0,        // SQL_UNSEARCHABLE
            LIKE_ONLY           = 1,        // SQL_LIKE_ONLY 
            ALL_EXCEPT_LIKE     = 2,        // SQL_ALL_EXCEPT_LIKE
            SEARCHABLE          = 3,        // SQL_SEARCHABLE
        }
 
        internal enum SQL_UNNAMED
        { 
            NAMED    = 0,                   // SQL_NAMED 
            UNNAMED    = 1,                 // SQL_UNNAMED
        } 
// todo:move
// internal constants
// not odbc specific
// 
        internal enum HANDLER
        { 
            IGNORE                  = 0x00000000, 
            THROW                   = 0x00000001,
        } 

        // values for SQLStatistics TYPE column
        internal enum SQL_STATISTICSTYPE
        { 
            TABLE_STAT          = 0,                    // TABLE Statistics
            INDEX_CLUSTERED     = 1,                    // CLUSTERED index statistics 
            INDEX_HASHED        = 2,                    // HASHED index statistics 
            INDEX_OTHER         = 3,                    // OTHER index statistics
        } 

        // values for SQLProcedures PROCEDURE_TYPE column
        internal enum SQL_PROCEDURETYPE
        { 
            UNKNOWN         = 0,                    // procedure is of unknow type
            PROCEDURE       = 1,                    // procedure is a procedure 
            FUNCTION        = 2,                    // procedure is a function 
        }
 
// private constants
// to define data types (see below)
//
        private const Int32 SIGNED_OFFSET   =    -20;    // SQL_SIGNED_OFFSET 
        private const Int32 UNSIGNED_OFFSET =    -22;    // SQL_UNSIGNED_OFFSET
 
        //C Data Types - used when getting data (SQLGetData) 
        internal enum SQL_C : short
        { 
            CHAR            =    1,                     //SQL_C_CHAR
            WCHAR           =   -8,                     //SQL_C_WCHAR
            SLONG           =    4 + SIGNED_OFFSET,     //SQL_C_LONG+SQL_SIGNED_OFFSET
//          ULONG           =    4 + UNSIGNED_OFFSET,   //SQL_C_LONG+SQL_UNSIGNED_OFFSET 
            SSHORT          =    5 + SIGNED_OFFSET,     //SQL_C_SSHORT+SQL_SIGNED_OFFSET
//          USHORT          =    5 + UNSIGNED_OFFSET,   //SQL_C_USHORT+SQL_UNSIGNED_OFFSET 
            REAL            =    7,                     //SQL_C_REAL 
            DOUBLE          =    8,                     //SQL_C_DOUBLE
            BIT             =   -7,                     //SQL_C_BIT 
//          STINYINT        =   -6 + SIGNED_OFFSET,     //SQL_C_STINYINT+SQL_SIGNED_OFFSET
            UTINYINT        =   -6 + UNSIGNED_OFFSET,   //SQL_C_UTINYINT+SQL_UNSIGNED_OFFSET
            SBIGINT         =   -5 + SIGNED_OFFSET,     //SQL_C_SBIGINT+SQL_SIGNED_OFFSET
            UBIGINT         =   -5 + UNSIGNED_OFFSET,   //SQL_C_UBIGINT+SQL_UNSIGNED_OFFSET 
            BINARY          =   -2,                     //SQL_C_BINARY
            TIMESTAMP       =   11,                     //SQL_C_TIMESTAMP 
 
            TYPE_DATE       =   91,                     //SQL_C_TYPE_DATE
            TYPE_TIME       =   92,                     //SQL_C_TYPE_TIME 
            TYPE_TIMESTAMP  =   93,                     //SQL_C_TYPE_TIMESTAMP

            NUMERIC         =    2,                     //SQL_C_NUMERIC
            GUID            =   -11,                    //SQL_C_GUID 
            DEFAULT         =   99,                     //SQL_C_DEFAULT
            ARD_TYPE        =   -99,                    //SQL_ARD_TYPE 
        } 

        //SQL Data Types - returned as column types (SQLColAttribute) 
        internal enum SQL_TYPE : short
        {
            CHAR            =   SQL_C.CHAR,             //SQL_CHAR
            VARCHAR         =   12,                     //SQL_VARCHAR 
            LONGVARCHAR     =   -1,                     //SQL_LONGVARCHAR
            WCHAR           =   SQL_C.WCHAR,            //SQL_WCHAR 
            WVARCHAR        =   -9,                     //SQL_WVARCHAR 
            WLONGVARCHAR    =   -10,                    //SQL_WLONGVARCHAR
            DECIMAL         =   3,                      //SQL_DECIMAL 
            NUMERIC         =   SQL_C.NUMERIC,          //SQL_NUMERIC
            SMALLINT        =   5,                      //SQL_SMALLINT
            INTEGER         =   4,                      //SQL_INTEGER
            REAL            =   SQL_C.REAL,             //SQL_REAL 
            FLOAT           =   6,                      //SQL_FLOAT
            DOUBLE          =   SQL_C.DOUBLE,           //SQL_DOUBLE 
            BIT             =   SQL_C.BIT,              //SQL_BIT 
            TINYINT         =   -6,                     //SQL_TINYINT
            BIGINT          =   -5,                     //SQL_BIGINT 
            BINARY          =   SQL_C.BINARY,           //SQL_BINARY
            VARBINARY       =   -3,                     //SQL_VARBINARY
            LONGVARBINARY   =   -4,                     //SQL_LONGVARBINARY
 
//          DATE            =   9,                      //SQL_DATE
            TYPE_DATE       =   SQL_C.TYPE_DATE,        //SQL_TYPE_DATE 
            TYPE_TIME       =   SQL_C.TYPE_TIME,        //SQL_TYPE_TIME 
            TIMESTAMP       =   SQL_C.TIMESTAMP,        //SQL_TIMESTAMP
            TYPE_TIMESTAMP  =   SQL_C.TYPE_TIMESTAMP,   //SQL_TYPE_TIMESTAMP 


            GUID            =   SQL_C.GUID,             //SQL_GUID
 
        //  from odbcss.h in mdac 9.0 sources!
        //  Driver specific SQL type defines. 
        //  Microsoft has -150 thru -199 reserved for Microsoft SQL Server driver usage. 
        //
            SS_VARIANT =                     -150, 
            SS_UDT =                         -151,
            SS_XML =                         -152,
            SS_UTCDATETIME =                 -153,
            SS_TIME_EX =                     -154, 
        }
 
        internal const Int16 SQL_ALL_TYPES = 0; 
        static internal readonly IntPtr  SQL_HANDLE_NULL  = ADP.PtrZero;
        internal const Int32  SQL_NULL_DATA     = -1;   // sql.h 
        internal const Int32  SQL_NO_TOTAL      = -4;   // sqlext.h

        internal const Int32  SQL_DEFAULT_PARAM= -5;
//      internal const Int32  SQL_IGNORE         = -6; 

// column ordinals for SQLProcedureColumns result set 
// this column ordinals are not defined in any c/c++ header but in the ODBC Programmer's Reference under SQLProcedureColumns 
//
        internal const Int32  COLUMN_NAME = 4; 
        internal const Int32  COLUMN_TYPE = 5;
        internal const Int32  DATA_TYPE = 6;
        internal const Int32  COLUMN_SIZE = 8;
        internal const Int32  DECIMAL_DIGITS = 10; 
        internal const Int32  NUM_PREC_RADIX = 11;
 
        internal enum SQL_ATTR 
        {
            APP_ROW_DESC        =   10010,              // (ODBC 3.0) 
            APP_PARAM_DESC      =   10011,              // (ODBC 3.0)
            IMP_ROW_DESC        =   10012,              // (ODBC 3.0)
            IMP_PARAM_DESC      =   10013,              // (ODBC 3.0)
            METADATA_ID         =   10014,              // (ODBC 3.0) 
            ODBC_VERSION        =   200,
            CONNECTION_POOLING  =   201, 
            AUTOCOMMIT          =   102, 
            TXN_ISOLATION       =   108,
            CURRENT_CATALOG     =   109, 
            LOGIN_TIMEOUT       =   103,
            QUERY_TIMEOUT       =   0,                  // from sqlext.h
            CONNECTION_DEAD     =   1209,               // from sqlext.h
 
            // from sqlncli.h
            SQL_COPT_SS_BASE          = 1200, 
            SQL_COPT_SS_ENLIST_IN_DTC = (SQL_COPT_SS_BASE + 7), 
            SQL_COPT_SS_TXN_ISOLATION = (SQL_COPT_SS_BASE + 27), // Used to set/get any driver-specific or ODBC-defined TXN iso level
        } 

        //SQLGetInfo
        internal enum SQL_INFO : ushort
        { 
            DATA_SOURCE_NAME            = 2,    // SQL_DATA_SOURCE_NAME in sql.h
            SERVER_NAME                 = 13,   // SQL_SERVER_NAME in sql.h 
            DRIVER_NAME                 = 6,    // SQL_DRIVER_NAME as defined in sqlext.h 
            DRIVER_VER                  = 7,    // SQL_DRIVER_VER as defined in sqlext.h
            ODBC_VER                    = 10,   // SQL_ODBC_VER as defined in sqlext.h 
            SEARCH_PATTERN_ESCAPE       = 14,   // SQL_SEARCH_PATTERN_ESCAPE from sql.h
            DBMS_VER                    = 18,
            DBMS_NAME                   = 17,   // SQL_DBMS_NAME as defined in sqlext.h
            IDENTIFIER_CASE             = 28,   // SQL_IDENTIFIER_CASE from sql.h 
            IDENTIFIER_QUOTE_CHAR       = 29,   // SQL_IDENTIFIER_QUOTE_CHAR from sql.h
            CATALOG_NAME_SEPARATOR      = 41,   // SQL_CATALOG_NAME_SEPARATOR 
            DRIVER_ODBC_VER             = 77,   // SQL_DRIVER_ODBC_VER as defined in sqlext.h 
            GROUP_BY                    = 88,   // SQL_GROUP_BY as defined in  sqlext.h
            KEYWORDS                    = 89,   // SQL_KEYWORDS as defined in sqlext.h 
            ORDER_BY_COLUMNS_IN_SELECT  = 90,   // SQL_ORDER_BY_COLUNS_IN_SELECT in sql.h
            QUOTED_IDENTIFIER_CASE      = 93,   // SQL_QUOTED_IDENTIFIER_CASE in sqlext.h
            SQL_OJ_CAPABILITIES_30 = 115, //SQL_OJ_CAPABILITIES from sql.h
            SQL_OJ_CAPABILITIES_20 = 65003, //SQL_OJ_CAPABILITIES from sqlext.h 
            SQL_SQL92_RELATIONAL_JOIN_OPERATORS = 161, //SQL_SQL92_RELATIONAL_JOIN_OPERATORS from sqlext.h
 
        } 

        static internal readonly IntPtr  SQL_OV_ODBC3      =  new IntPtr(3); 
        internal const Int32  SQL_NTS                 = -3;       //flags for null-terminated string

        //Pooling
        static internal readonly IntPtr  SQL_CP_OFF                        =  new IntPtr(0);       //Connection Pooling disabled 
        static internal readonly IntPtr  SQL_CP_ONE_PER_DRIVER  =  new IntPtr(1);       //One pool per driver
        static internal readonly IntPtr  SQL_CP_ONE_PER_HENV     =  new IntPtr(2);       //One pool per environment 
 
        /* values for SQL_ATTR_CONNECTION_DEAD */
        internal const Int32  SQL_CD_TRUE             = 1; 
        internal const Int32  SQL_CD_FALSE            = 0;

        internal const Int32 SQL_DTC_DONE = 0;
        internal const Int32 SQL_IS_POINTER = -4; 
        internal const Int32 SQL_IS_PTR = 1;
 
        internal enum SQL_DRIVER 
        {
            NOPROMPT            = 0, 
            COMPLETE            = 1,
            PROMPT              = 2,
            COMPLETE_REQUIRED   = 3,
        } 

// todo:move 
// internal const. not odbc specific 
//
        // Connection string max length 
        internal const Int32 MAX_CONNECTION_STRING_LENGTH    = 1024;

        // Column set for SQLPrimaryKeys
        internal enum SQL_PRIMARYKEYS : short 
        {
/* 
            CATALOGNAME         = 1,                    // TABLE_CAT 
            SCHEMANAME          = 2,                    // TABLE_SCHEM
            TABLENAME           = 3,                    // TABLE_NAME 
*/
            COLUMNNAME          = 4,                    // COLUMN_NAME
/*
            KEY_SEQ             = 5,                    // KEY_SEQ 
            PKNAME              = 6,                    // PK_NAME
*/ 
        } 

        // Column set for SQLStatistics 
        internal enum SQL_STATISTICS : short
        {
/*
            CATALOGNAME         = 1,                    // TABLE_CAT 
            SCHEMANAME          = 2,                    // TABLE_SCHEM
            TABLENAME           = 3,                    // TABLE_NAME 
            NONUNIQUE           = 4,                    // NON_UNIQUE 
            INDEXQUALIFIER      = 5,                    // INDEX_QUALIFIER
*/ 
            INDEXNAME           = 6,                    // INDEX_NAME
/*
            TYPE                = 7,                    // TYPE
*/ 
            ORDINAL_POSITION    = 8,                    // ORDINAL_POSITION
            COLUMN_NAME         = 9,                    // COLUMN_NAME 
/* 
            ASC_OR_DESC         = 10,                   // ASC_OR_DESC
            CARDINALITY         = 11,                   // CARDINALITY 
            PAGES               = 12,                   // PAGES
            FILTER_CONDITION    = 13,                   // FILTER_CONDITION
*/
        } 

        // Column set for SQLSpecialColumns 
        internal enum SQL_SPECIALCOLUMNSET : short 
        {
/* 
            SCOPE               = 1,                    // SCOPE
*/
            COLUMN_NAME         = 2,                    // COLUMN_NAME
/* 
            DATA_TYPE           = 3,                    // DATA_TYPE
            TYPE_NAME           = 4,                    // TYPE_NAME 
            COLUMN_SIZE         = 5,                    // COLUMN_SIZE 
            BUFFER_LENGTH       = 6,                    // BUFFER_LENGTH
            DECIMAL_DIGITS      = 7,                    // DECIMAL_DIGITS 
            PSEUDO_COLUMN       = 8,                    // PSEUDO_COLUMN
*/
        }
 
        internal const short SQL_DIAG_SQLSTATE = 4;
        internal const short SQL_RESULT_COL = 3; 
 
        // Helpers
        static internal OdbcErrorCollection GetDiagErrors(string source, OdbcHandle hrHandle, RetCode retcode) { 
            OdbcErrorCollection errors = new OdbcErrorCollection();
            GetDiagErrors(errors, source, hrHandle, retcode);
            return errors;
        } 

        static internal void GetDiagErrors(OdbcErrorCollection errors, string source, OdbcHandle hrHandle, RetCode retcode) { 
            Debug.Assert(retcode!=ODBC32.RetCode.INVALID_HANDLE, "retcode must never be ODBC32.RetCode.INVALID_HANDLE"); 
            if (RetCode.SUCCESS != retcode) {
                Int32       NativeError; 
                Int16       iRec            = 0;
                Int16       cchActual       = 0;

                StringBuilder message = new StringBuilder(1024); 
                string sqlState;
                bool moreerrors = true; 
                while(moreerrors) { 

                    ++iRec; 

                    retcode = hrHandle.GetDiagnosticRecord(iRec, out sqlState, message, out NativeError, out cchActual);
                    if ((RetCode.SUCCESS_WITH_INFO == retcode) && (message.Capacity-1 < cchActual)) {
                        message.Capacity = cchActual+1; 
                        retcode = hrHandle.GetDiagnosticRecord(iRec, out sqlState, message, out NativeError, out cchActual);
                    } 
 
                    //Note: SUCCESS_WITH_INFO from SQLGetDiagRec would be because
                    //the buffer is not large enough for the error string. 
                    moreerrors = (retcode == RetCode.SUCCESS || retcode == RetCode.SUCCESS_WITH_INFO);
                    if(moreerrors) {
                        //Sets up the InnerException as well...
                        errors.Add(new OdbcError( 
                            source,
                            message.ToString(), 
                            sqlState, 
                            NativeError
                            ) 
                        );
                    }
                }
            } 
        }
    } 
 
   sealed internal class TypeMap { // MDAC 68988
//      private TypeMap                                           (OdbcType odbcType,         DbType dbType,                Type type,        ODBC32.SQL_TYPE sql_type,       ODBC32.SQL_C sql_c,          ODBC32.SQL_C param_sql_c,   int bsize, int csize, bool signType) 
//      ---------------                                            ------------------         --------------                ----------        -------------------------       -------------------          -------------------------   -----------------------
        static private  readonly TypeMap _BigInt     = new TypeMap(OdbcType.BigInt,           DbType.Int64,                 typeof(Int64),    ODBC32.SQL_TYPE.BIGINT,         ODBC32.SQL_C.SBIGINT,        ODBC32.SQL_C.SBIGINT,         8, 20, true);
        static private  readonly TypeMap _Binary     = new TypeMap(OdbcType.Binary,           DbType.Binary,                typeof(byte[]),   ODBC32.SQL_TYPE.BINARY,         ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _Bit        = new TypeMap(OdbcType.Bit,              DbType.Boolean,               typeof(Boolean),  ODBC32.SQL_TYPE.BIT,            ODBC32.SQL_C.BIT,            ODBC32.SQL_C.BIT,             1,  1, false); 
        static internal readonly TypeMap _Char       = new TypeMap(OdbcType.Char,             DbType.AnsiStringFixedLength, typeof(String),   ODBC32.SQL_TYPE.CHAR,           ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false);
        static private  readonly TypeMap _DateTime   = new TypeMap(OdbcType.DateTime,         DbType.DateTime,              typeof(DateTime), ODBC32.SQL_TYPE.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, 16, 23, false); 
        static private  readonly TypeMap _Date       = new TypeMap(OdbcType.Date,             DbType.Date,                  typeof(DateTime), ODBC32.SQL_TYPE.TYPE_DATE,      ODBC32.SQL_C.TYPE_DATE,      ODBC32.SQL_C.TYPE_DATE,       6, 10, false); 
        static private  readonly TypeMap _Time       = new TypeMap(OdbcType.Time,             DbType.Time,                  typeof(TimeSpan), ODBC32.SQL_TYPE.TYPE_TIME,      ODBC32.SQL_C.TYPE_TIME,      ODBC32.SQL_C.TYPE_TIME,       6, 12, false);
        static private  readonly TypeMap _Decimal    = new TypeMap(OdbcType.Decimal,          DbType.Decimal,               typeof(Decimal),  ODBC32.SQL_TYPE.DECIMAL,        ODBC32.SQL_C.NUMERIC,        ODBC32.SQL_C.NUMERIC,        19, ADP.DecimalMaxPrecision28, false); 
//        static private  readonly TypeMap _Currency   = new TypeMap(OdbcType.Decimal,          DbType.Currency,              typeof(Decimal),  ODBC32.SQL_TYPE.DECIMAL,        ODBC32.SQL_C.NUMERIC,        ODBC32.SQL_C.NUMERIC,        19, ADP.DecimalMaxPrecision28, false);
        static private  readonly TypeMap _Double     = new TypeMap(OdbcType.Double,           DbType.Double,                typeof(Double),   ODBC32.SQL_TYPE.DOUBLE,         ODBC32.SQL_C.DOUBLE,         ODBC32.SQL_C.DOUBLE,          8, 15, false);
        static internal readonly TypeMap _Image      = new TypeMap(OdbcType.Image,            DbType.Binary,                typeof(Byte[]),   ODBC32.SQL_TYPE.LONGVARBINARY,  ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _Int        = new TypeMap(OdbcType.Int,              DbType.Int32,                 typeof(Int32),    ODBC32.SQL_TYPE.INTEGER,        ODBC32.SQL_C.SLONG,          ODBC32.SQL_C.SLONG,           4, 10, true); 
        static private  readonly TypeMap _NChar      = new TypeMap(OdbcType.NChar,            DbType.StringFixedLength,     typeof(String),   ODBC32.SQL_TYPE.WCHAR,          ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.WCHAR,          -1, -1, false);
        static internal readonly TypeMap _NText      = new TypeMap(OdbcType.NText,            DbType.String,                typeof(String),   ODBC32.SQL_TYPE.WLONGVARCHAR,   ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.WCHAR,          -1, -1, false); 
        static private  readonly TypeMap _Numeric    = new TypeMap(OdbcType.Numeric,          DbType.Decimal,               typeof(Decimal),  ODBC32.SQL_TYPE.NUMERIC,        ODBC32.SQL_C.NUMERIC,        ODBC32.SQL_C.NUMERIC,        19, ADP.DecimalMaxPrecision28, false); 
        static internal readonly TypeMap _NVarChar   = new TypeMap(OdbcType.NVarChar,         DbType.String,                typeof(String),   ODBC32.SQL_TYPE.WVARCHAR,       ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.WCHAR,          -1, -1, false);
        static private  readonly TypeMap _Real       = new TypeMap(OdbcType.Real,             DbType.Single,                typeof(Single),   ODBC32.SQL_TYPE.REAL,           ODBC32.SQL_C.REAL,           ODBC32.SQL_C.REAL,            4,  7, false); 
        static private  readonly TypeMap _UniqueId   = new TypeMap(OdbcType.UniqueIdentifier, DbType.Guid,                  typeof(Guid),     ODBC32.SQL_TYPE.GUID,           ODBC32.SQL_C.GUID,           ODBC32.SQL_C.GUID,           16, 36, false);
        static private  readonly TypeMap _SmallDT    = new TypeMap(OdbcType.SmallDateTime,    DbType.DateTime,              typeof(DateTime), ODBC32.SQL_TYPE.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, ODBC32.SQL_C.TYPE_TIMESTAMP, 16, 23, false);
        static private  readonly TypeMap _SmallInt   = new TypeMap(OdbcType.SmallInt,         DbType.Int16,                 typeof(Int16),    ODBC32.SQL_TYPE.SMALLINT,       ODBC32.SQL_C.SSHORT,         ODBC32.SQL_C.SSHORT,          2,  5, true);
        static internal readonly TypeMap _Text       = new TypeMap(OdbcType.Text,             DbType.AnsiString,            typeof(String),   ODBC32.SQL_TYPE.LONGVARCHAR,    ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false); 
        static private  readonly TypeMap _Timestamp  = new TypeMap(OdbcType.Timestamp,        DbType.Binary,                typeof(Byte[]),   ODBC32.SQL_TYPE.BINARY,         ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _TinyInt    = new TypeMap(OdbcType.TinyInt,          DbType.Byte,                  typeof(Byte),     ODBC32.SQL_TYPE.TINYINT,        ODBC32.SQL_C.UTINYINT,       ODBC32.SQL_C.UTINYINT,        1,  3, true); 
        static private  readonly TypeMap _VarBinary  = new TypeMap(OdbcType.VarBinary,        DbType.Binary,                typeof(Byte[]),   ODBC32.SQL_TYPE.VARBINARY,      ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false); 
        static internal readonly TypeMap _VarChar    = new TypeMap(OdbcType.VarChar,          DbType.AnsiString,            typeof(String),   ODBC32.SQL_TYPE.VARCHAR,        ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false);
        static private  readonly TypeMap _Variant    = new TypeMap(OdbcType.Binary,           DbType.Binary,                typeof(object),   ODBC32.SQL_TYPE.SS_VARIANT,     ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false); 
        static private  readonly TypeMap _UDT        = new TypeMap(OdbcType.Binary,           DbType.Binary,                typeof(object),   ODBC32.SQL_TYPE.SS_UDT,         ODBC32.SQL_C.BINARY,         ODBC32.SQL_C.BINARY,         -1, -1, false);
        static private  readonly TypeMap _XML        = new TypeMap(OdbcType.Text,             DbType.AnsiString,            typeof(String),   ODBC32.SQL_TYPE.LONGVARCHAR,    ODBC32.SQL_C.WCHAR,          ODBC32.SQL_C.CHAR,           -1, -1, false);

        internal readonly OdbcType _odbcType; 
        internal readonly DbType   _dbType;
        internal readonly Type     _type; 
 
        internal readonly ODBC32.SQL_TYPE _sql_type;
        internal readonly ODBC32.SQL_C    _sql_c; 
        internal readonly ODBC32.SQL_C    _param_sql_c;


        internal readonly int _bufferSize;  // fixed length byte size to reserve for buffer 
        internal readonly int _columnSize;  // column size passed to SQLBindParameter
        internal readonly bool _signType;   // this type may be has signature information 
 
        private TypeMap(OdbcType odbcType, DbType dbType, Type type, ODBC32.SQL_TYPE sql_type, ODBC32.SQL_C sql_c, ODBC32.SQL_C param_sql_c, int bsize, int csize, bool signType) {
            _odbcType = odbcType; 
            _dbType = dbType;
            _type = type;

            _sql_type = sql_type; 
            _sql_c = sql_c;
            _param_sql_c = param_sql_c; // alternative sql_c type for parameters 
 
            _bufferSize = bsize;
            _columnSize = csize; 
            _signType = signType;
        }

        static internal TypeMap FromOdbcType(OdbcType odbcType) { 
            switch(odbcType) {
            case OdbcType.BigInt: return _BigInt; 
            case OdbcType.Binary: return _Binary; 
            case OdbcType.Bit: return _Bit;
            case OdbcType.Char: return _Char; 
            case OdbcType.DateTime: return _DateTime;
            case OdbcType.Date: return _Date;
            case OdbcType.Time: return _Time;
            case OdbcType.Double: return _Double; 
            case OdbcType.Decimal: return _Decimal;
            case OdbcType.Image: return _Image; 
            case OdbcType.Int: return _Int; 
            case OdbcType.NChar: return _NChar;
            case OdbcType.NText: return _NText; 
            case OdbcType.Numeric: return _Numeric;
            case OdbcType.NVarChar: return _NVarChar;
            case OdbcType.Real: return _Real;
            case OdbcType.UniqueIdentifier: return _UniqueId; 
            case OdbcType.SmallDateTime: return _SmallDT;
            case OdbcType.SmallInt: return _SmallInt; 
            case OdbcType.Text: return _Text; 
            case OdbcType.Timestamp: return _Timestamp;
            case OdbcType.TinyInt: return _TinyInt; 
            case OdbcType.VarBinary: return _VarBinary;
            case OdbcType.VarChar: return _VarChar;
            default: throw ODBC.UnknownOdbcType(odbcType);
            } 
        }
 
        static internal TypeMap FromDbType(DbType dbType) { 
            switch(dbType) {
            case DbType.AnsiString: return _VarChar; 
            case DbType.AnsiStringFixedLength: return _Char;
            case DbType.Binary:     return _VarBinary;
            case DbType.Byte:       return _TinyInt;
            case DbType.Boolean:    return _Bit; 
            case DbType.Currency:   return _Decimal;
//            case DbType.Currency:   return _Currency; 
            case DbType.Date:       return _Date; 
            case DbType.Time:       return _Time;
            case DbType.DateTime:   return _DateTime; 
            case DbType.Decimal:    return _Decimal;
            case DbType.Double:     return _Double;
            case DbType.Guid:       return _UniqueId;
            case DbType.Int16:      return _SmallInt; 
            case DbType.Int32:      return _Int;
            case DbType.Int64:      return _BigInt; 
            case DbType.Single:     return _Real; 
            case DbType.String:     return _NVarChar;
            case DbType.StringFixedLength: return _NChar; 
            case DbType.Object:
            case DbType.SByte:
            case DbType.UInt16:
            case DbType.UInt32: 
            case DbType.UInt64:
            case DbType.VarNumeric: 
            default: throw ADP.DbTypeNotSupported(dbType, typeof(OdbcType)); 
            }
        } 

        static internal TypeMap FromSystemType(Type dataType) {
            switch(Type.GetTypeCode(dataType)) {
            case TypeCode.Empty:     throw ADP.InvalidDataType(TypeCode.Empty); 
            case TypeCode.Object:
                if (dataType == typeof(System.Byte[])) { 
                    return _VarBinary; 
                }
                else if (dataType == typeof(System.Guid)) { 
                    return _UniqueId;
                }
                else if (dataType == typeof(System.TimeSpan)) {
                    return _Time; 
                }
                else if (dataType == typeof(System.Char[])) { 
                    return _NVarChar; 
                }
                throw ADP.UnknownDataType(dataType); 

            case TypeCode.DBNull:    throw ADP.InvalidDataType(TypeCode.DBNull);
            case TypeCode.Boolean:   return _Bit;
 
// devnote: Char is actually not supported. Our _Char type is actually a fixed length string, not a single character
//            case TypeCode.Char:      return _Char; 
            case TypeCode.SByte:     return _SmallInt; 
            case TypeCode.Byte:      return _TinyInt;
            case TypeCode.Int16:     return _SmallInt; 
            case TypeCode.UInt16:    return _Int;
            case TypeCode.Int32:     return _Int;
            case TypeCode.UInt32:    return _BigInt;
            case TypeCode.Int64:     return _BigInt; 
            case TypeCode.UInt64:    return _Numeric;
            case TypeCode.Single:    return _Real; 
            case TypeCode.Double:    return _Double; 
            case TypeCode.Decimal:   return _Numeric;
            case TypeCode.DateTime:  return _DateTime; 

            case TypeCode.Char:
            case TypeCode.String:    return _NVarChar;
 
            default:                 throw ADP.UnknownDataTypeCode(dataType, Type.GetTypeCode(dataType));
            } 
        } 

        static internal TypeMap FromSqlType(ODBC32.SQL_TYPE sqltype) { 
            switch(sqltype) {
            case ODBC32.SQL_TYPE.CHAR: return _Char;
            case ODBC32.SQL_TYPE.VARCHAR: return _VarChar;
            case ODBC32.SQL_TYPE.LONGVARCHAR: return _Text; 
            case ODBC32.SQL_TYPE.WCHAR: return _NChar;
            case ODBC32.SQL_TYPE.WVARCHAR: return _NVarChar; 
            case ODBC32.SQL_TYPE.WLONGVARCHAR: return _NText; 
            case ODBC32.SQL_TYPE.DECIMAL: return _Decimal;
            case ODBC32.SQL_TYPE.NUMERIC: return _Numeric; 
            case ODBC32.SQL_TYPE.SMALLINT: return _SmallInt;
            case ODBC32.SQL_TYPE.INTEGER: return _Int;
            case ODBC32.SQL_TYPE.REAL: return _Real;
            case ODBC32.SQL_TYPE.FLOAT: return _Double; 
            case ODBC32.SQL_TYPE.DOUBLE: return _Double;
            case ODBC32.SQL_TYPE.BIT: return _Bit; 
            case ODBC32.SQL_TYPE.TINYINT: return _TinyInt; 
            case ODBC32.SQL_TYPE.BIGINT: return _BigInt;
            case ODBC32.SQL_TYPE.BINARY: return _Binary; 
            case ODBC32.SQL_TYPE.VARBINARY: return _VarBinary;
            case ODBC32.SQL_TYPE.LONGVARBINARY: return _Image;
            case ODBC32.SQL_TYPE.TYPE_DATE: return _Date;
            case ODBC32.SQL_TYPE.TYPE_TIME: return _Time; 
            case ODBC32.SQL_TYPE.TIMESTAMP:
            case ODBC32.SQL_TYPE.TYPE_TIMESTAMP: return _DateTime; 
            case ODBC32.SQL_TYPE.GUID: return _UniqueId; 
            case ODBC32.SQL_TYPE.SS_VARIANT: return _Variant;
            case ODBC32.SQL_TYPE.SS_UDT: return _UDT; 
            case ODBC32.SQL_TYPE.SS_XML: return _XML;

            case ODBC32.SQL_TYPE.SS_UTCDATETIME:
            case ODBC32.SQL_TYPE.SS_TIME_EX: 
                Debug.Assert(false, "Extended SqlServer Type that is not supported");
                throw ODBC.UnknownSQLType(sqltype); 
            default: 
                throw ODBC.UnknownSQLType(sqltype);
            } 
        }

        // Upgrade integer datatypes to missinterpretaion of the highest bit
        // (e.g. 0xff could be 255 if unsigned but is -1 if signed) 
        //
        static internal TypeMap UpgradeSignedType(TypeMap typeMap, bool unsigned) { 
            // upgrade unsigned types to be able to hold data that has the highest bit set 
            //
            if (unsigned == true) { 
                switch (typeMap._dbType) {
                    case DbType.Int64:
                        return _Decimal;        // upgrade to decimal
                    case DbType.Int32: 
                        return _BigInt;         // upgrade to 64 bit
                    case DbType.Int16: 
                        return _Int;            // upgrade to 32 bit 
                    default:
                        return typeMap; 
                } // end switch
            }
            else {
                switch (typeMap._dbType) { 
                    case DbType.Byte:
                        return _SmallInt;       // upgrade to 16 bit 
                    default: 
                        return typeMap;
                } // end switch 
            }
        } // end UpgradeSignedType
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK