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

📄 vmodbc.cpp

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

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


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

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

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

  ret = ::SQLFetchScroll( m_hstmt, SQL_FETCH_FIRST, 0 );
  if ( SQL_SUCCESS != ret )
  {
    DecodeSQLError( ret, 
                    m_hdbc, 
                    m_hstmt, 
                    __FILE__, 
                    __LINE__ );
  }
	
  m_bIsBOF = ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO;

  if ( m_bIsBOF )
  {
    m_bIsEOF = false;
  }
	return m_bIsBOF;
}
/* End of function "VMODBC::MoveToStart"
/*****************************************************************************/


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

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

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

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

  m_bIsEOF = ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO;
  
  if( m_bIsEOF )
  {
    m_bIsBOF = false;
  }
  return( m_bIsEOF );
}
/* End of function "VMODBC::MoveToEnd"
/*****************************************************************************/


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

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

           RETURNS:  instance count if the switch was found, -1 otherwise
*/
bool VMODBC::MoveForward( int iMoveAmount )
{
  do
  {
    ;
  } while( MoveNext() && --iMoveAmount >= 0 );

  if ( iMoveAmount == 0 )
  {
    return( true );
  }
  else
  {
    return( false );
  }
}
/* End of function "VMODBC::MoveForward"
/*****************************************************************************/


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

       DESCRIPTION:  cursor mover

             INPUT:  none
            OUTPUT:  none

           RETURNS:  instance count if the switch was found, -1 otherwise
*/
bool VMODBC::MoveBackward( int iMoveAmount )
{
  do
  {
    ;
  } while( MovePrev() && -- iMoveAmount >= 0 );

  if ( iMoveAmount == 0 )
  {
    return( true );
  }
  else
  {
    return( false );
  }
}
/* End of function "VMODBC::MoveBackward"
/*****************************************************************************/


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

       DESCRIPTION:  does any work required to move data from the sql buffers
                     into local buffers, then invokes the poDataExchange object
                     to move that data into the application space ( the exchanger
                     is expected to provide mediation services between this and
                     the application )

             INPUT:  poDataExchange : pointer to the data exchanger object
            OUTPUT:  none

           RETURNS:  void
