]> git.saurik.com Git - wxWidgets.git/blobdiff - src/iodbc/hstmt.c
Yielding from a non-gui thread needs to bail out, otherwise we end up
[wxWidgets.git] / src / iodbc / hstmt.c
index 425fe8b2e299b48d096f6e25aef4fcf6b49310e8..ccab2f4c404eef0f876b8b45d9d48207005ee910 100644 (file)
-/** Query statement object management functions
-
-    Copyright (C) 1995 by Ke Jin <kejin@empress.com>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-**/
-
-#include       <../iodbc/iodbc.h>
-
-#include       <../iodbc/isql.h>
-#include       <../iodbc/isqlext.h>
-
-#include        <../iodbc/dlproc.h>
-
-#include       <../iodbc/herr.h>
-#include       <../iodbc/henv.h>
-#include       <../iodbc/hdbc.h>
-#include       <../iodbc/hstmt.h>
-
-#include       <../iodbc/itrace.h>
-
-RETCODE SQL_API SQLAllocStmt (
-                        HDBC            hdbc,
-                        HSTMT FAR*      phstmt )
+/*
+ *  hstmt.c
+ *
+ *  $Id$
+ *
+ *  Query statement object management functions
+ *
+ *  The iODBC driver manager.
+ *  
+ *  Copyright (C) 1995 by Ke Jin <kejin@empress.com> 
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public
+ *  License along with this library; if not, write to the Free
+ *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include       "config.h"
+
+#include       "isql.h"
+#include       "isqlext.h"
+
+#include        "dlproc.h"
+
+#include       "herr.h"
+#include       "henv.h"
+#include       "hdbc.h"
+#include       "hstmt.h"
+
+#include       "itrace.h"
+
+RETCODE SQL_API 
+SQLAllocStmt (
+    HDBC hdbc,
+    HSTMT FAR * phstmt)
 {
-        DBC_t  FAR*     pdbc    = (DBC_t FAR*)hdbc;
-        STMT_t FAR*     pstmt   = NULL;
-        HPROC           hproc   = SQL_NULL_HPROC;
-        RETCODE         retcode = SQL_SUCCESS;
+  DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
+  STMT_t FAR *pstmt = NULL;
+  HPROC hproc = SQL_NULL_HPROC;
+  RETCODE retcode = SQL_SUCCESS;
 
 #if (ODBCVER >= 0x0300)
-        if( hdbc == SQL_NULL_HDBC
-         || pdbc->type != SQL_HANDLE_DBC )
+  if (hdbc == SQL_NULL_HDBC || pdbc->type != SQL_HANDLE_DBC)
 #else
-        if( hdbc == SQL_NULL_HDBC )
+  if (hdbc == SQL_NULL_HDBC)
 #endif
-        {
-                return SQL_INVALID_HANDLE;
-        }
+    {
+      return SQL_INVALID_HANDLE;
+    }
 
-        if( phstmt == NULL )
-        {
-                PUSHSQLERR ( pdbc->herr, en_S1009 );
+  if (phstmt == NULL)
+    {
+      PUSHSQLERR (pdbc->herr, en_S1009);
 
-                return SQL_ERROR;
-        }
+      return SQL_ERROR;
+    }
 
-        /* check state */
-        switch( pdbc->state )
-        {
-                case en_dbc_connected:
-                case en_dbc_hstmt:
-                        break;
+  /* check state */
+  switch (pdbc->state)
+     {
+     case en_dbc_connected:
+     case en_dbc_hstmt:
+       break;
 
-                case en_dbc_allocated:
-                case en_dbc_needdata:
-                        PUSHSQLERR ( pdbc->herr, en_08003 );
-                        *phstmt = SQL_NULL_HSTMT;
-                        return SQL_ERROR;
+     case en_dbc_allocated:
+     case en_dbc_needdata:
+       PUSHSQLERR (pdbc->herr, en_08003);
+       *phstmt = SQL_NULL_HSTMT;
+       return SQL_ERROR;
 
-                default:
-                        return SQL_INVALID_HANDLE;
-        }
+     default:
+       return SQL_INVALID_HANDLE;
+     }
 
