⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmodbcconnection.cpp

📁 TOOL (Tiny Object Oriented Language) is an easily-embedded, object-oriented, C++-like-language inter
💻 CPP
📖 第 1 页 / 共 4 页
字号:

  if ( ( Check( nRetCode ) )
    && ( dwDriverPosOperations & SQL_POS_UPDATE ) 
    && ( dwDriverPosOperations & SQL_POS_DELETE ) 
    && ( dwDriverPosOperations & SQL_POS_ADD ) )
  {
    m_dwUpdateOptions |= SQL_SETPOSUPDATES;
  }

  // Check for positioned update SQL support
  //
  UDWORD dwPositionedStatements;
  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_POSITIONED_STATEMENTS,
                           &dwPositionedStatements, 
                           sizeof( dwPositionedStatements ),
                           &nResult );

  if ( ( Check( nRetCode ) )
    && ( dwPositionedStatements & SQL_PS_POSITIONED_DELETE ) 
    && ( dwPositionedStatements & SQL_PS_POSITIONED_UPDATE ) )
  {
    m_dwUpdateOptions |= SQL_POSITIONEDSQL;
  }

  // Check for transaction support
  //
  SWORD nTxnCapable;
  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_TXN_CAPABLE, 
                           &nTxnCapable,
                           sizeof( nTxnCapable ), 
                           &nResult );

  if ( Check( nRetCode ) && nTxnCapable != SQL_TC_NONE ) 
  {
    m_bTransactions = true;
  }

  // Cache the effect of transactions on cursors
  //
  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_CURSOR_COMMIT_BEHAVIOR,
                           &m_nCursorCommitBehavior, 
                           sizeof( m_nCursorCommitBehavior ),
                           &nResult );

  if ( !Check( nRetCode ) )
  {
    m_nCursorCommitBehavior = SQL_ERROR;
  }

  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_CURSOR_ROLLBACK_BEHAVIOR,
                           &m_nCursorRollbackBehavior, 
                           sizeof( m_nCursorRollbackBehavior ),
                           &nResult );

  if ( !Check( nRetCode ) )
  {
    m_nCursorRollbackBehavior = SQL_ERROR;
  }

  // Cache bookmark attributes
  //
  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_BOOKMARK_PERSISTENCE,
                           &m_dwBookmarkAttributes, 
                           sizeof( m_dwBookmarkAttributes ),
                           &nResult );
  Check( nRetCode );

  UDWORD dwGetDataExtensions;
  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_GETDATA_EXTENSIONS,
                           &dwGetDataExtensions, 
                           sizeof( dwGetDataExtensions ),
                           &nResult );

  if ( !Check( nRetCode ) )
  {
    dwGetDataExtensions = 0;
  }

  if ( dwGetDataExtensions & SQL_GD_BOUND )
  {
    m_dwUpdateOptions |= SQL_GDBOUND;
  }

  if ( m_bUpdatable )
  {
    // Make sure data source is Updatable
    //
    char szReadOnly[10];

    nRetCode = ::SQLGetInfo( m_hdbc, 
                             SQL_DATA_SOURCE_READ_ONLY,
                             szReadOnly, 
                             sizeof( szReadOnly ), 
                             &nResult );

    if ( Check( nRetCode ) && nResult == 1 )
    {
      m_bUpdatable = !( lstrcmpA( szReadOnly, "Y" ) == 0 );
    }
    else
    {
      m_bUpdatable = false;
    }
  }
  else
  {
    // Make data source is !Updatable
    //
    nRetCode = ::SQLSetConnectOption( m_hdbc,
                                      SQL_ACCESS_MODE, 
                                      SQL_MODE_READ_ONLY );
  }

  // Cache the quote char to use when constructing SQL
  //
  char szIDQuoteChar[2];

  nRetCode = ::SQLGetInfo( m_hdbc, 
                           SQL_IDENTIFIER_QUOTE_CHAR,
                           szIDQuoteChar, 
                           sizeof( szIDQuoteChar ), 
                           &nResult );

  if ( Check( nRetCode ) && nResult == 1 )
  {
    m_chIDQuoteChar = szIDQuoteChar[0];
  }
  else
  {
    m_chIDQuoteChar = ' ';
  }
}
/* End of function "VMODBCConnection::GetConnectInfo"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:	VMODBCConnection::VerifySQLConnect

       DESCRIPTION:	Special verification function for database connections.

             INPUT:	retCode - the return code to check
                    pcFile - pointer to source file name of SQL call
                    ulLine - souce file line number of SQL call
           RETURNS:	TRUE if no error
                    FALSE if correctable error is detected
                    throws CMSgLog* exception in non-correctable error is detected.
*/
bool VMODBCConnection::VerifySQLConnect( RETCODE retCode, const char* pcFile, UINT uiLine )
{

  const char* pcMsg;
  char*       pcTest;

  if ( retCode == SQL_SUCCESS || retCode == SQL_SUCCESS_WITH_INFO )
  {
    // no connection errors
    //
    return( true );
  }

  GetErrorMessages( SQL_HANDLE_DBC, m_hdbc );
  pcMsg = (const char*)m_auchErrorMsg;

  // filter out the exceptable failure conditions
  //
  pcTest = strstr( pcMsg, UNABLE_TO_CONNECT );
  if( pcTest != NULL )
  {
    // unable to connect    
    return( false );
  }

  pcTest = strstr( pcMsg, ALREADY_IN_USE );
  if ( pcTest != NULL )
  {
    // connection in use
    return( false );
  }

  pcTest = strstr( pcMsg, COMM_LINK_FAILED );
  if ( pcTest != NULL )
  {
    // communication link failure
    return( false );
  }

  pcTest = strstr( pcMsg, COMM_LINK_FAILURE );
  if ( pcTest != NULL )
  {
    // communication link failure
    return( false );
  }

  // its not good, but we don't know what is wrong
  return( false );
}
/* end of function "VMODBCConnection::VerifySQLConnect" */
/*****************************************************************************/



