List:Commits« Previous MessageNext Message »
From:pharvey Date:May 12 2006 7:04am
Subject:Connector/ODBC 5 commit: r225 - MYSQLPlus/MYSQLPlusLib
View as plain text  
Modified:
   MYSQLPlus/MYSQLPlusLib/MResult.h
   MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp
   MYSQLPlus/MYSQLPlusLib/MResultPlus.h
   MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp
   MYSQLPlus/MYSQLPlusLib/MResultStmt.h
Log:


Modified: MYSQLPlus/MYSQLPlusLib/MResult.h
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResult.h	2006-05-11 19:43:45 UTC (rev 224)
+++ MYSQLPlus/MYSQLPlusLib/MResult.h	2006-05-12 05:04:38 UTC (rev 225)
@@ -61,18 +61,20 @@
     virtual SQLRETURN doPrepare( const SQLWCHAR *psStatement ) = 0;
     virtual SQLRETURN doPrev() = 0;
     virtual SQLRETURN doSkip( qlonglong nRows ) = 0;
+    virtual SQLRETURN doCommit() = 0;
 
     /* isers */
     virtual BOOLEAN isValidColumn( uint nColumn );
     virtual BOOLEAN isValidRow() = 0;
     virtual BOOLEAN isValidRow( qulonglong nRow ) = 0;
     BOOLEAN isBuffered();
+    virtual BOOLEAN isDirty() = 0;
 
 protected:
 
     /* setters */
     BOOLEAN setState( STATE nState );
-    virtual BOOLEAN setBuffered( BOOLEAN bBuffered );
+    virtual BOOLEAN   setBuffered( BOOLEAN bBuffered );
 
     /* getters */
     MStatement *    getStatement();

Modified: MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp	2006-05-11 19:43:45 UTC (rev 224)
+++ MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp	2006-05-12 05:04:38 UTC (rev 225)
@@ -312,6 +312,16 @@
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
+SQLRETURN MResultPlus::doCommit()
+{
+    MYODBCDbgEnter();
+
+    if ( getState() < STATE_EXECUTED )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
+
+    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010, 0,
tr("Resultset is read-only.") ) );
+}
+
 SQLRETURN MResultPlus::doGetTypeInfo( SQLSMALLINT nDataType )
 {
     MYODBCDbgEnter();
@@ -480,6 +490,12 @@
     MYODBCDbgReturn3( "%d", b );
 }
 
+BOOLEAN MResultPlus::isDirty()
+{
+    MYODBCDbgEnter();
+    MYODBCDbgReturn3( "%d", false );
+}
+
 SQLRETURN MResultPlus::doStateRollBack( STATE nState )
 {
     MYODBCDbgEnter();

Modified: MYSQLPlus/MYSQLPlusLib/MResultPlus.h
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultPlus.h	2006-05-11 19:43:45 UTC (rev 224)
+++ MYSQLPlus/MYSQLPlusLib/MResultPlus.h	2006-05-12 05:04:38 UTC (rev 225)
@@ -60,12 +60,14 @@
     SQLRETURN doPrepare( const SQLWCHAR *psStatement );
     SQLRETURN doPrev();
     SQLRETURN doSkip( qlonglong nRows );
+    SQLRETURN doCommit();
 
     SQLRETURN doGetTypeInfo( SQLSMALLINT nDataType );   /*<! \sa SQLGetTypeInfo */
 
     /* isers */
     BOOLEAN isValidRow();
     BOOLEAN isValidRow( qulonglong nRow );
+    BOOLEAN isDirty();
 
 protected:
     /* doers */

Modified: MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp	2006-05-11 19:43:45 UTC (rev 224)
+++ MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp	2006-05-12 05:04:38 UTC (rev 225)
@@ -12,6 +12,7 @@
 
     setState( STATE_UNINITIALIZED );
     pbindColumns    = NULL;
+    nRow            = 0;
 
     /* init pstm */
     pstm = mysql_stmt_init( (MYSQL*)(pStatement->getConnection()->getMySQL()) );
@@ -19,9 +20,11 @@
     {
         /*!
             \internal
-            \note   We turn STMT_ATTR_UPDATE_MAX_LENGTH on so we can allocate optimal
sized column buffers
-                    for returning data. This may be improved upon in the future using
chunking or possibly
-                    allocating buffers based upon the max a column could have according
to schema.
+            \note   
+
+            We turn STMT_ATTR_UPDATE_MAX_LENGTH on so we can allocate optimal sized
column buffers
+            for returning data. This may be improved upon in the future using chunking or
possibly
+            allocating buffers based upon the max a column could have according to
schema.
         */
         int bUpdateMaxLength = 1;
         if ( mysql_stmt_attr_set( pstm, STMT_ATTR_UPDATE_MAX_LENGTH,
&bUpdateMaxLength ) )
@@ -81,7 +84,7 @@
     /*! \internal
         \todo 
 
-        Revisit this method and see about implementing.
+        Implement.
     */
 
     MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0, tr("setData
not supported here at this time.") ) );
@@ -123,24 +126,20 @@
     if ( !isBuffered() )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("setRow() not supported for unbuffered resultset") ) );
 
-    if ( !isValidRow( nRow ) )
+    if ( nRow == 0 )
     {
-        nRow = 0;
+        this->nRow = nRow;
+        MYODBCDbgReturn( SQL_SUCCESS );
+    }
+    else if ( !isValidRow( nRow ) )
+    {
+        this->nRow = 0;
         MYODBCDbgReturn( SQL_NO_DATA );
     }
 
     Q_ASSERT( !pstm );
 
-    /*!
-        \internal MYSQL RULE
-
-        mysql_stmt_data_seek() has no return value and produces no errors - joy.
-    */
-    mysql_stmt_data_seek( pstm, nRow - 1 ); 
-    if ( mysql_stmt_errno( pstm ) )
-        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
-
-    MYODBCDbgReturn( SQL_SUCCESS );
+    MYODBCDbgReturn( doSeek( nRow ) );
 }
 
 /*! 
@@ -203,8 +202,18 @@
 
     if ( nColumn == 0 )
     {
+        /*!
+            \internal
+            \todo
+
+            Handle times when row does not work for a bookmark. For example; when
+            we can not get a valid row number from getRow() or when we are updating
+            the resultset with calls like doInsert().
+        */
         qulonglong nRow;
