List:Commits« Previous MessageNext Message »
From:pharvey Date:July 29 2006 6:20pm
Subject:Connector/ODBC 5 commit: r464 - trunk/MYSQLPlus/MYSQLPlusLib
View as plain text  
Modified:
   trunk/MYSQLPlus/MYSQLPlusLib/MCommand.cpp
   trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
Log:
more work on SQLMoreResults

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MCommand.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MCommand.cpp	2006-07-29 05:37:54 UTC (rev 463)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MCommand.cpp	2006-07-29 18:20:02 UTC (rev 464)
@@ -399,7 +399,9 @@
     /*!
         \internal MYSQL RULE
 
-        We support transactions on DML commands (not on DDL).
+        We support transactions on DML commands (not on DDL). But note that caller can
get this
+        from MConnection::getInfoTxnCapable() and MCommand::isDataManipulationLanguage()
instead
+        of using this method.
     */
     if ( isDataManipulationLanguage() )
         MYODBCDbgReturn3( "%d", true );

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-07-29 05:37:54 UTC (rev 463)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-07-29 18:20:02 UTC (rev 464)
@@ -2747,6 +2747,9 @@
 {
     MYODBCDbgEnter();
 
+    SQLRETURN nReturnPrepare;
+    SQLRETURN nReturnExecute;
+
     /*!
         \internal ODBC RULE
 
@@ -2758,6 +2761,10 @@
         \internal ODBC RULE (DM)
 
         The StatementHandle was not prepared.
+
+        \internal MYODBC RULE
+
+        Seems to make more sense that we must be executed - not just prepared.
     */
     if ( !isExecuted() )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
@@ -2790,6 +2797,14 @@
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
 
     /*!
+        \internal 
+
+        We have already iterated over all commands.
+    */
+    if ( pCommands->getPos() < 0 )
+        MYODBCDbgReturn( SQL_NO_DATA );
+
+    /*!
         \internal ODBC RULE
 
         It is driver-specific whether the entire batch statement is executed before any
results are 
@@ -2813,20 +2828,20 @@
      * PREPARE
      */
 
-    /* rollback to prepared state */
-    doStateRollBack( STATE_S3 );
-
     /* advance to next command */
     if ( pCommands->doNext() )
     {
-        delete pResult;
+        MResult *pResultOriginal = pResult;
         pResult = NULL;
 
-        nReturn = doPrepare( pCommands->getCommand() );
-        if ( !SQL_SUCCEEDED( nReturn ) )
+        nReturnPrepare = doPrepare( pCommands->getCommand() );
+        if ( !SQL_SUCCEEDED( nReturnPrepare ) )
         {
-            MYODBCDbgReturn( nReturn );
+            pResult = pResultOriginal;
+            doStateRollBack( STATE_S1 );
+            MYODBCDbgReturn( nReturnPrepare );
         }
+        delete pResultOriginal;
     }
     else
     {
@@ -2834,12 +2849,49 @@
         MYODBCDbgReturn( SQL_NO_DATA );
     }
 
+    doStateRollBack( STATE_S1 );
+
     /*
      * EXECUTE
      */
 
-    pResult->doExecute();
+    nReturnExecute = pResult->doExecute();
+    if ( !SQL_SUCCEEDED( nReturnExecute ) )
+    {
+        /*!
+            \internal ODBC RULE
+            \todo
 
+            If SQLExecute executes a searched update or delete statement that does 
+            not affect any rows at the data source, the call to SQLExecute returns 
+            SQL_NO_DATA.
+        */
+        /*!
+            \internal ODBC RULE
+            \todo
+
+            If SQLExecute encounters a data-at-execution parameter, it returns 
+            SQL_NEED_DATA. The application sends the data using SQLParamData and 
+            SQLPutData.
+        */
+        MYODBCDbgReturn( nReturnExecute );
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        No columns then no resultset - set state accordingly. Being in state S5 does
+        not imply that we have data/rows in the resultset - just that we have a 
+        resultset.
+    */
+    if ( getImpRowDesc()->getCount() )
+        setState( STATE_S5 );
+    else
+        setState( STATE_S4 );
+
+    if ( nReturnPrepare == SQL_SUCCESS_WITH_INFO || nReturnExecute ==
SQL_SUCCESS_WITH_INFO )
+        MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
@@ -3127,6 +3179,18 @@
         goto doPrepareExit2;
     }
 
+    /*!
+        \internal
+        \todo
+
+        Set SQL_DIAG_DYNAMIC_FUNCTION and SQL_DIAG_DYNAMIC_FUNCTION_CODE diagnostic
header fields and possibly use them instead
+        of statement type.
+    */
+    if ( pCommands->getCommand().isResultSetPossible() )
+        setState( STATE_S3 );
+    else
+        setState( STATE_S2 );
+
     MYODBCDbgReturn( nReturn );
 
 doPrepareExit2:
@@ -5204,6 +5268,31 @@
     MYODBCDbgReturn3( "%d", nUseBookmarks );
 }
 