/*****************************************************************************/
/*
     FUNCTION NAME:	VMODBCConnection::OnTimerEvent

       DESCRIPTION:	Called at intervals when the database connection is broken
                    to attempt a reconnection.

             INPUT:	uiTimerID - ID of the timer being triggerred.
           RETURNS:	none
*/
void VMODBCConnection::OnTimerEvent( UINT uiTimerID )
{
  try
  {
    if ( m_bReconnectTimer )
    {
      if ( Reconnect() )
      {        
        // kill the reconnect timer
        //
        m_bReconnectTimer = false;
      }
    }
    // IMPORTANT NOTE: This is the normal return from
    // this method if the connection can be re-established
    // with the target. See additional code AFTER the catch
    // blocks for code that will execute whenever the 
    // subordinates fail to reconnect (and therefore throw)
    //
    return;
  }
  catch( VMException* poEx )
  {
    delete poEx;
    m_iReconnectAttempts++;
  }
  catch( ... )
  {
    m_iReconnectAttempts++;
  }

  // this code should only execute after an exception has been
  // thrown in one of this functions subordinates. In other words,
  // the re-connection attempt failed.
  //
  char   chMsg[1024];
  ZeroMemory( chMsg, 1024 );
        
  strcat( chMsg, "Could not connect to database." );

  strcpy( chMsg, "" );
  sprintf( chMsg, 
           "Have Tried To Connect %i Times.", 
           m_iReconnectAttempts );

  strcpy( chMsg, "" );
  sprintf( chMsg, 
           "Will Re-Attempt To Connect In %i Minutes.", 
           m_uiReconnectWait / 60000 );
}
/* end of function "VMODBCConnection::OnTimerEvent" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:	VMODBCConnection::Reconnect

       DESCRIPTION:	Attempts to reconnect a lost database connection.

             INPUT:	none
           RETURNS:	TRUE if the connection is restored, FALSE otherwise
*/
bool VMODBCConnection::Reconnect( void )
{
  RETCODE re;
  char    acBuf[ 640 ];
  SWORD   sCountOut;

  // verify the conditions for a reconnect
  //
  assert( m_bReconnectTimer == true );
  assert( m_hdbc == SQL_NULL_HDBC );
  assert( m_hstmt == SQL_NULL_HSTMT );

  // attempt to connect
  try
  {
    re = ::SQLAllocConnect( m_henvAllConnections, &m_hdbc );    
    GetErrorMessages( SQL_HANDLE_DBC, m_hdbc );
 
    re = ::SQLDriverConnect( m_hdbc, HWND_DESKTOP,
                             (UCHAR*)(const char*)m_oConnect, 
                             m_oConnect.GetLength(),
    	                     (UCHAR*)acBuf, 
                             640, 
                             &sCountOut, 
                             SQL_DRIVER_NOPROMPT );

    // test for success(TRUE), broken connection(FALSE) or error(throws exception)
    //
    if( VerifySQLConnect( re, __FILE__, __LINE__ ) )
    {
      // reconnected! - get a statement handle & allow insertions
      //
      re = ::SQLAllocStmt( m_hdbc, &m_hstmt ); 
      GetErrorMessages( SQL_HANDLE_STMT, m_hstmt );
      return( true );
    }
  }
  catch( VMException* poEx )
  {
     // connection still broken - free the handle allocation
     //
     ::SQLFreeConnect( m_hdbc );
     m_hdbc = SQL_NULL_HDBC;
     throw poEx;
  }
  return( false );
}
/* end of function "VMODBCConnection::Reconnect" */
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBCConnection::BindParameters

       DESCRIPTION:  does nothing

             INPUT:  hStmt - statement handle
            OUTPUT:  none

           RETURNS:  void