-        variantData = getRow( &); // bookmark - using row has limitations  !!!
+        if ( !SQL_SUCCEEDED( getRow( &nRow ) ) )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("could not determine bookmark value") ) );
+        variantData = nRow; 
     }
     else
     {
@@ -268,229 +277,11 @@
 }
 
 
-/*!
-    \brief  This gets column data from the drivers row buffers.
-
-    \param  nColumn             The column we are dealing with.
-    \param  pDescriptorRecord   This is a bound ARD.
-
-    \return SQLRETURN
-
-    \sa     getData
-*/
-SQLRETURN MResultStmt::getData( uint nColumn, MDescriptorRecordARD *pDescriptorRecord )
-{
-    MYODBCDbgEnter();
-
-    QVariant        variantData;
-    MYSQL_BIND *    pbind           = &(pbindColumns[nColumn]);
-    SQLRETURN       nReturn         = getData( nColumn, variantData );
-    SQLPOINTER      pdata           = pDescriptorRecord->getDataPtr();
-    SQLINTEGER *    pnIndicator     = pDescriptorRecord->getIndicatorPtr();
-    SQLINTEGER *    pnOctetLength   = pDescriptorRecord->getOctetLengthPtr();
-
-    if ( getState() < STATE_EXECUTED )
-        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
-
-    if ( variantData.isNull() )
-    {
-        if ( pnIndicator ) 
-        {
-            *pnIndicator = SQL_NULL_DATA;
-            MYODBCDbgReturn( SQL_SUCCESS );
-        }
-        else
-            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_22002 ) );
-    }
-
-    if ( pnIndicator ) *pnIndicator = 0;
-
-    switch ( pDescriptorRecord->getConciseType() )
-    {
-        case SQL_C_CHAR:
-            {
-                if ( !variantData.canConvert<QString>() )
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                QString stringData = variantData.asString();
-                MYODBCC::doStrNCpy( (SQLWCHAR)pdata,
pDescriptorRecord->getOctetLength() / sizeof(SQLWCHAR), stringData.utf16() );
-                if ( pnOctetLength ) *pnOctetLength = stringData.length() *
sizeof(SQLWCHAR);
-            }
-            break;
-        case SQL_C_SSHORT:
-            {
-                if ( !variantData.canConvert<short int>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((short int*)pdata) = (short int)variantData.toInt();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(short int);
-            }
-            break;
-        case SQL_C_USHORT:
-            {
-                if ( !variantData.canConvert<unsigned short int>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((unsigned short int*)pdata) = (unsigned short int)variantData.toUInt();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned short int);
-            }
-            break;
-        case SQL_C_SLONG:
-            {
-                if ( !variantData.canConvert<long int>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((long int*)pdata) = (long int)variantData.toLongLong();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(long int);
-            }
-            break;
-        case SQL_C_ULONG:
-            {
-                if ( !variantData.canConvert<unsigned long int>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((unsigned long int*)pdata) = (unsigned long
int)variantData.toULongLong();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned long int);
-            }
-            break;
-        case SQL_C_FLOAT:
-            {
-                if ( !variantData.canConvert<float>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((float *)pdata) = (float)variantData.toDouble();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(float);
-            }
-            break;
-        case SQL_C_DOUBLE:
-            {
-                if ( !variantData.canConvert<double>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((double *)pdata) = (double)variantData.toDouble();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(double);
-            }
-            break;
-        case SQL_C_BIT:
-            {
-                if ( !variantData.canConvert<unsigned char>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((unsigned char *)pdata) = variantData.toInt();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned char);
-            }
-            break;
-        case SQL_C_STINYINT:
-            {
-                if ( !variantData.canConvert<char>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((char *)pdata) = variantData.toInt();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(char);
-            }
-            break;
-        case SQL_C_UTINYINT:
-            {
-                if ( !variantData.canConvert<unsigned char>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((unsigned char *)pdata) = variantData.toUInt();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned char);
-            }
-            break;
-        case SQL_C_SBIGINT:
-            {
-                if ( !variantData.canConvert<qint64>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((qint64*)pdata) = (qint64)variantData.toLongLong();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(qint64);
-            }
-            break;
-        case SQL_C_UBIGINT:
-            {
-                if ( !variantData.canConvert<quint64>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                *((quint64*)pdata) = (quint64)variantData.toULongLong();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(quint64);
-            }
-            break;
-        case SQL_C_BINARY:
-            {
-                QByteArray bytearray = variantData.toByteArray();
-
-                MYODBCC::doMemCpy( pdata, bytearray.constData(),
pDescriptorRecord->getOctetLength() );
-                if ( pnOctetLength ) *pnOctetLength = bytearray.size();
-            }
-            break;
-        case SQL_C_TYPE_DATE:
-            {
-                SQL_DATE_STRUCT *pdate = (SQL_DATE_STRUCT *)pdata;
-                
-                if ( !variantData.canConvert<QDate>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                QDate d         = variantData.toDate();
-                pdate->day      = d.day();
-                pdate->month    = d.month();
-                pdate->year     = d.year();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_DATE_STRUCT);
-            }
-            break;
-        case SQL_C_TYPE_TIME:
-            {
-                SQL_TIME_STRUCT *ptime = (SQL_TIME_STRUCT *)pdata;
-
-                if ( !variantData.canConvert<QTime>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                QTime t         = variantData.toTime();
-                ptime->hour     = t.hour();
-                ptime->minute   = t.minute();
-                ptime->second   = t.second();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_TIME_STRUCT);
-            }
-            break;
-        case SQL_C_TYPE_TIMESTAMP:
-            {
-                SQL_TIMESTAMP_STRUCT *p = (SQL_TIMESTAMP_STRUCT *)pdata;
-
-                if ( !variantData.canConvert<QDateTime>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                QDateTime t     = variantData.toDateTime();
-                p->day          = t.date().day();
-                p->fraction     = t.time().msec(); /* \todo fraction is not same as
msec - look into it */
-                p->hour         = t.time().hour();
-                p->minute       = t.time().minute();
-                p->month        = t.date().month();
-                p->second       = t.time().second();
-                p->year         = t.date().year();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_TIMESTAMP_STRUCT);
-            }
-            break;
-        case SQL_C_NUMERIC:
-            {
-                SQL_NUMERIC_STRUCT *p = (SQL_NUMERIC_STRUCT *)pdata;
-
-                if ( !variantData.canConvert<QDateTime>() ) 
-                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
-                QDateTime t     = variantData.toDateTime();
-                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_NUMERIC_STRUCT);
-            }
-            break;
-        case SQL_C_GUID:
-        case SQL_C_DEFAULT:
-        case SQL_C_INTERVAL_MONTH:
-        case SQL_C_INTERVAL_YEAR:
-        case SQL_C_INTERVAL_YEAR_TO_MONTH:
-        case SQL_C_INTERVAL_DAY:
-        case SQL_C_INTERVAL_HOUR:
-        case SQL_C_INTERVAL_MINUTE:
-        case SQL_C_INTERVAL_SECOND:
-        case SQL_C_INTERVAL_DAY_TO_HOUR:
-        case SQL_C_INTERVAL_DAY_TO_MINUTE:
-        case SQL_C_INTERVAL_DAY_TO_SECOND:
-        case SQL_C_INTERVAL_HOUR_TO_MINUTE:
-        case SQL_C_INTERVAL_HOUR_TO_SECOND:
-        case SQL_C_INTERVAL_MINUTE_TO_SECOND:
-            break;
-        default:
-    }
-
-    MYODBCDbgReturn( SQL_SUCCESS );
-}
-
 /*! 
     \brief  Use this to get current row number.
 
-            This will get the current row number in the result-set.
+            This will get the current row number in the result-set. The row
+            number will be 0 if eof/bof.
             
     \param  pnRow   Reference to storage for the row number.
 
@@ -533,6 +324,9 @@
     if ( getState() < STATE_EXECUTED )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
 
+    if ( !isBuffered() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("getRows() not supported for unbuffered resultset") ) );
+
     Q_ASSERT( !pnRow );
 
     /*!
@@ -540,6 +334,10 @@
 
         mysql_stmt_num_rows() returns number of rows (0-n) and generates no 
         errors.
+
+        \note
+
+        We try to report error anyway ;)
     */
     *pnRows = mysql_stmt_num_rows( pstm );
     if ( mysql_stmt_errno( pstm ) )
@@ -571,6 +369,12 @@
     if ( getStatement()->getConcurrency() == SQL_CONCUR_READ_ONLY )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Resultset is read-only.") ) );
 
+    /*!
+        \internal
+        \todo
+
+        Implement.
+    */
     MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doAppend not supported here at this time.") ) );
 }
 
@@ -621,6 +425,12 @@
     if ( getStatement()->getConcurrency() == SQL_CONCUR_READ_ONLY )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("Resultset is read-only.") ) );
 
+    /*!
+        \internal
+        \todo
+
+        Implement.
+    */
     MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doDelete not supported here at this time.") ) );
 }
 
@@ -656,16 +466,13 @@
     if ( mysql_stmt_execute( pstm ) )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
 
-    /*!
-        \internal MYSQLPlus RULE
+    if ( isBuffered() )
+    {
+        if ( mysql_stmt_store_result( pstm ) )
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
+    }
 
-        We always use buffered data and other bits of logic depend upon this. In the
-        future we should make this an option and simply report failure or warning when
-        we are unable to meet the other requests with unbuffered. For example; row count
-        currently assumes we have all the data and know the real number of rows.
-    */
-    if ( mysql_stmt_store_result( pstm ) )
-        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
+    nRow = 0; /* eof/bof */
 
     setState( STATE_EXECUTED );
 
@@ -696,23 +503,41 @@
 {
     MYODBCDbgEnter();
 
+    if ( nRow == 0 )
+        MYODBCDbgReturn( doNext() );
+
     if ( getState() < STATE_EXECUTED )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
 
     if ( getStatement()->getCursorType() == SQL_CURSOR_FORWARD_ONLY )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doFirst() not supported when SQL_CURSOR_FORWARD_ONLY") ) );
 
+    if ( !isBuffered() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doFirst() not supported for unbuffered resultset") ) );
+
     if ( !isValidRow( 1 ) )
     {
         nRow = 0;
         MYODBCDbgReturn( SQL_NO_DATA );
     }
 
-    nRow = 1;
+    /*!
+        \internal MYSQL RULE
+
+        mysql_stmt_data_seek() does not provide any error information or status. 
+
+        \note
+
+        We check for errors just in case it works ;)
+    */
     mysql_stmt_data_seek( pstm, nRow - 1 ); 
     if ( mysql_stmt_errno( pstm ) )
+    {
+        nRow = 0;
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
+    }
 
+    nRow = 1;
     doRefresh();
 
     MYODBCDbgReturn( SQL_SUCCESS );
@@ -774,6 +599,9 @@
     if ( getStatement()->getCursorType() == SQL_CURSOR_FORWARD_ONLY )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doLast() not supported when SQL_CURSOR_FORWARD_ONLY") ) );
 
+    if ( !isBuffered() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doLast() not supported for unbuffered resultset") ) );
+
     qulonglong nRows = 0;
     getRows( &nRows );
     if ( nRows == 0 )
@@ -782,8 +610,19 @@
         MYODBCDbgReturn( SQL_NO_DATA );
     }
 
+    /*!
+        \internal MYSQL RULE
+
+        mysql_stmt_data_seek() has no return value and produces no errors - joy.
+
+        \note
+
+        We check for errors anyway :)
+    */
     nRow = nRows;
     mysql_stmt_data_seek( pstm, nRow - 1 ); 
+    if ( mysql_stmt_errno( pstm ) )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
 
     doRefresh();
 
@@ -820,22 +659,29 @@
     if ( getState() < STATE_EXECUTED )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
 
-    if ( !isValidRow() )
-        MYODBCDbgReturn( doFirst() );
-
-    nRow++;
-    if ( !isValidRow() )
+    int n = mysql_stmt_fetch( pstm );
+    switch ( n )
     {
-        nRow = 0;
-        MYODBCDbgReturn( SQL_NO_DATA );
-    }
+        case 0:
+            nRow++;
+            MYODBCDbgReturn( doRefresh() );
 
-    mysql_stmt_fetch( pstm );
+        case 1:
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
 
-//    mysql_stmt_data_seek( pstm, nRow - 1 ); 
+        case MYSQL_NO_DATA:
+            nRow = 0;
+            MYODBCDbgReturn( SQL_NO_DATA );
 
-    doRefresh();
+        case MYSQL_DATA_TRUNCATED:
+            nRow++;
+            doRefresh();
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_22001,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
 
+        default:
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, n,
tr("unknown return code from mysql_stmt_fetch()") ) );
+    }
+
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
@@ -870,7 +716,7 @@
     nReturn = doLoadMetaData();
     if ( !SQL_SUCCEEDED( nReturn ) )
     {
-        doStateRollBack( STATE_INITIALIZED ); /* ...so this call will do a cleanup.   */
+        doStateRollBack( STATE_INITIALIZED );
         MYODBCDbgReturn( nReturn );
     }
 
