Modified:
trunk/SDK/MYSQLPlus/Library/MResult.cpp
trunk/SDK/MYSQLPlus/Library/MResult.h
Log:
changes/additions for block-cursor support
Modified: trunk/SDK/MYSQLPlus/Library/MResult.cpp
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResult.cpp 2006-09-12 03:32:41 UTC (rev 540)
+++ trunk/SDK/MYSQLPlus/Library/MResult.cpp 2006-09-13 06:40:44 UTC (rev 541)
@@ -607,6 +607,14 @@
/*!
\brief Refresh the application buffers.
+ We must handle the following types of binding;
+
+ 1. normal row binding
+ 2. array binding - column-wise
+ 3. array binding - row-wise
+
+ In anycase we process all rows in RowSet.
+
- SQL_ATTR_ROW_STATUS_PTR (row status buffer - must match the RowSetSize)
- SQL_ROW_SUCCESS
- SQL_ROW_SUCCESS_WITH_INFO
@@ -628,29 +636,50 @@
if ( getState() < STATE_EXECUTED )
MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
+ if ( !isValidResultSetRow() )
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_24000 ) );
+
resultSetData.doClear();
resultGetData.doClear();
- SQLUINTEGER nRow = 0;
+ /* save some cycles by getting this here */
+ MDescriptor *pDescriptor = getAppRowDesc();
- /* get index into vectorRows for ResultSetRow (first row of RowSet) */
- if ( isValidResultSetRow() )
- nRow = getResultSetRowIndex();
+ /*!
+ \internal ODBC RULE
+ ...points to a buffer in which to return the number of rows fetched after a call
to SQLFetch or SQLFetchScroll; the number of rows affected
+ by a bulk operation performed by a call to SQLSetPos with an Operation argument
of SQL_REFRESH; or the number of rows affected by a bulk
+ operation performed by SQLBulkOperations. This number includes error rows.
+ */
+ if ( pDescriptor->getRowsProcessedPtr() )
+ *(pDescriptor->getRowsProcessedPtr()) = getRowSetRows();
+
+ /* short circuit if nothing to do... */
+ if ( getRowSetSize() )
+ {
+ if ( !pDescriptor->getCount() && !pDescriptor->getArrayStatusPtr()
)
+ MYODBCDbgReturn( SQL_SUCCESS );
+ }
+ else if ( !pDescriptor->getCount() )
+ MYODBCDbgReturn( SQL_SUCCESS );
+
/* for each row in RowSet */
- for ( ; nRow < nRowSetSize; nRow++ )
+ for ( SQLUINTEGER nRowSetRow = 1; nRowSetRow <= getRowSetSize(); nRowSetRow++ )
{
- if ( getRowSetSize() > 1 )
+ SQLRETURN nReturn;
+
+ /* bound array? */
+ if ( getRowSetSize() )
{
- SQLUINTEGER nRowBindType = getAppRowDesc()->getBindType();
-
- if ( nRowBindType == SQL_BIND_BY_COLUMN )
- doRefreshArray( nRow );
+ /* column or row-wise binding? */
+ if ( pDescriptor->getBindType() == SQL_BIND_BY_COLUMN )
+ nReturn = doRefreshArray( nRowSetRow );
else
- doRefreshArray( nRow, nRowBindType /* length of a structure or an
instance of a buffer */ );
+ nReturn = doRefreshArray( nRowSetRow, pDescriptor->getBindType() /*
length of a structure */ );
}
else
- doRefresh( nRow );
+ nReturn = doRefresh( nRowSetRow );
}
MYODBCDbgReturn( SQL_SUCCESS );
@@ -1079,7 +1108,7 @@
SQL_NO_DATA - ResultSet is empty.
SQL_ERROR - State < STATE_EXECUTED
*/
-SQLRETURN MResult::doSkip( qlonglong nRows )
+SQLRETURN MResult::doSkip( qlonglong nRows, BOOLEAN bRefresh )
{
MYODBCDbgEnter();
@@ -1103,7 +1132,7 @@
+--------------------------------------------------+-----------------------------------+
*/
if ( ( isBeforeStart() && nRows > 0 ) || ( isAfterEnd() && nRows
< 0 ) )
- MYODBCDbgReturn( doGoto( nRows ) );
+ MYODBCDbgReturn( doGoto( nRows, bRefresh ) );
/*!
\internal ODBC RULE
@@ -1690,7 +1719,7 @@
This supports the getData() which operates on RowSetRow AND doRefresh()
(bound array or single row).
*/
-SQLRETURN MResult::getData( SQLUINTEGER nRow, SQLUSMALLINT nColumn, SQLSMALLINT
nTargetType, SQLPOINTER pTarget, SQLINTEGER nBufferLength, SQLINTEGER *pnLength,
SQLINTEGER *pnIndicator )
+SQLRETURN MResult::getData( SQLUINTEGER nRowsIndex, SQLUSMALLINT nColumn, SQLSMALLINT
nTargetType, SQLPOINTER pTarget, SQLINTEGER nBufferLength, SQLINTEGER *pnLength,
SQLINTEGER *pnIndicator )
{
MYODBCDbgEnter();
@@ -1700,7 +1729,7 @@
We are chunking data when we get the same row & column being used for more
than 1 successive call
to here.
*/
- if ( resultGetData.isChunkingRequest( nRow, nColumn ) )
+ if ( resultGetData.isChunkingRequest( nRowsIndex, nColumn ) )
{
if ( MDescriptorRecordIRD::isVariableLength(
resultGetData.pDescriptorRecordIRD->getConciseType() ) )
{
@@ -1744,7 +1773,7 @@
resultGetData.pnBytesRemaining = pnLength;
resultGetData.pnIndicator = pnIndicator;
resultGetData.pTarget = pTarget;
- resultGetData.nRow = nRow;
+ resultGetData.nRow = nRowsIndex;
if ( !resultGetData.pnBytesRemaining )
resultGetData.pnBytesRemaining = &resultGetData.nBytesRemaining;
@@ -1990,9 +2019,22 @@
SQLUINTEGER MResult::getRowSetRowIndex()
{
MYODBCDbgEnter();
+ MYODBCDbgReturn3( "%d", getRowSetRowIndex( getRowSetRow() ) );
+}
- SQLUINTEGER nIndex = getResultSetRowIndex() + getRowSetRow() - 1;
+/*!
+ \brief Get the index into vectorRows for given RowSetRow.
+ \param nRowSetRow The desired RowSetRow. This is 1-based and *assumed* valid.
+
+ \return SQLUINTEGER 0-based index into vectorRows.
+*/
+SQLUINTEGER MResult::getRowSetRowIndex( SQLUSMALLINT nRowSetRow )
+{
+ MYODBCDbgEnter();
+
+ SQLUINTEGER nIndex = getResultSetRowIndex() + nRowSetRow - 1;
+
MYODBCDbgReturn3( "%d", nIndex );
}
@@ -4719,12 +4761,11 @@
We assume nRow is valid.
- \param nRow Desired row. An index into vectorRows.
+ \param nRowSetRow Desired row. This is 1-based. We assume its valid.
\return SQLRETURN
-
*/
-SQLRETURN MResult::doRefresh( SQLUINTEGER nRow )
+SQLRETURN MResult::doRefresh( SQLUINTEGER nRowSetRow )
{
MYODBCDbgEnter();
@@ -4735,24 +4776,32 @@
Load any bound columns from SQLBindCol/ARD. Use getData to reduce redundant code.
Using
getData in this way may not be optimal - need to revisit.
*/
- MDescriptor *pDescriptor = getAppRowDesc();
- SQLSMALLINT nColumns = pDescriptor->getCount();
+ MDescriptor *pAppRowDesc = getAppRowDesc();
+ SQLUINTEGER nRowsIndex = getRowSetRowIndex( nRowSetRow );
- for ( SQLSMALLINT nColumn = 0; nColumn <= nColumns; nColumn++ )
+ for ( SQLSMALLINT nColumn = 0; nColumn <= pAppRowDesc->getCount(); nColumn++ )
{
- MDescriptorRecordARD *pDescriptorRecord = (MDescriptorRecordARD
*)pDescriptor->getRecord( nColumn );
+ MDescriptorRecord *pAppRowDescRec = pAppRowDesc->getRecord( nColumn );
- if ( pDescriptorRecord->getDataPtr() )
+ /* is column bound? */
+ if ( pAppRowDescRec->getDataPtr() )
{
- SQLRETURN nReturn = MResult::getData( nRow,
- nColumn,
- pDescriptorRecord->getConciseType(),
- pDescriptorRecord->getDataPtr(),
- pDescriptorRecord->getLength(),
-
pDescriptorRecord->getOctetLengthPtr(),
- pDescriptorRecord->getIndicatorPtr()
);
- if ( nReturn != SQL_SUCCESS )
- MYODBCDbgReturn( nReturn );
+ SQLINTEGER *pnOctetLengthPtr= pAppRowDescRec->getOctetLengthPtr();
+ SQLINTEGER *pnIndicatorPtr = pAppRowDescRec->getIndicatorPtr();
+
+ if ( (pnOctetLengthPtr && *pnOctetLengthPtr == SQL_COLUMN_IGNORE) ||
+ (pnIndicatorPtr && *pnIndicatorPtr == SQL_COLUMN_IGNORE) )
+ {
+ SQLRETURN nReturn = MResult::getData( nRowsIndex,
+ nColumn,
+
pAppRowDescRec->getConciseType(),
+ pAppRowDescRec->getDataPtr(),
+ pAppRowDescRec->getLength(),
+ pnOctetLengthPtr,
+ pnIndicatorPtr );
+ if ( nReturn != SQL_SUCCESS )
+ MYODBCDbgReturn( nReturn );
+ }
}
}
@@ -4760,35 +4809,76 @@
}
/*!
+ \brief Refresh the application buffers.
- - SQL_ATTR_ROW_BIND_TYPE
+ In this case we are dealing with a bound array and our RowSetSize > 1. In
this case
+ binding in the ARD is for COLUMN wise binding.
- - SQL_DESC_INDICATOR_PTR
- - SQL_DESC_OCTET_LENGTH_PTR (if diff than SQL_DESC_INDICATOR_PTR)
+ \param nRowSetRow Desired row. This is 1-based. We assume its valid.
+
+ \return SQLRETURN
*/
-SQLRETURN MResult::doRefreshArray( SQLUINTEGER nRow )
+SQLRETURN MResult::doRefreshArray( SQLUINTEGER nRowSetRow )
{
MYODBCDbgEnter();
+ MDescriptor *pAppRowDesc = getAppRowDesc();
+ MDescriptor *pImpRowDesc = getImpRowDesc();
+ SQLUINTEGER nRowsIndex = getRowSetRowIndex( nRowSetRow );
+
/*!
\internal ODBC RULE
Entries in the row status array state whether each row was fetched successfully,
whether
- it was updated, added, or deleted since it was last fetched, and whether an error
occurred
+ it was updated, added, or deleted *since it was last fetched*, and whether an
error occurred
while fetching the row.
*/
- SQLUSMALLINT *pnArrayStatus = getImpRowDesc()->getArrayStatusPtr();
+ if ( pImpRowDesc->getArrayStatusPtr() )
+ pImpRowDesc->getArrayStatusPtr()[nRowSetRow-1] = vectorRows.at( nRowsIndex
).nStatus;
- if ( pnArrayStatus )
- pnArrayStatus[nRow] = vectorRows.at( nRow ).nStatus;
+ for ( SQLSMALLINT nColumn = 0; nColumn <= pAppRowDesc->getCount(); nColumn++ )
+ {
+ MDescriptorRecord *pAppRowDescRec = pAppRowDesc->getRecord( nColumn );
+ char * pDataPtr = NULL;
+ SQLINTEGER * pnOctetLengthPtr= NULL;
+ SQLINTEGER * pnIndicatorPtr = NULL;
+
+ if ( pAppRowDescRec->getDataPtr() )
+ pDataPtr = ((char**)pAppRowDescRec->getDataPtr())[nRowSetRow-1];
+
+ if ( pAppRowDescRec->getOctetLengthPtr() )
+ pnOctetLengthPtr =
((SQLINTEGER**)pAppRowDescRec->getOctetLengthPtr())[nRowSetRow-1];
+
+ if ( pAppRowDescRec->getIndicatorPtr() )
+ pnIndicatorPtr =
((SQLINTEGER**)pAppRowDescRec->getIndicatorPtr())[nRowSetRow-1];
+
+ /* is column bound? */
+ if ( pDataPtr )
+ {
+ if ( (pnOctetLengthPtr && *pnOctetLengthPtr == SQL_COLUMN_IGNORE) ||
+ (pnIndicatorPtr && *pnIndicatorPtr == SQL_COLUMN_IGNORE) )
+ {
+ SQLRETURN nReturn = MResult::getData( nRowsIndex,
+ nColumn,
+
pAppRowDescRec->getConciseType(),
+ pDataPtr,
+ pAppRowDescRec->getLength(),
+ pnOctetLengthPtr,
+ pnIndicatorPtr );
+ if ( nReturn != SQL_SUCCESS )
+ MYODBCDbgReturn( nReturn );
+ }
+ }
+ }
+
MYODBCDbgReturn( SQL_SUCCESS );
}
-SQLRETURN MResult::doRefreshArray( SQLUINTEGER nRow, SQLUINTEGER nLengthOrBuffer )
+SQLRETURN MResult::doRefreshArray( SQLUINTEGER /* nRowSetRow */, SQLUINTEGER /* nLength
*/ )
{
MYODBCDbgEnter();
- MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_DIA_HYC00, 0,
tr("Row-wise binding not supported.") ) );
+ MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HYC00, 0,
tr("Row-wise binding not supported.") ) );
}
Modified: trunk/SDK/MYSQLPlus/Library/MResult.h
===================================================================
--- trunk/SDK/MYSQLPlus/Library/MResult.h 2006-09-12 03:32:41 UTC (rev 540)
+++ trunk/SDK/MYSQLPlus/Library/MResult.h 2006-09-13 06:40:44 UTC (rev 541)
@@ -405,14 +405,15 @@
MYSQL * getMySQL();
virtual SQLUINTEGER getResultSetRowIndex();
virtual SQLUINTEGER getRowSetRowIndex();
+ virtual SQLUINTEGER getRowSetRowIndex( SQLUSMALLINT nRowSetRow /* 1-based */ );
MStatement * getStatement();
/* doers */
virtual SQLRETURN doStateRollBack( STATE nState ) = 0;
SQLRETURN doLoadMetaDataField( unsigned int nField, MYSQL_FIELD *pField,
MDescriptorIRD *pDescriptor );
- virtual SQLRETURN doRefresh( SQLUINTEGER nRow );
- virtual SQLRETURN doRefreshArray( SQLUINTEGER nRow );
- virtual SQLRETURN doRefreshArray( SQLUINTEGER nRow, SQLUINTEGER nLengthOrBuffer );
+ virtual SQLRETURN doRefresh( SQLUINTEGER nRowSetRow );
+ virtual SQLRETURN doRefreshArray( SQLUINTEGER nRowSetRow );
+ virtual SQLRETURN doRefreshArray( SQLUINTEGER nRowSetRow, SQLUINTEGER nLength );
/*!
\name from*SQL
| Thread |
|---|
| • Connector/ODBC 5 commit: r541 - trunk/SDK/MYSQLPlus/Library | pharvey | 13 Sep |