-        pstmt = (STMT_t FAR*)MEM_ALLOC(sizeof(STMT_t));
+  pstmt = (STMT_t FAR *) MEM_ALLOC (sizeof (STMT_t));
 
-        if( pstmt == NULL )
-        {
-                PUSHSQLERR ( pdbc->herr, en_S1001 );
-                *phstmt = SQL_NULL_HSTMT;
+  if (pstmt == NULL)
+    {
+      PUSHSQLERR (pdbc->herr, en_S1001);
+      *phstmt = SQL_NULL_HSTMT;
 
-                return SQL_ERROR;
-        }
+      return SQL_ERROR;
+    }
 
 #if (ODBCVER >= 0x0300)
-        pstmt->type = SQL_HANDLE_STMT;
+  pstmt->type = SQL_HANDLE_STMT;
 #endif
-        /* initiate the object */
-        pstmt->herr = SQL_NULL_HERR;
-        pstmt->hdbc = hdbc;
-        pstmt->state = en_stmt_allocated;
-        pstmt->cursor_state = en_stmt_cursor_no;
-        pstmt->prep_state = 0;
-        pstmt->asyn_on = en_NullProc;
-        pstmt->need_on = en_NullProc;
-
-        /* call driver's function */
+
+  /* initiate the object */
+  pstmt->herr = SQL_NULL_HERR;
+  pstmt->hdbc = hdbc;
+  pstmt->state = en_stmt_allocated;
+  pstmt->cursor_state = en_stmt_cursor_no;
+  pstmt->prep_state = 0;
+  pstmt->asyn_on = en_NullProc;
+  pstmt->need_on = en_NullProc;
+
+  /* call driver's function */
+
 #if (ODBCVER >= 0x0300)
-        hproc = _iodbcdm_getproc( hdbc, en_AllocHandle );
-
-        if( hproc )
-        {
-                CALL_DRIVER ( pstmt->hdbc, hdbc, retcode, hproc,
-                        en_AllocHandle, (
-                        SQL_HANDLE_STMT,
-                        pdbc->dhdbc,
-                        &(pstmt->dhstmt) ) )
-        }
-        else
+  hproc = _iodbcdm_getproc (hdbc, en_AllocHandle);
+
+  if (hproc)
+    {
+      CALL_DRIVER (pstmt->hdbc, hdbc, retcode, hproc, en_AllocHandle, 
+        (SQL_HANDLE_STMT, pdbc->dhdbc, &(pstmt->dhstmt)))
+    }
+  else
 #endif
-        {
-                hproc = _iodbcdm_getproc( hdbc, en_AllocStmt );
 
-                if( hproc == SQL_NULL_HPROC )
-                {
-                        PUSHSQLERR ( pstmt->herr, en_IM001 );
-                        *phstmt = SQL_NULL_HSTMT;
-                        MEM_FREE ( pstmt );
+    {
+      hproc = _iodbcdm_getproc (hdbc, en_AllocStmt);
 
-                        return SQL_ERROR;
-                }
+      if (hproc == SQL_NULL_HPROC)
+       {
+         PUSHSQLERR (pstmt->herr, en_IM001);
+         *phstmt = SQL_NULL_HSTMT;
+         MEM_FREE (pstmt);
 
-                CALL_DRIVER ( hdbc, retcode, hproc, en_AllocStmt, (
-                                pdbc->dhdbc, &(pstmt->dhstmt) ) )
-        }
+         return SQL_ERROR;
+       }
 
-        if( retcode != SQL_SUCCESS
-         && retcode != SQL_SUCCESS_WITH_INFO )
-        {
-                *phstmt = SQL_NULL_HSTMT;
-                MEM_FREE ( pstmt );
+      CALL_DRIVER (hdbc, retcode, hproc, en_AllocStmt, 
+        (pdbc->dhdbc, &(pstmt->dhstmt)))
+    }
 
-                return retcode;
-        }
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      *phstmt = SQL_NULL_HSTMT;
+      MEM_FREE (pstmt);
 
