List:Commits« Previous MessageNext Message »
From:pharvey Date:September 13 2006 8:40am
Subject:Connector/ODBC 5 commit: r541 - trunk/SDK/MYSQLPlus/Library
View as plain text  
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/Librarypharvey13 Sep