*/
void VMODBC::ExchangeData( VMDataExchanger* poDataExchange )
{
  bool bCanExchange = true;
  if ( m_bIsBound )
  {
    // simple, all columns are bound, so cursor lib already did the work
  }
  else
  {
    // harder have to fetch data ourselves since no buffers are bound
    //
    COLUMN_INFO_BY_INDEX_ITER oIndexIter;
    for ( oIndexIter  = m_oColumnsByIndex.begin();
          oIndexIter != m_oColumnsByIndex.end();
          oIndexIter++ )
    {
      VMColumnInfo* poColumnInfo = *oIndexIter;
      RETCODE       nRetCode;

      switch( poColumnInfo->m_iSqlDataType )
      {
        // directly transfer simple types, 
        // no additional buffer allocations needed
        //
        case SQL_DECIMAL:
        case SQL_NUMERIC:
        case SQL_BIT:
        case SQL_TINYINT:
        case SQL_SMALLINT:
        case SQL_INTEGER:
        case SQL_REAL:
        case SQL_FLOAT:
        case SQL_DOUBLE:
        case SQL_GUID:
        {
          nRetCode = ::SQLGetData( m_hstmt, 
                                   poColumnInfo->m_iColumnIndex, 
                                   poColumnInfo->m_iCDataType, 
                                   poColumnInfo->m_pvData, 
                                   sizeof( poColumnInfo->m_pvData ), 
                                   NULL );
        }
        break;
		
        case SQL_BIGINT:
        {
          // since SQL_C_BIGINT is not defined for
          // our version of library, must fall back
          // to this approach:
          //
          // get as a string, then convert to _int64
          //
          char achValue[ 50 ];

          nRetCode = ::SQLGetData( m_hstmt, 
                                   poColumnInfo->m_iColumnIndex, 
                                   poColumnInfo->m_iCDataType, 
                                   achValue, 
                                   sizeof( achValue ), 
                                   NULL );
         #ifdef _UNICODE
            *( (_int64*)poColumnInfo->m_pvData ) = _wtoi64( achValue );
         #else
            *( (_int64*)poColumnInfo->m_pvData ) = _atoi64( achValue );
         #endif
        }
        break;

        case SQL_CHAR:
        case SQL_VARCHAR:
        case SQL_WCHAR:
        case SQL_WVARCHAR:
        // 
        // mjs: are these correctly interpreted as strings?
        //
        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:
        {
          VMString* poText = ((VMString*)poColumnInfo->m_pvData);
          char*        pchBuffer = poText->GetBufferSetLength( 1000 );

          long          iLength;
          nRetCode = ::SQLGetData( m_hstmt, 
                                   poColumnInfo->m_iColumnIndex, 
                                   poColumnInfo->m_iCDataType, 
                                   pchBuffer, 
                                   1000, 
                                   &iLength );

          int iTestFlags = IS_TEXT_UNICODE_ASCII16;
          if ( IsTextUnicode( pchBuffer, iLength, &iTestFlags ) )
          {
            // stupid db did some unicode crap, undo it....
            //
            if ( iLength > 0 )
            {
              char* pchTemp = new char[ iLength ];
              if ( WideCharToMultiByte( CP_ACP, 
                                        0, 
                                        (const unsigned short*)pchBuffer, 
                                        -1,
                                        pchTemp,
                                        iLength,
                                        NULL,
                                        NULL ) )
              {
                poText->ReleaseBuffer();
                *poText = pchTemp;
              }
              delete [] pchTemp;
            }
          }
          else
          {
            poText->ReleaseBuffer();
          }
        }
        break;

        case SQL_LONGVARCHAR:
        case SQL_WLONGVARCHAR:
        {
          VMString* poText = ((VMString*)poColumnInfo->m_pvData);
          poText->Empty();
          SQLCHAR      achLocalBuffer[ 5000 ];
          SQLINTEGER   iLengthIndicator;

          memset( achLocalBuffer, 0, 5000 );
          while ( SQL_NO_DATA != ( nRetCode = ::SQLGetData( m_hstmt, 
                                                            poColumnInfo->m_iColumnIndex, 
                                                            poColumnInfo->m_iCDataType, 
                                                            achLocalBuffer, 
                                                            sizeof( achLocalBuffer ), 
                                                            &iLengthIndicator ) ) )
          {
            if ( RC_NOTSUCCESSFUL( nRetCode ) )
            {
              DecodeSQLError( nRetCode, 
                              m_hdbc, 
                              m_hstmt, 
                              __FILE__,
                              __LINE__ );
              break;
            }
            *poText += (const char*)achLocalBuffer; 
            memset( achLocalBuffer, 0, 5000 );
          }
        }
        break;

        case SQL_DATE:
        case SQL_TIME:
        case SQL_TIMESTAMP:
        {
          nRetCode = ::SQLGetData( m_hstmt, 
                                   poColumnInfo->m_iColumnIndex, 
                                   poColumnInfo->m_iCDataType, 
                                   poColumnInfo->m_pvData, 
                                   sizeof( poColumnInfo->m_pvData ), 
                                   NULL );
        }
        break;

        case SQL_BINARY:
        case SQL_VARBINARY:
        case SQL_LONGVARBINARY:
        {
          VMByteArray* poData = ((VMByteArray*)poColumnInfo->m_pvData);
 
          poData->FreeAll();

          SQLCHAR*     pchLocalBuffer;
          SQLINTEGER   iLengthIndicator;
          int          iBufferLength;

          if ( poColumnInfo->m_iSqlDataType == SQL_LONGVARBINARY )
          {
            iBufferLength = 32576;
          }
          else
          {
            iBufferLength = 256;
          }

          poData->SetSize( iBufferLength );

          pchLocalBuffer = new SQLCHAR[ iBufferLength ];
          memset( pchLocalBuffer, 0, 5000 );
          while ( SQL_NO_DATA != ( nRetCode = ::SQLGetData( m_hstmt, 
                                                            poColumnInfo->m_iColumnIndex, 
                                                            poColumnInfo->m_iCDataType, 
                                                            pchLocalBuffer, 
                                                            iBufferLength, 
                                                            &iLengthIndicator ) ) )
          {
            if ( RC_NOTSUCCESSFUL( nRetCode ) )
            {
              DecodeSQLError( nRetCode, 
                              m_hdbc, 
                              m_hstmt, 
                              __FILE__,
                              __LINE__ );
              break;
            }
            for ( int iLoop = 0; 
                      ( iLoop < 5000 ) && ( iLoop < iLengthIndicator ); 
                      iLoop++ )
            {
              poData->Add( (BYTE)pchLocalBuffer[ iLoop ] );
            }
            memset( pchLocalBuffer, 0, iBufferLength * sizeof( SQLCHAR ) );
          }
          delete [] pchLocalBuffer;
        }
        break;
      }
      if ( RC_NOTSUCCESSFUL( nRetCode ) )
      {
        bCanExchange = false;
        DecodeSQLError( nRetCode, 
                        m_hdbc, 
                        m_hstmt, 
                        __FILE__,
                        __LINE__ );
      }
    }
  }
  if ( bCanExchange && poDataExchange )
  {
    poDataExchange->ExchangeData( this );
  }
}
/* End of function "VMODBC::ExchangeData"
/*****************************************************************************/


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

       DESCRIPTION:  does all the work required to operate against the meta
                     data for an sql result set, and then calls on subordinates
                     to use that meta data for the creation of local buffers for
                     data exchange

             INPUT:  void
            OUTPUT:  essentially inits this....

           RETURNS:  true if worked, false if not
*/
bool VMODBC::MakeColumnListFromQuery( void )
{
  bool           bResult = false;  // Assume we'll fail; allow reselect
  RETCODE        nRetCode;         // Return code from ODBC functions
  VMColumnInfo*  poColumnInfo;     // Data type output for each column
  int            iIndex;           // Index for columns
  short          iColumns;         // the number of columns in this query

  // check to see if this object was constructed sans open CDatabase
  //
  if ( m_hstmt == SQL_NULL_HSTMT ) 
  {
    DEBUGOUT( "ERROR!!!!! >>>NO STATEMENT HANDLE<<<" );
    throw new VMException( __FILE__, __LINE__, "Invalid Connection or SQL State" );
  }
	
  if ( !IsOpen() )
  {
    DEBUGOUT( "ERROR!!!!! >>>DB CONNECTION CLOSED<<<" );
    throw new VMException( __FILE__, __LINE__, "Invalid Connection or SQL State" );
  }

  // how many columns are there in the result
  //
  nRetCode = ::SQLNumResultCols( m_hstmt, &iColumns );
  if ( RC_NOTSUCCESSFUL( nRetCode ) ) 
  {
     DecodeSQLError( nRetCode, 
                     m_hdbc, 
                     m_hstmt, 
                     __FILE__,
                     __LINE__ );
     goto cleanup;
  }
	
  // now loop through the column set gathering facts about each one
  // to store in a CColumn class for each column. All the CColumn 
  // classes will be added to the m_CPA_ColumnInfoList 
  //
  for( iIndex = 0;  iIndex < iColumns;  iIndex++ ) 
  {
    poColumnInfo = new VMColumnInfo;

    if ( poColumnInfo == NULL )
    {
      goto cleanup;
    }
      
    poColumnInfo->m_iColumnIndex = iIndex + 1;

    // get the SQL_xxx type (and related info) for the column
    //
    nRetCode = ::SQLDescribeCol( m_hstmt,
                                 (UWORD)( iIndex + 1 ), 
                                 NULL, 
                                 0, 
                                 NULL,
                                 &poColumnInfo->m_iSqlDataType,
                                 &poColumnInfo->m_dwPrecision,
                                 &poColumnInfo->m_iScale,
                                 &poColumnInfo->m_iIsNullable );

    if ( RC_NOTSUCCESSFUL( nRetCode ) )
    {
      DecodeSQLError( nRetCode, 
                      m_hdbc, 
                      m_hstmt, 
                      __FILE__, 
                      __LINE__ );
      goto cleanup;
    }

    // Get the named type of the column for mapping
    //
    nRetCode = ::SQLColAttributes( m_hstmt,
                                   (UWORD)( iIndex + 1 ),
                                   SQL_COLUMN_TYPE_NAME,           
                                   &poColumnInfo->m_achNamedType,
                                   sizeof( poColumnInfo->m_achNamedType ),
                                   NULL,
                                   NULL );
    if ( RC_NOTSUCCESSFUL( nRetCode ) )
    {
      DecodeSQLError( nRetCode, 
                      m_hdbc, 
                      m_hstmt, 
                      __FILE__, 
                      __LINE__ );
      goto cleanup;
    }

⌨️ 快捷键说明

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