-        /* insert into list */
-        pstmt->next = pdbc->hstmt;
-        pdbc->hstmt = pstmt;
+      return retcode;
+    }
 
-        *phstmt = (HSTMT)pstmt;
+  /* insert into list */
+  pstmt->next = pdbc->hstmt;
+  pdbc->hstmt = pstmt;
 
-        /* state transition */
-        pdbc->state = en_dbc_hstmt;
+  *phstmt = (HSTMT) pstmt;
 
-        return SQL_SUCCESS;
+  /* state transition */
+  pdbc->state = en_dbc_hstmt;
+
+  return SQL_SUCCESS;
 }
 
-RETCODE _iodbcdm_dropstmt( HSTMT hstmt )
+
+RETCODE 
+_iodbcdm_dropstmt (HSTMT hstmt)
 {
-        STMT_t FAR*     pstmt = (STMT_t FAR*)hstmt;
-        STMT_t FAR*     tpstmt;
-        DBC_t  FAR*     pdbc;
-
-        if( hstmt == SQL_NULL_HSTMT )
-        {
-                return SQL_INVALID_HANDLE;
-        }
-
-        pdbc = (DBC_t FAR*)(pstmt->hdbc);
-
-        for(tpstmt  = (STMT_t FAR*)pdbc->hstmt;
-            tpstmt != NULL;
-            tpstmt  = tpstmt->next )
-        {
-                if(tpstmt == pstmt)
-                {
-                        pdbc->hstmt = (HSTMT)pstmt->next;
-                        break;
-                }
-
-                if(tpstmt->next == pstmt)
-                {
-                        tpstmt->next = pstmt->next;
-                        break;
-                }
-        }
-
-        if( tpstmt == NULL )
-        {
-                return SQL_INVALID_HANDLE;
-        }
-
-        _iodbcdm_freesqlerrlist(pstmt->herr);
-        MEM_FREE(hstmt);
-
-        return SQL_SUCCESS;
+  STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
+  STMT_t FAR *tpstmt;
+  DBC_t FAR *pdbc;
+
+  if (hstmt == SQL_NULL_HSTMT)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  pdbc = (DBC_t FAR *) (pstmt->hdbc);
+
+  for (tpstmt = (STMT_t FAR *) pdbc->hstmt;
+      tpstmt != NULL;
+      tpstmt = tpstmt->next)
+    {
+      if (tpstmt == pstmt)
+       {
+         pdbc->hstmt = (HSTMT) pstmt->next;
+         break;
+       }
+
+      if (tpstmt->next == pstmt)
+       {
+         tpstmt->next = pstmt->next;
+         break;
+       }
+    }
+
+  if (tpstmt == NULL)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  _iodbcdm_freesqlerrlist (pstmt->herr);
+  MEM_FREE (hstmt);
+
+  return SQL_SUCCESS;
 }
 
