Beispiel #1
0
 // Dynamically load column descriptions as needed.
 private OdbcColumn GetColumn(int ordinal)
 {
     if (cols [ordinal] == null)
     {
         short      bufsize        = 255;
         byte []    colname_buffer = new byte [bufsize];
         string     colname;
         short      colname_size = 0;
         uint       ColSize = 0;
         short      DecDigits = 0, Nullable = 0, dt = 0;
         OdbcReturn ret = libodbc.SQLDescribeCol(hstmt, Convert.ToUInt16(ordinal + 1),
                                                 colname_buffer, bufsize, ref colname_size, ref dt, ref ColSize,
                                                 ref DecDigits, ref Nullable);
         if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
         {
             throw Connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
         }
         colname = RemoveTrailingNullChar(Encoding.Unicode.GetString(colname_buffer));
         OdbcColumn c = new OdbcColumn(colname, (SQL_TYPE)dt);
         c.AllowDBNull = (Nullable != 0);
         c.Digits      = DecDigits;
         if (c.IsVariableSizeType)
         {
             c.MaxLength = (int)ColSize;
         }
         cols [ordinal] = c;
     }
     return(cols [ordinal]);
 }
Beispiel #2
0
        private string GetColumnAttributeStr(int column, FieldIdentifier fieldId)
        {
            OdbcReturn ret = OdbcReturn.Error;

            byte [] buffer  = new byte [255];
            short   outsize = 0;
            int     val     = 0;

            ret = libodbc.SQLColAttribute(hstmt, (short)column, fieldId,
                                          buffer, (short)buffer.Length,
                                          ref outsize, ref val);
            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw new OdbcException(new OdbcError("SQLColAttribute",
                                                      OdbcHandleType.Stmt,
                                                      hstmt));
            }
            string value = string.Empty;

            if (outsize > 0)
            {
                value = Encoding.Default.GetString(buffer, 0, outsize);
            }
            return(value);
        }
Beispiel #3
0
        private void FreeStatement(bool unlink)
        {
            prepared = false;

            if (hstmt == IntPtr.Zero)
            {
                return;
            }

            if (unlink)
            {
                Connection.Unlink(this);
            }

            // free previously allocated handle.
            OdbcReturn ret = libodbc.SQLFreeStmt(hstmt, libodbc.SQLFreeStmtOptions.Close);

            if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
            {
                throw connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
            }

            ret = libodbc.SQLFreeHandle((ushort)OdbcHandleType.Stmt, hstmt);
            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
            }
            hstmt = IntPtr.Zero;
        }
Beispiel #4
0
 // Dynamically load column descriptions as needed.
 private OdbcColumn GetColumn(int ordinal)
 {
     if (cols [ordinal] == null)
     {
         short      bufsize        = 255;
         byte []    colname_buffer = new byte [bufsize];
         string     colname;
         short      colname_size = 0;
         uint       ColSize = 0;
         short      DecDigits = 0, Nullable = 0, dt = 0;
         OdbcReturn ret = libodbc.SQLDescribeCol(hstmt, Convert.ToUInt16(ordinal + 1),
                                                 colname_buffer, bufsize, ref colname_size, ref dt, ref ColSize,
                                                 ref DecDigits, ref Nullable);
         if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
         {
             throw new OdbcException(new OdbcError("SQLDescribeCol", OdbcHandleType.Stmt, hstmt));
         }
         colname = System.Text.Encoding.Default.GetString(colname_buffer);
         colname = colname.Replace((char)0, ' ').Trim();
         OdbcColumn c = new OdbcColumn(colname, (SQL_TYPE)dt);
         c.AllowDBNull = (Nullable != 0);
         c.Digits      = DecDigits;
         if (c.IsVariableSizeType)
         {
             c.MaxLength = (int)ColSize;
         }
         cols [ordinal] = c;
     }
     return(cols [ordinal]);
 }