@@ -975,81 +821,31 @@
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
-/*! 
-    \brief  Refreshs the row data.
 
-            This call causes the drivers column data buffers to get refreshed and for any
bound columns (as per ARD)
-            to be refreshed. This action includes data type conversions from the driver
column data buffers to any
-            bound columns.
-
-    \note   It may be that in the future we allow setting column data and keep track of
such changes but for now
-            we always refresh all columns.
-            
-    \return SQLRETURN
-    
-    \sa     setRow
-            getRow
-            getRows
-            doNext
-            doPrev
-            doFirst
-            doLast
-            doSkip
-*/
-SQLRETURN MResultStmt::doRefresh()
+SQLRETURN MResultStmt::doCommit()
 {
     MYODBCDbgEnter();
 
     if ( getState() < STATE_EXECUTED )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
 
-    /*  
-        Get all column data. Optimize this later - but for now - this will cover us for
SQLBindCol/ARD and 
-        for SQLGetData.
-    */
-    {
-        uint        nOffset = 0;
-        int         nResult;
-        SQLSMALLINT nColumns = getImpRowDesc()->getCount();
+    if ( !isDirty() )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_01000, 0, tr("no
changes to commit") ) );
 
-        for ( SQLSMALLINT nColumn = 0; nColumn < nColumns; nColumn++ )
-        {
-            nResult = mysql_stmt_fetch_column( pstm, &(pbindColumns[nColumn]),
nColumn, nOffset );
-            switch ( nResult )
-            {
-                case 0:
-                    break;
-                case CR_INVALID_PARAMETER_NO:
-                    MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::DIA_HY000, 0, tr("CR_INVALID_PARAMETER_NO") ) );
-                case CR_NO_DATA:
-                    MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::DIA_HY000, 0, tr("CR_NO_DATA") ) );
-                default:
-                    MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::DIA_HY000, 0, tr("Unknown error from mysql_stmt_fetch_column().") ) );
-            }
-        }
-    }
+    /*!
+        \internal
+        \todo
 
-    /* 
-        Load any bound columns from SQLBindCol/ARD. Use getData to lean on Qt/QVariant
here.
-    */
-    {
-        MDescriptor *pDescriptor    = getAppRowDesc();
-        SQLSMALLINT nColumns        = pDescriptor->getCount();
+        At some point we will keep track of modified rows and then allow a doCommit() to
commit
+        changes to the backend. For now; the resultset is never dirty (readonly).
 
-        for ( SQLSMALLINT nColumn = 0; nColumn <= nColumns; nColumn++ )
-        {
-            MDescriptorRecordARD *pDescriptorRecord = (MDescriptorRecordARD
*)pDescriptor->getRecord( nColumn ); 
+        \note
 
-            if ( pDescriptorRecord->getDataPtr() )
-            {
-                SQLRETURN nReturn = getData( nColumn, pDescriptorRecord );
-                if ( nReturn != SQL_SUCCESS )
-                    MYODBCDbgReturn( nReturn );
-            }
-        }
-    }
+        doCommit() works within the framework of backend transactions - it is not meant
to substitute
+        for it.
+    */
 