-RETCODE SQL_API SQLFreeStmt (
-                        HSTMT   hstmt,
-                        UWORD   fOption )
+
+RETCODE SQL_API 
+SQLFreeStmt (
+    HSTMT hstmt,
+    UWORD fOption)
 {
-        STMT_t FAR*     pstmt = (STMT_t FAR*)hstmt;
-        STMT_t FAR*     tpstmt;
-        DBC_t  FAR*     pdbc;
-
-        HPROC           hproc = SQL_NULL_HPROC;
-        RETCODE         retcode;
-
-        if( hstmt == SQL_NULL_HSTMT
-         || pstmt->hdbc == SQL_NULL_HDBC )
-        {
-                return SQL_INVALID_HANDLE;
-        }
-
-        pdbc = (DBC_t FAR*)(pstmt->hdbc);
-
-        /* check option */
-        switch( fOption )
-        {
-                case SQL_DROP:
-                case SQL_CLOSE:
-                case SQL_UNBIND:
-                case SQL_RESET_PARAMS:
-                        break;
-
-                default:
-                        PUSHSQLERR ( pstmt->herr, en_S1092 );
-                        return SQL_ERROR;
-        }
-
-        /* check state */
-        if( pstmt->state >= en_stmt_needdata
-         || pstmt->asyn_on != en_NullProc )
-        {
-                PUSHSQLERR ( pstmt->herr, en_S1010 );
-
-                return SQL_ERROR;
-        }
-
-        hproc == SQL_NULL_HPROC;
+  STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
+  STMT_t FAR *tpstmt;
+  DBC_t FAR *pdbc;
 
-#if (ODBCVER >= 0x0300)
-        if( fOption == SQL_DROP )
-        {
-                hproc = _iodbcdm_getproc( pstmt->hdbc, en_FreeHandle );
-
-                if( hproc )
-                {
-                        CALL_DRIVER( pstmt->hdbc, retcode, hproc, en_FreeHandle, (
-                                SQL_HANDLE_STMT, pstmt->dhstmt )
-                }
-        }
-#endif
+  HPROC hproc = SQL_NULL_HPROC;
+  RETCODE retcode;
 
-        if( hproc == SQL_NULL_HPROC )
-        {
-                hproc = _iodbcdm_getproc( pstmt->hdbc, en_FreeStmt);
-
-                if( hproc == SQL_NULL_HPROC )
-                {
-                        PUSHSQLERR ( pstmt->herr, en_IM001 );
-
-                        return SQL_ERROR;
-                }
-
-                CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_FreeStmt, (
-                                pstmt->dhstmt, fOption) )
-        }
-
-        if( retcode != SQL_SUCCESS
-         && retcode != SQL_SUCCESS_WITH_INFO )
-        {
-                return retcode;
-        }
-
-        /* state transition */
-        switch( fOption )
-        {
-                case SQL_DROP:
-                        /* delet this object (ignore return) */
-                        _iodbcdm_dropstmt( hstmt );
-                        break;
-
-                case SQL_CLOSE:
-                        pstmt->cursor_state = en_stmt_cursor_no;
-                        /* This means cursor name set by
-                         * SQLSetCursorName() call will also
-                         * be erased.
-                         */
-
-                        switch( pstmt->state )
-                        {
-                                case en_stmt_allocated:
-                                case en_stmt_prepared:
-                                        break;
-
-                                case en_stmt_executed:
-                                case en_stmt_cursoropen:
-                                case en_stmt_fetched:
-                                case en_stmt_xfetched:
-                                        if( pstmt->prep_state )
-                                        {
-                                                pstmt->state =
-                                                en_stmt_prepared;
-                                        }
-                                        else
-                                        {
-                                                pstmt->state =
-                                                en_stmt_allocated;
-                                        }
-                                        break;
-
-                                default:
-                                        break;
-                        }
-                        break;
-
-                case SQL_UNBIND:
-                case SQL_RESET_PARAMS:
-                default:
-                        break;
-        }
-
-        return retcode;
-}
+  if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
 
