List:Commits« Previous MessageNext Message »
From:pharvey Date:July 10 2006 7:07am
Subject:Connector/ODBC 5 commit: r431 - trunk/MYSQLPlus/MYSQLPlusLib
View as plain text  
Added:
   trunk/MYSQLPlus/MYSQLPlusLib/MCommand.h
   trunk/MYSQLPlus/MYSQLPlusLib/MCommands.h
Modified:
   trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp
   trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
   trunk/MYSQLPlus/MYSQLPlusLib/MYSQLPlusLib.vpj
Log:
- begin effort to make most of the command prepare independent of MStatement and
MStatement state (to support SQLNativeSQL) while at the same time making the
preprocessing of commands more feature rich and extensible (to enforce more ODBC rules)

Added: trunk/MYSQLPlus/MYSQLPlusLib/MCommand.h
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MCommand.h	2006-07-07 23:07:30 UTC (rev 430)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MCommand.h	2006-07-10 05:07:27 UTC (rev 431)
@@ -0,0 +1,88 @@
+/*! 
+    \file       MCommand.h
+    \author     Peter Harvey <pharvey@stripped>
+                Copyright (C) MySQL AB 2004-2006, Released under GPL.
+    \version    Connector/ODBC v5
+    \date       2006
+*/
+
+#ifndef MCOMMAND_H
+#define MCOMMAND_H
+
+#include "MInternal.h"
+
+/*!
+    \brief  A single command (usually a SQL DDL/DML statement) to be sent to the server.
+
+            This will preprocess (prepare) the given command. It will;
+
+            - translate any ODBC specific syntax into syntax supported by the server (ie
"{d <dateval>}" )
+            - process escape sequences as needed
+            - provide parameter marker information
+            - provide feature information (ie is command viable for a transaction)
+
+            This can be used independent of any particular statement so as to support
SQLNativeSQL (which
+            happens at the connection level).
+
+    \note   This is not intended to be a complete SQL parser - mostly because that is a
lot of work. However;
+            a complete parser would be useful as we can not get all of this information
via the 
+            mysqlclient/server - certianly not in the connection/statement states we need
them in.
+
+    \sa     MCommands
+*/
+class MCommand : public QObject
+{
+public:
+    enum COMMAND_TYPE
+    {
+        COMMAND_TYPE_NULL,          /*!< we do not have a statement                   
        */
+        COMMAND_TYPE_SELECT,        /*!< SELECT statement has been prepared           
        */
+        COMMAND_TYPE_SELECT_INTO,   /*!< SELECT INTO statement has been prepared      
        */
+        COMMAND_TYPE_SHOW,          /*!< SHOW statement has been prepared             
        */
+        COMMAND_TYPE_UPDATE,        /*!< UPDATE statement has been prepared           
        */
+        COMMAND_TYPE_DELETE,        /*!< DELETE statement has been prepared           
        */
+        COMMAND_TYPE_INSERT,        /*!< INSERT statement has been prepared           
        */
+        COMMAND_TYPE_CALL,          /*!< CALL statement has been prepared             
        */
+        COMMAND_TYPE_CREATE,        /*!< CALL statement has been prepared             
        */
+        COMMAND_TYPE_GRANT,         /*!< CALL statement has been prepared             
        */
+        COMMAND_TYPE_SET            /*!< CALL statement has been prepared             
        */
+    };
+
+    MCommand( MConnection *pConnection );
+    MCommand( MStatement *pStatement );
+
+    /* setters */
+    SQLRETURN setCommand( const QString &stringCommand );   // this can include ODBC
specifics not supported by server
+
+    /* getters */
+    QString         getCommand();                           // simply returns the Text
provided to setText()
+    QString         getCommandNative();                     // version of text which has
any ODBC specifics switched to server friendly syntax
+    COMMAND_TYPE    getCommandType();                       // general type of the
command as indicated by first keyword
+
+    /* doers */
+
+    /* isers */
+    BOOLEAN isDataManipulationLanguage();
+    BOOLEAN isDataDefinitionLanguage();
+    BOOLEAN isTransactionPossible();
+    BOOLEAN isResultSetPossible();
+    BOOLEAN isDataModificationPossible();
+
+protected:
+
+    /* setters */
+
+    /* getters */
+    MDiagnostic *   getDiagnostic();
+
+private:
+    MConnection *   pConnection;            /*!< connection we are supporting         
                                     */
+    MStatement *    pStatement;             /*!< statement we are supporting (null if
we just supporting the connection)    */
+    QString         stringCommand;          /*!< the command we are based upon  */
+    QString         stringCommandNative;    /*!< native (prepared) command      */
+    COMMAND_TYPE    nCommandType;           /*!< the command type               */
+};
+
+#endif
+
+