Beispiel #5
0
        // Set Auto-commit (102) connection attribute
        // [MonoTODO]: nice to have before svn: define libodbc.SQL_IS_UINTEGER = -5
        private static void SetAutoCommit(OdbcConnection conn, bool isAuto)
        {
            OdbcReturn ret = libodbc.SQLSetConnectAttr(conn.hDbc,
                                                       OdbcConnectionAttribute.AutoCommit,
                                                       (IntPtr)(isAuto ? 1 : 0), -5);

            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw conn.CreateOdbcException(OdbcHandleType.Dbc, conn.hDbc);
            }
        }
Beispiel #6
0
        internal OdbcError(string Source, OdbcHandleType HandleType, IntPtr Handle)
        {
            short      buflen = 256, txtlen = 0;
            OdbcReturn ret = OdbcReturn.Success;

            byte [] buf_MsgText  = new byte [buflen];
            byte [] buf_SqlState = new byte [buflen];
            bool    NeedsDecode  = true;

            _source = Source;
            switch (HandleType)
            {
            case OdbcHandleType.Dbc:
                ret = libodbc.SQLError(IntPtr.Zero, Handle, IntPtr.Zero, buf_SqlState,
                                       ref _nativeerror, buf_MsgText, buflen, ref txtlen);
                break;

            case OdbcHandleType.Stmt:
                ret = libodbc.SQLError(IntPtr.Zero, IntPtr.Zero, Handle, buf_SqlState,
                                       ref _nativeerror, buf_MsgText, buflen, ref txtlen);
                break;

            case OdbcHandleType.Env:
                ret = libodbc.SQLError(Handle, IntPtr.Zero, IntPtr.Zero, buf_SqlState,
                                       ref _nativeerror, buf_MsgText, buflen, ref txtlen);
                break;

            default:
                _nativeerror = 1;
                _source      = Source;
                _message     = "Error in " + _source;
                _state       = "";
                NeedsDecode  = false;
                break;
            }
            if (NeedsDecode)
            {
                if (ret != OdbcReturn.Success)
                {
                    _nativeerror = 1;
                    _source      = Source;
                    _message     = "Unable to retrieve error information from ODBC driver manager";
                    _state       = "";
                }
                else
                {
                    _state   = System.Text.Encoding.Default.GetString(buf_SqlState).Replace((char)0, ' ').Trim();
                    _message = System.Text.Encoding.Default.GetString(buf_MsgText).Replace((char)0, ' ').Trim();
                }
            }
        }
Beispiel #7
0
        internal OdbcException CreateOdbcException(OdbcHandleType HandleType, IntPtr Handle)
        {
            short      buflen      = 256;
            short      txtlen      = 0;
            int        nativeerror = 0;
            OdbcReturn ret         = OdbcReturn.Success;

            OdbcErrorCollection errors = new OdbcErrorCollection();

            while (true)
            {
                byte [] buf_MsgText  = new byte [buflen * 2];
                byte [] buf_SqlState = new byte [buflen * 2];

                switch (HandleType)
                {
                case OdbcHandleType.Dbc:
                    ret = libodbc.SQLError(IntPtr.Zero, Handle, IntPtr.Zero, buf_SqlState,
                                           ref nativeerror, buf_MsgText, buflen, ref txtlen);
                    break;

                case OdbcHandleType.Stmt:
                    ret = libodbc.SQLError(IntPtr.Zero, IntPtr.Zero, Handle, buf_SqlState,
                                           ref nativeerror, buf_MsgText, buflen, ref txtlen);
                    break;

                case OdbcHandleType.Env:
                    ret = libodbc.SQLError(Handle, IntPtr.Zero, IntPtr.Zero, buf_SqlState,
                                           ref nativeerror, buf_MsgText, buflen, ref txtlen);
                    break;
                }

                if (ret != OdbcReturn.Success)
                {
                    break;
                }

                string state   = RemoveTrailingNullChar(Encoding.Unicode.GetString(buf_SqlState));
                string message = Encoding.Unicode.GetString(buf_MsgText, 0, txtlen * 2);

                errors.Add(new OdbcError(message, state, nativeerror));
            }

            string source = SafeDriver;

            foreach (OdbcError error in errors)
            {
                error.SetSource(source);
            }
            return(new OdbcException(errors));
        }
