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

📄 vmodbc.cpp

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

      $Revision:   $
          $Date:   $
        $Author:   $

    Description:   Implementation of an ODBC wrapper class that can bind to
                   and read data from any sql result set 

                      TOOL And XML FORMS License
                      ==========================

                      Except where otherwise noted, all of the documentation 
                      and software included in the TOOL package is 
                      copyrighted by Michael Swartzendruber.

                      Copyright (C) 2005 Michael John Swartzendruber. 
                      All rights reserved.

                      Access to this code, whether intentional or accidental,
                      does NOT IMPLY any transfer of rights.

                      This software is provided "as-is," without any express 
                      or implied warranty. In no event shall the author be held
                      liable for any damages arising from the use of this software.

                      Permission is granted to anyone to use this software for 
                      any purpose, including commercial applications, and to 
                      alter and redistribute it, provided that the following 
                      conditions are met:

                      1. All redistributions of source code files must retain 
                         all copyright notices that are currently in place, 
                         and this list of conditions without modification.

                      2. The origin of this software must not be misrepresented;
                         you must not claim that you wrote the original software.

                      3. If you use this software in another product, an acknowledgment
                         in the product documentation would be appreciated but is
                         not required.

                      4. Modified versions in source or binary form must be plainly 
                         marked as such, and must not be misrepresented as being 
                         the original software.
*/
static char OBJECT_ID[] = "$Revision: 2 $ : $Date: 3/14/00 3:33p $";
/*****************************************************************************/

#include "../../../stdafx.h"
#include <string.h>
#include <memory.h>
#include <assert.h>

#pragma warning( disable : 4786 )

#include "VMODBCConnection.h"
#include "../TraceTools/VMWatcherOutput.h"
#include "../VMException.h"
#include "VMByteArray.h"
#include "VMODBC.h"


/////////////////////////////////////////////////////////////////////////////
//
// simple macros for checking SQLfuncx return values for success and warnings
//
#define RC_SUCCESSFUL( rc )    ( !( ( rc ) >> 1 ) )
#define RC_NOTSUCCESSFUL( rc ) ( ( rc ) >> 1 )


const int ciMaxMsgSize = 500;



/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::VMODBC

       DESCRIPTION:  ctor

             INPUT:  none
            OUTPUT:  none

           RETURNS:  none
*/
VMODBC::VMODBC( void ) : VMODBCConnection()
{
  m_bIsEOF       = true;
  m_bIsBOF       = true;
  m_bIsBound     = true;
  m_bShouldBind  = false;
  m_bIsEmpty     = true;
  m_hstmt        = INVALID_HANDLE_VALUE;
  m_iColumnCount = 0;
}
/* End of function "VMODBC::VMODBC"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::~VMODBC

       DESCRIPTION:  dtor

             INPUT:  none
            OUTPUT:  none

           RETURNS:  none
*/
VMODBC::~VMODBC( void )
{
  ReleaseColumns();
}
/* End of function "VMODBC::~VMODBC"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::ReleaseColumns

       DESCRIPTION:  releases all local buffers and column objects

             INPUT:  void
            OUTPUT:  none

           RETURNS:  void
*/
void VMODBC::ReleaseColumns( void )
{
  COLUMN_INFO_BY_INDEX_ITER oIndexIter;
  for ( oIndexIter  = m_oColumnsByIndex.begin();
        oIndexIter != m_oColumnsByIndex.end();
        oIndexIter++ )
  {
    VMColumnInfo* poColumnInfo = *oIndexIter;

    switch ( poColumnInfo->m_iSqlDataType )
    {
      // character family
      //
      case SQL_CHAR:
      case SQL_VARCHAR:
      case SQL_LONGVARCHAR:
      //
      // mjs: is this right for unicode as well?
      //
      case SQL_WCHAR:
      case SQL_WVARCHAR:
      case SQL_WLONGVARCHAR:
        delete (VMString*)poColumnInfo->m_pvData;
      break;

      // Integer family
      //
      case SQL_BIT:
        delete (BOOL*)poColumnInfo->m_pvData;
      break;

      case SQL_TINYINT:
        delete (unsigned char *)poColumnInfo->m_pvData;
      break;

      case SQL_SMALLINT:
        delete (int*)poColumnInfo->m_pvData;
	    break;

      case SQL_INTEGER:
        delete (long*)poColumnInfo->m_pvData;
      break;

      case SQL_BIGINT:
        delete (_int64*)poColumnInfo->m_pvData;
      break;

      // Floating-point type family and Fixed-point exact numerics.  
      //
      case SQL_NUMERIC:
        delete (double*)poColumnInfo->m_pvData;
//        delete (SQL_NUMERIC_STRUCT*)poColumnInfo->m_pvData;
      break;

      //    case SQL_DECIMAL:
      case SQL_REAL:
      case SQL_FLOAT:
        delete (float*)poColumnInfo->m_pvData;
      break;

      case SQL_DECIMAL:
      case SQL_DOUBLE:
        delete (double*)poColumnInfo->m_pvData;
      break;

      case SQL_BINARY:
      case SQL_VARBINARY:
      case SQL_LONGVARBINARY:
        delete (VMByteArray*)poColumnInfo->m_pvData;
      break;

      // Date/Time family
      //
      case SQL_DATE:
        delete (SQL_TIMESTAMP_STRUCT*)poColumnInfo->m_pvData;
      break;

      case SQL_TIME:
        delete (SQL_TIME_STRUCT*)poColumnInfo->m_pvData;
      break;

      case SQL_TIMESTAMP:
        delete (SQL_TIMESTAMP_STRUCT*)poColumnInfo->m_pvData;
      break;

      case SQL_GUID:
        delete (SQLGUID*)poColumnInfo->m_pvData;
      break;

      case SQL_INTERVAL_DAY:
      case SQL_INTERVAL_DAY_TO_MINUTE:
      case SQL_INTERVAL_HOUR:
      case SQL_INTERVAL_DAY_TO_SECOND:
      case SQL_INTERVAL_MINUTE:
      case SQL_INTERVAL_HOUR_TO_MINUTE:
      case SQL_INTERVAL_SECOND:
      case SQL_INTERVAL_HOUR_TO_SECOND:
      case SQL_INTERVAL_DAY_TO_HOUR:
      case SQL_INTERVAL_MINUTE_TO_SECOND:
        delete (VMString*)poColumnInfo->m_pvData;
      break;

      default:
       delete poColumnInfo->m_pvData;                      
      break;
    }
    delete poColumnInfo;
  }
  m_oColumnsByIndex.clear();
  m_oColumnsByName.clear();
}
/* End of function "VMODBC::ReleaseColumns"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::Close

       DESCRIPTION:  essentially shuts this down.

             INPUT:  none
            OUTPUT:  none

           RETURNS:  true
*/
void VMODBC::Close( void )
{
  if ( m_hstmt != INVALID_HANDLE_VALUE )
  {
    ::SQLCloseCursor( m_hstmt );
    ::SQLFreeStmt( m_hstmt, SQL_UNBIND );
    m_hstmt = INVALID_HANDLE_VALUE;

    ReleaseColumns();
  }
  m_bIsEmpty = true;
  m_bIsBOF   = true;
  m_bIsEOF   = true;
}
/* End of function "VMODBC::Close"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::ExecuteQuery

       DESCRIPTION:  top level public function. Allows a query to be specified
                     and then will issue the query. After the query returns will
                     then build this record set object to bind to whatever the
                     query came back with

             INPUT:  pchToExecute : pointer to the query to run ( a string )
            OUTPUT:  none

           RETURNS:  true if worked, false if not
*/
bool VMODBC::ExecuteQuery( const char* pchToExecute )
{
  RETCODE nRetCode;

  m_bIsEmpty = false;
  m_bIsEOF   = false;
  m_bIsBOF   = false;

  // in case some is getting sloppy, free up resources and
  // get ready to bind again
  //
  if ( m_hstmt != INVALID_HANDLE_VALUE )
  {
    ::SQLCloseCursor( m_hstmt );
    ::SQLFreeStmt( m_hstmt, SQL_UNBIND );;
    m_hstmt = INVALID_HANDLE_VALUE;
    ReleaseColumns();

  }
 
  ::SQLAllocStmt( m_hdbc, &m_hstmt );

  nRetCode = SQLSetStmtAttr( m_hstmt, 
                             SQL_ATTR_CURSOR_SCROLLABLE,
                             (SQLPOINTER)SQL_SCROLLABLE,
                             SQL_IS_INTEGER );
  nRetCode = SQLSetStmtAttr( m_hstmt, 
                             SQL_ATTR_CURSOR_SENSITIVITY,
                             (SQLPOINTER)SQL_INSENSITIVE,
                             SQL_IS_INTEGER );

  nRetCode = ::SQLExecDirect( m_hstmt, 
                             (SQLCHAR*)pchToExecute, 
                              strlen( pchToExecute ) );

  if ( RC_SUCCESSFUL( nRetCode ) )
  {
    if ( nRetCode != SQL_NO_DATA )
    {
      if ( MakeColumnListFromQuery() )
      {
        if ( m_bShouldBind )
        {
          bool bBoundWithSuccess = true;

          COLUMN_INFO_BY_INDEX_ITER oIndexIter;
          for ( oIndexIter  = m_oColumnsByIndex.begin();
                oIndexIter != m_oColumnsByIndex.end();
                oIndexIter++ )
          {
            VMColumnInfo* poColumnInfo = *oIndexIter;
            bBoundWithSuccess &= BindColumn( poColumnInfo );
          }
          m_bIsBound = bBoundWithSuccess;
        }
        else
        {
          // make sure this is set right
          //
          m_bIsBound = false;
        }
      }
      else
      {
        return( false );
      }
    }
    else
    {
      m_bIsEmpty = true;
      m_bIsBOF   = true;
      m_bIsEOF   = true;
      return( true );
    }
  }
  else
  {
    return( false );
  }
  MoveToStart();
  return( true );
}
/* End of function "VMODBC::ExecuteQuery"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::MoveToIndexFromStart

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

           RETURNS:  instance count if the switch was found, -1 otherwise
*/
bool VMODBC::MoveToIndexFromStart( int iIndex )
{
  SQLRETURN ret;

  ret = ::SQLFetchScroll( m_hstmt, SQL_FETCH_ABSOLUTE, iIndex );
  if ( SQL_SUCCESS != ret )
  {
    DecodeSQLError( ret, 
                    m_hdbc, 
                    m_hstmt, 
                    __FILE__, 
                    __LINE__ );
  }

  m_bIsBOF = ret == SQL_NO_DATA;
  m_bIsEOF = false;

  return( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO );
}
/* End of function "VMODBC::MoveToIndexFromStart"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::MoveToIndexFromEnd

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

           RETURNS:  instance count if the switch was found, -1 otherwise
*/
bool VMODBC::MoveToIndexFromEnd( int iIndex )
{
  SQLRETURN ret;

  iIndex = -1 * abs( iIndex );

  ret = ::SQLFetchScroll( m_hstmt, SQL_FETCH_ABSOLUTE, iIndex );
  if ( SQL_SUCCESS != ret )
  {
    DecodeSQLError( ret, 
                    m_hdbc, 
                    m_hstmt, 
                    __FILE__, 
                    __LINE__ );
  }

  m_bIsEOF = ret == SQL_NO_DATA;
  m_bIsBOF = false;

  return( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO );
}
/* End of function "VMODBC::MoveToIndexFromEnd"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::MoveNext

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

           RETURNS:  instance count if the switch was found, -1 otherwise
*/
bool VMODBC::MoveNext( void )
{
  SQLRETURN ret;

  ret = ::SQLFetchScroll( m_hstmt, SQL_FETCH_NEXT, 0 );
  if ( SQL_SUCCESS != ret )
  {
    DecodeSQLError( ret, 
                    m_hdbc, 
                    m_hstmt, 
                    __FILE__, 
                    __LINE__ );
  }

  m_bIsEOF = ret == SQL_NO_DATA;
  m_bIsBOF = false;

  return( ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO );
}
/* End of function "VMODBC::MoveNext"
/*****************************************************************************/


/*****************************************************************************/
/*
     FUNCTION NAME:  VMODBC::MovePrev

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

           RETURNS:  instance count if the switch was found, -1 otherwise
*/
bool VMODBC::MovePrev( void )
{
  SQLRETURN ret;

  ret = ::SQLFetchScroll( m_hstmt, SQL_FETCH_PRIOR, 0 );
  if ( SQL_SUCCESS != ret )
  {
    DecodeSQLError( ret, 
                    m_hdbc, 
                    m_hstmt, 
                    __FILE__, 
                    __LINE__ );
  }

  m_bIsBOF = ret == SQL_NO_DATA;

⌨️ 快捷键说明

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