-RETCODE SQL_API SQLSetStmtOption (
-                        HSTMT   hstmt,
-                        UWORD   fOption,
-                        UDWORD  vParam )
-{
-        STMT_t FAR*     pstmt   = (STMT_t FAR*)hstmt;
-        HPROC           hproc;
-        int             sqlstat = en_00000;
-        RETCODE         retcode;
-
-        if( hstmt == SQL_NULL_HSTMT
-         || pstmt->hdbc == SQL_NULL_HDBC )
-        {
-                return SQL_INVALID_HANDLE;
-        }
-
-        /* check option */
-        if(/* fOption < SQL_STMT_OPT_MIN || */
-              fOption > SQL_STMT_OPT_MAX )
-        {
-                PUSHSQLERR ( pstmt->herr, en_S1092 );
-
-                return SQL_ERROR;
-        }
-
-        if( fOption == SQL_CONCURRENCY
-         || fOption == SQL_CURSOR_TYPE
-         || fOption == SQL_SIMULATE_CURSOR
-         || fOption == SQL_USE_BOOKMARKS )
-        {
-                if( pstmt->asyn_on != en_NullProc )
-                {
-                        if( pstmt->prep_state )
-                        {
-                                sqlstat = en_S1011;
-                        }
-                }
-                else
-                {
-                        switch( pstmt->state )
-                        {
-                                case en_stmt_prepared:
-                                        sqlstat = en_S1011;
-                                        break;
-
-                                case en_stmt_executed:
-                                case en_stmt_cursoropen:
-                                case en_stmt_fetched:
-                                case en_stmt_xfetched:
-                                        sqlstat = en_24000;
-                                        break;
-
-                                case en_stmt_needdata:
-                                case en_stmt_mustput:
-                                case en_stmt_canput:
-                                        if( pstmt->prep_state )
-                                        {
-                                                sqlstat = en_S1011;
-                                        }
-                                        break;
-
-                                default:
-                                        break;
-                        }
-                }
-        }
-        else
-        {
-                if( pstmt->asyn_on != en_NullProc )
-                {
-                        if( ! pstmt->prep_state )
-                        {
-                                sqlstat = en_S1010;
-                        }
-                }
-                else
-                {
-                        if( pstmt->state >= en_stmt_needdata )
-                        {
-                                sqlstat = en_S1010;
-                        }
-                }
-        }
-
-        if( sqlstat != en_00000 )
-        {
-                PUSHSQLERR ( pstmt->herr, sqlstat );
-
-                return SQL_ERROR;
-        }
-
-        hproc = _iodbcdm_getproc( pstmt->hdbc, en_SetStmtOption );
-
-        if( hproc == SQL_NULL_HPROC )
-        {
-                PUSHSQLERR ( pstmt->herr, en_IM001 );
-
-                return SQL_ERROR;
-        }
-
-        CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_SetStmtOption, (
-                        pstmt->dhstmt, fOption, vParam ) )
-
-#if 0
-        retcode = hproc ( pstmt->dhstmt, fOption, vParam );
-#endif
+  pdbc = (DBC_t FAR *) (pstmt->hdbc);
 
-        return retcode;
-}
+  /* check option */
+  switch (fOption)
+     {
+     case SQL_DROP:
+     case SQL_CLOSE:
+     case SQL_UNBIND:
+     case SQL_RESET_PARAMS:
+       break;
 
-RETCODE SQL_API SQLGetStmtOption (
-                        HSTMT   hstmt,
-                        UWORD   fOption,
-                        PTR     pvParam )
-{
-        STMT_t FAR*     pstmt   = (STMT_t*)hstmt;
-        HPROC           hproc;
-        int             sqlstat = en_00000;
-        RETCODE         retcode;
-
-        if( hstmt == SQL_NULL_HSTMT
-         || pstmt->hdbc == SQL_NULL_HDBC )
-        {
-                return SQL_INVALID_HANDLE;
-        }
-
-        /* check option */
-        if( /* fOption < SQL_STMT_OPT_MIN || */
-               fOption > SQL_STMT_OPT_MAX )
-        {
-                PUSHSQLERR ( pstmt->herr, en_S1092 );
-
-                return SQL_ERROR;
-        }
-
-        /* check state */
-        if( pstmt->state >= en_stmt_needdata
-         || pstmt->asyn_on != en_NullProc )
-        {
-                sqlstat = en_S1010;
-        }
-        else
-        {
-                switch( pstmt->state )
-                {
-                        case en_stmt_allocated:
-                        case en_stmt_prepared:
-                        case en_stmt_executed:
-                        case en_stmt_cursoropen:
-                                if( fOption == SQL_ROW_NUMBER
-                                 || fOption == SQL_GET_BOOKMARK )
-                                {
-                                        sqlstat = en_24000;
-                                }
-                                break;
-
-                        default:
-                                break;
-                }
-        }
-
-        if( sqlstat != en_00000 )
-        {
-                PUSHSQLERR ( pstmt->herr, sqlstat );
-
-                return SQL_ERROR;
-        }
-
-        hproc = _iodbcdm_getproc( pstmt->hdbc, en_GetStmtOption);
-
-        if( hproc == SQL_NULL_HPROC )
-        {
-                PUSHSQLERR ( pstmt->herr, en_IM001 );
-                return SQL_ERROR;
-        }
-
-        CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_GetStmtOption, (
-                        pstmt->dhstmt, fOption, pvParam ) )
-
-#if 0
-        retcode = hproc ( pstmt->dhstmt, fOption, pvParam );
-#endif
+     default:
+       PUSHSQLERR (pstmt->herr, en_S1092);
+       return SQL_ERROR;
+     }
 
-        return retcode;
-}
+  /* check state */
+  if (pstmt->state >= en_stmt_needdata || pstmt->asyn_on != en_NullProc)
+    {
+      PUSHSQLERR (pstmt->herr, en_S1010);
 
-RETCODE SQL_API SQLCancel ( HSTMT hstmt )
-{
-        STMT_t FAR*     pstmt   = (STMT_t FAR*)hstmt;
-        HPROC           hproc;
-        RETCODE         retcode;
+      return SQL_ERROR;
+    }
 
-        if( hstmt == SQL_NULL_HSTMT
-         || pstmt->hdbc == SQL_NULL_HDBC )
-        {
-                return SQL_INVALID_HANDLE;
-        }
+  hproc = SQL_NULL_HPROC;
 
-        /* check argument */
-        /* check state */
+#if (ODBCVER >= 0x0300)
+  if (fOption == SQL_DROP)
+    {
+      hproc = _iodbcdm_getproc (pstmt->hdbc, en_FreeHandle);
+
+      if (hproc)
+       {
+         CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_FreeHandle, 
+           (SQL_HANDLE_STMT, pstmt->dhstmt))
+       }
+    }
+#endif
 
-        /* call driver */
-        hproc = _iodbcdm_getproc( pstmt->hdbc, en_Cancel );
+  if (hproc == SQL_NULL_HPROC)
+    {
+      hproc = _iodbcdm_getproc (pstmt->hdbc, en_FreeStmt);
+
+      if (hproc == SQL_NULL_HPROC)
+       {
+         PUSHSQLERR (pstmt->herr, en_IM001);
+
+         return SQL_ERROR;
+       }
+
+      CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_FreeStmt, 
+       (pstmt->dhstmt, fOption))
+    }
+
+  if (retcode != SQL_SUCCESS
+      && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      return retcode;
+    }
+
+  /* state transition */
+  switch (fOption)
+     {
+     case SQL_DROP:
+       /* delet this object (ignore return) */
+       _iodbcdm_dropstmt (hstmt);
+       break;
+
+     case SQL_CLOSE:
+       pstmt->cursor_state = en_stmt_cursor_no;
+       /* This means cursor name set by
+        * SQLSetCursorName() call will also 
+        * be erased.
+        */
+
+       switch (pstmt->state)
+         {
+         case en_stmt_allocated:
+         case en_stmt_prepared:
+           break;
+
+         case en_stmt_executed:
+         case en_stmt_cursoropen:
+         case en_stmt_fetched:
+         case en_stmt_xfetched:
+           if (pstmt->prep_state)
+             {
+               pstmt->state =
+                   en_stmt_prepared;
+             }
+           else
+             {
+               pstmt->state =
+                   en_stmt_allocated;
+             }
+           break;
+
+         default:
+           break;
+         }
+       break;
+
+     case SQL_UNBIND:
+     case SQL_RESET_PARAMS:
+     default:
+       break;
+     }
+
+  return retcode;
+}
 
-        if( hproc == SQL_NULL_HPROC )
-        {
-                PUSHSQLERR ( pstmt->herr, en_IM001 );
 
-                return SQL_ERROR;
-        }
+RETCODE SQL_API 
+SQLSetStmtOption (
+    HSTMT hstmt,
+    UWORD fOption,
+    UDWORD vParam)
+{
+  STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
+  HPROC hproc;
+  int sqlstat = en_00000;
+  RETCODE retcode;
+
+  if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check option */
+  if (                         /* fOption < SQL_STMT_OPT_MIN || */
+      fOption > SQL_STMT_OPT_MAX)
+    {
+      PUSHSQLERR (pstmt->herr, en_S1092);
+
+      return SQL_ERROR;
+    }
+
+  if (fOption == SQL_CONCURRENCY
+      || fOption == SQL_CURSOR_TYPE
+      || fOption == SQL_SIMULATE_CURSOR
+      || fOption == SQL_USE_BOOKMARKS)
+    {
+      if (pstmt->asyn_on != en_NullProc)
+       {
+         if (pstmt->prep_state)
+           {
+             sqlstat = en_S1011;
+           }
+       }
+      else
+       {
+         switch (pstmt->state)
+            {
+            case en_stmt_prepared:
+              sqlstat = en_S1011;
+              break;
+
+            case en_stmt_executed:
+            case en_stmt_cursoropen:
+            case en_stmt_fetched:
+            case en_stmt_xfetched:
+              sqlstat = en_24000;
+              break;
+
+            case en_stmt_needdata:
+            case en_stmt_mustput:
+            case en_stmt_canput:
+              if (pstmt->prep_state)
+                {
+                  sqlstat = en_S1011;
+                }
+              break;
+
+            default:
+              break;
+            }
+       }
+    }
+  else
+    {
+      if (pstmt->asyn_on != en_NullProc)
+       {
+         if (!pstmt->prep_state)
+           {
+             sqlstat = en_S1010;
+           }
+       }
+      else
+       {
+         if (pstmt->state >= en_stmt_needdata)
+           {
+             sqlstat = en_S1010;
+           }
+       }
+    }
+
+  if (sqlstat != en_00000)
+    {
+      PUSHSQLERR (pstmt->herr, sqlstat);
+
+      return SQL_ERROR;
+    }
+
+  hproc = _iodbcdm_getproc (pstmt->hdbc, en_SetStmtOption);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      PUSHSQLERR (pstmt->herr, en_IM001);
+
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_SetStmtOption,
+    (pstmt->dhstmt, fOption, vParam))
+
+  return retcode;
+}
 
-        CALL_DRIVER ( pstmt->hdbc, retcode, hproc, en_Cancel, (pstmt->dhstmt) )
 
-#if 0
-        retcode = hproc ( pstmt->dhstmt );
-#endif
+RETCODE SQL_API 
+SQLGetStmtOption (
+    HSTMT hstmt,
+    UWORD fOption,
+    PTR pvParam)
+{
+  STMT_t FAR *pstmt = (STMT_t *) hstmt;
+  HPROC hproc;
+  int sqlstat = en_00000;
+  RETCODE retcode;
+
+  if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check option */
+  if (                         /* fOption < SQL_STMT_OPT_MIN || */
+      fOption > SQL_STMT_OPT_MAX)
+    {
+      PUSHSQLERR (pstmt->herr, en_S1092);
+
+      return SQL_ERROR;
+    }
+
+  /* check state */
+  if (pstmt->state >= en_stmt_needdata
+      || pstmt->asyn_on != en_NullProc)
+    {
+      sqlstat = en_S1010;
+    }
+  else
+    {
+      switch (pstmt->state)
+        {
+        case en_stmt_allocated:
+        case en_stmt_prepared:
+        case en_stmt_executed:
+        case en_stmt_cursoropen:
+          if (fOption == SQL_ROW_NUMBER || fOption == SQL_GET_BOOKMARK)
+            {
+              sqlstat = en_24000;
+            }
+          break;
+
+        default:
+          break;
+        }
+    }
+
+  if (sqlstat != en_00000)
+    {
+      PUSHSQLERR (pstmt->herr, sqlstat);
+
+      return SQL_ERROR;
+    }
+
+  hproc = _iodbcdm_getproc (pstmt->hdbc, en_GetStmtOption);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      PUSHSQLERR (pstmt->herr, en_IM001);
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_GetStmtOption,
+    (pstmt->dhstmt, fOption, pvParam))
+
+  return retcode;
+}
 