Beispiel #8
0
        private static IsolationLevel GetIsolationLevel(OdbcConnection conn)
        {
            int        lev;
            int        length;
            OdbcReturn ret = libodbc.SQLGetConnectAttr(conn.hDbc,
                                                       OdbcConnectionAttribute.TransactionIsolation,
                                                       out lev, 0, out length);

            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw conn.CreateOdbcException(OdbcHandleType.Dbc, conn.hDbc);
            }
            return(MapOdbcIsolationLevel((OdbcIsolationLevel)lev));
        }
Beispiel #9
0
 void Cancel()
 {
     if (hstmt != IntPtr.Zero)
     {
         OdbcReturn Ret = libodbc.SQLCancel(hstmt);
         if ((Ret != OdbcReturn.Success) && (Ret != OdbcReturn.SuccessWithInfo))
         {
             throw new OdbcException(new OdbcError("SQLCancel", OdbcHandleType.Stmt, hstmt));
         }
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
Beispiel #10
0
 void Cancel()
 {
     if (hstmt != IntPtr.Zero)
     {
         OdbcReturn Ret = libodbc.SQLCancel(hstmt);
         if (Ret != OdbcReturn.Success && Ret != OdbcReturn.SuccessWithInfo)
         {
             throw connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
         }
     }
     else
     {
         throw new InvalidOperationException();
     }
 }
Beispiel #11
0
        bool NextResult()
        {
            OdbcReturn ret = OdbcReturn.Success;

            ret = libodbc.SQLMoreResults(hstmt);
            if (ret == OdbcReturn.Success)
            {
                short colcount = 0;
                libodbc.SQLNumResultCols(hstmt, ref colcount);
                cols             = new OdbcColumn [colcount];
                _dataTableSchema = null;                 // force fresh creation
                GetColumns();
            }
            return(ret == OdbcReturn.Success);
        }
Beispiel #12
0
        void Close()
        {
            OdbcReturn ret = OdbcReturn.Error;

            if (State == ConnectionState.Open)
            {
                lock (this) {
                    // close any associated commands
                    // NOTE: we may 'miss' some if the garbage collector has
                    // already started to destroy them.
                    if (linkedCommands != null)
                    {
                        for (int i = 0; i < linkedCommands.Count; i++)
                        {
                            WeakReference wr = (WeakReference)linkedCommands [i];
                            if (wr == null)
                            {
                                continue;
                            }
                            OdbcCommand c = (OdbcCommand)wr.Target;
                            if (c != null)
                            {
                                c.Unlink();
                            }
                        }
                        linkedCommands = null;
                    }

                    // disconnect
                    ret = libodbc.SQLDisconnect(hdbc);
                }
                // There could be OdbcCommands outstanding (see NOTE above); their
                // hstmts will have been freed and therefore will be invalid.
                // However, they will find that their definition of Generation
                // does not match the connection's, so they won't try and free
                // those hstmt.
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
                }

                FreeHandles();
                transaction = null;
                RaiseStateChange(ConnectionState.Open, ConnectionState.Closed);
            }
        }
Beispiel #13
0
        private int ExecuteNonQuery(string method, CommandBehavior behavior, bool createReader)
        {
            int records = 0;

            if (Connection == null)
            {
                throw new InvalidOperationException(string.Format(
                                                        "{0}: Connection is not set.", method));
            }
            if (Connection.State == ConnectionState.Closed)
            {
                throw new InvalidOperationException(string.Format(
                                                        "{0}: Connection state is closed", method));
            }
            if (CommandText.Length == 0)
            {
                throw new InvalidOperationException(string.Format(
                                                        "{0}: CommandText is not set.", method));
            }

            ExecSQL(behavior, createReader, CommandText);

            // .NET documentation says that except for INSERT, UPDATE and
            // DELETE  where the return value is the number of rows affected
            // for the rest of the commands the return value is -1.
            if ((CommandText.ToUpper().IndexOf("UPDATE") != -1) ||
                (CommandText.ToUpper().IndexOf("INSERT") != -1) ||
                (CommandText.ToUpper().IndexOf("DELETE") != -1))
            {
                int        numrows = 0;
                OdbcReturn ret     = libodbc.SQLRowCount(hstmt, ref numrows);
                records = numrows;
            }
            else
            {
                records = -1;
            }

            if (!createReader && !prepared)
            {
                FreeStatement();
            }

            return(records);
        }
Beispiel #14
0
        void Close()
        {
            OdbcReturn ret = OdbcReturn.Error;

            if (State == ConnectionState.Open)
            {
                // disconnect
                ret = libodbc.SQLDisconnect(hdbc);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw new OdbcException(new OdbcError("SQLDisconnect", OdbcHandleType.Dbc, hdbc));
                }

                FreeHandles();
                transaction = null;
                RaiseStateChange(ConnectionState.Open, ConnectionState.Closed);
            }
        }
Beispiel #15
0
        private int GetColumnAttribute(int column, FieldIdentifier fieldId)
        {
            OdbcReturn ret = OdbcReturn.Error;

            byte [] buffer  = new byte [255];
            short   outsize = 0;
            int     val     = 0;

            ret = libodbc.SQLColAttribute(hstmt, (short)column, fieldId,
                                          buffer, (short)buffer.Length,
                                          ref outsize, ref val);
            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw Connection.CreateOdbcException(
                          OdbcHandleType.Stmt, hstmt);
            }
            return(val);
        }
Beispiel #16
0
        internal string GetInfo(OdbcInfo info)
        {
            if (State == ConnectionState.Closed)
            {
                throw new InvalidOperationException("The connection is closed.");
            }

            OdbcReturn ret        = OdbcReturn.Error;
            short      max_length = 512;

            byte [] buffer       = new byte [512];
            short   actualLength = 0;

            ret = libodbc.SQLGetInfo(hdbc, info, buffer, max_length, ref actualLength);
            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
            }
            return(Encoding.Unicode.GetString(buffer, 0, actualLength));
        }
Beispiel #17
0
        void ChangeDatabase(string value)
        {
            IntPtr     ptr = IntPtr.Zero;
            OdbcReturn ret = OdbcReturn.Error;

            try {
                ptr = Marshal.StringToHGlobalUni(value);
                ret = libodbc.SQLSetConnectAttr(hdbc, OdbcConnectionAttribute.CurrentCatalog, ptr, value.Length * 2);

                if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
                {
                    throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
                }
            } finally {
                if (ptr != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(ptr);
                }
            }
        }
Beispiel #18
0
        string GetSafeInfo(OdbcInfo info)
        {
            if (State == ConnectionState.Closed)
            {
                return(null);
            }

            OdbcReturn ret        = OdbcReturn.Error;
            short      max_length = 512;

            byte [] buffer       = new byte [512];
            short   actualLength = 0;

            ret = libodbc.SQLGetInfo(hdbc, info, buffer, max_length, ref actualLength);
            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                return(null);
            }
            return(Encoding.Unicode.GetString(buffer, 0, actualLength));
        }
Beispiel #19
0
        private void FreeStatement(bool unlink)
        {
            prepared = false;

            if (hstmt == IntPtr.Zero)
            {
                return;
            }

            // Normally the command is unlinked from the connection, but during
            // OdbcConnection.Close() this would be pointless and (quadratically)
            // slow.
            if (unlink)
            {
                Connection.Unlink(this);
            }

            // Serialize with respect to the connection's own destruction
            lock (Connection) {
                // If the connection has already called SQLDisconnect then hstmt
                // may have already been freed, in which case it is not safe to
                // use.  Thus the generation check.
                if (Connection.Generation == generation)
                {
                    // free previously allocated handle.
                    OdbcReturn ret = libodbc.SQLFreeStmt(hstmt, libodbc.SQLFreeStmtOptions.Close);
                    if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                    {
                        throw connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
                    }

                    ret = libodbc.SQLFreeHandle((ushort)OdbcHandleType.Stmt, hstmt);
                    if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
                    {
                        throw connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
                    }
                }
                hstmt = IntPtr.Zero;
            }
        }
Beispiel #20
0
        private int ExecuteNonQuery(bool freeHandle)
        {
            int records = 0;

            if (Connection == null)
            {
                throw new InvalidOperationException("No open connection");
            }
            if (Connection.State == ConnectionState.Closed)
            {
                throw new InvalidOperationException("Connection state is closed");
            }
            // FIXME: a third check is mentioned in .NET docs

            ExecSQL(CommandText);

            // .NET documentation says that except for INSERT, UPDATE and
            // DELETE  where the return value is the number of rows affected
            // for the rest of the commands the return value is -1.
            if ((CommandText.ToUpper().IndexOf("UPDATE") != -1) ||
                (CommandText.ToUpper().IndexOf("INSERT") != -1) ||
                (CommandText.ToUpper().IndexOf("DELETE") != -1))
            {
                int        numrows = 0;
                OdbcReturn ret     = libodbc.SQLRowCount(hstmt, ref numrows);
                records = numrows;
            }
            else
            {
                records = -1;
            }

            if (freeHandle && !prepared)
            {
                FreeStatement();
            }

            return(records);
        }
Beispiel #21
0
        private void FreeStatement()
        {
            if (hstmt == IntPtr.Zero)
            {
                return;
            }

            // free previously allocated handle.
            OdbcReturn ret = libodbc.SQLFreeStmt(hstmt, libodbc.SQLFreeStmtOptions.Close);

            if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
            {
                throw new OdbcException(new OdbcError("SQLCloseCursor", OdbcHandleType.Stmt, hstmt));
            }

            ret = libodbc.SQLFreeHandle((ushort)OdbcHandleType.Stmt, hstmt);
            if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
            {
                throw new OdbcException(new OdbcError("SQLFreeHandle", OdbcHandleType.Stmt, hstmt));
            }
            hstmt = IntPtr.Zero;
        }
Beispiel #22
0
        internal string GetInfo(OdbcInfo info)
        {
            if (State == ConnectionState.Closed)
            {
                throw new InvalidOperationException("The connection is closed.");
            }

            OdbcReturn ret        = OdbcReturn.Error;
            short      max_length = 256;

            byte [] buffer       = new byte [max_length];
            short   actualLength = 0;

            ret = libodbc.SQLGetInfo(hdbc, info, buffer, max_length, ref actualLength);
            if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
            {
                throw new OdbcException(new OdbcError("SQLGetInfo",
                                                      OdbcHandleType.Dbc,
                                                      hdbc));
            }

            return(System.Text.Encoding.Default.GetString(buffer).Substring(0, actualLength));
        }
Beispiel #23
0
        /// <remarks>
        /// Load the next row in the current result set.
        /// </remarks>
        private bool NextRow()
        {
            OdbcReturn ret = libodbc.SQLFetch(hstmt);

            if (ret != OdbcReturn.Success)
            {
                currentRow = -1;
            }
            else
            {
                currentRow++;
            }

            // Clear cached values from last record
            foreach (OdbcColumn col in cols)
            {
                if (col != null)
                {
                    col.Value = null;
                }
            }
            return(ret == OdbcReturn.Success);
        }
Beispiel #24
0
        void Close()
        {
            OdbcReturn ret = OdbcReturn.Error;

            if (State == ConnectionState.Open)
            {
                // close any associated commands
                if (linkedCommands != null)
                {
                    for (int i = 0; i < linkedCommands.Count; i++)
                    {
                        WeakReference wr = (WeakReference)linkedCommands [i];
                        if (wr == null)
                        {
                            continue;
                        }
                        OdbcCommand c = (OdbcCommand)wr.Target;
                        if (c != null)
                        {
                            c.Unlink();
                        }
                    }
                    linkedCommands = null;
                }

                // disconnect
                ret = libodbc.SQLDisconnect(hdbc);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
                }

                FreeHandles();
                transaction = null;
                RaiseStateChange(ConnectionState.Open, ConnectionState.Closed);
            }
        }