*/
void VMODBCConnection::BindParameters( HSTMT hStmt )
{
  // Must override and call SQLBindParameter directly
}
/* End of function "VMODBCConnection::BindParameters"
/*****************************************************************************/


/*****************************************************************************/
/*

     FUNCTION NAME:  VMODBCConnection::GetErrorMessages

       DESCRIPTION:  Retrieve Errors from the ODBC Driver stack

             INPUT:  iHandleType - the type of handle to get errors for
                     hSqlHandle - the handle to get errors for
                     bIsConnected - true if drivers are connected to dbms
            OUTPUT:  

           RETURNS:  void  
*/
void VMODBCConnection::GetErrorMessages( SQLSMALLINT iHandleType, SQLHANDLE hSqlHandle, bool bIsConnected )
{
  return;

  #define MAXBUFLEN    1024

  RETCODE      hRetCode                 = SQL_SUCCESS;
  UCHAR        achSqlState[ MAXBUFLEN ] = "";
  UCHAR        achErrorMsg[ MAXBUFLEN ] = "";
  SDWORD       dwNativeError            = 0L;
  SWORD        wErrorMsg                = 0;
  SQLSMALLINT  iRecordNumber            = 1;
  SDWORD       dwMsgState               = 0;
  SDWORD       dwSeverity               = 0;
  SQLINTEGER   iRownumber               = 0;
  USHORT       usLine;
  SQLSMALLINT  iProcessName;
  SQLSMALLINT  iServerName;
  SQLCHAR      achProcessName[ MAXNAME ];
  SQLCHAR      achServerName[ MAXNAME ];

  while ( hRetCode != SQL_NO_DATA_FOUND ) 
  {
    hRetCode = SQLGetDiagRec( iHandleType, 
                                 hSqlHandle,
                                 iRecordNumber, 
                                 achSqlState, 
                                 &dwNativeError,
                                 achErrorMsg, 
                                 MAXBUFLEN - 1, 
                                 &wErrorMsg );

    // Note that if the application has not yet made a
    // successful connection, the SQLGetDiagField
    // information has not yet been cached by ODBC
    // Driver Manager and these calls to SQLGetDiagField
    // will fail.
    //
    if ( hRetCode != SQL_NO_DATA_FOUND ) 
    {
      if ( bIsConnected ) 
      {
        hRetCode = SQLGetDiagField( iHandleType, 
                                       hSqlHandle, 
                                       iRecordNumber,
                                       SQL_DIAG_ROW_NUMBER, 
                                       &iRownumber,
                                       SQL_IS_INTEGER,
                                       NULL );

        hRetCode = SQLGetDiagField( iHandleType, 
                                       hSqlHandle, 
                                       iRecordNumber,
                                       SQL_DIAG_SS_LINE, 
                                       &usLine,
                                       SQL_IS_INTEGER,
                                       NULL );

        hRetCode = SQLGetDiagField( iHandleType, 
                                       hSqlHandle, 
                                       iRecordNumber,
                                       SQL_DIAG_SS_MSGSTATE, 
                                       &dwMsgState,
                                       SQL_IS_INTEGER,
                                       NULL );

        hRetCode = SQLGetDiagField( iHandleType, 
                                       hSqlHandle, 
                                       iRecordNumber,
                                       SQL_DIAG_SS_SEVERITY, 
                                       &dwSeverity,
                                       SQL_IS_INTEGER,
                                       NULL );

        hRetCode = SQLGetDiagField( iHandleType, 
                                       hSqlHandle, 
                                       iRecordNumber,
                                       SQL_DIAG_SS_PROCNAME, 
                                       &achProcessName,
                                       sizeof( achProcessName ),
                                       &iProcessName );

        hRetCode = SQLGetDiagField( iHandleType, 
                                       hSqlHandle, 
                                       iRecordNumber,
                                       SQL_DIAG_SS_SRVNAME, 
                                       &achServerName,
                                       sizeof( achServerName ),
                                       &iServerName );
      }

      if ( bIsConnected ) 
      {
      }
    }
    iRecordNumber++;
  }
}
/* End of function "VMODBCConnection::GetErrorMessages"
/*****************************************************************************/


/*****************************************************************************/
/* Check-in history */
/*
 *$Log:  $
*/
/*****************************************************************************/


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -