2424#include " getdata.h"
2525#include " dbspecific.h"
2626#include < datetime.h>
27+ #include " handle.h"
2728
2829enum
2930{
@@ -682,7 +683,6 @@ int GetDiagRecs(Cursor* cur)
682683 return 0 ;
683684}
684685
685- static bool first_prepare = false ;
686686static PyObject * prepare_statement (Cursor* cur, PyObject* pSql, PyObject* params, bool skip_first)
687687{
688688 // Internal function to execute SQL, called by .prepareStatement
@@ -712,13 +712,14 @@ static PyObject * prepare_statement(Cursor* cur, PyObject* pSql, PyObject* param
712712 return 0 ;
713713 }
714714
715- first_prepare = true ;
716715 Py_INCREF (cur);
717- return (PyObject*)cur;
716+ Handle *hndl = Handle_New (cur);
717+ hndl->hstmt = cur->hstmt ;
718+ return (PyObject*)hndl;
718719}
719720
720721
721- static PyObject* executePreparedStatement (Cursor* cur, PyObject* params, bool skip_first)
722+ static PyObject* executePreparedStatement (Cursor* cur, Handle *hndl, PyObject* params, bool skip_first)
722723{
723724
724725 if (params)
@@ -736,23 +737,16 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
736737
737738 FreeParameterData (cur);
738739
739- SQLCancelHandle (SQL_HANDLE_STMT, cur->hstmt );
740- /* if (first_prepare) {
741- //SQLFreeStmt(cur->hstmt, SQL_CLOSE);
742- //SQLFreeStmt(cur->hstmt, SQL_UNBIND);
743- //SQLFreeStmt(cur->hstmt, SQL_RESET_PARAMS);
744- first_prepare = false;
745- } else {
746- SQLCancelHandle(SQL_HANDLE_DBC, cur->hstmt);
747- }*/
740+ SQLCancelHandle (SQL_HANDLE_STMT, hndl->hstmt );
741+
748742 const char * szLastFunction = " " ;
749743
750744 if (!Bind (cur, params, skip_first))
751745 return 0 ;
752746
753747 szLastFunction = " SQLExecute" ;
754748 Py_BEGIN_ALLOW_THREADS
755- ret = SQLExecute (cur ->hstmt );
749+ ret = SQLExecute (hndl ->hstmt );
756750 Py_END_ALLOW_THREADS
757751
758752
@@ -768,7 +762,7 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
768762 {
769763 // We could try dropping through the while and if below, but if there is an error, we need to raise it before
770764 // FreeParameterData calls more ODBC functions.
771- RaiseErrorFromHandle (cur->cnxn , " SQLExecDirectW" , cur->cnxn ->hdbc , cur ->hstmt );
765+ RaiseErrorFromHandle (cur->cnxn , " SQLExecDirectW" , cur->cnxn ->hdbc , hndl ->hstmt );
772766 FreeParameterData (cur);
773767 return 0 ;
774768 }
@@ -791,11 +785,11 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
791785 szLastFunction = " SQLParamData" ;
792786 ParamInfo* pInfo;
793787 Py_BEGIN_ALLOW_THREADS
794- ret = SQLParamData (cur ->hstmt , (SQLPOINTER*)&pInfo);
788+ ret = SQLParamData (hndl ->hstmt , (SQLPOINTER*)&pInfo);
795789 Py_END_ALLOW_THREADS
796790
797791 if (ret != SQL_NEED_DATA && ret != SQL_NO_DATA && !SQL_SUCCEEDED (ret))
798- return RaiseErrorFromHandle (cur->cnxn , " SQLParamData" , cur->cnxn ->hdbc , cur ->hstmt );
792+ return RaiseErrorFromHandle (cur->cnxn , " SQLParamData" , cur->cnxn ->hdbc , hndl ->hstmt );
799793
800794 TRACE (" SQLParamData() --> %d\n " , ret);
801795
@@ -830,7 +824,7 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
830824 ret = SQLPutData (cur->hstmt , (SQLPOINTER)&p[offset], remaining);
831825 Py_END_ALLOW_THREADS
832826 if (!SQL_SUCCEEDED (ret))
833- return RaiseErrorFromHandle (cur->cnxn , " SQLPutData" , cur->cnxn ->hdbc , cur ->hstmt );
827+ return RaiseErrorFromHandle (cur->cnxn , " SQLPutData" , cur->cnxn ->hdbc , hndl ->hstmt );
834828 offset += remaining;
835829 }
836830 while (offset < cb);
@@ -881,19 +875,19 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
881875 hasTvpRows = 1 ;
882876 }
883877 Py_BEGIN_ALLOW_THREADS
884- ret = SQLPutData (cur ->hstmt , hasTvpRows ? (SQLPOINTER)1 : 0 , hasTvpRows);
878+ ret = SQLPutData (hndl ->hstmt , hasTvpRows ? (SQLPOINTER)1 : 0 , hasTvpRows);
885879 Py_END_ALLOW_THREADS
886880 if (!SQL_SUCCEEDED (ret))
887- return RaiseErrorFromHandle (cur->cnxn , " SQLPutData" , cur->cnxn ->hdbc , cur ->hstmt );
881+ return RaiseErrorFromHandle (cur->cnxn , " SQLPutData" , cur->cnxn ->hdbc , hndl ->hstmt );
888882 }
889883 else
890884 {
891885 // TVP column sent as DAE
892886 Py_BEGIN_ALLOW_THREADS
893- ret = SQLPutData (cur ->hstmt , pInfo->ParameterValuePtr , pInfo->BufferLength );
887+ ret = SQLPutData (hndl ->hstmt , pInfo->ParameterValuePtr , pInfo->BufferLength );
894888 Py_END_ALLOW_THREADS
895889 if (!SQL_SUCCEEDED (ret))
896- return RaiseErrorFromHandle (cur->cnxn , " SQLPutData" , cur->cnxn ->hdbc , cur ->hstmt );
890+ return RaiseErrorFromHandle (cur->cnxn , " SQLPutData" , cur->cnxn ->hdbc , hndl ->hstmt );
897891 }
898892 ret = SQL_NEED_DATA;
899893 }
@@ -910,29 +904,29 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
910904 }
911905
912906 if (!SQL_SUCCEEDED (ret))
913- return RaiseErrorFromHandle (cur->cnxn , szLastFunction, cur->cnxn ->hdbc , cur ->hstmt );
907+ return RaiseErrorFromHandle (cur->cnxn , szLastFunction, cur->cnxn ->hdbc , hndl ->hstmt );
914908
915909 SQLLEN cRows = -1 ;
916910 Py_BEGIN_ALLOW_THREADS
917- ret = SQLRowCount (cur ->hstmt , &cRows);
911+ ret = SQLRowCount (hndl ->hstmt , &cRows);
918912 Py_END_ALLOW_THREADS
919913 if (!SQL_SUCCEEDED (ret))
920- return RaiseErrorFromHandle (cur->cnxn , " SQLRowCount" , cur->cnxn ->hdbc , cur ->hstmt );
914+ return RaiseErrorFromHandle (cur->cnxn , " SQLRowCount" , cur->cnxn ->hdbc , hndl ->hstmt );
921915
922916 cur->rowcount = (int )cRows;
923917
924918 TRACE (" SQLRowCount: %d\n " , cRows);
925919
926920 SQLSMALLINT cCols = 0 ;
927921 Py_BEGIN_ALLOW_THREADS
928- ret = SQLNumResultCols (cur ->hstmt , &cCols);
922+ ret = SQLNumResultCols (hndl ->hstmt , &cCols);
929923 Py_END_ALLOW_THREADS
930924 if (!SQL_SUCCEEDED (ret))
931925 {
932926 // Note: The SQL Server driver sometimes returns HY007 here if multiple statements (separated by ;) were
933927 // submitted. This is not documented, but I've seen it with multiple successful inserts.
934928
935- return RaiseErrorFromHandle (cur->cnxn , " SQLNumResultCols" , cur->cnxn ->hdbc , cur ->hstmt );
929+ return RaiseErrorFromHandle (cur->cnxn , " SQLNumResultCols" , cur->cnxn ->hdbc , hndl ->hstmt );
936930 }
937931
938932 TRACE (" SQLNumResultCols: %d\n " , cCols);
@@ -944,7 +938,7 @@ static PyObject* executePreparedStatement(Cursor* cur, PyObject* params, bool sk
944938 }
945939
946940 if (!SQL_SUCCEEDED (ret))
947- return RaiseErrorFromHandle (cur->cnxn , " SQLRowCount" , cur->cnxn ->hdbc , cur ->hstmt );
941+ return RaiseErrorFromHandle (cur->cnxn , " SQLRowCount" , cur->cnxn ->hdbc , hndl ->hstmt );
948942
949943 if (cCols != 0 )
950944 {
@@ -1329,18 +1323,17 @@ PyObject* Cursor_executePreparedStatement(PyObject* self, PyObject* args)
13291323
13301324 if (cParams < 0 )
13311325 {
1332- PyErr_SetString (PyExc_TypeError, " execute () takes at least 1 argument (0 given)" );
1326+ PyErr_SetString (PyExc_TypeError, " executePreparedStatement () takes at least 1 argument (0 given)" );
13331327 return 0 ;
13341328 }
1335- /*
1336- TODO: Leave the first argument slot open for the handle. Handle to be implemented later
1337- PyObject* pSql = PyTuple_GET_ITEM(args, 0);
13381329
1339- if (!PyUnicode_Check(pSql) && !PyUnicode_Check(pSql))
1330+ PyObject* hndl = PyTuple_GET_ITEM (args, 0 );
1331+
1332+ if (!Handle_Check (hndl))
13401333 {
1341- PyErr_SetString(PyExc_TypeError, "The first argument to execute must be a string or unicode query.");
1334+ PyErr_SetString (PyExc_TypeError, " The first argument to executePreparedStatement must be a query handle ." );
13421335 return 0 ;
1343- }*/
1336+ }
13441337
13451338 // Figure out if there were parameters and how they were passed. Our optional parameter passing complicates this slightly.
13461339
@@ -1350,7 +1343,6 @@ TODO: Leave the first argument slot open for the handle. Handle to be implemente
13501343 {
13511344 // There is a single argument and it is a sequence, so we must treat it as a sequence of parameters. (This is
13521345 // the normal Cursor.execute behavior.)
1353-
13541346 params = PyTuple_GET_ITEM (args, 1 );
13551347 skip_first = false ;
13561348 }
@@ -1362,7 +1354,7 @@ TODO: Leave the first argument slot open for the handle. Handle to be implemente
13621354
13631355 // Execute.
13641356
1365- return executePreparedStatement (cursor, params, skip_first);
1357+ return executePreparedStatement (cursor, (Handle *)hndl, params, skip_first);
13661358}
13671359
13681360static char execute_doc[] =
0 commit comments