Beispiel #25
0
        private void FreeHandles()
        {
            OdbcReturn ret = OdbcReturn.Error;

            if (hdbc != IntPtr.Zero)
            {
                ret = libodbc.SQLFreeHandle((ushort)OdbcHandleType.Dbc, hdbc);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
                }
            }
            hdbc = IntPtr.Zero;

            if (henv != IntPtr.Zero)
            {
                ret = libodbc.SQLFreeHandle((ushort)OdbcHandleType.Env, henv);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw CreateOdbcException(OdbcHandleType.Env, henv);
                }
            }
            henv = IntPtr.Zero;
        }
Beispiel #26
0
        void Rollback()
        {
            if (!isOpen)
            {
                throw ExceptionHelper.TransactionNotUsable(GetType());
            }

            if (connection.transaction == this)
            {
                OdbcReturn ret = libodbc.SQLEndTran((short)OdbcHandleType.Dbc, connection.hDbc, 1);
                if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
                {
                    throw connection.CreateOdbcException(OdbcHandleType.Dbc, connection.hDbc);
                }
                SetAutoCommit(connection, true);                     // restore default auto-commit
                connection.transaction = null;
                connection             = null;
                isOpen = false;
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Beispiel #27
0
        void Open()
        {
            if (State == ConnectionState.Open)
            {
                throw new InvalidOperationException();
            }

            OdbcReturn    ret = OdbcReturn.Error;
            OdbcException e   = null;

            try {
                // allocate Environment handle
                ret = libodbc.SQLAllocHandle(OdbcHandleType.Env, IntPtr.Zero, ref henv);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    OdbcErrorCollection errors = new OdbcErrorCollection();
                    errors.Add(new OdbcError(this));
                    e = new OdbcException(errors);
                    MessageHandler(e);
                    throw e;
                }

                ret = libodbc.SQLSetEnvAttr(henv, OdbcEnv.OdbcVersion, (IntPtr)libodbc.SQL_OV_ODBC3, 0);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw CreateOdbcException(OdbcHandleType.Env, henv);
                }

                // allocate connection handle
                ret = libodbc.SQLAllocHandle(OdbcHandleType.Dbc, henv, ref hdbc);
                if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                {
                    throw CreateOdbcException(OdbcHandleType.Env, henv);
                }

                // DSN connection
                if (ConnectionString.ToLower().IndexOf("dsn=") >= 0)
                {
                    string    _uid = string.Empty, _pwd = string.Empty, _dsn = string.Empty;
                    string [] items = ConnectionString.Split(new char[1] {
                        ';'
                    });
                    foreach (string item in items)
                    {
                        string [] parts = item.Split(new char[1] {
                            '='
                        });
                        switch (parts [0].Trim().ToLower())
                        {
                        case "dsn":
                            _dsn = parts [1].Trim();
                            break;

                        case "uid":
                            _uid = parts [1].Trim();
                            break;

                        case "pwd":
                            _pwd = parts [1].Trim();
                            break;
                        }
                    }
                    ret = libodbc.SQLConnect(hdbc, _dsn, -3, _uid, -3, _pwd, -3);
                    if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                    {
                        throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
                    }
                }
                else
                {
                    // DSN-less Connection
                    string OutConnectionString = new String(' ', 1024);
                    short  OutLen = 0;
                    ret = libodbc.SQLDriverConnect(hdbc, IntPtr.Zero, ConnectionString, -3,
                                                   OutConnectionString, (short)OutConnectionString.Length, ref OutLen, 0);
                    if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
                    {
                        throw CreateOdbcException(OdbcHandleType.Dbc, hdbc);
                    }
                }

                RaiseStateChange(ConnectionState.Closed, ConnectionState.Open);
            } catch {
                // free handles if any.
                FreeHandles();
                throw;
            }
            disposed = false;
        }