-    MYODBCDbgReturn( SQL_SUCCESS );
+    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("doCommit() not supported at this time") ) );
 }
 
 /*! 
@@ -1065,23 +861,22 @@
 */
 BOOLEAN MResultStmt::isValidRow()
 {
-    BOOLEAN b;
-
     MYODBCDbgEnter();
 
     if ( getState() < STATE_EXECUTED )
         MYODBCDbgReturn3( "%d", false );
 
-    b = isValidRow( nRow );
+    /* eof/bof */
+    if ( nRow == 0 )
+        MYODBCDbgReturn3( "%d", false );
 
-    MYODBCDbgReturn3( "%d", b );
+    MYODBCDbgReturn3( "%d", true );
 }
 
 /*! 
     \brief  Informs called whether or not the provided row is a valid row.
 
-            This is used to validate a row position before requesting it become current
and
-            to support isValidRow().
+            This is used to validate a row position before requesting it become current.
 
     \param  nRow    Row to be checked.
                 
@@ -1100,13 +895,32 @@
     if ( getState() < STATE_EXECUTED )
         MYODBCDbgReturn3( "%d", false );
 
+    if ( nRow == 0 )
+        MYODBCDbgReturn3( "%d", false );
+
     nReturn = getRows( &nRows );
     if ( !SQL_SUCCEEDED( nReturn ) )
         MYODBCDbgReturn3( "%d", false );
 
-    MYODBCDbgReturn3( "%d", ( nRow > 0 && nRow <= nRows ) );
+    MYODBCDbgReturn3( "%d", ( nRow <= nRows ) );
 }
 
+BOOLEAN MResultStmt::isDirty()
+{
+    MYODBCDbgEnter();
+
+    /*!
+        \internal
+        \todo
+
+        At some point we will keep track of modified rows and then allow a doCommit() to
commit
+        changes to the backend. For now; the resultset is never dirty (readonly).
+    */
+
+    MYODBCDbgReturn3( "%d", false );
+}
+
+
 /*! 
     \brief  Set the state.
 
@@ -1176,7 +990,331 @@
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
+SQLRETURN MResultStmt::doSeek( qulonglong nRow )
+{
+    MYODBCDbgEnter();
+
+    /* state etc validation done by caller */
+    /* this must only be called when isBuffered() but we leave that up to the caller */
+
+    /*!
+        \internal MYSQL RULE
+
+        mysql_stmt_data_seek() has no return value and produces no errors - joy.
+
+        \note
+
+        We check for errors anyway :)
+    */
+    mysql_stmt_data_seek( pstm, nRow - 1 ); 
+    if ( mysql_stmt_errno( pstm ) )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
+
+    SQLRETURN nReturn = doRefresh();
+    if ( !SQL_SUCCEEDED( nReturn ) )
+        this->nRow = nRow;
+    else
+        this->nRow = nRow;
+
+    MYODBCDbgReturn( nReturn );
+}
+
+/*!
+    \brief  This gets column data from the drivers row buffers.
+
+    \param  nColumn             The column we are dealing with.
+    \param  pDescriptorRecord   This is a bound ARD.
+
+    \return SQLRETURN
+
+    \sa     getData
+*/
+SQLRETURN MResultStmt::getData( uint nColumn, MDescriptorRecordARD *pDescriptorRecord )
+{
+    MYODBCDbgEnter();
+
+    QVariant        variantData;
+    MYSQL_BIND *    pbind           = &(pbindColumns[nColumn]);
+    SQLRETURN       nReturn         = getData( nColumn, variantData );
+    SQLPOINTER      pdata           = pDescriptorRecord->getDataPtr();
+    SQLINTEGER *    pnIndicator     = pDescriptorRecord->getIndicatorPtr();
+    SQLINTEGER *    pnOctetLength   = pDescriptorRecord->getOctetLengthPtr();
+
+    if ( getState() < STATE_EXECUTED )
+        MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY010 ) );
+
+    if ( variantData.isNull() )
+    {
+        if ( pnIndicator ) 
+        {
+            *pnIndicator = SQL_NULL_DATA;
+            MYODBCDbgReturn( SQL_SUCCESS );
+        }
+        else
+            MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_22002 ) );
+    }
+
+    if ( pnIndicator ) *pnIndicator = 0;
+
+    switch ( pDescriptorRecord->getConciseType() )
+    {
+        case SQL_C_CHAR:
+            {
+                if ( !variantData.canConvert<QString>() )
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                QString stringData = variantData.asString();
+                MYODBCC::doStrNCpy( (SQLWCHAR)pdata,
pDescriptorRecord->getOctetLength() / sizeof(SQLWCHAR), stringData.utf16() );
+                if ( pnOctetLength ) *pnOctetLength = stringData.length() *
sizeof(SQLWCHAR);
+            }
+            break;
+        case SQL_C_SSHORT:
+            {
+                if ( !variantData.canConvert<short int>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((short int*)pdata) = (short int)variantData.toInt();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(short int);
+            }
+            break;
+        case SQL_C_USHORT:
+            {
+                if ( !variantData.canConvert<unsigned short int>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((unsigned short int*)pdata) = (unsigned short int)variantData.toUInt();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned short int);
+            }
+            break;
+        case SQL_C_SLONG:
+            {
+                if ( !variantData.canConvert<long int>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((long int*)pdata) = (long int)variantData.toLongLong();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(long int);
+            }
+            break;
+        case SQL_C_ULONG:
+            {
+                if ( !variantData.canConvert<unsigned long int>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((unsigned long int*)pdata) = (unsigned long
int)variantData.toULongLong();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned long int);
+            }
+            break;
+        case SQL_C_FLOAT:
+            {
+                if ( !variantData.canConvert<float>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((float *)pdata) = (float)variantData.toDouble();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(float);
+            }
+            break;
+        case SQL_C_DOUBLE:
+            {
+                if ( !variantData.canConvert<double>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((double *)pdata) = (double)variantData.toDouble();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(double);
+            }
+            break;
+        case SQL_C_BIT:
+            {
+                if ( !variantData.canConvert<unsigned char>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((unsigned char *)pdata) = variantData.toInt();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned char);
+            }
+            break;
+        case SQL_C_STINYINT:
+            {
+                if ( !variantData.canConvert<char>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((char *)pdata) = variantData.toInt();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(char);
+            }
+            break;
+        case SQL_C_UTINYINT:
+            {
+                if ( !variantData.canConvert<unsigned char>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((unsigned char *)pdata) = variantData.toUInt();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(unsigned char);
+            }
+            break;
+        case SQL_C_SBIGINT:
+            {
+                if ( !variantData.canConvert<qint64>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((qint64*)pdata) = (qint64)variantData.toLongLong();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(qint64);
+            }
+            break;
+        case SQL_C_UBIGINT:
+            {
+                if ( !variantData.canConvert<quint64>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                *((quint64*)pdata) = (quint64)variantData.toULongLong();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(quint64);
+            }
+            break;
+        case SQL_C_BINARY:
+            {
+                QByteArray bytearray = variantData.toByteArray();
+
+                MYODBCC::doMemCpy( pdata, bytearray.constData(),
pDescriptorRecord->getOctetLength() );
+                if ( pnOctetLength ) *pnOctetLength = bytearray.size();
+            }
+            break;
+        case SQL_C_TYPE_DATE:
+            {
+                SQL_DATE_STRUCT *pdate = (SQL_DATE_STRUCT *)pdata;
+                
+                if ( !variantData.canConvert<QDate>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                QDate d         = variantData.toDate();
+                pdate->day      = d.day();
+                pdate->month    = d.month();
+                pdate->year     = d.year();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_DATE_STRUCT);
+            }
+            break;
+        case SQL_C_TYPE_TIME:
+            {
+                SQL_TIME_STRUCT *ptime = (SQL_TIME_STRUCT *)pdata;
+
+                if ( !variantData.canConvert<QTime>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                QTime t         = variantData.toTime();
+                ptime->hour     = t.hour();
+                ptime->minute   = t.minute();
+                ptime->second   = t.second();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_TIME_STRUCT);
+            }
+            break;
+        case SQL_C_TYPE_TIMESTAMP:
+            {
+                SQL_TIMESTAMP_STRUCT *p = (SQL_TIMESTAMP_STRUCT *)pdata;
+
+                if ( !variantData.canConvert<QDateTime>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                QDateTime t     = variantData.toDateTime();
+                p->day          = t.date().day();
+                p->fraction     = t.time().msec(); /* \todo fraction is not same as
msec - look into it */
+                p->hour         = t.time().hour();
+                p->minute       = t.time().minute();
+                p->month        = t.date().month();
+                p->second       = t.time().second();
+                p->year         = t.date().year();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_TIMESTAMP_STRUCT);
+            }
+            break;
+        case SQL_C_NUMERIC:
+            {
+                SQL_NUMERIC_STRUCT *p = (SQL_NUMERIC_STRUCT *)pdata;
+
+                if ( !variantData.canConvert<QDateTime>() ) 
+                    MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_07006
) );
+                QDateTime t     = variantData.toDateTime();
+                if ( pnOctetLength ) *pnOctetLength = sizeof(SQL_NUMERIC_STRUCT);
+            }
+            break;
+        case SQL_C_GUID:
+        case SQL_C_DEFAULT:
+        case SQL_C_INTERVAL_MONTH:
+        case SQL_C_INTERVAL_YEAR:
+        case SQL_C_INTERVAL_YEAR_TO_MONTH:
+        case SQL_C_INTERVAL_DAY:
+        case SQL_C_INTERVAL_HOUR:
+        case SQL_C_INTERVAL_MINUTE:
+        case SQL_C_INTERVAL_SECOND:
+        case SQL_C_INTERVAL_DAY_TO_HOUR:
+        case SQL_C_INTERVAL_DAY_TO_MINUTE:
+        case SQL_C_INTERVAL_DAY_TO_SECOND:
+        case SQL_C_INTERVAL_HOUR_TO_MINUTE:
+        case SQL_C_INTERVAL_HOUR_TO_SECOND:
+        case SQL_C_INTERVAL_MINUTE_TO_SECOND:
+            break;
+        default:
+    }
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
 /*! 
+    \brief  Refreshs the row data.
+
+            This call causes the drivers column data buffers to get refreshed and for any
bound columns (as per ARD)
+            to be refreshed. This action includes data type conversions from the driver
column data buffers to any
+            bound columns.
+
+    \note   It may be that in the future we allow setting column data and keep track of
such changes but for now
+            we always refresh all columns.
+            
+    \return SQLRETURN
+    
+    \sa     setRow
+            getRow
+            getRows
+            doNext
+            doPrev
+            doFirst
+            doLast
+            doSkip
+*/
+SQLRETURN MResultStmt::doRefresh()
+{
+    MYODBCDbgEnter();
+
+    /* state etc validation done by caller */
+
+    /*  
+        Get all column data. Optimize this later - but for now - this will cover us for
SQLBindCol/ARD and 
+        for SQLGetData.
+    */
+    {
+        uint        nOffset = 0;
+        int         nResult;
+        SQLSMALLINT nColumns = getImpRowDesc()->getCount();
+
+        for ( SQLSMALLINT nColumn = 0; nColumn < nColumns; nColumn++ )
+        {
+            nResult = mysql_stmt_fetch_column( pstm, &(pbindColumns[nColumn]),
nColumn, nOffset );
+            switch ( nResult )
+            {
+                case 0:
+                    break;
+                case CR_INVALID_PARAMETER_NO:
+                    MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::DIA_HY000, 0, tr("CR_INVALID_PARAMETER_NO") ) );
+                case CR_NO_DATA:
+                    MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::DIA_HY000, 0, tr("CR_NO_DATA") ) );
+                default:
+                    MYODBCDbgReturn( getDiagnostic()->doAppend(
MDiagnostic::DIA_HY000, 0, tr("Unknown error from mysql_stmt_fetch_column().") ) );
+            }
+        }
+    }
+
+    /* 
+        Load any bound columns from SQLBindCol/ARD. Use getData to lean on Qt/QVariant
here.
+    */
+    {
+        MDescriptor *pDescriptor    = getAppRowDesc();
+        SQLSMALLINT nColumns        = pDescriptor->getCount();
+
+        for ( SQLSMALLINT nColumn = 0; nColumn <= nColumns; nColumn++ )
+        {
+            MDescriptorRecordARD *pDescriptorRecord = (MDescriptorRecordARD
*)pDescriptor->getRecord( nColumn ); 
+
+            if ( pDescriptorRecord->getDataPtr() )
+            {
+                SQLRETURN nReturn = getData( nColumn, pDescriptorRecord );
+                if ( nReturn != SQL_SUCCESS )
+                    MYODBCDbgReturn( nReturn );
+            }
+        }
+    }
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+/*! 
     \brief  Loads result-set meta data.
 
             This is called (by doPrepare) after a statement is prepared and is loaded
into

Modified: MYSQLPlus/MYSQLPlusLib/MResultStmt.h
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultStmt.h	2006-05-11 19:43:45 UTC (rev 224)
+++ MYSQLPlus/MYSQLPlusLib/MResultStmt.h	2006-05-12 05:04:38 UTC (rev 225)
@@ -56,7 +56,6 @@
 
     SQLRETURN getColumns( uint *pnColumns );
     SQLRETURN getData( uint nColumn, QVariant &variantData );
-    SQLRETURN getData( uint nColumn, MDescriptorRecordARD *pDescriptorRecord );
     SQLRETURN getRow( qulonglong *pnRow );
     SQLRETURN getRows( qulonglong *pnRows );
 
@@ -71,10 +70,11 @@
     SQLRETURN doPrepare( const SQLWCHAR *psStatement );
     SQLRETURN doPrev();
     SQLRETURN doSkip( qlonglong nRows );
-    SQLRETURN doRefresh();
+    SQLRETURN doCommit();
 
     BOOLEAN isValidRow();
     BOOLEAN isValidRow( qulonglong nRow );
+    BOOLEAN isDirty();
 
 protected:
     /* doers */
@@ -84,14 +84,24 @@
     MYSQL_STMT *    pstm;               /*!< MySQL prepared statement                 
                                                                 */
     MYSQL_BIND *    pbindColumns;       /*!< binds for every col in res - loaded witb
call to mysql_stmt_fetch_column() as needed                       */
 
+    qulonglong      nRow;               /*!< Current row number where 0=eof/bof. We
need to keep track of this due to lack of functionality in client.  */
+
+    /* setters */
+    SQLRETURN doSeek( qulonglong nRow );
+
+    /* getters */
+    SQLRETURN getData( uint nColumn, MDescriptorRecordARD *pDescriptorRecord );
+
+    /* doers */
+    SQLRETURN doRefresh();
     /* prepare MYSQL_BIND for a call to mysql_stmt_fetch_column() - used by SQLColBind
and SQLGetData */
 //    SQLRETURN   doInitBindCol( MYODBC_BIND_COL *pbind, uint nColumn, SQLSMALLINT
nTargetType, SQLPOINTER pTarget, SQLINTEGER nTargetSize, SQLINTEGER *pnStrLenInd );
     /* for some types we have had to use our own data buffer. for example mysql knows
nothing about SQL_NUMERIC_STRUCT - this is freed in here */
 //    SQLRETURN   doFiniBindCol( MYODBC_BIND_COL *pbind );
-
     SQLRETURN doLoadMetaData();     /* load resultset meta data (IRD)                  
*/
     SQLRETURN doLoadMetaDataField( unsigned int nField, MYSQL_FIELD *pField ); /* load
resultset column meta data (IRD) */
 };
 
 #endif
 
+

Thread
Connector/ODBC 5 commit: r225 - MYSQLPlus/MYSQLPlusLibpharvey12 May