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/MYSQLPlusLib | pharvey | 12 May |