Beispiel #28
0
        internal OdbcTransaction(OdbcConnection conn, IsolationLevel isolationlevel)
        {
            // Set Auto-commit (102) to false
            SetAutoCommit(conn, false);
            // Handle isolation level
            OdbcIsolationLevel      lev  = OdbcIsolationLevel.ReadCommitted;
            OdbcConnectionAttribute attr = OdbcConnectionAttribute.TransactionIsolation;

            switch (isolationlevel)
            {
            case IsolationLevel.ReadUncommitted:
                lev = OdbcIsolationLevel.ReadUncommitted;
                break;

            case IsolationLevel.ReadCommitted:
                lev = OdbcIsolationLevel.ReadCommitted;
                break;

            case IsolationLevel.RepeatableRead:
                lev = OdbcIsolationLevel.RepeatableRead;
                break;

            case IsolationLevel.Serializable:
                lev = OdbcIsolationLevel.Serializable;
                break;

            case IsolationLevel.Snapshot:
                // badly broken on MS:
                // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=305736
                lev = OdbcIsolationLevel.Snapshot;

                // SQL_ATTR_TXN_ISOLATION can be used to set all other isolation
                // levels except for SQL_TXN_SS_SNAPSHOT. If you want to use snapshot
                // isolation, you must set SQL_TXN_SS_SNAPSHOT through
                // SQL_COPT_SS_TXN_ISOLATION. However, you can retrieve the
                // isolation level by using either SQL_ATTR_TXN_ISOLATION or
                // SQL_COPT_SS_TXN_ISOLATION.
                // Source:
                // http://msdn2.microsoft.com/en-us/library/ms131709.aspx
                attr = OdbcConnectionAttribute.CoptTransactionIsolation;
                break;

            case IsolationLevel.Unspecified:
                // when isolationlevel is not specified, then use
                // default isolation level of the driver and
                // lazy initialize it in the IsolationLevel property
                break;

            case IsolationLevel.Chaos:
                throw new ArgumentOutOfRangeException("IsolationLevel",
                                                      string.Format(CultureInfo.CurrentCulture,
                                                                    "The IsolationLevel enumeration " +
                                                                    "value, {0}, is not supported by " +
                                                                    "the .Net Framework Odbc Data " +
                                                                    "Provider.", (int)isolationlevel));

            default:
                throw new ArgumentOutOfRangeException("IsolationLevel",
                                                      string.Format(CultureInfo.CurrentCulture,
                                                                    "The IsolationLevel enumeration value, {0}, is invalid.",
                                                                    (int)isolationlevel));
            }

            // only change isolation level if it was explictly set
            if (isolationlevel != IsolationLevel.Unspecified)
            {
                // mbd: Getting the return code of the second call to SQLSetConnectAttr is missing from original code!
                OdbcReturn ret = libodbc.SQLSetConnectAttr(conn.hDbc,
                                                           attr, (IntPtr)lev, 0);
                if (ret != OdbcReturn.Success && ret != OdbcReturn.SuccessWithInfo)
                {
                    throw conn.CreateOdbcException(OdbcHandleType.Dbc, conn.hDbc);
                }
            }
            this.isolationlevel = isolationlevel;
            connection          = conn;
            isOpen = true;
        }
