Modified:
trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
Log:
more work to integrate MCommands
Modified: trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp
===================================================================
--- trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp 2006-07-13 23:17:46 UTC (rev 440)
+++ trunk/MYSQLPlus/MYSQLPlusLib/MStatement.cpp 2006-07-14 00:16:58 UTC (rev 441)
@@ -3007,44 +3007,73 @@
doStateRollBack( STATE_S1 );
/* get our statement text into a friendly QString */
- QString stringStatementText;
+ QString stringStatement;
+ if ( nLength1 == SQL_NTS )
+ stringStatement = QString::fromUtf16( psStatementText );
+ else
+ stringStatement = QString::fromUtf16( psStatementText, nLength1 );
/* get our statement text into an MCommand (preprocess it) */
pCommands = new MCommands( this );
- SQLRETURN nReturn = pCommands->setCommands( stringStatementText );
+ SQLRETURN nReturn = pCommands->setCommands( stringStatement );
if ( !SQL_SUCCEEDED( nReturn ) )
{
- delete pCommands;
- pCommands = NULL;
+ goto doPrepareExit1;
}
- MCommand command = pCommands->
+ /*!
+ \internal MYODBC RULE
- /* what flavour of resultset do we want? */
- switch ( getConnection()->getStatementType() )
+ We must have at least one command.
+ */
+ if ( !pCommands->count() )
{
- case MConnection::STATEMENT_DYNAMIC:
- /*!
- \internal
- \todo
+ nReturn = getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0, tr("Failed to
find a command to execute.") );
+ goto doPrepareExit1;
+ }
- Make us smart enough to decide based upon the;
+ /* get 1st command - this is the one we will prepare for execute now */
+ MCommand command = pCommands->at( pCommands->getCurrent() );
- - environment attributes
- - connection attributes
- - statement attributes
- - client feature support
- - server feature support
- - SQL statement
- - resultset characteristics expected (if possible)
- */
- getDiagnostic()->doAppend( MDiagnostic::DIA_01000, 0,
tr("STATEMENT_DYNAMIC is same as STATEMENT_RES at this time") );
- isServerSidePreparePossible()
- if ( pCommands->at( getCurrent() ).)
- {
- }
+ /* what flavour of resultset do we want? */
+ int nStatementType = getConnection()->getStatementType();
+ /*!
+ \internal
+ \todo
+
+ Make us smart enough to decide based upon the;
+
+ - environment attributes
+ - connection attributes
+ - statement attributes
+ - client feature support
+ - server feature support
+ - SQL statement
+ - resultset characteristics expected (if possible)
+
+ Our bias is toward using server-side prepared.
+ */
+ if ( nStatementType == MConnection::STATEMENT_DYNAMIC )
+ {
+ if ( command.isServerSidePreparePossible() )
+ nStatementType = MConnection::STATEMENT_STMT;
+ else
+ nStatementType = MConnection::STATEMENT_RES;
+ }
+
+ /* 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") );
+ nStatementType = MConnection::STATEMENT_RES;
+ }
+
+ /* create appropriate resultset object */
+ switch ( nStatementType )
+ {
+ case MConnection::STATEMENT_DYNAMIC:
case MConnection::STATEMENT_RES:
pResult = new MResultRes( this );
break;
@@ -3052,104 +3081,71 @@
case MConnection::STATEMENT_STMT:
pResult = new MResultStmt( this );
break;
+
+ default:
+ nReturn = getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0, QString(
tr("Unknown statement type %1") ).arg( nStatementType ) );
+ goto doPrepareExit1;
}
- /* do it */
- SQLRETURN nReturn = pResult->doPrepare( psStatementText );
+ /* ask resultset to do any further prepare */
+ nReturn = pResult->doPrepare( psStatementText );
if ( !SQL_SUCCEEDED( nReturn ) )
{
- Q_ASSERT( !pResult );
- delete pResult;
- pResult = NULL;
+ goto doPrepareExit2;
}
/*!
\internal
- \todo
+ \note
- Set SQL_DIAG_DYNAMIC_FUNCTION and SQL_DIAG_DYNAMIC_FUNCTION_CODE diagnostic
header fields and possibly use them instead
- of MResult statement type.
+ We silently start a transaction as needed. We do not rely upon the server doing
this for us but perhaps we should - will see.
*/
- switch ( pResult->getStatementType() )
- {
- case MResult::STATEMENT_TYPE_UPDATE:
- case MResult::STATEMENT_TYPE_DELETE:
- case MResult::STATEMENT_TYPE_INSERT:
- setState( STATE_S2 );
- break;
- case MResult::STATEMENT_TYPE_NULL:
- getDiagnostic()->doAppend( MDiagnostic::DIA_01000, 0,
tr("STATEMENT_TYPE_NULL should not happen here") );
- case MResult::STATEMENT_TYPE_MULTI:
- case MResult::STATEMENT_TYPE_SELECT:
- case MResult::STATEMENT_TYPE_SHOW:
- case MResult::STATEMENT_TYPE_PLUS:
- case MResult::STATEMENT_TYPE_OTHER:
- setState( STATE_S3 );
- break;
- }
-
- /*
- Handle transaction.
- */
- MConnection *pConnection = getConnection();
- switch ( pConnection->getInfoTxnCapable() )
- {
- case SQL_TC_NONE:
- break;
- case SQL_TC_DML:
- /*!
- \internal ODBC RULE
-
- Transactions can contain only Data Manipulation Language (DML) statements
(SELECT, INSERT, UPDATE,
- DELETE). Data Definition Language (DDL) statements encountered in a
transaction cause an error.
- */
- switch ( pResult->getStatementType() )
- {
- case MResult::STATEMENT_TYPE_SELECT:
- case MResult::STATEMENT_TYPE_UPDATE:
- case MResult::STATEMENT_TYPE_DELETE:
- case MResult::STATEMENT_TYPE_INSERT:
- if ( pConnection->getInfoTxnCapable() == SQL_TC_DML ||
pConnection->getInfoTxnCapable() == SQL_TC_ALL )
- break;
- case MResult::STATEMENT_TYPE_NULL:
- case MResult::STATEMENT_TYPE_MULTI:
- case MResult::STATEMENT_TYPE_SHOW:
- case MResult::STATEMENT_TYPE_PLUS:
- case MResult::STATEMENT_TYPE_OTHER:
- }
- case SQL_TC_DDL_COMMIT:
- case SQL_TC_DDL_IGNORE:
- case SQL_TC_ALL:
- }
-
-SQLRETURN MConnection::doTransactionStart()
-
if ( pConnection->isTransaction() == false )
{
- /* do we support transactions? */
- if ( pConnection->getInfoTxnCapable() == SQL_TC_NONE )
+ MConnection *pConnection = getConnection();
+ SQLRETURN nReturnTransactionStart = SQL_SUCCESS;
+ switch ( pConnection->getInfoTxnCapable() )
{
- /* should we start a transaction? */
- switch ( pResult->getStatementType() )
- {
- case MResult::STATEMENT_TYPE_SELECT:
- case MResult::STATEMENT_TYPE_UPDATE:
- case MResult::STATEMENT_TYPE_DELETE:
- case MResult::STATEMENT_TYPE_INSERT:
- if ( pConnection->getInfoTxnCapable() == SQL_TC_DML ||
pConnection->getInfoTxnCapable() == SQL_TC_ALL )
- break;
- case MResult::STATEMENT_TYPE_NULL:
- case MResult::STATEMENT_TYPE_MULTI:
- case MResult::STATEMENT_TYPE_SHOW:
- case MResult::STATEMENT_TYPE_PLUS:
- case MResult::STATEMENT_TYPE_OTHER:
- }
+ case SQL_TC_NONE:
+ break;
+ case SQL_TC_DML:
+ if ( command.isDataManipulationLanguage() )
+ nReturnTransactionStart = MConnection::doTransactionStart();
+ break;
+ case SQL_TC_DDL_COMMIT:
+ case SQL_TC_DDL_IGNORE:
+ break;
+ case SQL_TC_ALL:
+ nReturnTransactionStart = MConnection::doTransactionStart();
+ default:
+ nReturn = getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Unknown value from getInfoTxnCapable()") );
+ 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 ( command.isResultSetPossible() )
+ setState( STATE_S3 );
+ else
+ setState( STATE_S2 );
MYODBCDbgReturn( nReturn );
+
+doPrepareExit2:
+ delete pResult;
+ pResult = NULL;
+
+doPrepareExit1:
+ delete pCommands;
+ pCommands = NULL;
+
+ MYODBCDbgReturn( nReturn );
}
SQLRETURN MStatement::doPrimaryKeys( SQLWCHAR *psCatalog, SQLSMALLINT nLength1, SQLWCHAR
*psSchema, SQLSMALLINT nLength2, SQLWCHAR *psTable, SQLSMALLINT nLength3 )
| Thread |
|---|
| • Connector/ODBC 5 commit: r441 - trunk/MYSQLPlus/MYSQLPlusLib | pharvey | 14 Jul |