-        /* state transition */
-        if( retcode != SQL_SUCCESS
-         && retcode != SQL_SUCCESS_WITH_INFO )
-        {
-                return retcode;
-        }
-
-        switch( pstmt->state )
-        {
-                case en_stmt_allocated:
-                case en_stmt_prepared:
-                        break;
-
-                case en_stmt_executed:
-                        if( pstmt->prep_state )
-                        {
-                                pstmt->state = en_stmt_prepared;
-                        }
-                        else
-                        {
-                                pstmt->state = en_stmt_allocated;
-                        }
-                        break;
-
-                case en_stmt_cursoropen:
-                case en_stmt_fetched:
-                case en_stmt_xfetched:
-                        if( pstmt->prep_state )
-                        {
-                                pstmt->state = en_stmt_prepared;
-                        }
-                        else
-                        {
-                                pstmt->state = en_stmt_allocated;
-                        }
-                        break;
-
-                case en_stmt_needdata:
-                case en_stmt_mustput:
-                case en_stmt_canput:
-                        switch( pstmt->need_on )
-                        {
-                                case en_ExecDirect:
-                                        pstmt->state = en_stmt_allocated;
-                                        break;
-
-                                case en_Execute:
-                                        pstmt->state = en_stmt_prepared;
-                                        break;
-
-                                case en_SetPos:
-                                        pstmt->state = en_stmt_xfetched;
-                                        break;
-
-                                default:
-                                        break;
-                        }
-                        pstmt->need_on = en_NullProc;
-                        break;
-
-                default:
-                        break;
-        }
-
-        return retcode;
+
+RETCODE SQL_API 
+SQLCancel (HSTMT hstmt)
+{
+  STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
+  HPROC hproc;
+  RETCODE retcode;
+
+  if (hstmt == SQL_NULL_HSTMT || pstmt->hdbc == SQL_NULL_HDBC)
+    {
+      return SQL_INVALID_HANDLE;
+    }
+
+  /* check argument */
+  /* check state */
+
+  /* call driver */
+  hproc = _iodbcdm_getproc (pstmt->hdbc, en_Cancel);
+
+  if (hproc == SQL_NULL_HPROC)
+    {
+      PUSHSQLERR (pstmt->herr, en_IM001);
+
+      return SQL_ERROR;
+    }
+
+  CALL_DRIVER (pstmt->hdbc, retcode, hproc, en_Cancel, 
+    (pstmt->dhstmt))
+
+  /* state transition */
+  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
+    {
+      return retcode;
+    }
+
+  switch (pstmt->state)
+     {
+     case en_stmt_allocated:
+     case en_stmt_prepared:
+       break;
+
+     case en_stmt_executed:
+       if (pstmt->prep_state)
+        {
+          pstmt->state = en_stmt_prepared;
+        }
+       else
+        {
+          pstmt->state = en_stmt_allocated;
+        }
+       break;
+
+     case en_stmt_cursoropen:
+     case en_stmt_fetched:
+     case en_stmt_xfetched:
+       if (pstmt->prep_state)
+        {
+          pstmt->state = en_stmt_prepared;
+        }
+       else
+        {
+          pstmt->state = en_stmt_allocated;
+        }
+       break;
+
+     case en_stmt_needdata:
+     case en_stmt_mustput:
+     case en_stmt_canput:
+       switch (pstmt->need_on)
+         {
+         case en_ExecDirect:
+           pstmt->state = en_stmt_allocated;
+           break;
+
+         case en_Execute:
+           pstmt->state = en_stmt_prepared;
+           break;
+
+         case en_SetPos:
+           pstmt->state = en_stmt_xfetched;
+           break;
+
+         default:
+           break;
+         }
+       pstmt->need_on = en_NullProc;
+       break;
+
+     default:
+       break;
+     }
+
+  return retcode;
 }