Beispiel #29
0
        long GetBytes(int i, long dataIndex, byte[] buffer, int bufferIndex, int length)
        {
            if (IsClosed)
            {
                throw new InvalidOperationException("Reader is not open.");
            }
            if (currentRow == -1)
            {
                throw new InvalidOperationException("No data available.");
            }

            OdbcReturn ret = OdbcReturn.Error;
            bool       copyBuffer = false;
            int        returnVal = 0, outsize = 0;

            byte [] tbuff = new byte [length + 1];

            if (buffer == null)
            {
                length = 0;
            }
            ret = libodbc.SQLGetData(hstmt, (ushort)(i + 1), SQL_C_TYPE.BINARY, tbuff, length,
                                     ref outsize);

            if (ret == OdbcReturn.NoData)
            {
                return(0);
            }

            if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
            {
                throw Connection.CreateOdbcException(OdbcHandleType.Stmt, hstmt);
            }

            OdbcException odbcException = null;

            if ((ret == OdbcReturn.SuccessWithInfo))
            {
                odbcException = Connection.CreateOdbcException(
                    OdbcHandleType.Stmt, hstmt);
            }

            if (buffer == null)
            {
                return(outsize);                //if buffer is null,return length of the field
            }
            if (ret == OdbcReturn.SuccessWithInfo)
            {
                if (outsize == (int)OdbcLengthIndicator.NoTotal)
                {
                    copyBuffer = true;
                }
                else if (outsize == (int)OdbcLengthIndicator.NullData)
                {
                    copyBuffer = false;
                    returnVal  = -1;
                }
                else
                {
                    string sqlstate = odbcException.Errors [0].SQLState;
                    //SQLState: String Data, Right truncated
                    if (sqlstate != libodbc.SQLSTATE_RIGHT_TRUNC)
                    {
                        throw odbcException;
                    }
                    copyBuffer = true;
                }
            }
            else
            {
                copyBuffer = outsize == -1 ? false : true;
                returnVal  = outsize;
            }

            if (copyBuffer)
            {
                if (outsize == (int)OdbcLengthIndicator.NoTotal)
                {
                    int j = 0;
                    while (tbuff [j] != libodbc.C_NULL)
                    {
                        buffer [bufferIndex + j] = tbuff [j];
                        j++;
                    }
                    returnVal = j;
                }
                else
                {
                    int read_bytes = Math.Min(outsize, length);
                    for (int j = 0; j < read_bytes; j++)
                    {
                        buffer [bufferIndex + j] = tbuff [j];
                    }
                    returnVal = read_bytes;
                }
            }
            return(returnVal);
        }
Beispiel #30
0
        long GetBytes(int ordinal, long dataIndex, byte[] buffer, int bufferIndex, int length)
        {
            OdbcReturn ret = OdbcReturn.Error;
            bool       copyBuffer = false;
            int        returnVal = 0, outsize = 0;

            byte [] tbuff = new byte [length + 1];

            length = buffer == null ? 0 : length;
            ret    = libodbc.SQLGetData(hstmt, (ushort)(ordinal + 1), SQL_C_TYPE.BINARY, tbuff, length,
                                        ref outsize);

            if (ret == OdbcReturn.NoData)
            {
                return(0);
            }

            if ((ret != OdbcReturn.Success) && (ret != OdbcReturn.SuccessWithInfo))
            {
                throw new OdbcException(new OdbcError("SQLGetData", OdbcHandleType.Stmt, hstmt));
            }

            OdbcError odbcErr = null;

            if ((ret == OdbcReturn.SuccessWithInfo))
            {
                odbcErr = new OdbcError("SQLGetData", OdbcHandleType.Stmt, hstmt);
            }

            if (buffer == null)
            {
                return(outsize);                //if buffer is null,return length of the field
            }
            if (ret == OdbcReturn.SuccessWithInfo)
            {
                if (outsize == (int)OdbcLengthIndicator.NoTotal)
                {
                    copyBuffer = true;
                }
                else if (outsize == (int)OdbcLengthIndicator.NullData)
                {
                    copyBuffer = false;
                    returnVal  = -1;
                }
                else
                {
                    string sqlstate = odbcErr.SQLState;
                    //SQLState: String Data, Right truncated
                    if (sqlstate != libodbc.SQLSTATE_RIGHT_TRUNC)
                    {
                        throw new OdbcException(odbcErr);
                    }
                    copyBuffer = true;
                }
            }
            else
            {
                copyBuffer = outsize == -1 ? false : true;
                returnVal  = outsize;
            }

            if (copyBuffer)
            {
                int i = 0;
                while (tbuff [i] != libodbc.C_NULL)
                {
                    buffer [bufferIndex + i] = tbuff [i];
                    i++;
                }
                returnVal = i;
            }
            return(returnVal);
        }