List:Commits« Previous MessageNext Message »
From:pharvey Date:April 26 2006 7:24pm
Subject:Connector/ODBC 5 commit: r126 - MYSQLCC/MYSQLCCLib
View as plain text  
Added:
   MYSQLCC/MYSQLCCLib/MDiagnostic.cpp
   MYSQLCC/MYSQLCCLib/MDiagnostic.h
   MYSQLCC/MYSQLCCLib/MDiagnosticRecord.cpp
   MYSQLCC/MYSQLCCLib/MDiagnosticRecord.h
Modified:
   MYSQLCC/MYSQLCCLib/MEnvironment.cpp
Log:


Added: MYSQLCC/MYSQLCCLib/MDiagnostic.cpp
===================================================================
--- MYSQLCC/MYSQLCCLib/MDiagnostic.cpp	2006-04-26 17:34:24 UTC (rev 125)
+++ MYSQLCC/MYSQLCCLib/MDiagnostic.cpp	2006-04-26 19:24:01 UTC (rev 126)
@@ -0,0 +1,595 @@
+#include "MYODBCDiaInternal.h"
+
+/*!
+    \brief  Allocates a new diagnostics structure.
+
+            Allocates and initializes a new diagnostics 
+            structure. Should be free using MYODBCDiaFree().
+
+    \return a viable diagnostic structure
+        
+    \sa     MYODBCDiaFree
+*/
+MYODBCDia::MYODBCDia()
+{
+    MYODBCDbgEnter();
+
+    nCursorRowCount         = 0;
+    nDynamicFunctionCode    = SQL_DIAG_UNKNOWN_STATEMENT;
+    nReturnCode             = SQL_SUCCESS;
+    nRowCount               = 0;
+
+    /*!
+        \internal ODBC Rule
+
+        A string that indicates the name of the connection that the diagnostic 
+        record relates to. This field is driver-defined. For diagnostic data 
+        structures associated with the environment handle and for diagnostics 
+        that do not relate to any connection, this field is a zero-length string.
+    */    
+    stringConnectionName    = "";
+    stringServerName        = "";
+
+    MYODBCDbgReturn2();
+}
+
+/*!
+    \brief  Frees a diagnostics structure.
+
+            Frees a diagnostics structure previously allocated with
+            MYODBCDiaAlloc(). 
+    
+    \param  hDia    Diagnostic handle created with MYODBCDiaAlloc.
+                        
+    \sa     MYODBCDiaAlloc
+*/
+MYODBCDia::~MYODBCDia()
+{
+    MYODBCDbgEnter();
+
+    while ( !listRecords.isEmpty() )
+        delete listRecords.takeFirst();
+
+    MYODBCDbgReturn2();
+}
+
+SQLRETURN MYODBCDia::setCursorRowCount( SQLINTEGER nCursorRowCount )
+{
+    MYODBCDbgEnter();
+
+    this->nCursorRowCount = nCursorRowCount;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDia::setDynamicFunctionCode( SQLINTEGER nDynamicFunctionCode )
+{
+    MYODBCDbgEnter();
+
+    this->nDynamicFunctionCode = nDynamicFunctionCode;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDia::setReturnCode( SQLRETURN nReturn )
+{
+    MYODBCDbgEnter();
+
+    this->nReturnCode = nReturn;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDia::setRowCount( SQLINTEGER nRowCount )
+{
+    MYODBCDbgEnter();
+
+    this->nRowCount = nRowCount;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDia::setConnectionName( const QString &stringConnectionName )
+{
+    MYODBCDbgEnter();
+
+    if ( stringConnectionName.isNull() )
+        this->stringConnectionName = "";
+    else
+        this->stringConnectionName = stringConnectionName;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDia::setServerName( const QString &stringServerName )
+{
+    MYODBCDbgEnter();
+
+    if ( stringServerName.isNull() )
+        this->stringServerName = "";
+    else
+        this->stringServerName = stringServerName;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDia::getDiagRec( SQLSMALLINT nRecNumber, SQLWCHAR *psSqlstate, SQLINTEGER
*pnNativeErrorPtr, SQLWCHAR *pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT
*pnTextLengthPtr )
+{
+    MYODBCDbgEnter();
+
+    if ( nRecNumber < 1 )
+        MYODBCDbgReturn( SQL_ERROR );
+    if ( nRecNumber > getNumber() )
+        MYODBCDbgReturn( SQL_NO_DATA );
+
+    MYODBCDbgReturn( listRecords[nRecNumber - 1]->getDiagRec( psSqlstate,
pnNativeErrorPtr, pszMessageText, nBufferLength, pnTextLengthPtr ) );
+}
+
+/*!
+    \brief  Gets a specific diagnostic field value.
+
+            The field can be a header field or a record field.
+
+    \param  hDia            Diagnostic handle allocated with MYODBCDiaAlloc.
+    \param  nRecord         The desired record. 0 if header field else 1+.
+    \param  nField          Header or record diagnostic field.
+    \param  pBuffer         Place to return the value.
+    \param  nBufferLength   The size of pBuffer.
+    \param  pnStrLenPtr     Length of string data available.
+
+    \return SQLRETURN
+
+    \retval SQL_SUCCESS             Success!
+    \retval SQL_SUCCESS_WITH_INFO   Character data was truncated.
+    \retval SQL_ERROR               General error.
+    \retval SQL_NO_DATA             No data to return (ie requested record does not
exist).
+*/
+SQLRETURN MYODBCDia::getDiagField( SQLSMALLINT nRecNumber, SQLSMALLINT nDiagIdentifier,
SQLPOINTER pDiagInfoPtr, SQLSMALLINT nBufferLength, SQLSMALLINT *pnStringLengthPtr )
+{
+    SQLSMALLINT  nStringLength;
+
+    MYODBCDbgEnter();
+
+    /* use dummy when no pnStringLengthPtr */
+    if ( !pnStringLengthPtr )
+        pnStringLengthPtr = &nStringLength;
+
+    /* 
+        These are the fields we know about listed by category
+        (header/record) and in _alpha_ order.
+    */
+    switch ( nDiagIdentifier )
+    {
+        case SQL_DIAG_CURSOR_ROW_COUNT:
+            *(SQLINTEGER*)pDiagInfoPtr = getCursorRowCount();
+            break;
+
+        case SQL_DIAG_DYNAMIC_FUNCTION:
+            {
+                QString stringDynamicFunction = getDynamicFunction();
+                if ( nBufferLength < 1 || stringDynamicFunction.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringDynamicFunction.utf16() );
+                *pnStringLengthPtr = stringDynamicFunction.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
+            *(SQLINTEGER*)pDiagInfoPtr = getDynamicFunctionCode();
+            break;
+
+        case SQL_DIAG_NUMBER:
+            *(SQLINTEGER*)pDiagInfoPtr = getNumber();
+            break;
+
+        case SQL_DIAG_RETURNCODE:
+            *(SQLRETURN*)pDiagInfoPtr = getReturnCode();
+            break;
+
+        case SQL_DIAG_ROW_COUNT:
+            *(SQLINTEGER*)pDiagInfoPtr = getRowCount();
+            break;
+        default:
+            if ( nRecNumber < 1 )
+                MYODBCDbgReturn( SQL_ERROR );
+            if ( nRecNumber > getNumber() )
+                MYODBCDbgReturn( SQL_NO_DATA );
+            MYODBCDbgReturn( listRecords[nRecNumber - 1]->getDiagField(
nDiagIdentifier, pDiagInfoPtr, nBufferLength, pnStringLengthPtr ) );
+    }
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+
+SQLINTEGER MYODBCDia::getCursorRowCount()
+{
+    MYODBCDbgEnter();
+
+    return nCursorRowCount;
+}
+
+QString MYODBCDia::getDynamicFunction()
+{
+    MYODBCDbgEnter();
+
+    switch ( nDynamicFunctionCode )
+    {
+        case SQL_DIAG_ALTER_DOMAIN:
+            MYODBCDbgReturn3( "%s", "ALTER DOMAIN" );
+        case SQL_DIAG_ALTER_TABLE:
+            MYODBCDbgReturn3( "%s", "ALTER TABLE" );
+        case SQL_DIAG_CALL:
+            MYODBCDbgReturn3( "%s", "CALL" );
+        case SQL_DIAG_CREATE_ASSERTION:
+            MYODBCDbgReturn3( "%s", "CREATE ASSERTION" );
+        case SQL_DIAG_CREATE_CHARACTER_SET:
+            MYODBCDbgReturn3( "%s", "CREATE CHARACTER SET)" );
+        case SQL_DIAG_CREATE_COLLATION:
+            MYODBCDbgReturn3( "%s", "CREATE COLLATION" );
+        case SQL_DIAG_CREATE_DOMAIN:
+            MYODBCDbgReturn3( "%s", "CREATE DOMAIN" );
+        case SQL_DIAG_CREATE_INDEX:
+            MYODBCDbgReturn3( "%s", "CREATE INDEX" );
+        case SQL_DIAG_CREATE_SCHEMA:
+            MYODBCDbgReturn3( "%s", "CREATE SCHEMA" );
+        case SQL_DIAG_CREATE_TABLE:
+            MYODBCDbgReturn3( "%s", "CREATE TABLE" );
+        case SQL_DIAG_CREATE_TRANSLATION:
+            MYODBCDbgReturn3( "%s", "CREATE TRANSLATION" );
+        case SQL_DIAG_CREATE_VIEW:
+            MYODBCDbgReturn3( "%s", "CREATE VIEW" );
+        case SQL_DIAG_DELETE_WHERE:
+            MYODBCDbgReturn3( "%s", "DELETE WHERE" );
+        case SQL_DIAG_DROP_ASSERTION:
+            MYODBCDbgReturn3( "%s", "DROP ASSERTION" );
+        case SQL_DIAG_DROP_CHARACTER_SET:
+            MYODBCDbgReturn3( "%s", "DROP CHARACTER SET" );
+        case SQL_DIAG_DROP_COLLATION:
+            MYODBCDbgReturn3( "%s", "DROP COLLATION" );
+        case SQL_DIAG_DROP_DOMAIN:
+            MYODBCDbgReturn3( "%s", "DROP DOMAIN" );
+        case SQL_DIAG_DROP_INDEX:
+            MYODBCDbgReturn3( "%s", "DROP INDEX" );
+        case SQL_DIAG_DROP_SCHEMA:
+            MYODBCDbgReturn3( "%s", "DROP SCHEMA" );
+        case SQL_DIAG_DROP_TABLE:
+            MYODBCDbgReturn3( "%s", "DROP TABLE" );
+        case SQL_DIAG_DROP_TRANSLATION:
+            MYODBCDbgReturn3( "%s", "DROP TRANSLATION" );
+        case SQL_DIAG_DROP_VIEW:
+            MYODBCDbgReturn3( "%s", "DROP VIEW" );
+        case SQL_DIAG_DYNAMIC_DELETE_CURSOR:
+            MYODBCDbgReturn3( "%s", "DYNAMIC DELETE CURSOR" );
+        case SQL_DIAG_DYNAMIC_UPDATE_CURSOR:
+            MYODBCDbgReturn3( "%s", "DYNAMIC UPDATE CURSOR" );
+        case SQL_DIAG_GRANT:
+            MYODBCDbgReturn3( "%s", "GRANT" );
+        case SQL_DIAG_INSERT:
+            MYODBCDbgReturn3( "%s", "INSERT" );
+        case SQL_DIAG_REVOKE:
+            MYODBCDbgReturn3( "%s", "REVOKE" );
+        case SQL_DIAG_SELECT_CURSOR:
+            MYODBCDbgReturn3( "%s", "SELECT CURSOR" );
+        case SQL_DIAG_UPDATE_WHERE:
+            MYODBCDbgReturn3( "%s", "UPDATE_WHERE" );
+/*        case SQL_DIAG_UNKNOWN_STATEMENT:
+            return "UNKNOWN_STATEMENT"; */
+    }
+
+    MYODBCDbgReturn3( "%s", "UNKNOWN_STATEMENT" );
+}
+
+SQLINTEGER MYODBCDia::getDynamicFunctionCode()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nDynamicFunctionCode );
+}
+
+SQLINTEGER MYODBCDia::getNumber()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", listRecords.count() );
+}
+
+SQLRETURN MYODBCDia::getReturnCode()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nReturnCode );
+}
+
+SQLINTEGER MYODBCDia::getRowCount()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nRowCount );
+}
+
+QString MYODBCDia::getClassOrigin( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getClassOrigin() );
+}
+
+SQLINTEGER MYODBCDia::getColumnNumber( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%d", listRecords[nRecNumber - 1]->getColumnNumber() );
+}
+
+QString MYODBCDia::getConnectionName( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getConnectionName() );
+}
+
+QString MYODBCDia::getMessageText( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getMessageText() );
+}
+
+QString MYODBCDia::getMessage( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getMessage() );
+}
+
+SQLINTEGER MYODBCDia::getNative( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%d", listRecords[nRecNumber - 1]->getNative() );
+}
+
+SQLINTEGER MYODBCDia::getRowNumber( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%d", listRecords[nRecNumber - 1]->getRowNumber() );
+}
+
+QString MYODBCDia::getServerName( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getServerName() );
+}
+
+QString MYODBCDia::getSQLState( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getSQLState() );
+}
+
+QString MYODBCDia::getSubClassOrigin( SQLSMALLINT nRecNumber)
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( nRecNumber < 1 );
+    Q_ASSERT( nRecNumber > getNumber() );
+
+    MYODBCDbgReturn3( "%s", listRecords[nRecNumber - 1]->getSubClassOrigin() );
+}
+
+QString MYODBCDia::getConnectionName()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", stringConnectionName );
+}
+
+QString MYODBCDia::getServerName()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", stringServerName );
+}
+
+/*!
+    \brief  Appends a diagnostic record to the given handle.
+    
+            This function is called to append a diagnostic record to the
+            given diagnostic structure. This function is called often 
+            when there are errors or warnings.
+
+            Unlike MYODBCDiaAppend2, this function does not require row 
+            or col number to be passed.
+    
+            The final message stored will conform to the format specified
+            in the ODBC specification and will result in a message larger
+            than anything provided in pszMessage. The final message MUST
+            not be larger than SQL_MAX_MESSAGE_LENGTH (typically 512 bytes).
+             
+    \param  hDia        Diagnostic handle created with MYODBCDiaAlloc.
+    \param  nState      Numeric id for an SQL state.
+    \param  diag_native Native (perhaps DBMS specific) error code.
+    \param  pszMessage  Message (if any) to be associated with 
+                        diagnostic record.
+
+    \return             SQL return code corresponding to the nState.
+
+    \sa     MYODBCDiaAppend2
+*/
+SQLRETURN MYODBCDia::doAppend( MYODBC_DIA_ID nState, SQLINTEGER nNative, const QString
&stringMessage )
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn( doAppend( nState, nNative, stringMessage, SQL_NO_ROW_NUMBER,
SQL_NO_COLUMN_NUMBER ) );
+}
+
+/*!
+    \brief  Appends a diagnostic record to the given handle.
+    
+            This function is called to append a diagnostic record to the
+            given handle. This function is called when row and/or col
+            number are relevant.
+
+            The final message stored will conform to the format specified
+            in the ODBC specification and will result in a message larger
+            than anything provided in pszMessage. The final message MUST
+            not be larger than SQL_MAX_MESSAGE_LENGTH (typically 512 bytes).
+             
+    \param  hDia            Diagnostic handle created with MYODBCDiaAlloc.
+    \param  nState          numeric id for an SQL state
+    \param  diag_native     native (perhaps DBMS specific) error code
+    \param  pszMessage      message (if any) to be associated with diagnostic record
+    \param  diag_row_number the relevant row number or SQL_NO_ROW_NUMBER
+    \param  diag_col_number the relevant col number or SQL_NO_COLUMN_NUMBER
+
+    \return                 SQL return code corresponding to the nState.
+    
+    \sa     MYODBCDiaAppend
+*/
+SQLRETURN MYODBCDia::doAppend( MYODBC_DIA_ID nState, SQLINTEGER nNative, const QString
&stringMessage, SQLINTEGER nRowNumber, SQLINTEGER nColumnNumber )
+{
+    MYODBCDbgEnter();
+
+    /* sanity checks */
+    Q_ASSERT( nState >= MYODBC_DIA_MAX );
+
+    MYODBCDiaRec *pdiarec = new MYODBCDiaRec( this, nState );
+    pdiarec->setNative( nNative );
+    pdiarec->setColumnNumber( nColumnNumber );
+    pdiarec->setRowNumber( nRowNumber );
+    pdiarec->setMessage( stringMessage );
+    listRecords.append( pdiarec );
+
+    MYODBCDbgReturn( MYODBCDia_pStates[nState].diag_returncode );
+}
+
+/*!
+    \brief  Clears the diagnostic information for the given handle.
+    
+            This function is called at most entry points to the ODBC 
+            API to clear diagnostic information from a previous call 
+            to the ODBC API.
+    
+    \param  hDia    Diagnostic handle created with MYODBCDiaAlloc.
+
+    \sa     MYODBCDiaAlloc
+            MYODBCDiaFree
+*/
+void MYODBCDia::doClear()
+{
+    MYODBCDbgEnter();
+
+    /* delete any records we may have */
+    while (!listRecords.isEmpty())
+        delete listRecords.takeFirst();
+
+    /*
+        \internal ODBC Rule
+
+        When SQLExecute, SQLExecDirect, SQLBulkOperations, SQLSetPos, or 
+        SQLMoreResults is called, the SQL_DIAG_ROW_COUNT field of the 
+        diagnostic data structure is set to the row count, and the row 
+        count is cached in an implementation-dependent way. SQLRowCount 
+        returns the cached row count value. The cached row count value is 
+        valid until the statement handle is set back to the prepared or 
+        allocated state, the statement is reexecuted, or SQLCloseCursor is 
+        called. Note that if a function has been called since the 
+        SQL_DIAG_ROW_COUNT field was set, the value returned by SQLRowCount 
+        might be different from the value in the SQL_DIAG_ROW_COUNT field 
+        because the SQL_DIAG_ROW_COUNT field is reset to 0 by any function 
+        call.
+
+        see SQLRowCount
+    */      
+    nRowCount = 0;
+
+    /*
+        \internal MYODBC Rule
+
+        It is assumed, by the \internal ODBC Rule on diag_row_count that we should
+        reinit all dia fields with the exception of;
+          diag_connection_name
+          diag_server_name 
+    */      
+    nCursorRowCount      = 0;
+    nDynamicFunctionCode = SQL_DIAG_UNKNOWN_STATEMENT;
+    nReturnCode          = SQL_SUCCESS;
+
+    MYODBCDbgReturn2();
+}
+
+SQLRETURN MYODBCDia::doDelete( SQLSMALLINT nRecNumber )
+{
+    MYODBCDbgEnter();
+
+    if ( nRecNumber < 1 || nRecNumber > getNumber() )
+        MYODBCDbgReturn( SQL_ERROR );
+
+    delete listRecords.takeAt( nRecNumber - 1 );
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+/*!
+    \internal
+    \brief  Dumps the contents to stream.
+
+            This is useful for debugging.
+
+    \param  
+*/  
+QTextStream &operator<<( QTextStream &stream, const MYODBCDia &rval )
+{
+    stream << "DIAGNOSTIC..." << endl;
+    stream << "SQL_DIAG_CURSOR_ROW_COUNT     : " << rval.nCursorRowCount
<< endl;
+    stream << "SQL_DIAG_DYNAMIC_FUNCTION_CODE: " << rval.nDynamicFunctionCode
<< endl;
+    stream << "SQL_DIAG_NUMBER               : " << rval.listRecords.count()
<< endl;
+    stream << "SQL_DIAG_RETURNCODE           : " << rval.nReturnCode <<
endl;
+    stream << "SQL_DIAG_ROW_COUNT            : " << rval.nRowCount <<
endl;
+
+    QListIterator<MYODBCDiaRec*> i( rval.listRecords );
+    while ( i.hasNext() )
+    {
+        stream << "Record..." << endl;
+        stream << i.next();
+    }
+
+    return stream;
+}
+
+
+

Added: MYSQLCC/MYSQLCCLib/MDiagnostic.h
===================================================================
--- MYSQLCC/MYSQLCCLib/MDiagnostic.h	2006-04-26 17:34:24 UTC (rev 125)
+++ MYSQLCC/MYSQLCCLib/MDiagnostic.h	2006-04-26 19:24:01 UTC (rev 126)
@@ -0,0 +1,116 @@
+/*! \file   MYODBCDia.h
+    \author Peter Harvey <pharvey@stripped>
+    \brief  This code is used to support diagnostic information
+            associated with various handles.
+
+            This code is for internal use and as such is for MyODBC 
+            developers only. 
+            
+            0 - n diagnostic records can be associated with the following 
+            ODBC handles;
+            
+            - Environment
+            - Connection
+            - Statement
+            - Descriptor
+            
+            Diagnostic information can be retreived by calling;
+            
+            - SQLGetDiagRec
+            - SQLGetDiagField
+            
+            Diagnostic information, if any, should be retreived immediatly after
+            calling an ODBC function because it will be lost when more ODBC
+            functions are called. The exceptions to this are SQLGetDiagRec and 
+            SQLGetDiagField - these functions never clear diagnostic information.
+*/
+
+#ifndef MYODBC_DIA_H
+#define MYODBC_DIA_H
+
+#include <MYODBCC.h>
+#include <MYODBCDbg.h>
+
+#include <QList>
+#include <QString>
+#include <QStringList>
+#include <QTextStream>
+
+#include "MYODBCDiaState.h"
+
+class MYODBCDiaRec;
+
+/*!
+    \internal
+    \brief  This is the main handle for diagnostic information.
+    
+            This contains the diagnostic header fields and 0 - n 
+            diagnostic records. Each; environment, connection, statement
+            and descriptor handle has one of these. 
+*/
+class MYODBCDia 
+{
+    friend class MYODBCDiaRec;
+    friend QTextStream &operator<<( QTextStream &stream, const MYODBCDia
&rval );
+public:
+    MYODBCDia();
+    ~MYODBCDia();
+
+    /* header fields... */
+    SQLRETURN setCursorRowCount( SQLINTEGER nCursorRowCount );
+    SQLRETURN setDynamicFunctionCode( SQLINTEGER nDynamicFunctionCode );
+    SQLRETURN setReturnCode( SQLRETURN nReturn );
+    SQLRETURN setRowCount( SQLINTEGER nRowCount );
+    /* record fields... */
+    /* N/A (only set by doAppend) */
+    /* these are cached so doAppend has them when called... */
+    SQLRETURN setConnectionName( const QString &stringConnectionName );
+    SQLRETURN setServerName( const QString &stringServerName );
+
+    /* these for direct support for odbc api calls (most relevant odbc rules in these)...
*/
+    SQLRETURN   getDiagRec( SQLSMALLINT nRecNumber /* 1-based */, SQLWCHAR *psSqlstate,
SQLINTEGER *pnNativeErrorPtr, SQLWCHAR *pszMessageText, SQLSMALLINT nBufferLength,
SQLSMALLINT *pnTextLengthPtr );
+    SQLRETURN   getDiagField( SQLSMALLINT nRecNumber /* 1-based */, SQLSMALLINT
nDiagIdentifier, SQLPOINTER pDiagInfoPtr, SQLSMALLINT nBufferLength, SQLSMALLINT
*pnStringLengthPtr );
+    /* header fields... */
+    SQLINTEGER  getCursorRowCount();
+    QString     getDynamicFunction();       /*!< String indicating type of SQL
executed (ie "UPDATE WHERE")                   */
+    SQLINTEGER  getDynamicFunctionCode();
+    SQLINTEGER  getNumber();             /*!< The number of status records in records
array.                               */
+    SQLRETURN   getReturnCode();
+    SQLINTEGER  getRowCount();
+    /* record fields... */
+    QString     getClassOrigin( SQLSMALLINT nRecNumber );       /*!< Doc that defines
the class portion of the SQLSTATE val in this rec.    */
+    SQLINTEGER  getColumnNumber( SQLSMALLINT nRecNumber );
+    QString     getConnectionName( SQLSMALLINT nRecNumber );
+    QString     getMessageText( SQLSMALLINT nRecNumber );       /*!< Formatted,
informational message on the error or warning. No max length.                          
*/
+    QString     getMessage( SQLSMALLINT nRecNumber );           /*!< Unformatted,
informational message on the error or warning. Should be !> SQL_MAX_MESSAGE_LENGTH   
*/
+    SQLINTEGER  getNative( SQLSMALLINT nRecNumber );
+    SQLINTEGER  getRowNumber( SQLSMALLINT nRecNumber );
+    QString     getServerName( SQLSMALLINT nRecNumber );
+    QString     getSQLState( SQLSMALLINT nRecNumber );          /*!< A five-character
SQLSTATE diagnostic code.                             */
+    QString     getSubClassOrigin( SQLSMALLINT nRecNumber);
+    /* these are cached so doAppend has them when called... */
+    QString     getConnectionName();
+    QString     getServerName();
+
+    SQLRETURN   doAppend( MYODBC_DIA_ID nState, SQLINTEGER nNative = 0, const QString
&stringMessage = QString::null );
+    SQLRETURN   doAppend( MYODBC_DIA_ID nState, SQLINTEGER nNative, const QString
&stringMessage, SQLINTEGER nRowNumber, SQLINTEGER nColumnNumber );
+    void        doClear();
+    SQLRETURN   doDelete( SQLSMALLINT nRecNumber );
+
+protected:
+    SQLINTEGER  nCursorRowCount;        /*!< Count of rows in the cursor.             
                                   */
+    SQLINTEGER  nDynamicFunctionCode;   /*!< Code indicating type of SQL executed (ie
SQL_DIAG_UPDATE_WHERE)              */
+    SQLRETURN   nReturnCode;            /*!< Return code (as in SQLRETURN) returned by
the function.                      */
+    SQLINTEGER  nRowCount;              /*!< The number of rows affected by an insert,
delete, or update.                 */
+
+    /* these values are copied by new records */
+    QString   stringConnectionName;     /*!< This is dbc->server.                  
                                      */
+    QString   stringServerName;         /*!< This is dbc->dsn. Same as
SQL_DATA_SOURCE_NAME in SQLGetInfo().              */
+
+    QList<MYODBCDiaRec*> listRecords;/*!< the records we own                    
                                      */
+};
+
+
+#endif
+
+

Added: MYSQLCC/MYSQLCCLib/MDiagnosticRecord.cpp
===================================================================
--- MYSQLCC/MYSQLCCLib/MDiagnosticRecord.cpp	2006-04-26 17:34:24 UTC (rev 125)
+++ MYSQLCC/MYSQLCCLib/MDiagnosticRecord.cpp	2006-04-26 19:24:01 UTC (rev 126)
@@ -0,0 +1,529 @@
+#include "MYODBCDiaInternal.h"
+
+#include <QString>
+
+/*!
+    \internal
+    \brief  This is a static table of all SQL state information.
+    
+            This static table is referenced using a corresponding numeric
+            identifier MYODBC_DIA_ID. The information in this table is used
+            to format diagnostic messages.
+        
+            The number of elements in here should ALWAYS be (MYODBC_DIA_MAX - 1).
+    
+    \sa     MYODBC_DIA_ID 
+            MYODBC_DIA_STATE
+*/
+MYODBC_DIA_STATE MYODBCDia_pStates[]=
+{
+    {"ISO 9075","01000","01","General warning",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01001","01","Cursor operation conflict",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01002","01","Disconnect error",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01003","01","NULL value eliminated in set
function",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01004","01","String data right-truncated",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01006","01","Privilege not revoked",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01007","01","Privilege not granted",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S00","01","Invalid connection string
attribute",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S01","01","Error in row",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S02","01","Option value changed",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S06","01","Attempt to fetch before the result set returned the first
rowset",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S07","01","Fractional truncation",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S08","01","Error saving File DSN",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","01S09","01","Invalid keyword",SQL_SUCCESS_WITH_INFO},
+    {"ISO 9075","07001","07","Wrong number of parameters",SQL_ERROR},
+    {"ISO 9075","07002","07","COUNT field incorrect",SQL_ERROR},
+    {"ISO 9075","07005","07","Prepared statement not a cursor-specification",SQL_ERROR},
+    {"ISO 9075","07006","07","Restricted data type attribute violation",SQL_ERROR},
+    {"ISO 9075","07009","07","Invalid descriptor index",SQL_ERROR},
+    {"ISO 9075","07S01","07","Invalid use of default parameter",SQL_ERROR},
+    {"ISO 9075","08001","08","Client unable to establish connection",SQL_ERROR},
+    {"ISO 9075","08002","08","Connection name in use",SQL_ERROR},
+    {"ISO 9075","08003","08","Connection does not exist",SQL_ERROR},
+    {"ISO 9075","08004","08","Server rejected the connection",SQL_ERROR},
+    {"ISO 9075","08007","08","Connection failure during transaction",SQL_ERROR},
+    {"ISO 9075","08S01","08","Communication link failure",SQL_ERROR},
+    {"ISO 9075","21S01","21","Insert value list does not match column list",SQL_ERROR},
+    {"ISO 9075","21S02","21","Degree of derived table does not match column
list",SQL_ERROR},
+    {"ISO 9075","22001","22","String data right-truncated",SQL_ERROR},
+    {"ISO 9075","22002","22","Indicator variable required but not supplied",SQL_ERROR},
+    {"ISO 9075","22003","22","Numeric value out of range",SQL_ERROR},
+    {"ISO 9075","22007","22","Invalid datetime format",SQL_ERROR},
+    {"ISO 9075","22008","22","Datetime field overflow",SQL_ERROR},
+    {"ISO 9075","22012","22","Division by zero",SQL_ERROR},
+    {"ISO 9075","22015","22","Interval field overflow",SQL_ERROR},
+    {"ISO 9075","22018","22","Invalid character value for cast specification",SQL_ERROR},
+    {"ISO 9075","22019","22","Invalid escape character",SQL_ERROR},
+    {"ISO 9075","22025","22","Invalid escape sequence",SQL_ERROR},
+    {"ISO 9075","22026","22","String data length mismatch",SQL_ERROR},
+    {"ISO 9075","23000","23","Integrity constraint violation",SQL_ERROR},
+    {"ISO 9075","24000","24","Invalid cursor state",SQL_ERROR},
+    {"ISO 9075","25000","25","Invalid transaction state",SQL_ERROR},
+    {"ISO 9075","25S01","25","Transaction state",SQL_ERROR},
+    {"ISO 9075","25S02","25","Transaction is still active",SQL_ERROR},
+    {"ISO 9075","25S03","25","Transaction is rolled back",SQL_ERROR},
+    {"ISO 9075","28000","28","Invalid authorization specification",SQL_ERROR},
+    {"ISO 9075","34000","34","Invalid cursor name",SQL_ERROR},
+    {"ISO 9075","3C000","3C","Duplicate cursor name",SQL_ERROR},
+    {"ISO 9075","3D000","3D","Invalid catalog name",SQL_ERROR},
+    {"ISO 9075","3F000","3F","Invalid schema name",SQL_ERROR},
+    {"ISO 9075","40001","40","Serialization failure",SQL_ERROR},
+    {"ISO 9075","40002","40","Integrity constraint violation",SQL_ERROR},
+    {"ISO 9075","40003","40","Statement completion unknown",SQL_ERROR},
+    {"ISO 9075","42000","42","Syntax error or access violation",SQL_ERROR},
+    {"ISO 9075","42S01","42","Base table or view already exists",SQL_ERROR},
+    {"ISO 9075","42S02","42","Base table or view not found",SQL_ERROR},
+    {"ISO 9075","42S11","42","Index already exists",SQL_ERROR},
+    {"ISO 9075","42S12","42","Index not found",SQL_ERROR},
+    {"ISO 9075","42S21","42","Column already exists",SQL_ERROR},
+    {"ISO 9075","42S22","42","Column not found",SQL_ERROR},
+    {"ISO 9075","44000","44","WITH CHECK OPTION violation",SQL_ERROR},
+    {"ISO 9075","HY000","HY","General error",SQL_ERROR},
+    {"ISO 9075","HY001","HY","Memory allocation error",SQL_ERROR},
+    {"ISO 9075","HY003","HY","Invalid application buffer type",SQL_ERROR},
+    {"ISO 9075","HY004","HY","Invalid SQL data type",SQL_ERROR},
+    {"ISO 9075","HY007","HY","Associated statement is not prepared",SQL_ERROR},
+    {"ISO 9075","HY008","HY","Operation canceled",SQL_ERROR},
+    {"ISO 9075","HY009","HY","Invalid use of null pointer",SQL_ERROR},
+    {"ISO 9075","HY010","HY","Function sequence error",SQL_ERROR},
+    {"ISO 9075","HY011","HY","Attribute cannot be set now",SQL_ERROR},
+    {"ISO 9075","HY012","HY","Invalid transaction operation code",SQL_ERROR},
+    {"ISO 9075","HY013","HY","Memory management error",SQL_ERROR},
+    {"ISO 9075","HY014","HY","Limit on the number of handles exceeded",SQL_ERROR},
+    {"ISO 9075","HY015","HY","No cursor name available",SQL_ERROR},
+    {"ISO 9075","HY016","HY","Cannot modify an implementation row descriptor",SQL_ERROR},
+    {"ISO 9075","HY017","HY","Invalid use of an automatically allocated descriptor
handle",SQL_ERROR},
+    {"ISO 9075","HY018","HY","Server declined cancel request",SQL_ERROR},
+    {"ISO 9075","HY019","HY","Non-character and non-binary data sent in
pieces",SQL_ERROR},
+    {"ISO 9075","HY020","HY","Attempt to concatenate a null value",SQL_ERROR},
+    {"ISO 9075","HY021","HY","Inconsistent descriptor information",SQL_ERROR},
+    {"ISO 9075","HY024","HY","Invalid attribute value",SQL_ERROR},
+    {"ISO 9075","HY090","HY","Invalid string or buffer length",SQL_ERROR},
+    {"ISO 9075","HY091","HY","Invalid descriptor field identifier",SQL_ERROR},
+    {"ISO 9075","HY092","HY","Invalid attribute/option identifier",SQL_ERROR},
+    {"ISO 9075","HY095","HY","Function type out of range",SQL_ERROR},
+    {"ISO 9075","HY096","HY","Invalid information type",SQL_ERROR},
+    {"ISO 9075","HY097","HY","Column type out of range",SQL_ERROR},
+    {"ISO 9075","HY098","HY","Scope type out of range",SQL_ERROR},
+    {"ISO 9075","HY099","HY","Nullable type out of range",SQL_ERROR},
+    {"ISO 9075","HY100","HY","Uniqueness option type out of range",SQL_ERROR},
+    {"ISO 9075","HY101","HY","Accuracy option type out of range",SQL_ERROR},
+    {"ISO 9075","HY103","HY","Invalid retrieval code",SQL_ERROR},
+    {"ISO 9075","HY104","HY","Invalid precision or scale value",SQL_ERROR},
+    {"ISO 9075","HY105","HY","Invalid parameter type",SQL_ERROR},
+    {"ISO 9075","HY106","HY","Fetch type out of range",SQL_ERROR},
+    {"ISO 9075","HY107","HY","Row value out of range",SQL_ERROR},
+    {"ISO 9075","HY109","HY","Invalid cursor position",SQL_ERROR},
+    {"ISO 9075","HY110","HY","Invalid driver completion",SQL_ERROR},
+    {"ISO 9075","HY111","HY","Invalid bookmark value",SQL_ERROR},
+    {"ISO 9075","HYC00","HY","Optional feature not implemented",SQL_ERROR},
+    {"ISO 9075","HYT00","HY","Timeout expired",SQL_ERROR},
+    {"ISO 9075","HYT01","HY","Connection timeout expired",SQL_ERROR},
+    {"ODBC 3.0","IM001","IM","Driver does not support this function",SQL_ERROR},
+    {"ODBC 3.0","IM002","IM","Data source name not found and no default driver
specified",SQL_ERROR},
+    {"ODBC 3.0","IM003","IM","Specified driver could not be loaded",SQL_ERROR},
+    {"ODBC 3.0","IM004","IM","Driver's SQLAllocHandle on SQL_HANDLE_ENV
failed",SQL_ERROR},
+    {"ODBC 3.0","IM005","IM","Driver's SQLAllocHandle on SQL_HANDLE_DBC
failed",SQL_ERROR},
+    {"ODBC 3.0","IM006","IM","Driver's SQLSetConnectAttr failed",SQL_ERROR},
+    {"ODBC 3.0","IM007","IM","No data source or driver specified; dialog
prohibited",SQL_ERROR},
+    {"ODBC 3.0","IM008","IM","Dialog failed",SQL_ERROR},
+    {"ODBC 3.0","IM009","IM","Unable to load translation DLL",SQL_ERROR},
+    {"ODBC 3.0","IM010","IM","Data source name too long",SQL_ERROR},
+    {"ODBC 3.0","IM011","IM","Driver name too long",SQL_ERROR},
+    {"ODBC 3.0","IM012","IM","DRIVER keyword syntax error",SQL_ERROR},
+    {"ODBC 3.0","IM013","IM","Trace file error",SQL_ERROR},
+    {"ODBC 3.0","IM014","IM","Invalid name of File DSN",SQL_ERROR},
+    {"ODBC 3.0","IM015","IM","Corrupt file data source",SQL_ERROR}
+};
+
+
+/*!
+    \internal
+    \brief  Allocates and initializes a diagnostic record.
+
+            Allocates and initializes a diagnostic record
+            and appends it to the given diagnostic structure.
+            
+            Ultimately this needs to be freed by 
+            MYODBCDiaRecFree but this should be done 
+            automatically by array element call-back.
+
+            Does not set diag_message_text and a couple of 
+            other fields to anything useful so caller should
+            consider doing this.
+            
+    \param  pDiagnostic a diagnostic structure
+    \param  nState      SQL state to initialize record with
+
+    \return pointer to a valid diagnostic record
+
+    \sa     MYODBCDiaRecFree
+*/    
+MYODBCDiaRec::MYODBCDiaRec( MYODBCDia *pdia, MYODBC_DIA_ID nState )
+{
+    MYODBCDbgEnter();
+
+    Q_ASSERT( !pdia );
+
+    this->pdia          = pdia;
+    this->nState        = nState;
+    this->nColumnNumber = SQL_NO_COLUMN_NUMBER;
+    this->nRowNumber    = SQL_NO_ROW_NUMBER;
+    stringServerName    = pdia->getServerName();
+    stringConnectionName= pdia->getConnectionName();
+
+    MYODBCDbgReturn2();
+}
+
+/*!
+    \internal
+    \brief  Free memory used by the given diagnostic record.
+
+            This function is probably only called as a call-back
+            function by MYODBCArray functions when the record is
+            being deleted from array.
+
+    \param  pRecord diagnostic record allocated by MYODBCDiaRecAlloc
+
+    \sa     MYODBCDiaAlloc MYODBCDiaRecAlloc
+*/    
+MYODBCDiaRec::~MYODBCDiaRec()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn2();
+}
+
+SQLRETURN MYODBCDiaRec::setColumnNumber( SQLINTEGER nColumnNumber )
+{
+    MYODBCDbgEnter();
+
+    this->nColumnNumber = nColumnNumber;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDiaRec::setMessage( const QString &stringMessage )
+{
+    MYODBCDbgEnter();
+
+    this->stringMessage = stringMessage;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDiaRec::setNative( SQLINTEGER nNative )
+{
+    MYODBCDbgEnter();
+
+    this->nNative = nNative;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDiaRec::setRowNumber( SQLINTEGER nRowNumber )
+{
+    MYODBCDbgEnter();
+
+    this->nRowNumber = nRowNumber;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+
+SQLRETURN MYODBCDiaRec::getDiagRec( SQLWCHAR *psSqlstate, SQLINTEGER *pnNativeErrorPtr,
SQLWCHAR *pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT *pnTextLengthPtr )
+{
+    SQLRETURN   nReturn;
+    bool        bHasInfo = false;
+    SQLSMALLINT nStringLength;
+
+    MYODBCDbgEnter();
+
+    nReturn = getDiagField( SQL_DIAG_SQLSTATE, psSqlstate, 5, &nStringLength );
+    if ( nReturn == SQL_SUCCESS_WITH_INFO )
+        bHasInfo = true;
+    if ( !SQL_SUCCEEDED( nReturn ) )
+        MYODBCDbgReturn( nReturn );
+
+    nReturn = getDiagField( SQL_DIAG_NATIVE, pnNativeErrorPtr, SQL_IS_INTEGER, NULL );
+    if ( nReturn == SQL_SUCCESS_WITH_INFO )
+        bHasInfo = true;
+    if ( !SQL_SUCCEEDED( nReturn ) )
+        MYODBCDbgReturn( nReturn );
+
+    nReturn = getDiagField( SQL_DIAG_SQLSTATE, pszMessageText, nBufferLength,
&nStringLength );
+    if ( pnTextLengthPtr ) *pnTextLengthPtr = nStringLength;
+    if ( nReturn == SQL_SUCCESS_WITH_INFO )
+        bHasInfo = true;
+    if ( !SQL_SUCCEEDED( nReturn ) )
+        MYODBCDbgReturn( nReturn );
+
+    if ( bHasInfo )
+        MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MYODBCDiaRec::getDiagField( SQLSMALLINT nDiagIdentifier, SQLPOINTER
pDiagInfoPtr, SQLSMALLINT nBufferLength, SQLSMALLINT *pnStringLengthPtr )
+{
+    SQLSMALLINT nStringLength;
+
+    MYODBCDbgEnter();
+
+    /* use dummy when no pnStringLengthPtr */
+    if ( !pnStringLengthPtr )
+        pnStringLengthPtr = &nStringLength;
+
+    /* which record field? */
+    switch ( nDiagIdentifier )
+    {
+        case SQL_DIAG_CLASS_ORIGIN:
+            {
+                QString stringClassOrigin = getClassOrigin();
+                if ( nBufferLength < 1 || stringClassOrigin.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringClassOrigin.utf16() );
+                *pnStringLengthPtr = stringClassOrigin.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        case SQL_DIAG_COLUMN_NUMBER:
+            *(SQLINTEGER*)pDiagInfoPtr = getColumnNumber();
+            break;
+
+        case SQL_DIAG_CONNECTION_NAME:
+            {
+                QString stringConnectionName = getConnectionName();
+                if ( nBufferLength < 1 || stringConnectionName.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringConnectionName.utf16() );
+                *pnStringLengthPtr = stringConnectionName.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        case SQL_DIAG_MESSAGE_TEXT:
+            {
+                QString stringMessageText = getMessageText();
+                if ( nBufferLength < 1 || stringMessageText.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringMessageText.utf16() );
+                *pnStringLengthPtr = stringMessageText.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        case SQL_DIAG_NATIVE:
+            *(SQLINTEGER*)pDiagInfoPtr = getNative();
+            break;
+
+        case SQL_DIAG_ROW_NUMBER:
+            *(SQLINTEGER*)pDiagInfoPtr = getRowNumber();
+            break;
+
+        case SQL_DIAG_SERVER_NAME:
+            {
+                QString stringServerName = getServerName();
+                if ( nBufferLength < 1 || stringServerName.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringServerName.utf16() );
+                *pnStringLengthPtr = stringServerName.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        case SQL_DIAG_SQLSTATE:
+            {
+                QString stringSQLState = getSQLState();
+                if ( nBufferLength < 1 || stringSQLState.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringSQLState.utf16() );
+                *pnStringLengthPtr = stringSQLState.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        case SQL_DIAG_SUBCLASS_ORIGIN:
+            {
+                QString stringSubClassOrigin = getSubClassOrigin();
+                if ( nBufferLength < 1 || stringSubClassOrigin.isNull() )
+                    MYODBCDbgReturn( SQL_ERROR );
+
+                MYODBCC::doStrNCpy( (SQLWCHAR*)pDiagInfoPtr, nBufferLength /
sizeof(SQLWCHAR), stringSubClassOrigin.utf16() );
+                *pnStringLengthPtr = stringSubClassOrigin.length() * sizeof(SQLWCHAR);
+
+                if ( *pnStringLengthPtr > nBufferLength )
+                    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
+            }
+            break;
+
+        default:
+            MYODBCDbgReturn( SQL_ERROR );
+    }
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+
+QString MYODBCDiaRec::getClassOrigin()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", MYODBCDia_pStates[nState].diag_class_origin );
+}
+
+SQLINTEGER MYODBCDiaRec::getColumnNumber()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nColumnNumber );
+}
+
+QString MYODBCDiaRec::getConnectionName()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", stringConnectionName );
+}
+
+QString MYODBCDiaRec::getMessageText()
+{
+    MYODBCDbgEnter();
+
+    /* this message formated according to odbc spec */
+    if ( nNative )
+    {
+        /* server message */
+        if ( stringMessage.isEmpty() )
+        {
+            MYODBCDbgReturn3( "%s", (QString( "[%1][%2 %3][%4] %5 %6" )
+                                    .arg( MYODBC_VENDOR )
+                                    .arg( MYODBC_NAME )
+                                    .arg( MYODBC_DRIVER_VER )
+                                    .arg( MYODBC_VENDOR )
+                                    .arg( nNative )
+                                    .arg( MYODBCDia_pStates[nState].diag_text )) );
+        }
+        else
+            MYODBCDbgReturn3( "%s", (QString( "[%1][%2 %3][%4] %5 %6" )
+                                    .arg( MYODBC_VENDOR )
+                                    .arg( MYODBC_NAME )
+                                    .arg( MYODBC_DRIVER_VER )
+                                    .arg( MYODBC_VENDOR )
+                                    .arg( nNative )
+                                    .arg( stringMessage )) );
+    }
+    else
+    {
+        /* driver message */
+        if ( stringMessage.isEmpty() )
+        {
+            MYODBCDbgReturn3( "%s", QString( "[%1][%2 %3][%4] %5" )
+                                    .arg( MYODBC_VENDOR )
+                                    .arg( MYODBC_NAME )
+                                    .arg( MYODBC_DRIVER_VER )
+                                    .arg( MYODBCDia_pStates[nState].diag_sqlstate )
+                                    .arg( MYODBCDia_pStates[nState].diag_text ) );
+        }
+        else
+            MYODBCDbgReturn3( "%s", QString( "[%1][%2 %3][%4] %5" )
+                                    .arg( MYODBC_VENDOR )
+                                    .arg( MYODBC_NAME )
+                                    .arg( MYODBC_DRIVER_VER )
+                                    .arg( MYODBCDia_pStates[nState].diag_sqlstate )
+                                    .arg( stringMessage ) );
+    }
+
+    MYODBCDbgReturn3( "%s", stringMessage );
+}
+
+QString MYODBCDiaRec::getMessage()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", stringMessage );
+}
+
+SQLINTEGER MYODBCDiaRec::getNative()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nNative );
+}
+
+SQLINTEGER MYODBCDiaRec::getRowNumber()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nRowNumber );
+}
+
+QString MYODBCDiaRec::getServerName()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", stringServerName );
+}
+
+QString MYODBCDiaRec::getSQLState()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", MYODBCDia_pStates[nState].diag_sqlstate );
+}
+
+
+QString MYODBCDiaRec::getSubClassOrigin()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%s", MYODBCDia_pStates[nState].diag_class_origin );
+}
+
+MYODBCDia *MYODBCDiaRec::getDia()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%p", pdia );
+}
+
+/*!
+    \internal
+    \brief  Dumps the contents to stream.
+
+            This is useful for debugging.
+
+    \param  
+*/  
+QTextStream &operator<<( QTextStream &stream, const MYODBCDiaRec &rval
)
+{
+    stream << "SQL_DIAG_CLASS_ORIGIN    : " <<
MYODBCDia_pStates[rval.nState].diag_class_origin << endl;
+    stream << "SQL_DIAG_COLUMN_NUMBER   : " << rval.nColumnNumber <<
endl;
+    stream << "SQL_DIAG_CONNECTION_NAME : " << rval.stringConnectionName
<< endl;
+    stream << "SQL_DIAG_MESSAGE_TEXT    : " << rval.stringMessage <<
endl;
+    stream << "SQL_DIAG_NATIVE          : " << rval.nNative << endl;
+    stream << "SQL_DIAG_ROW_NUMBER      : " << rval.nRowNumber << endl;
+    stream << "SQL_DIAG_SERVER_NAME     : " << rval.stringServerName <<
endl;
+    stream << "SQL_DIAG_SQLSTATE        : " <<
MYODBCDia_pStates[rval.nState].diag_sqlstate << endl;
+    stream << "SQL_DIAG_SUBCLASS_ORIGIN : " <<
MYODBCDia_pStates[rval.nState].diag_class_origin << endl;
+
+    return stream;
+}
+
+

Added: MYSQLCC/MYSQLCCLib/MDiagnosticRecord.h
===================================================================
--- MYSQLCC/MYSQLCCLib/MDiagnosticRecord.h	2006-04-26 17:34:24 UTC (rev 125)
+++ MYSQLCC/MYSQLCCLib/MDiagnosticRecord.h	2006-04-26 19:24:01 UTC (rev 126)
@@ -0,0 +1,68 @@
+#ifndef MYODBC_DIA_RECORD_H
+#define MYODBC_DIA_RECORD_H
+
+#include "../include/MYODBCDiaState.h"
+
+/*!
+    \brief This is a diagnostic record.
+    
+            A new diagnostic record is created whenever an ODBC function
+            generates an error or warning and also under some other 
+            circumstances (to provide general information back to the 
+            application). The exception to this is when no viable handle is
+            available to store the diagnostic information - for example when
+            failure to create an environment handle.
+
+            The formatted message is created when the record is created. This
+            may not be best - certianly not in terms of storage - but may make
+            sense in that some of the information used to format the message
+            may change before the application requests the message.
+*/    
+class MYODBCDiaRec
+{
+    friend QTextStream &operator<<( QTextStream &stream, const MYODBCDiaRec
&rval );
+public:
+    MYODBCDiaRec( MYODBCDia *pdia, MYODBC_DIA_ID nState );
+    ~MYODBCDiaRec();
+
+    /* record fields... */
+    SQLRETURN setColumnNumber( SQLINTEGER nColumnNumber );
+    SQLRETURN setMessage( const QString &stringMessage );
+    SQLRETURN setNative( SQLINTEGER nNative );
+    SQLRETURN setRowNumber( SQLINTEGER nRowNumber );
+
+    /* these for direct support for odbc api calls (most relevant odbc rules in these)...
*/
+    SQLRETURN   getDiagRec( SQLWCHAR *psSqlstate, SQLINTEGER *pnNativeErrorPtr, SQLWCHAR
*pszMessageText, SQLSMALLINT nBufferLength, SQLSMALLINT *pnTextLengthPtr );
+    SQLRETURN   getDiagField( SQLSMALLINT nDiagIdentifier, SQLPOINTER pDiagInfoPtr,
SQLSMALLINT nBufferLength, SQLSMALLINT *pnStringLengthPtr );
+    /* record fields... */
+    QString     getClassOrigin();       /*!< Doc that defines the class portion of the
SQLSTATE val in this rec.    */
+    SQLINTEGER  getColumnNumber();
+    QString     getConnectionName();
+    QString     getMessageText();       /*!< Formatted, informational message on the
error or warning. No max length.                           */
+    QString     getMessage();           /*!< Unformatted, informational message on the
error or warning. Should be !> SQL_MAX_MESSAGE_LENGTH    */
+    SQLINTEGER  getNative();
+    SQLINTEGER  getRowNumber();
+    QString     getServerName();
+    QString     getSQLState();          /*!< A five-character SQLSTATE diagnostic
code.                             */
+    QString     getSubClassOrigin();    /*!< */
+
+    MYODBCDia * getDia(); 
+
+protected:
+    MYODBCDia *     pdia;               /*!< Diagnostic which owns us - we do not
exist without it.                 */
+
+    MYODBC_DIA_ID   nState;
+    QString         stringMessage;      /*! Unformatted/short message.                   
                          */
+
+    /* the var names reflect the field names used in the ODBC specification */
+    SQLINTEGER  nColumnNumber;          /*!< Col num in the result set or the param
num in the set of parameters.   */
+    QString     stringConnectionName;   /*!< This is dbc->server.                  
                                */
+    SQLINTEGER  nNative;                /*!< A driver/data source+    SQLINTEGER  nRowNumber;             /*!< Row num in the rowset, or the param num
in the set of parameters.      */
+    QString     stringServerName;       /*!< This is dbc->dsn. Same as
SQL_DATA_SOURCE_NAME in SQLGetInfo().        */
+
+};
+
+
+#endif
+

Modified: MYSQLCC/MYSQLCCLib/MEnvironment.cpp
===================================================================
--- MYSQLCC/MYSQLCCLib/MEnvironment.cpp	2006-04-26 17:34:24 UTC (rev 125)
+++ MYSQLCC/MYSQLCCLib/MEnvironment.cpp	2006-04-26 19:24:01 UTC (rev 126)
@@ -61,13 +61,9 @@
     switch ( nAttribute )
     {
         case SQL_ATTR_CONNECTION_POOLING:
-            if ( (SQLUINTEGER)pValue != nConnectionPooling )
-                MYODBCDbgReturn( diagnostic.doAppend( MYODBC_DIA_HYC00, 0, NULL ) );
-            break;
+            MYODBCDbgReturn( setConnectionPooling( (SQLUINTEGER)pValue ) );
         case SQL_ATTR_CP_MATCH:
-            if ( (SQLUINTEGER)pValue != nCPMatch )
-                MYODBCDbgReturn( diagnostic.doAppend( MYODBC_DIA_HYC00, 0, NULL ) );
-            break;
+            MYODBCDbgReturn( setCPMatch( (SQLUINTEGER)pValue ) );
         case SQL_ATTR_ODBC_VERSION:
             MYODBCDbgReturn( setODBCVersion( (SQLINTEGER)pValue ) );
         case SQL_ATTR_OUTPUT_NTS:

Thread
Connector/ODBC 5 commit: r126 - MYSQLCC/MYSQLCCLibpharvey26 Apr