+/*!
+    \brief  Roll back the state.
+
+            This will roll back the state - ensuring that things get cleaned up along 
+            the way.
+
+            This is *the* method for rolling back state - other nethods should always
+            use this to roll back a state. However; there are some exceptional
circumstances
+            such as \sa doMoreResults which needs to partially roll back to a STATE_S1
from
+            an executed state.
+
+    \param  nState  The desired state. This must be greater than the current state. The
actual
+                    state set may differ. For example; request STATE_S3 from an executed
state
+                    may result in STATE_S2 depending upon the current command.
+
+    \return SQLRETURN
+
+    \retval SUCCESS
+    \retval WARNING
+    \retval ERROR
+
+    \sa     getState
+            setState
+            doMoreResults
+*/
 SQLRETURN MStatement::doStateRollBack( STATE nState )
 {
     MYODBCDbgEnter();
@@ -5258,6 +5347,15 @@
                     nState = STATE_S3; // we will have a resultset
                 else
                 {
+                    /*!
+                        \note
+
+                        Once we have iterated over all the results with doMoreResults we
end up with a kind of EOF pos. In
+                        this case doMoreResults will only return SQL_NO_DATA. doExecute
can be used to go back to the first
+                        command, execute it, and allow doMoreResults to execute next
command (if any).
+                    */
+                    pCommands->doFirst();
+
                     if ( pCommands->getCommand().isResultSetPossible() )
                         nState = STATE_S3; // we will have a resultset
                 }
@@ -5307,6 +5405,19 @@
 
             The idea here is that this can be called from \sa doPrepare() and \sa
doMoreResults().
 
+            pResult needs to be NULL coming into here. The state should be STATE_S1 or an
executed
+            state.
+
+    \return SQLRETURN
+
+    \retval SUCCESS Called succeeded;
+                        - state unchanged (caller should adjust)
+                        - pResult will be viable
+
+    \retval ERROR   Call failed;
+                        - state unchanged
+                        - pResult unchanged
+
     \sa     doPrepare
             doMoreResults
 */
@@ -5330,8 +5441,6 @@
         - server feature support
         - SQL statement
         - resultset characteristics expected (if possible)
-
-        Our bias is toward using server-side prepared.
     */
     if ( nStatementType == MConnection::STATEMENT_DYNAMIC )
     {
@@ -5344,7 +5453,7 @@
     /* if app wants server-side prepare but we can not use it then we fall back to
client-side and throw a warning */
     if ( nStatementType == MConnection::STATEMENT_STMT &&
!command.isServerSidePreparePossible() )
     {
-        getDiagnostic()->doAppend( MDiagnostic::DIA_01000, 0, tr("STATEMENT_STMT will
not support command - will use STATEMENT_RES instead") );
+        getDiagnostic()->doAppend( MDiagnostic::DIA_01000, 0, tr("Server-side prepare
not possible for this command - using client-side.") );
         nStatementType = MConnection::STATEMENT_RES;
     }
 
@@ -5361,13 +5470,16 @@
             break;
 
         default:
-            nReturn = getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0, QString(
tr("Unknown statement type %1") ).arg( nStatementType ) );
-            goto doPrepareExit1;
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
QString( tr("Unknown statement type %1") ).arg( nStatementType ) ) );
     }
 
     SQLRETURN nReturn = pResult->doPrepare( command );
     if ( !SQL_SUCCEEDED( nReturn ) )
+    {
+        delete pResult;
+        pResult = NULL;
         MYODBCDbgReturn( nReturn );
+    }
 
     /*!
         \internal
@@ -5376,7 +5488,7 @@
 
         We silently start a transaction as needed. We do not rely upon the server doing
this for us but perhaps we should - will see.
     */
-    MConnection *   pConnection = getConnection();
+    MConnection *pConnection = getConnection();
 
     if ( pConnection->isTransaction() == false )
     {
@@ -5395,22 +5507,12 @@
             case SQL_TC_ALL:
                 nReturn = pConnection->doTransactionStart();
             default:
+                delete pResult;
+                pResult = NULL;
                 MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Unknown value from getInfoTxnCapable()") ) );
         }
     }
 
-    /*!
-        \internal
-        \todo
-
-        Set SQL_DIAG_DYNAMIC_FUNCTION and SQL_DIAG_DYNAMIC_FUNCTION_CODE diagnostic
header fields and possibly use them instead
-        of statement type.
-    */
-    if ( command.isResultSetPossible() )
-        setState( STATE_S3 );
-    else
-        setState( STATE_S2 );
-
     MYODBCDbgReturn( nReturn );
 }
 

Thread
Connector/ODBC 5 commit: r464 - trunk/MYSQLPlus/MYSQLPlusLibpharvey29 Jul