Modified:
trunk/SDK/C/include/MYODBCC.h
trunk/SDK/MYSQLPlus/Library/MResult.cpp
trunk/SDK/MYSQLPlus/Library/MResult.h
trunk/SDK/MYSQLPlus/Library/MResultPlus.h
trunk/SDK/MYSQLPlus/Library/MResultRes.cpp
trunk/SDK/MYSQLPlus/Library/MResultRes.h
trunk/SDK/MYSQLPlus/Library/MStatement.cpp
Log:
ENH: Mostly in place implementation of SQL_DATA_AT_EXEC support.
Modified: trunk/SDK/C/include/MYODBCC.h
===================================================================
--- trunk/SDK/C/include/MYODBCC.h 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/C/include/MYODBCC.h 2006-11-24 04:14:39 UTC (rev 688)
@@ -99,6 +99,8 @@
#define MYODBCCSet( A, B ) if ( A ) *A = B
+#define MYODBCCIsDataAtExec( A ) ( A && ( ( *A <= (-100) ) || ( *A ==
SQL_DATA_AT_EXEC ) ) )
+
/*!
\internal
\note
Modified: trunk/SDK/MYSQLPlus/Library/MResult.cpp
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResult.cpp 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/MYSQLPlus/Library/MResult.cpp 2006-11-24 04:14:39 UTC (rev 688)
@@ -101,12 +101,14 @@
{
MYODBCDbgEnter();
+ nPrevCall = PREV_CALL_NONE;
pDescriptorIPD = NULL;
pDescriptorAPD = NULL;
stringCommand.clear();
stringlistCommandSegments.clear();
nParameterFirst = 0;
nParameter = 0;
+ nCommandSegment = 0;
statePutData.doClear();
MYODBCDbgReturn2();
@@ -142,7 +144,7 @@
nConcurrency = SQL_CONCUR_READ_ONLY; // ReadOnly ResultSet
nCursorScrollable = SQL_NONSCROLLABLE; // doNext is only viable
cursor operation
nCursorSensitivity = SQL_UNSPECIFIED; // we do not share changes to
ResultSet enthusiastically
- nCursorType = SQL_CURSOR_FORWARD_ONLY; // Cursor can only scroll
forward
+ nCursorType = SQL_CURSOR_FORWARD_ONLY; // Cursor can only scroll
forward
nKeySetSize = 0; // cache keys for all rows
nMaxLength = 0; // get all column data for
large data types
nMaxRows = 0; // get all rows for resultset
@@ -683,6 +685,17 @@
MYODBCDbgReturn3( "%d", nState );
}
+SQLRETURN MResult::doPutData( SQLPOINTER pData, SQLINTEGER nStrLenOrInd )
+{
+ MYODBCDbgEnter();
+
+ SQLRETURN nReturn = SQL_SUCCESS;
+
+ stateExecute.nPrevCall = MStateExecute::PREV_CALL_PUT_DATA;
+
+ MYODBCDbgReturn( nReturn );
+}
+
/*!
\brief Refresh the application buffers.
@@ -1047,6 +1060,16 @@
MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::STATE_HY000, 0,
tr("Unknown condition in doNext().") ) );
}
+SQLRETURN MResult::doParamData( SQLPOINTER pValue )
+{
+ MYODBCDbgEnter();
+
+ SQLRETURN nReturn = doSubmitCommand( &stateExecute, pValue );
+ stateExecute.nPrevCall = MStateExecute::PREV_CALL_PARAM_DATA;
+
+ MYODBCDbgReturn( nReturn );
+}
+
/*!
\brief Prepares the provided statement.
Modified: trunk/SDK/MYSQLPlus/Library/MResult.h
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResult.h 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/MYSQLPlus/Library/MResult.h 2006-11-24 04:14:39 UTC (rev 688)
@@ -84,16 +84,28 @@
class MStateExecute
{
public:
+ enum PREV_CALL
+ {
+ PREV_CALL_NONE,
+ PREV_CALL_EXECUTE,
+ PREV_CALL_BULK_OPERATIONS,
+ PREV_CALL_SET_POS,
+ PREV_CALL_PARAM_DATA,
+ PREV_CALL_PUT_DATA
+ };
+
MStateExecute();
void doClear();
+ PREV_CALL nPrevCall; /*!< out state is based upon prev.
call made */
MDescriptorIPD *pDescriptorIPD; /*!< current IPD
*/
MDescriptorAPD *pDescriptorAPD; /*!< current APD
*/
QString stringCommand; /*!< command we will submit to server
*/
QStringList stringlistCommandSegments; /*!< command split on parameter
markers */
SQLUSMALLINT nParameterFirst; /*!< offset because parameters may be
spread out over multiple commands */
int nParameter; /*!< current parameter
*/
+ int nCommandSegment; /*!< current command segment
*/
MStatePutData statePutData; /*!< state to support doPutData
*/
};
@@ -320,8 +332,10 @@
virtual SQLRETURN doInsert() = 0; /*!<
Operates on RowSetRow. */
virtual SQLRETURN doLast( BOOL bRefresh = true ); /*!<
Moves cursor/rowset to end of resultset. */
virtual SQLRETURN doNext( BOOL bRefresh = true ); /*!<
Moves cursor/rowset forward by 1 rowset size. */
+ SQLRETURN doParamData( SQLPOINTER pValue );
virtual SQLRETURN doPrepare( MCommand *pCommand ); /*!<
Prepare the given command. */
virtual SQLRETURN doPrev( BOOL bRefresh = true ); /*!<
Moves cursor/rowset back by 1 rowset size. */
+ SQLRETURN doPutData( SQLPOINTER pData, SQLINTEGER nStrLenOrInd );
virtual SQLRETURN doRefresh(); /*!<
Load/refreshs bound buffers provided by application. */
virtual SQLRETURN doSkip( qlonglong nRowSets, BOOL bRefresh = true ); /*!<
Moves cursor/rowset relative to current row in resultset. */
@@ -423,7 +437,7 @@
virtual SQLRETURN doRefresh( SQLUINTEGER nRowSetRow );
virtual SQLRETURN doRefreshArray( SQLUINTEGER nRowSetRow );
virtual SQLRETURN doRefreshArray( SQLUINTEGER nRowSetRow, SQLUINTEGER nLength );
- virtual SQLRETURN doSubmitCommand( MStateExecute *pStateExecute ) = 0;
+ virtual SQLRETURN doSubmitCommand( MStateExecute *pStateExecute, SQLPOINTER pValue
= NULL ) = 0;
virtual SQLRETURN doSubmitCommand( const QString &stringCommand ) = 0;
/*!
Modified: trunk/SDK/MYSQLPlus/Library/MResultPlus.h
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResultPlus.h 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/MYSQLPlus/Library/MResultPlus.h 2006-11-24 04:14:39 UTC (rev 688)
@@ -83,7 +83,7 @@
SQLRETURN doStateRollBack( STATE nState );
SQLRETURN doApplyCursorRestrictions();
SQLRETURN doAppendVarChar();
- SQLRETURN doSubmitCommand( MStateExecute * ) { MYODBCDbgEnter(); MYODBCDbgReturn(
SQL_SUCCESS ); }
+ SQLRETURN doSubmitCommand( MStateExecute *, SQLPOINTER ) { MYODBCDbgEnter();
MYODBCDbgReturn( SQL_SUCCESS ); }
SQLRETURN doSubmitCommand( const QString & ) { MYODBCDbgEnter(); MYODBCDbgReturn(
SQL_SUCCESS ); }
/*!
Modified: trunk/SDK/MYSQLPlus/Library/MResultRes.cpp
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResultRes.cpp 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/MYSQLPlus/Library/MResultRes.cpp 2006-11-24 04:14:39 UTC (rev 688)
@@ -191,6 +191,15 @@
if ( getState() > STATE_PREPARED )
doStateRollBack( STATE_PREPARED );
+ /*!
+ \internal ODBC RULE (DM)
+
+ SQLExecute, SQLExecDirect, SQLBulkOperations, or SQLSetPos was called for the
StatementHandle and returned SQL_NEED_DATA.
+ This function was called before data was sent for all data-at-execution
parameters or columns.
+ */
+ if ( stateExecute.nPrevCall != MStateExecute::PREV_CALL_NONE )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::STATE_HY010 ) );
+
stateExecute.pDescriptorIPD = (MDescriptorIPD*)getImpParamDesc();
stateExecute.pDescriptorAPD = (MDescriptorAPD*)getAppParamDesc();
@@ -232,6 +241,8 @@
SQLRETURN nReturn = doSubmitCommand( &stateExecute );
+ stateExecute.nPrevCall = MStateExecute::PREV_CALL_EXECUTE;
+
MYODBCDbgReturn( nReturn );
}
@@ -287,7 +298,7 @@
\retval SQL_NEED_DATA
\retval SQL_ERROR
*/
-SQLRETURN MResultRes::doSubmitCommand( MStateExecute *pStateExecute )
+SQLRETURN MResultRes::doSubmitCommand( MStateExecute *pStateExecute, SQLPOINTER pValue )
{
MYODBCDbgEnter();
@@ -303,43 +314,66 @@
SQLBindParameter was greater than the number of parameters in the SQL statement
contained in *StatementText.
*/
/* Insert any parameters */
-
- pStateExecute->nParameter = 1;
- for ( int nCommandSegment = 0; nCommandSegment <
pStateExecute->stringlistCommandSegments.count(); nCommandSegment++ )
+ while ( pStateExecute->nCommandSegment <
pStateExecute->stringlistCommandSegments.count() )
{
/* parameter marker? */
- if ( pStateExecute->stringlistCommandSegments.at( nCommandSegment ) == "?" )
+ if ( pStateExecute->stringlistCommandSegments.at(
pStateExecute->nCommandSegment ) == "?" )
{
pStateExecute->statePutData.doClear();
pStateExecute->statePutData.pDescriptorRecordIPD =
(MDescriptorRecordIPD*)pStateExecute->pDescriptorIPD->getRecord(
pStateExecute->nParameterFirst + pStateExecute->nParameter );
pStateExecute->statePutData.pDescriptorRecordAPD =
(MDescriptorRecordAPD*)pStateExecute->pDescriptorAPD->getRecord(
pStateExecute->nParameterFirst + pStateExecute->nParameter );
- nReturnInternal = fromC( &pStateExecute->statePutData );
- switch ( nReturnInternal )
+ SQLINTEGER *pnOctetLengthPtr =
pStateExecute->statePutData.pDescriptorRecordAPD->getOctetLengthPtr();
+ /* data-at-exec? If so we need to use doParamData & doPutData. */
+ if ( MYODBCCIsDataAtExec( pnOctetLengthPtr ) )
{
- case SQL_SUCCESS:
- break;
- case SQL_SUCCESS_WITH_INFO:
- nReturn = nReturnInternal;
- break;
- case SQL_ERROR:
- default:
- doStateRollBack( STATE_INITIALIZED );
- MYODBCDbgReturn( nReturnInternal );
+ /* called by doExecute etc? If so defer to doParamData (which will bring
us back to here). */
+ if ( pStateExecute->nPrevCall == MStateExecute::PREV_CALL_NONE )
+ MYODBCDbgReturn( SQL_NEED_DATA );
+
+ /* called by doParamData *after* doPutData? If so we have data to get
into stringCommand. */
+ if ( pStateExecute->nPrevCall == MStateExecute::PREV_CALL_PUT_DATA )
+ ;
+ else if ( pStateExecute->nPrevCall ==
MStateExecute::PREV_CALL_PUT_DATA )
+ ;
+ else
+ MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::STATE_07006 ) );
+ MYODBCDbgReturn( SQL_NEED_DATA );
+
}
-#if MYODBC_DBG > 1
-MYODBCDbgInfo( QString( "variantData.isNull=%1" ).arg(
pStateExecute->statePutData.variantData.isNull() ) );
-MYODBCDbgInfo( QString( "variantData=%1" ).arg(
pStateExecute->statePutData.variantData.toString() ) );
-#endif
+ else
+ {
+ pStateExecute->nParameter++;
+
+ nReturnInternal = fromC( &pStateExecute->statePutData );
+ switch ( nReturnInternal )
+ {
+ case SQL_SUCCESS:
+ break;
+ case SQL_SUCCESS_WITH_INFO:
+ nReturn = nReturnInternal;
+ break;
+ case SQL_ERROR:
+ default:
+ doStateRollBack( STATE_INITIALIZED );
+ MYODBCDbgReturn( nReturnInternal );
+ }
+ #if MYODBC_DBG > 1
+ MYODBCDbgInfo( QString( "variantData.isNull=%1" ).arg(
pStateExecute->statePutData.variantData.isNull() ) );
+ MYODBCDbgInfo( QString( "variantData=%1" ).arg(
pStateExecute->statePutData.variantData.toString() ) );
+ #endif
+ }
+
pStateExecute->stringCommand +=
pStateExecute->statePutData.variantData.toString();
- pStateExecute->nParameter++;
- continue;
}
+ else
+ /* plain statement segment */
+ pStateExecute->stringCommand +=
pStateExecute->stringlistCommandSegments.at( pStateExecute->nCommandSegment );
- /* plain statement segment */
- pStateExecute->stringCommand +=
pStateExecute->stringlistCommandSegments.at( nCommandSegment );
- }
+ pStateExecute->nCommandSegment++;
+ } // while segments
+
/* All parameters have been resolved so submit command to server... */
nReturn = doSubmitCommand( pStateExecute->stringCommand );
Modified: trunk/SDK/MYSQLPlus/Library/MResultRes.h
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResultRes.h 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/MYSQLPlus/Library/MResultRes.h 2006-11-24 04:14:39 UTC (rev 688)
@@ -43,7 +43,7 @@
protected:
/* doers */
- virtual SQLRETURN doSubmitCommand( MStateExecute *pStateExecute );
+ virtual SQLRETURN doSubmitCommand( MStateExecute *pStateExecute, SQLPOINTER pValue
= NULL );
virtual SQLRETURN doSubmitCommand( const QString &stringCommand );
/*!
Modified: trunk/SDK/MYSQLPlus/Library/MStatement.cpp
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MStatement.cpp 2006-11-23 15:36:13 UTC (rev 687)
+++ trunk/SDK/MYSQLPlus/Library/MStatement.cpp 2006-11-24 04:14:39 UTC (rev 688)
@@ -3833,7 +3833,7 @@
*/
pDiagnostic->doClear();
- MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::STATE_IM001 ) );
+ MYODBCDbgReturn( getResult()->doParamData( ppValuePtrPtr ) );
}
/*!
@@ -4529,7 +4529,7 @@
source */
- MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::STATE_IM001 ) );
+ MYODBCDbgReturn( getResult()->doPutData( pDataPtr, nStrLenOrInd ) );
}
SQLRETURN MStatement::doRowCount( SQLINTEGER *pnRowCount )
| Thread |
|---|
| • Connector/ODBC 5 commit: r688 - in trunk/SDK: C/include MYSQLPlus/Library | pharvey | 24 Nov |