Added: trunk/MYSQLPlus/MYSQLPlusLib/MCommands.h
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MCommands.h	2006-07-07 23:07:30 UTC (rev 430)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MCommands.h	2006-07-10 05:07:27 UTC (rev 431)
@@ -0,0 +1,67 @@
+/*! 
+    \file       MCommands.h
+    \author     Peter Harvey <pharvey@stripped>
+                Copyright (C) MySQL AB 2004-2006, Released under GPL.
+    \version    Connector/ODBC v5
+    \date       2006
+*/
+
+#ifndef MCOMMAND_H
+#define MCOMMAND_H
+
+#include "MInternal.h"
+
+/*!
+    \brief  List of commands (usually SQL DDL/DML statements) to be sent to the server.
+
+            This will preprocess (prepare) the given command(s). It will;
+
+            - break apart multiple commands based upon ';' command separator
+            - translate any ODBC specific syntax into syntax supported by the server (ie
"{d <dateval>}" )
+            - process escape sequences as needed
+            - provide parameter marker information
+            - provide feature information (ie is command viable for a transaction)
+
+            This can be used independent of any particular statement so as to support
SQLNativeSQL (which
+            happens at the connection level).
+
+    \note   This is not intended to be a complete SQL parser - mostly because that is a
lot of work. However;
+            a complete parser would be useful as we can not get all of this information
via the 
+            mysqlclient/server - certianly not in the connection/statement states we need
them in.
+
+    \sa     MCommand
+*/
+class MCommands : public QList<MCommand>
+{
+public:
+    MCommands( MConnection *pConnection );
+    MCommands( MStatement *pStatement );
+
+    /* setters */
+    SQLRETURN setCommands( const QString &stringCommands ); // this can include ODBC
specifics not supported by server
+
+    /* getters */
+    QString getCommands();          // simply returns the text provided to setCommands()
+    QString getCommandsNative();    // version of text which has any ODBC specifics
switched to server friendly syntax etc (prepared)
+
+    /* doers */
+
+    /* isers */
+    BOOLEAN isTransactionPossible();
+    BOOLEAN isResultSetPossible();
+
+protected:
+    /* setters */
+
+    /* getters */
+    MDiagnostic *   getDiagnostic();
+
+private:
+    MConnection *   pConnection;    /*!< connection we are supporting                 
                             */
+    MStatement *    pStatement;     /*!< statement we are supporting (null if we just
supporting the connection)    */
+    QString         stringCommands;  
+};
+
+#endif
+
+

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp	2006-07-07 23:07:30 UTC (rev 430)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MConnection.cpp	2006-07-10 05:07:27 UTC (rev 431)
@@ -2006,24 +2006,11 @@
     if ( !isTransaction() )
         MYODBCDbgReturn( SQL_SUCCESS );
 
-    /*!
-        \internal
-        \note
-
-        We could use mysql_commit() or mysql_rollback() but we do not want to deal with
the 
-        possibility that our connection could be closed (see C API doc) so we use an SQL 
-        statement.
-
-        \sa mysql_commit
-            mysql_rollback
-    */
-    QString stringCommand;
-
+    /* do it */
     switch ( nCompletionType )
     {
         case SQL_COMMIT:
-            stringCommand = "COMMIT";
-            break;
+            MYODBCDbgReturn( doTransactionCommit() );
 
         case SQL_ROLLBACK:
             /*!
@@ -2034,92 +2021,15 @@
             if ( getInfoTxnCapable() == SQL_TC_NONE )
                 MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HYC00 )
);
 
-            stringCommand = "ROLLBACK";
-            break;
-
-        default:
-            /*!
-                \internal ODBC RULE (DM)
-
-                The value specified for the argument CompletionType was neither
SQL_COMMIT nor SQL_ROLLBACK.
-            */
-            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY012 ) );
+            MYODBCDbgReturn( doTransactionRollback() );
     }
 
-    if ( !SQL_SUCCEEDED( doSubmitCommand( stringCommand ) ) )
-        /*!
-            \internal ODBC RULE
-
-            The HandleType was SQL_HANDLE_DBC, and the connection associated with the
Handle failed during the execution of the 
-            function, and it cannot be determined whether the requested COMMIT or
ROLLBACK occurred before the failure.
-        */
-        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_08007 ) );
-
     /*!
-        \internal ODBC RULE
+        \internal ODBC RULE (DM)
 
-        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_DELETE, SQLEndTran 
-        closes and deletes all open cursors on all statements associated with the
connection 
-        and discards all pending results. SQLEndTran leaves any statement present in an
allocated (unprepared) 
-        state; the application can reuse them for subsequent SQL requests or can call
SQLFreeStmt or 
-        SQLFreeHandle with a HandleType of SQL_HANDLE_STMT to deallocate them.
+        The value specified for the argument CompletionType was neither SQL_COMMIT nor
SQL_ROLLBACK.
     */
-    if ( (nCompletionType == SQL_COMMIT     && getInfoCursorCommitBehavior()   
== SQL_CB_DELETE) || 
-         (nCompletionType == SQL_ROLLBACK   && getInfoCursorRollbackBehavior() 
== SQL_CB_DELETE) )
-    {
-        QList<QObject*> listObjects;
-        QListIterator<QObject*> i( (QList<QObject*>)children() );
-
-        while ( i.hasNext() ) 
-        {
-            QObject *pObject = i.next();
-            if ( pObject->objectName() == "MStatement" )
-            {
-                MStatement *pStatement = (MStatement*)pObject;
-                pStatement->doStateRollBack( MStatement::STATE_S1 );
-            }
-        }
-    }
-
-    /*!
-        \internal ODBC RULE
-
-        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_CLOSE, SQLEndTran 
-        closes all open cursors on all statements associated with the connection.
SQLEndTran leaves any statement 
-        present in a prepared state; the application can call SQLExecute for a statement
associated with the 
-        connection without first calling SQLPrepare.
-    */
-    if ( (nCompletionType == SQL_COMMIT     && getInfoCursorCommitBehavior()   
== SQL_CB_CLOSE) || 
-         (nCompletionType == SQL_ROLLBACK   && getInfoCursorRollbackBehavior() 
== SQL_CB_CLOSE) )
-    {
-        QList<QObject*> listObjects;
-        QListIterator<QObject*> i( (QList<QObject*>)children() );
-
-        while ( i.hasNext() ) 
-        {
-            QObject *pObject = i.next();
-            if ( pObject->objectName() == "MStatement" )
-            {
-                MStatement *pStatement = (MStatement*)pObject;
-                pStatement->doStateRollBack( MStatement::STATE_S3 );
-            }
-        }
-    }
-
-    /*!
-        \internal ODBC RULE
-
-        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_PRESERVE, SQLEndTran 
-        does not affect open cursors associated with the connection. Cursors remain at
the row they pointed to 
-        prior to the call to SQLEndTran.
-    */
-    if ( (nCompletionType == SQL_COMMIT     && getInfoCursorCommitBehavior()   
== SQL_CB_PRESERVE) || 
-         (nCompletionType == SQL_ROLLBACK   && getInfoCursorRollbackBehavior() 
== SQL_CB_PRESERVE) )
-    {
-        /* do nothing special  */
-    }
-
-    MYODBCDbgReturn( SQL_SUCCESS );
+    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY012 ) );
 }
 
 /*!
@@ -4885,6 +4795,8 @@
             This is a convenience function which is used to request that the server
             starts a transaction.
 
+            This will adjust the state to STATE_C6 if success.
+
     \note   The caller must ensure that this request fits in with the state, config
options
             and features available. This just sends the request to the server.
 
@@ -4898,6 +4810,8 @@
     if ( !SQL_SUCCEEDED( doSubmitCommand( "START TRANSACTION" ) ) )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Failed to start transaction.") ) );
 
+    setState( STATE_C6 );
+
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
@@ -4907,6 +4821,8 @@
             This is a convenience function which is used to request that the server
             commit a transaction.
 
+            This will adjust the state (away from STATE_C6) if success.
+
     \note   The caller must ensure that this request fits in with the state, config
options
             and features available. This just sends the request to the server.
 
@@ -4936,6 +4852,73 @@
         */
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_08007 ) );
 
+    /*!
+        \internal ODBC RULE
+
+        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_DELETE, SQLEndTran 
+        closes and deletes all open cursors on all statements associated with the
connection 
+        and discards all pending results. SQLEndTran leaves any statement present in an
allocated (unprepared) 
+        state; the application can reuse them for subsequent SQL requests or can call
SQLFreeStmt or 
+        SQLFreeHandle with a HandleType of SQL_HANDLE_STMT to deallocate them.
+    */
+    if ( nCompletionType == SQL_COMMIT && getInfoCursorCommitBehavior() ==
SQL_CB_DELETE )
+    {
+        QList<QObject*> listObjects;
+        QListIterator<QObject*> i( (QList<QObject*>)children() );
+
+        while ( i.hasNext() ) 
+        {
+            QObject *pObject = i.next();
+            if ( pObject->objectName() == "MStatement" )
+            {
+                MStatement *pStatement = (MStatement*)pObject;
+                pStatement->doStateRollBack( MStatement::STATE_S1 );
+            }
+        }
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_CLOSE, SQLEndTran 
+        closes all open cursors on all statements associated with the connection.
SQLEndTran leaves any statement 
+        present in a prepared state; the application can call SQLExecute for a statement
associated with the 
+        connection without first calling SQLPrepare.
+    */
+    if ( nCompletionType == SQL_COMMIT && getInfoCursorCommitBehavior() ==
SQL_CB_CLOSE )
+    {
+        QList<QObject*> listObjects;
+        QListIterator<QObject*> i( (QList<QObject*>)children() );
+
+        while ( i.hasNext() ) 
+        {
+            QObject *pObject = i.next();
+            if ( pObject->objectName() == "MStatement" )
+            {
+                MStatement *pStatement = (MStatement*)pObject;
+                if ( pStatement->isImplicitPrepare() )
+                    pStatement->doStateRollBack( MStatement::STATE_S1 );
+                else
+                    pStatement->doStateRollBack( MStatement::STATE_S3 );
+            }
+        }
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_PRESERVE, SQLEndTran 
+        does not affect open cursors associated with the connection. Cursors remain at
the row they pointed to 
+        prior to the call to SQLEndTran.
+    */
+    if ( nCompletionType == SQL_COMMIT && getInfoCursorCommitBehavior() ==
SQL_CB_PRESERVE )
+    {
+        /* do nothing special  */
+    }
+
+    /* we no longer have a transaction in play so... */
+    setState( STATE_C5 );
+
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
@@ -4945,6 +4928,8 @@
             This is a convenience function which is used to request that the server
             rollback a transaction.
 
+            This will adjust the state (away from STATE_C6) if success.
+
     \note   The caller must ensure that this request fits in with the state, config
options
             and features available. This just sends the request to the server.
 
@@ -4974,6 +4959,73 @@
         */
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_08007 ) );
 
+    /*!
+        \internal ODBC RULE
+
+        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_DELETE, SQLEndTran 
+        closes and deletes all open cursors on all statements associated with the
connection 
+        and discards all pending results. SQLEndTran leaves any statement present in an
allocated (unprepared) 
+        state; the application can reuse them for subsequent SQL requests or can call
SQLFreeStmt or 
+        SQLFreeHandle with a HandleType of SQL_HANDLE_STMT to deallocate them.
+    */
+    if ( nCompletionType == SQL_ROLLBACK && getInfoCursorRollbackBehavior() ==
SQL_CB_DELETE )
+    {
+        QList<QObject*> listObjects;
+        QListIterator<QObject*> i( (QList<QObject*>)children() );
+
+        while ( i.hasNext() ) 
+        {
+            QObject *pObject = i.next();
+            if ( pObject->objectName() == "MStatement" )
+            {
+                MStatement *pStatement = (MStatement*)pObject;
+                pStatement->doStateRollBack( MStatement::STATE_S1 );
+            }
+        }
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_CLOSE, SQLEndTran 
+        closes all open cursors on all statements associated with the connection.
SQLEndTran leaves any statement 
+        present in a prepared state; the application can call SQLExecute for a statement
associated with the 
+        connection without first calling SQLPrepare.
+    */
+    if ( nCompletionType == SQL_ROLLBACK && getInfoCursorRollbackBehavior() ==
SQL_CB_CLOSE )
+    {
+        QList<QObject*> listObjects;
+        QListIterator<QObject*> i( (QList<QObject*>)children() );
+
+        while ( i.hasNext() ) 
+        {
+            QObject *pObject = i.next();
+            if ( pObject->objectName() == "MStatement" )
+            {
+                MStatement *pStatement = (MStatement*)pObject;
+                if ( pStatement->isImplicitPrepare() )
+                    pStatement->doStateRollBack( MStatement::STATE_S1 );
+                else
+                    pStatement->doStateRollBack( MStatement::STATE_S3 );
+            }
+        }
+    }
+
+    /*!
+        \internal ODBC RULE
+
+        If the SQL_CURSOR_ROLLBACK_BEHAVIOR or SQL_CURSOR_COMMIT_BEHAVIOR value equals
SQL_CB_PRESERVE, SQLEndTran 
+        does not affect open cursors associated with the connection. Cursors remain at
the row they pointed to 
+        prior to the call to SQLEndTran.
+    */
+    if ( nCompletionType == SQL_ROLLBACK && getInfoCursorRollbackBehavior() ==
SQL_CB_PRESERVE )
+    {
+        /* do nothing special  */
+    }
+
+    /* we no longer have a transaction in play so... */
+    setState( STATE_C5 );
+
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-07-07 23:07:30 UTC (rev 430)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-07-10 05:07:27 UTC (rev 431)
@@ -3080,7 +3080,7 @@
         case SQL_TC_ALL:
     }
 
-"START TRANSACTION"
+SQLRETURN MConnection::doTransactionStart()
 
     if ( pConnection->isTransaction() == false )
     {

Modified: trunk/MYSQLPlus/MYSQLPlusLib/MYSQLPlusLib.vpj
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MYSQLPlusLib.vpj	2006-07-07 23:07:30 UTC (rev 430)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MYSQLPlusLib.vpj	2006-07-10 05:07:27 UTC (rev 431)
@@ -52,6 +52,7 @@
 		<Folder
 			Name="Source Files"
 			Filters="*.c;*.C;*.cc;*.cpp;*.cp;*.cxx;*.prg;*.pas;*.dpr;*.asm;*.s;*.bas;*.java;*.cs;*.sc;*.e;*.cob;*.html;*.rc;*.tcl;*.py;*.pl">
+			<F N="MCommands.cpp"/>
 			<F N="MConnection.cpp"/>
 			<F N="MDescriptor.cpp"/>
 			<F N="MDescriptorAPD.cpp"/>
@@ -75,6 +76,8 @@
 		<Folder
 			Name="Header Files"
 			Filters="*.h;*.H;*.hh;*.hpp;*.hxx;*.inc;*.sh;*.cpy;*.if">
+			<F N="MCommand.h"/>
+			<F N="MCommands.h"/>
 			<F N="MDescriptorAPD.h"/>
 			<F N="MDescriptorARD.h"/>
 			<F N="MDescriptorIPD.h"/>

Thread
Connector/ODBC 5 commit: r431 - trunk/MYSQLPlus/MYSQLPlusLibpharvey10 Jul