hbodbc

  Previous topic Next topic JavaScript is required for the print function Mail us feedback on this topic! Mail us feedback on this topic!  
c:\harbour\contrib\hbodbc
odbc.c
TypeFunctionSourceLine
HB_FUNCSQLALLOCEN(void)
HB_FUNC( SQLALLOCEN ) /* HB_SQLALLOCENV( @hEnv ) --> nRetCode */
{
   HENV hEnv;
   RETCODE ret = SQLAllocEnv( &hEnv );

   hb_storptr( hEnv, 1 );
   hb_retni( ret );
}
odbc.c121
HB_FUNCSQLALLOCCO(void)
HB_FUNC( SQLALLOCCO ) /* HB_SQLALLOCCONNECT( hEnv, @ hDbc ) --> nRetCode */
{
   HDBC hDbc;
   RETCODE ret = SQLAllocConnect( ( HENV ) hb_parptr( 1 ), &hDbc );

   hb_storptr( hDbc, 2 );
   hb_retni( ret );
}
odbc.c130
HB_FUNCSQLDRIVERC(void)
HB_FUNC( SQLDRIVERC ) /* HB_SQLDRIVERCONNECT( hDbc, @ cConnectString ) --> nRetCode */
{
   SWORD  wLen;
   RETCODE ret;

#if defined( HB_OS_WIN_32 ) && defined( UNICODE )

   LPTSTR lpStr = HB_TCHAR_CONVTO( hb_parcx( 2 ) );
   TCHAR buffer[ 1024 ];
   buffer[ 0 ] = '\0';
   ret = SQLDriverConnect( ( HDBC ) hb_parptr( 1 ),
                           GetDesktopWindow(),
                           lpStr,
                           ( SQLSMALLINT ) hb_parclen( 2 ),
                           buffer,
                           sizeof( buffer ),
                           &wLen,
                           SQL_DRIVER_COMPLETE );
   HB_TCHAR_FREE( lpStr );
   if( ISBYREF( 3 ) )
   {
      char * szStr = HB_TCHAR_CONVFROM( buffer );
      hb_storc( szStr, 3 );
      HB_TCHAR_FREE( szStr );
   }
#else
   BYTE buffer[ 1024 ];
   buffer[ 0 ] = '\0';
   ret = SQLDriverConnect( ( HDBC ) hb_parptr( 1 ),
                           0,
                           ( SQLCHAR * ) hb_parcx( 2 ),
                           ( SQLSMALLINT ) hb_parclen( 2 ),
                           buffer,
                           sizeof( buffer ),
                           &wLen,
                           SQL_DRIVER_COMPLETE );
   hb_storc( ( char * ) buffer, 3 );
#endif
   hb_retni( ret );
}
odbc.c139
HB_FUNCSQLCONNECT(void)
HB_FUNC( SQLCONNECT ) /* HB_SQLCONNECT( hDbc, cDSN, cUseName, cPassword ) --> nRetCode */
{
   RETCODE ret;
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
   LPTSTR lpDSN      = HB_TCHAR_CONVTO( hb_parcx( 2 ) ),
          lpUseName  = HB_TCHAR_CONVTO( hb_parcx( 3 ) ),
          lpPassword = HB_TCHAR_CONVTO( hb_parcx( 4 ) );

   ret =  SQLConnect( ( HDBC ) hb_parptr( 1 ),
                      lpDSN,
                      ( SQLSMALLINT ) hb_parclen( 2 ),
                      lpUseName,
                      ( SQLSMALLINT ) hb_parclen( 3 ),
                      lpPassword,
                      ( SQLSMALLINT ) hb_parclen( 4 ) );

   HB_TCHAR_FREE( lpDSN );
   HB_TCHAR_FREE( lpUseName );
   HB_TCHAR_FREE( lpPassword );
#else
   ret =  SQLConnect( ( HDBC ) hb_parptr( 1 ),
                      ( unsigned char * ) hb_parcx( 2 ),
                      ( SQLSMALLINT ) hb_parclen( 2 ),
                      ( unsigned char * ) hb_parcx( 3 ),
                      ( SQLSMALLINT ) hb_parclen( 3 ),
                      ( unsigned char * ) hb_parcx( 4 ),
                      ( SQLSMALLINT ) hb_parclen( 4 ) );
#endif
   hb_retni( ret );
}
odbc.c180
HB_FUNCSQLDISCONN(void)
HB_FUNC( SQLDISCONN )  /* HB_SQLDISCONNECT( hDbc ) --> nRetCode */
{
   hb_retni( SQLDisconnect( ( HDBC ) hb_parptr( 1 ) ) );
}
odbc.c211
HB_FUNCSQLFREECON(void)
HB_FUNC( SQLFREECON )  /* HB_SQLFREECONNECT( hDbc ) --> nRetCode */
{
   hb_retni( SQLFreeConnect( ( HDBC ) hb_parptr( 1 ) ) );
}
odbc.c216
HB_FUNCSQLFREEENV(void)
HB_FUNC( SQLFREEENV )  /* HB_SQLFREEENV( hEnv ) --> nRetCode */
{
   hb_retni( SQLFreeEnv( ( HENV ) hb_parptr( 1 ) ) );
}
odbc.c221
HB_FUNCSQLALLOCST(void)
HB_FUNC( SQLALLOCST )  /* HB_SQLALLOCSTMT( hDbc, @hStmt ) --> nRetCode */
{
   HSTMT hStmt;

   hb_retni( SQLAllocStmt( ( HDBC ) hb_parptr( 1 ), &hStmt ) );
   hb_storptr( hStmt, 2 );
}
odbc.c226
HB_FUNCSQLFREESTM(void)
HB_FUNC( SQLFREESTM ) /* HB_SQLFREESTMT( hStmt, nType ) --> nRetCode */
{
   hb_retni( SQLFreeStmt( ( HSTMT ) hb_parptr( 1 ), ( SQLUSMALLINT ) hb_parni( 2 ) ) );
}
odbc.c234
HB_FUNCSQLEXECDIR(void)
HB_FUNC( SQLEXECDIR )  /* HB_SQLEXECDIRECT( hStmt, cStatement ) --> nRetCode */
{
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
   LPTSTR lpStr = HB_TCHAR_CONVTO( hb_parcx( 2 ) );
   hb_retni( SQLExecDirect( ( HSTMT ) hb_parptr( 1 ), lpStr, hb_parclen( 2 ) ) );
   HB_TCHAR_FREE( lpStr );
#else
   hb_retni( SQLExecDirect( ( HSTMT ) hb_parptr( 1 ), ( unsigned char * ) hb_parcx( 2 ), hb_parclen( 2 ) ) );
#endif
}
odbc.c239
HB_FUNCSQLFETCH(void)
HB_FUNC( SQLFETCH )   /* HB_SQLFETCH( hStmt ) --> nRetCode */
{
   hb_retni( SQLFetch( ( HSTMT ) hb_parptr( 1 ) ) );
}
odbc.c250
HB_FUNCSQLGETDATA(void)
HB_FUNC( SQLGETDATA ) /* HB_SQLGETDATA( hStmt, nField, nType, nLen, @cBuffer ) --> nRetCode */
{
   SQLLEN lLen, lInitBuff, lBuffLen;
   PTR  bBuffer, bOut;
   WORD wType, wResult;
   int iReallocs = 0;

   wType = ( WORD ) hb_parni( 3 );
   if( !wType )
      wType = ( WORD ) SQL_BINARY;
   lLen = ( SQLLEN ) hb_parnl( 4 );
   if( !lLen )
      lLen = 64;
   bBuffer    = hb_xgrab( (ULONG) lLen + 1 );
   bOut       = NULL;
   lInitBuff  = lLen;
   lBuffLen   = 0;

   wResult = ! SQL_NO_DATA;
   while( wResult != SQL_NO_DATA )
   {
      wResult = SQLGetData( ( HSTMT ) hb_parptr( 1 ), ( SQLUSMALLINT ) hb_parni( 2 ), wType, ( PTR ) bBuffer, lLen, &lLen );
      if( wResult == SQL_SUCCESS && iReallocs == 0 )
      {
         hb_storclen( ( LPSTR ) bBuffer, ( ULONG ) ( lLen < 0 ? 0 : ( lLen < hb_parnl( 4 ) ? lLen : hb_parnl( 4 ) ) ), 5 );
         break;
      }
      else if ( wResult == SQL_SUCCESS_WITH_INFO && iReallocs == 0 )
      {
         /* Perhaps a data truncation */
         if( lLen >= lInitBuff )
         {
            /* data right truncated! */
            lBuffLen = lLen;
            bOut = ( char * ) hb_xgrab( ( ULONG ) lBuffLen + 1 );
            hb_strncpy( ( char * ) bOut, ( char * ) bBuffer, lLen );
            lLen = lLen - lInitBuff + 2;
            bBuffer = ( char * ) hb_xrealloc( bBuffer, ( ULONG ) lLen );
            iReallocs++;
         }
         else
         {
            hb_storclen( ( LPSTR ) bBuffer, ( ULONG ) ( lLen < 0 ? 0 : ( lLen < hb_parnl( 4 ) ? lLen : hb_parnl( 4 ) ) ), 5 );
            break;
         }
      }
      else if( ( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO ) && iReallocs > 0 )
      {
         hb_strncat( ( char * ) bOut, ( char * ) bBuffer, lBuffLen );
         hb_storclen( ( LPSTR ) bOut, ( ULONG ) ( lLen + lInitBuff - 1 ), 5 );
         wResult = SQL_SUCCESS;
         break;
      }
      else
      {
         break;
      }
   }
   hb_xfree( ( PTR ) bBuffer );
   if( bOut )
   {
      hb_xfree( ( PTR ) bOut );
   }
   hb_retni( wResult );
}
odbc.c255
HB_FUNCSQLNUMRES(void)
HB_FUNC( SQLNUMRES )
{
   SQLSMALLINT nCols;
   WORD wResult = SQLNumResultCols( ( HSTMT ) hb_parptr( 1 ), &nCols );

/* if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO ) */
      hb_stornl( ( LONG ) nCols, 2 );

   hb_retni( wResult );
}
odbc.c321
HB_FUNCSQLDESCRIB(void)
HB_FUNC( SQLDESCRIB )
{
   SDWORD      lLen      = ( SDWORD ) hb_parnl( 4 );
   SQLSMALLINT wBufLen   = ( SQLUSMALLINT ) hb_parni( 5 );
   SQLSMALLINT wDataType = ( SQLUSMALLINT ) hb_parni( 6 );
   SQLULEN     wColSize  = hb_parni( 7 );
   SQLSMALLINT wDecimals = ( SQLUSMALLINT ) hb_parni( 8 );
   SQLSMALLINT wNullable = ( SQLUSMALLINT ) hb_parni( 9 );
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
   LPTSTR      buffer    = ( LPTSTR ) hb_xgrab( lLen * sizeof( TCHAR ) );
#else
   SQLCHAR *   buffer    = ( SQLCHAR * ) hb_xgrab( lLen * sizeof( SQLCHAR ) );
#endif
   WORD        wResult;

   wResult = SQLDescribeCol( ( HSTMT ) hb_parptr( 1 ),
                             ( SQLUSMALLINT ) hb_parni( 2 ),
                             buffer,
                             ( SQLSMALLINT ) lLen,
                             &wBufLen,
                             &wDataType, 
                             &wColSize,
                             &wDecimals,
                             &wNullable );

   if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO )
   {
      if( ISBYREF( 3 ) )
      {
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
         char * szStr = HB_TCHAR_CONVFROM( buffer );
         hb_storc( szStr, 3 );
         HB_TCHAR_FREE( szStr );
#else
         hb_storclen( ( char * ) buffer, ( WORD ) wBufLen, 3 );
#endif
      }
      hb_stornl( ( LONG ) wBufLen, 5 );
      hb_stornl( ( LONG ) wDataType, 6 );
      hb_stornl( ( LONG ) wColSize, 7 );
      hb_stornl( ( LONG ) wDecimals, 8 );
      hb_stornl( ( LONG ) wNullable, 9 );
   }

   hb_xfree( buffer );
   hb_retni( wResult );
}
odbc.c333
HB_FUNCSQLCOLATTRIBUTE(void)
HB_FUNC( SQLCOLATTRIBUTE )
{
   SDWORD      lLen      = ( SDWORD ) hb_parnl( 5 );
   PTR         bBuffer   = hb_xgrab( lLen );
   SQLSMALLINT wBufLen   = ( SQLUSMALLINT ) hb_parni( 6 );
#if defined(__DMC__)
   SQLINTEGER  wNumPtr   = hb_parni( 7 );
#else
   SQLLEN      wNumPtr   = hb_parni( 7 );
#endif
   WORD        wResult   = SQLColAttribute( ( HSTMT ) hb_parptr( 1 ),
                                            ( SQLUSMALLINT ) hb_parni( 2 ),
                                            ( SQLUSMALLINT ) hb_parni( 3 ),
                                            ( unsigned char * ) bBuffer, 
                                            ( SQLUSMALLINT ) hb_parni( 5 ), 
                                            &wBufLen,
                                            &wNumPtr );

   if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO )
   {
      hb_storclen( ( LPSTR ) bBuffer,
                   ( WORD ) wBufLen, 4 );
      hb_stornl( ( LONG ) wBufLen, 6 );
      hb_stornl( ( LONG ) wNumPtr, 7 );
   }

   hb_xfree( ( PTR ) bBuffer );
   hb_retni( wResult );
}
odbc.c382
HB_FUNCSQLEXTENDE(void)
HB_FUNC( SQLEXTENDE )
{
#if defined(__POCC__) || defined(__XCC__)
   SQLROWSETSIZE uiRowCountPtr = hb_parni( 4 );
#else
   SQLULEN       uiRowCountPtr = hb_parni( 4 );
#endif
   SQLUSMALLINT  siRowStatus   = ( SQLUSMALLINT ) hb_parni( 5 );
   WORD          wResult       = SQLExtendedFetch( ( HSTMT ) hb_parptr( 1 ),
                                                   ( USHORT ) hb_parnl( 2 ),
                                                   ( USHORT ) hb_parnl( 3 ),
                                                   &uiRowCountPtr,
                                                   &siRowStatus );

   if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO )
   {
      hb_stornl( ( LONG ) uiRowCountPtr, 4 );
      hb_stornl( ( LONG ) siRowStatus, 5 );
   }

   hb_retni( wResult );
}
odbc.c413
HB_FUNCSQLFETCHSC(void)
HB_FUNC( SQLFETCHSC )
{
   hb_retni( SQLFetchScroll( ( HSTMT ) hb_parptr( 1 ),
                             ( SHORT ) hb_parnl( 2 ),
                             hb_parnl( 3 ) ) );
}
odbc.c437
HB_FUNCSQLERROR(void)
HB_FUNC( SQLERROR ) /* hEnv, hDbc, hStmt, @ cErrorClass, @ nType, @ cErrorMsg */
{
   SQLINTEGER lError;
   SWORD      wLen;
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
   TCHAR      buffer[ 256 ], szErrorMsg[ 256 ];
#else
   BYTE       buffer[ 256 ], szErrorMsg[ 256 ];
#endif
   hb_retni( SQLError( ( HENV ) hb_parptr( 1 ),
                       ( HDBC ) hb_parptr( 2 ),
                       ( HSTMT ) hb_parnl( 3 ),
                       buffer,
                       &lError,
                       szErrorMsg,
                       sizeof( szErrorMsg ),
                       &wLen ) );

   if( ISBYREF( 4 ) )
   {
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
      char * szStr = HB_TCHAR_CONVFROM( buffer );
      hb_storc( szStr, 4 );
      HB_TCHAR_FREE( szStr );
#else
      hb_storc( ( char * ) buffer, 4 );
#endif
   }
   hb_stornl( ( LONG ) lError, 5 );
   if( ISBYREF( 6 ) )
   {
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
      char * szStr = HB_TCHAR_CONVFROM( szErrorMsg );
      hb_storc( szStr, 6 );
      HB_TCHAR_FREE( szStr );
#else
      hb_storc( ( char * ) szErrorMsg, 6 );
#endif
   }
}
odbc.c444
HB_FUNCSQLROWCOUN(void)
HB_FUNC( SQLROWCOUN )
{
    SQLLEN  iRowCountPtr = hb_parni( 2 );
    WORD    wResult      = SQLRowCount( ( HSTMT ) hb_parptr( 1 ),
                                        &iRowCountPtr );
    if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO )
    {
       hb_stornl( ( LONG ) iRowCountPtr, 2 );
    }

    hb_retni( wResult );
}
odbc.c485
HB_FUNCSQLGETINFO(void)
HB_FUNC( SQLGETINFO ) /* hDbc, nType, @cResult */
{
   BYTE bBuffer[ 512 ];
   SQLSMALLINT wLen;
   WORD wResult = SQLGetInfo( ( HDBC ) hb_parptr( 1 ),
                              ( UWORD ) hb_parnl( 2 ), 
                              bBuffer,
                              sizeof( bBuffer ),
                              &wLen );

   hb_storclen( ( char * ) bBuffer, wLen, 3 );
   hb_retni( wResult );
}
odbc.c498
HB_FUNCSQLSETCONNECTOPTION(void)
HB_FUNC( SQLSETCONNECTOPTION ) /* hDbc, nOption, uOption */
{
#if (ODBCVER >= 0x0300)
   hb_retni( SQLSetConnectAttr( ( SQLHDBC ) hb_parptr( 1 ),
                                ( SQLINTEGER ) hb_parnl( 2 ),
                                ISCHAR( 3 ) ? ( SQLPOINTER ) hb_parcx( 3 ) : ( SQLPOINTER ) hb_parnl( 3 ), 
                                ISCHAR( 3 ) ? ( SQLINTEGER ) hb_parclen( 3 ) : ( SQLINTEGER ) SQL_IS_INTEGER ) );
#else
   hb_retni( SQLSetConnectOption( ( HDBC ) hb_parptr( 1 ),
                                  ( UWORD ) hb_parnl( 2 ),
                                  ( UDWORD ) ISCHAR( 3 ) ? ( LONG ) hb_parcx( 3 ) : hb_parnl( 3 ) ) );
#endif
}
odbc.c512
HB_FUNCSQLSETSTMTOPTION(void)
HB_FUNC( SQLSETSTMTOPTION ) /* hStmt, nOption, uOption )  --> nRetCode */
{
#if (ODBCVER >= 0x0300)
   hb_retni( SQLSetStmtAttr( ( SQLHSTMT ) hb_parptr( 1 ),
                             ( SQLINTEGER ) hb_parnl( 2 ),
                             ISCHAR( 3 ) ? ( SQLPOINTER ) hb_parcx( 3 ) : ( SQLPOINTER ) hb_parnl( 3 ), 
                             ISCHAR( 3 ) ? ( SQLINTEGER ) hb_parclen( 3 ) : ( SQLINTEGER ) SQL_IS_INTEGER ) );
#else
   hb_retni( SQLSetStmtOption( ( SQLHSTMT ) hb_parptr( 1 ),
                               ( UWORD ) hb_parnl( 2 ),
                               ( UDWORD ) ISCHAR( 3 ) ? ( LONG ) hb_parcx( 3 ) : hb_parnl( 3 ) ) );
#endif
}
odbc.c526
HB_FUNCSQLGETCONNECTOPTION(void)
HB_FUNC( SQLGETCONNECTOPTION ) /* hDbc, nOption, @cOption */
{
#if (ODBCVER >= 0x0300)
   SQLPOINTER buffer[ 512 ];
   SQLINTEGER len;
   SQLRETURN result = SQLGetConnectAttr( ( SQLHDBC ) hb_parptr( 1 ), 
                                         ( SQLINTEGER ) hb_parni( 2 ), 
                                         buffer,
                                         ( SQLINTEGER ) sizeof( buffer ),
                                         &len );
   hb_storclen( result == SQL_SUCCESS ? ( char * ) buffer : NULL, len, 3 );
   hb_retni( result );
#else
   BYTE bBuffer[ 512 ];
   WORD result = SQLGetConnectOption( ( HDBC ) hb_parptr( 1 ), hb_parni( 2 ), bBuffer );

   hb_storclen( result == SQL_SUCCESS ? ( char * ) bBuffer : NULL, sizeof( bBuffer ), 3 );
   hb_retni( result );
#endif
}
odbc.c540
HB_FUNCSQLGETSTMTOPTION(void)
HB_FUNC( SQLGETSTMTOPTION ) /* hStmt, nOption, @cOption */
{
#if (ODBCVER >= 0x0300)
   SQLPOINTER buffer[ 512 ];
   SQLINTEGER len;
   SQLRETURN result = SQLGetStmtAttr( ( SQLHSTMT ) hb_parptr( 1 ), 
                                      ( SQLINTEGER ) hb_parni( 2 ), 
                                      buffer,
                                      ( SQLINTEGER ) sizeof( buffer ),
                                      &len );

   hb_storclen( result == SQL_SUCCESS ? ( char * ) buffer : NULL, len, 3 );
   hb_retni( result );
#else
   BYTE bBuffer[ 512 ];
   WORD result = SQLGetStmtOption( ( SQLHSTMT ) hb_parptr( 1 ), hb_parni( 2 ), bBuffer );

   hb_storclen( result == SQL_SUCCESS ? ( char * ) bBuffer : NULL, sizeof( bBuffer ), 3 );
   hb_retni( result );
#endif
}
odbc.c561
HB_FUNCSQLCOMMIT(void)
HB_FUNC( SQLCOMMIT ) /* hEnv, hDbc */
{
   hb_retni( SQLTransact( ( HENV ) hb_parptr( 1 ), ( HDBC ) hb_parptr( 2 ), SQL_COMMIT ) );
}
odbc.c583
HB_FUNCSQLROLLBACK(void)
HB_FUNC( SQLROLLBACK )  /* hEnv, hDbc */
{
   hb_retni( SQLTransact( ( HENV ) hb_parptr( 1 ), ( HDBC ) hb_parptr( 2 ), SQL_ROLLBACK ) );
}
odbc.c588
HB_FUNCSETNUMLEN(void)
HB_FUNC( SETNUMLEN )  /* SETNUMLEN( nValue, nSize, nDecimals ) ==> nValue (nSize, nDec) */
{
   hb_retnlen( hb_parnd( 1 ), hb_parni( 2 ), hb_parni( 3 ) );
}
odbc.c593
HB_FUNCSQLPREPARE(void)
HB_FUNC( SQLPREPARE )  /* HB_SQLPREPARE( hStmt, cStatement ) --> nRetCode */
{
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
   LPTSTR lpStr = HB_TCHAR_CONVTO( hb_parcx( 2 ) );
   hb_retni( SQLPrepare( ( HSTMT ) hb_parptr( 1 ), lpStr, SQL_NTS ) );
   HB_TCHAR_FREE( lpStr );
#else
   hb_retni( SQLPrepare( ( HSTMT ) hb_parptr( 1 ), ( unsigned char * ) hb_parcx( 2 ), SQL_NTS ) );
#endif
}
odbc.c598
HB_FUNCSQLEXECUTE(void)
HB_FUNC( SQLEXECUTE )  /* HB_SQLEXECUTE( hStmt ) --> nRetCode */
{
   hb_retni( SQLExecute( ( HSTMT ) hb_parptr( 1 ) ) );
}
odbc.c609
HB_FUNCSQLEXECUTESCALAR(void)
HB_FUNC( SQLEXECUTESCALAR )
{
   HSTMT hStmt;
   SQLLEN lLen;
   BYTE bBuffer[ 256 ];
   SWORD wResult;

   wResult = SQLAllocStmt( ( HDBC ) hb_parptr( 2 ), &hStmt );

   if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO )
   {
#if defined( HB_OS_WIN_32 ) && defined( UNICODE )
      LPTSTR lpStr = HB_TCHAR_CONVTO( hb_parcx( 1 ) );
      wResult = SQLExecDirect( ( HSTMT ) hStmt, lpStr, SQL_NTS );
      HB_TCHAR_FREE( lpStr );
#else
      wResult = SQLExecDirect( ( HSTMT ) hStmt, ( unsigned char * ) hb_parcx( 1 ), SQL_NTS );
#endif
      if( wResult == SQL_SUCCESS || wResult == SQL_SUCCESS_WITH_INFO )
      {
         wResult = SQLFetch( ( HSTMT ) hStmt );
         if( wResult != SQL_NO_DATA )
         {
            wResult = SQLGetData( ( HSTMT ) hStmt, 1, SQL_C_CHAR, bBuffer, sizeof( bBuffer ), &lLen );
            hb_storc( ( char * ) bBuffer, 3 );
         }
      }
   }

   hb_retni( wResult );

   SQLFreeStmt( ( HSTMT ) hStmt, 0 );
}
odbc.c614
HB_FUNCSQLSTOD(void)
HB_FUNC( SQLSTOD )
{
   if( hb_parclen( 1 ) >= 10 )
   {
      char * szSqlDate = hb_parc( 1 );  /* YYYY-MM-DD */
      char szHrbDate[9];               /* YYYYMMDD */

      szHrbDate[ 0 ] = szSqlDate[ 0 ];
      szHrbDate[ 1 ] = szSqlDate[ 1 ];
      szHrbDate[ 2 ] = szSqlDate[ 2 ];
      szHrbDate[ 3 ] = szSqlDate[ 3 ];
      szHrbDate[ 4 ] = szSqlDate[ 5 ];
      szHrbDate[ 5 ] = szSqlDate[ 6 ];
      szHrbDate[ 6 ] = szSqlDate[ 8 ];
      szHrbDate[ 7 ] = szSqlDate[ 9 ];
      szHrbDate[ 8 ] = '\0';
      hb_retds( szHrbDate );
   }
   else
   {
      hb_retds( NULL );
   }
}
odbc.c648
HB_FUNCSQLMORERESULTS(void)
HB_FUNC( SQLMORERESULTS ) /* hEnv, hDbc */
{
   hb_retni( SQLMoreResults( ( SQLHSTMT ) hb_parptr( 1 ) ) );
}
odbc.c672
HB_FUNCSQLBINDOUTPARAM(void)
HB_FUNC( SQLBINDOUTPARAM ) /* SqlBindOutParam( nStatementHandle, nParameterNumber, nParameterType, ColumnSize, DecimalDigits, @ParamValue, @ParamLength    ) --> nRetCode */
{
   SQLLEN lLen = hb_parnl( 7 );
   RETCODE ret;

   ret = SQLBindParameter( ( HSTMT ) hb_parptr( 1 ),
                           ( USHORT ) hb_parni( 2 ),
                           SQL_PARAM_OUTPUT,
                           SQL_CHAR,
                           ( USHORT ) hb_parni( 3 ),
                           ( USHORT ) hb_parni( 4 ),
                           ( USHORT ) hb_parni( 5 ),
                           hb_parcx( 6 ),
                           hb_parclen( 6 ),
                           &lLen );
   hb_stornl( ( LONG ) lLen, 7 );
   hb_retni( ret );
}
odbc.c678
browodbc.prg
TypeFunctionSourceLine
FUNCTIONBrowseODBC( nTop, nLeft, nBottom, nRight, oDataSource )
function BrowseODBC( nTop, nLeft, nBottom, nRight, oDataSource )

   local oBrw
   local cOldScreen
   local n, nOldCursor
   local nKey := 0
   local lExit := .f.
   local lGotKey := .f.
   local bAction
   local oColumn
   //LOCAL cFName
   
   //TODO: Check if datasource is open   
   //if ! Used()
   //   return .f.
   //end

   if PCount() < 4
      nTop    := 1
      nLeft   := 0
      nBottom := MaxRow()
      nRight  := MaxCol()
   endif

   nOldCursor := SetCursor( 0 )
   cOldScreen := SaveScreen( nTop, nLeft, nBottom, nRight )

   @ nTop, nLeft TO nBottom, nRight
   @ nTop + 1, nLeft + 1 SAY Space( nRight - nLeft - 1 )

   oBrw:= TBrowseNew(nTop + 2, nLeft + 1, nBottom - 1, nRight - 1 )

   oBrw:SkipBlock     := { | nRecs | Skipped( nRecs,oDataSource ) }
   oBrw:GoTopBlock    := { || oDataSource:first() }
   oBrw:GoBottomBlock := { || oDataSource:last() }

   oBrw:HeadSep := "-"
   
   
   // TODO: Find out number of columns in ODBC result set, up to then you have to add columns by hand
   for n := 1 to len(oDataSource:Fields)
      oColumn:= TBColumn():New( oDataSource:Fields[n]:FieldName,  ODBCFget(oDataSource:Fields[n]:FieldName,oDataSource))
      oBrw:AddColumn(oColumn)
   next
   
   oBrw:Configure()

   oBrw:ForceStable()

   while ! lExit

      if nKey == 0
         while !oBrw:stabilize() .and. NextKey() == 0
         enddo
      endif

      if NextKey() == 0

         oBrw:forceStable()
         Statline( oBrw, oDataSource)

         nKey := Inkey( 0 )

         if ( bAction := SetKey( nKey ) ) != nil
            Eval( bAction, ProcName( 1 ), ProcLine( 1 ), "" )
            loop
         endif
      else
         nKey := Inkey()
      endif

      do case
         case nKey == K_ESC
            lExit := .t.

         case nKey == K_UP
            oBrw:Up()

         case nKey == K_DOWN
            oBrw:Down()

         case nKey == K_END
            oBrw:End()

         case nKey == K_HOME
            oBrw:Home()

         case nKey == K_LEFT
            oBrw:Left()

         case nKey == K_RIGHT
            oBrw:Right()

         case nKey == K_PGUP
            oBrw:PageUp()

         case nKey == K_PGDN
            oBrw:PageDown()

         case nKey == K_CTRL_PGUP
            oBrw:GoTop()

         case nKey == K_CTRL_PGDN
            oBrw:GoBottom()

         case nKey == K_CTRL_LEFT
            oBrw:panLeft()

         case nKey == K_CTRL_RIGHT
            oBrw:panRight()

         case nKey == K_CTRL_HOME
            oBrw:panHome()

         case nKey == K_CTRL_END
            oBrw:panEnd()

      endcase
   end

   RestScreen( nTop, nLeft, nBottom, nRight, cOldScreen )
   SetCursor( nOldCursor )

return .t.
browodbc.prg64
STATIC PROCEDUREStatline( oBrw, oDataSource )
static procedure Statline( oBrw, oDataSource )

   local nTop   := oBrw:nTop - 1
   local nRight := oBrw:nRight

   @ nTop, nRight - 27 SAY "Record "

   if oDataSource:LastRec() == 0
      @ nTop, nRight - 20 SAY "               "
   elseif oDataSource:RecNo() == oDataSource:LastRec() + 1
      @ nTop, nRight - 40 SAY "         "
      @ nTop, nRight - 20 SAY "                "
   else
      @ nTop, nRight - 20 SAY PadR( LTrim( Str( oDataSource:RecNo() ) ) + "/" +;
                                    Ltrim( Str( oDataSource:LastRec() ) ), 16 ) +;
                              iif( oBrw:hitTop, "", "     " )+;
                              iif( oBrw:hitBottom, "", "     " )
   endif

return
browodbc.prg189
STATIC FUNCTIONSkipped( nRecs, oDataSource )
STATIC FUNCTION Skipped( nRecs, oDataSource )

   LOCAL nSkipped := 0
   IF .not. oDataSource:Eof()
      IF nRecs == 0
         // ODBC doesn't have skip(0)
      ELSEIF nRecs > 0 
         DO WHILE nSkipped < nRecs
           IF .NOT. oDataSource:Eof()
             oDataSource:next( )
             IF oDataSource:Eof()
               oDataSource:prior( )
               EXIT
             ENDIF
             nSkipped++
           ENDIF  
         ENDDO
      ELSEIF nRecs < 0
         DO WHILE nSkipped > nRecs
           IF .NOT. oDataSource:Bof()
             oDataSource:prior( )
             IF oDataSource:Bof()
               EXIT
             ENDIF
             nSkipped--
           ENDIF  
         ENDDO
      ENDIF
   ENDIF
RETURN nSkipped
browodbc.prg210
STATIC FUNCTIONODBCFGet(cFieldName,oDataSource)
STATIC FUNCTION ODBCFGet(cFieldName,oDataSource)

   IF ISCHARACTER( cFieldName )
      // For changing value rather write a decent SQL statement
      RETURN {| x | iif( x == NIL, oDataSource:FieldByName(cFieldName):value,NIL ) }
   ENDIF

RETURN NIL
browodbc.prg241
todbc.prg
TypeFunctionSourceLine
CLASSTODBCField FROM HBClass
CLASS TODBCField FROM HBClass

   DATA FieldID
   DATA FieldName
   DATA DataType
   DATA DataSize
   DATA DataDecs
   DATA AllowNull
   DATA Value
   DATA OriginalType
   DATA OriginalLen
   DATA OriginalDec

   METHOD New()

ENDCLASS
todbc.prg80
TODBCFIELD:METHODNew() CLASS TODBCField
METHOD New() CLASS TODBCField

   ::FieldId   := - 1
   ::FieldName := ""
   ::DataType  := - 1
   ::DataSize  := - 1
   ::DataDecs  := - 1
   ::AllowNull := .F.
   ::Value     := NIL

RETURN Self

*+--------------------------------------------------------------------
*+
*+    Class TODBC
*+    Manages ODBC access
*+
*+--------------------------------------------------------------------
todbc.prg99
CLASSTODBC FROM HBClass
CLASS TODBC FROM HBClass

   DATA hEnv
   DATA hDbc
   DATA hStmt
   DATA cODBCStr
   DATA cODBCRes
   DATA cSQL
   DATA Active
   DATA Fields
   DATA nEof
   DATA lBof
   DATA nRetCode
   DATA nRecCount            // number of rows in current recordset
   DATA nRecNo               // Current row number in current recordset
   DATA lCacheRS             // Do we want to cache recordset in memory
   DATA aRecordSet           // Array to store cached recordset

   DATA lAutoCommit AS LOGICAL INIT .T.   // Autocommit is usually on at startup

   METHOD New( cODBCStr, cUserName, cPassword, lCache )
   METHOD Destroy()

   METHOD SetSQL( cSQL )
   METHOD Open()
   METHOD ExecSQL()
   METHOD CLOSE()

   METHOD LoadData()
todbc.prg118
TODBC:METHODClearData()
   METHOD ClearData() INLINE ( AEVAL(::Fields, {|oField| oField:Value := nil}) )
   METHOD FieldByName( cField )

   METHOD Fetch( nFetchType, nOffSet )

   METHOD Next()
   METHOD Prior()
   METHOD First()
   METHOD last()
   METHOD MoveBy( nSteps )
   METHOD GoTo( nRecNo )
   METHOD Skip()
   METHOD Eof()
   METHOD Bof()
   METHOD RecCount()
   METHOD Lastrec()
   METHOD RecNo()

   METHOD SQLErrorMessage()

   METHOD SetCnnOptions( nType, uBuffer )
   METHOD GetCnnOptions( nType )
   METHOD Commit()
   METHOD RollBack()
   METHOD SetStmtOptions( nType, uBuffer )
   METHOD GetStmtOptions( nType )
   METHOD SetAutocommit( lEnable )

ENDCLASS
todbc.prg147
TODBC:METHODSQLErrorMessage() CLASS TODBC
METHOD SQLErrorMessage() CLASS TODBC

   LOCAL cErrorClass, nType, cErrorMsg

   SQLError( ::hEnv, ::hDbc, ::hStmt, @cErrorClass, @nType, @cErrorMsg )

RETURN "Error " + cErrorClass + " - " + cErrorMsg
todbc.prg179
TODBC:METHODNew( cODBCStr, cUserName, cPassword, lCache ) CLASS TODBC
METHOD New( cODBCStr, cUserName, cPassword, lCache ) CLASS TODBC

   LOCAL xBuf
   LOCAL nRet

   IF cUserName != NIL
     DEFAULT cPassword TO ""
   ENDIF

   DEFAULT lCache TO .T.

   ::cODBCStr  := cODBCStr
   ::Active    := .F.
   ::Fields    := {}
   ::nEof      := 0
   ::lBof      := .F.
   ::nRecCount := 0
   ::nRecNo    := 0
   ::lCacheRS  := lCache
   ::aRecordSet:= {}

   // Allocates SQL Environment
   IF ( (nRet := SQLAllocEn( @xBuf )) == SQL_SUCCESS )
      ::hEnv := xBuf

   ELSE
      ::nRetCode := nRet
      alert( "SQLAllocEnvironment Error" )
      alert( ::SQLErrorMessage() )
   ENDIF

   SQLAllocCo( ::hEnv, @xBuf )                 // Allocates SQL Connection
   ::hDbc := xBuf

   IF cUserName == NIL
     SQLDriverC( ::hDbc, ::cODBCStr, @xBuf )     // Connects to Driver
     ::cODBCRes := xBuf
   ELSE
      IF .not. ( (nRet := SQLConnect( ::hDbc, cODBCStr, cUserName, cPassword)) == SQL_SUCCESS .or. nRet == SQL_SUCCESS_WITH_INFO )
         //TODO: Some error here
      ENDIF
   ENDIF

RETURN Self
todbc.prg189
TODBC:METHODSetAutocommit( lEnable ) CLASS TODBC
METHOD SetAutocommit( lEnable ) CLASS TODBC

   local lOld := ::lAutoCommit

   DEFAULT lEnable TO .T.

   If lEnable != lOld
      ::SetCnnOptions( SQL_AUTOCOMMIT, iif( lEnable, SQL_AUTOCOMMIT_ON, SQL_AUTOCOMMIT_OFF ) )
      ::lAutoCommit := lEnable
   EndIf

Return lOld
todbc.prg236
TODBC:METHODDestroy() CLASS TODBC
METHOD Destroy() CLASS TODBC

   SQLDisconn( ::hDbc )                        // Disconnects from Driver
   SQLFreeCon( ::hDbc )                        // Frees the connection
   SQLFreeEnv( ::hEnv )                        // Frees the environment

RETURN NIL
todbc.prg251
TODBC:METHODGetCnnOptions( nType ) CLASS TODBC
METHOD GetCnnOptions( nType ) CLASS TODBC

   local cBuffer:=space(256)
   ::nRetCode := SQLGETCONNECTOPTION( ::hDbc, nType, @cBuffer )

return cBuffer
todbc.prg261
TODBC:METHODSetCnnOptions( nType, uBuffer ) CLASS TODBC
METHOD SetCnnOptions( nType, uBuffer ) CLASS TODBC

return ::nRetCode := SQLSetConnectOption( ::hDbc, nType, uBuffer )
todbc.prg270
TODBC:METHODCommit() CLASS TODBC
METHOD Commit() CLASS TODBC

return ::nRetCode := SQLCommit( ::hEnv, ::hDbc )
todbc.prg276
TODBC:METHODRollBack() CLASS TODBC
METHOD RollBack() CLASS TODBC

return ::nRetCode := SQLRollBack( ::hEnv, ::hDbc )
todbc.prg282
TODBC:METHODGetStmtOptions( nType ) CLASS TODBC
METHOD GetStmtOptions( nType ) CLASS TODBC

   local cBuffer := Space( 256 )

   ::nRetCode := SQLGetStmtOption( ::hStmt, nType, @cBuffer )

return cBuffer
todbc.prg288
TODBC:METHODSetStmtOptions( nType, uBuffer ) CLASS TODBC
METHOD SetStmtOptions( nType, uBuffer ) CLASS TODBC

return ::nRetCode := SQLSetStmtOption( ::hStmt, nType, uBuffer )
todbc.prg298
TODBC:METHODSetSQL( cSQL ) CLASS TODBC
METHOD SetSQL( cSQL ) CLASS TODBC

   // If the DataSet is active, close it
   // before assigning new statement

   IF ::Active
      ::Close()
   ENDIF

   ::cSQL := cSQL

RETURN NIL
todbc.prg304
TODBC:METHODOpen() CLASS TODBC
METHOD Open() CLASS TODBC

   LOCAL nRet
   LOCAL nCols
   LOCAL nRows
   LOCAL i
   LOCAL cColName
   LOCAL nNameLen
   LOCAL nDataType
   LOCAL nColSize
   LOCAL nDecimals
   LOCAL nNul
   LOCAL xBuf
   LOCAL nResult
   LOCAL aCurRow

   WHILE .T.

      // Dataset must be closed
      IF ::Active

         // TODO: Some error here
         // Cannot do this operation on an opened dataset

         nRet := - 1
         EXIT

      ENDIF

      // SQL statement is mandatory
      IF empty( ::cSQL )

         // TODO: Some error here
         // SQL Statement not defined

         nRet := - 1
         EXIT

      ENDIF

      // Allocates and executes the statement
      xBuf := ::hStmt
      SQLAllocSt( ::hDbc, @xBuf )
      ::hStmt := xBuf
      nRet    := SQLExecDir( ::hStmt, ::cSQL )

      // Get result information about fields and stores it
      // on Fields collection
      SQLNumRes( ::hStmt, @nCols )

      // Get number of rows in result set
      nResult := SQLRowCoun(::hStmt, @nRows )
      if nResult  == SQL_SUCCESS
         ::nRecCount := nRows
      endif

      ::Fields := {}

      FOR i := 1 TO nCols

         SQLDescrib( ::hStmt, i, @cColName, 255, @nNameLen, @nDataType, ;
                     @ nColSize, @nDecimals, @nNul )

         aadd( ::Fields, TODBCField():New() )
         ::Fields[ len( ::Fields ) ] :FieldID   := i
         ::Fields[ len( ::Fields ) ] :FieldName := cColName
         ::Fields[ len( ::Fields ) ] :DataSize  := nColsize
         ::Fields[ len( ::Fields ) ] :DataType  := nDataType
         ::Fields[ len( ::Fields ) ] :DataDecs  := nDecimals
         ::Fields[ len( ::Fields ) ] :AllowNull := ( nNul != 0 )

      NEXT
      

      // Do we cache recordset?
      IF ::lCacheRS
        ::aRecordSet:={}
        WHILE ::Fetch( SQL_FETCH_NEXT, 1 ) == SQL_SUCCESS

          aCurRow :={}
          FOR i := 1 TO nCols
        
            aadd(aCurRow,::Fields[i]:value)
          NEXT
          aadd(::aRecordSet,aCurRow)
        END

        ::nRecCount := len(::aRecordSet)
    
      ELSE

         if ::First() == SQL_SUCCESS
            ::nRecCount := 1
         else
            ::nRecCount := 0
         endif

      ENDIF

      // Newly opened recordset - we are on first row
      ::nRecNo := 1

      // Sets the Dataset state to active
      ::Active := .T.

      EXIT

   ENDDO

RETURN nRet == SQL_SUCCESS
todbc.prg319
TODBC:METHODExecSQL() CLASS TODBC
METHOD ExecSQL() CLASS TODBC
   LOCAL xBuf
   LOCAL nRet

   WHILE .T.

      // SQL statement is mandatory
      IF empty( ::cSQL )

         nRet := SQL_ERROR
         EXIT

      ENDIF

      // Allocates and executes the statement
      xBuf := ::hStmt
      SQLAllocSt( ::hDbc, @xBuf )
      ::hStmt := xBuf
      nRet    := SQLExecDir( ::hStmt, ::cSQL )

      ::Close()
      EXIT

   ENDDO

RETURN nRet
todbc.prg433
TODBC:METHODCLOSE() CLASS TODBC
METHOD CLOSE() CLASS TODBC

   // Frees the statement
   SQLFreeStm( ::hStmt, SQL_DROP )
   ::Active := .F.

   // Reset all recordset related variables
   IF ::lCacheRS
     ::aRecordSet := {}
   ENDIF
   ::nRecCount := 0
   ::nRecNo    := 0
   ::lBof      := .T.

RETURN NIL
todbc.prg463
TODBC:METHODFieldByName( cField ) CLASS TODBC
METHOD FieldByName( cField ) CLASS TODBC

   LOCAL nRet := ascan( ::Fields, { | x | upper( x:FieldName ) == upper( cField ) } )
   LOCAL xRet

   IF nRet == 0
      // TODO: Some error here
      // Invalid field name
      xRet := NIL

   ELSE
      xRet := ::Fields[ nRet ]

   ENDIF

RETURN xRet
todbc.prg482
TODBC:METHODFetch( nFetchType, nOffset ) CLASS TODBC
METHOD Fetch( nFetchType, nOffset ) CLASS TODBC

   LOCAL nRows
   LOCAL nResult
   LOCAL nPos:=NIL

   // First clear fields
   ::ClearData()

   // Do we have cached recordset?
   IF ::lCacheRS .AND. ::Active  // looks like we do ...
     // Change Recno according to nFetchType and nOffset
     DO CASE
       CASE nFetchType == SQL_FETCH_NEXT

         IF ( ::nRecNo == ::nRecCount )
           nResult := SQL_NO_DATA_FOUND
         ELSE
           nResult := SQL_SUCCESS
           nPos := ::nRecNo + 1
         ENDIF

       CASE nFetchType == SQL_FETCH_PRIOR
         IF ( ::nRecNo == 1 )
           nResult := SQL_NO_DATA_FOUND
         ELSE
           nResult := SQL_SUCCESS
           nPos := ::nRecNo - 1
         ENDIF
       
       CASE nFetchType == SQL_FETCH_FIRST
         nResult := SQL_SUCCESS
         nPos := 1

       CASE nFetchType == SQL_FETCH_LAST
         nResult := SQL_SUCCESS
         nPos := ::nRecCount

       CASE nFetchType == SQL_FETCH_RELATIVE
         IF ( ::nRecNo + nOffset ) > ::nRecCount .OR. ( ::nRecNo + nOffset ) < 1  // TODO: Should we go to the first/last row if out of bounds?
           nResult := SQL_ERROR
         ELSE
           nResult := SQL_SUCCESS
           nPos := ::nRecNo + nOffset
         ENDIF

       CASE nFetchType == SQL_FETCH_ABSOLUTE
         IF nOffset  > ::nRecCount .OR. nOffset  < 1  // TODO: Should we go to the first/last row if out of bounds?
           nResult := SQL_ERROR
         ELSE
           nResult := SQL_SUCCESS
           nPos := nOffset
         ENDIF

       OTHERWISE
         nResult := SQL_ERROR
     ENDCASE

   ELSE           // apearently we don't have
//     nResult := SQLFetch( ::hStmt /*, nFetchType, nOffSet */)
     nResult := SQLExtende( ::hStmt, nFetchType, nOffSet, @nRows, 0 )
       
   ENDIF

   IF nResult == SQL_SUCCESS .or. nResult == SQL_SUCCESS_WITH_INFO
      nResult := SQL_SUCCESS

      ::LoadData(nPos)
      ::lBof := .F.
   ELSE
      // TODO: Report error here
   ENDIF

RETURN nResult
todbc.prg502
TODBC:METHODNEXT () CLASS TODBC
METHOD NEXT () CLASS TODBC

   LOCAL nResult

   nResult := ::Fetch( SQL_FETCH_NEXT, 1 )
   if nResult == SQL_SUCCESS
     ::nRecno := ::nRecno + 1
     if ::nRecNo > ::nRecCount
        ::nRecCount := ::nRecNo
     endif
   elseif ( nResult == SQL_NO_DATA_FOUND ) .AND. ( ::nRecNo==::nRecCount ) // permit skip on last row, so that EOF() can work properly
     ::nRecno := ::nRecno + 1
   else
     //TODO: Error handling
   endif

RETURN nResult
todbc.prg580
TODBC:METHODPrior() CLASS TODBC
METHOD Prior() CLASS TODBC

   LOCAL nResult

   nResult := ::Fetch( SQL_FETCH_PRIOR, 1 )
   if nResult == SQL_SUCCESS
     ::nRecno := ::nRecno - 1
   elseif ( nResult == SQL_NO_DATA_FOUND ) .AND. ( ::nRecNo==1 ) // permit skip-1 on first row, so that BOF() can work properly
     ::nRecno := ::nRecno - 1
     ::next()
     ::lBof := .T.
   else
     //TODO: Error handling
   endif

RETURN nResult
todbc.prg601
TODBC:METHODFirst() CLASS TODBC
METHOD First() CLASS TODBC

   LOCAL nResult

   nResult := ::Fetch( SQL_FETCH_FIRST, 1 )
   if nResult == SQL_SUCCESS
     ::nRecno := 1
   else
     //TODO: Error handling
   endif

RETURN nResult
todbc.prg621
TODBC:METHODlast() CLASS TODBC
METHOD last() CLASS TODBC

   LOCAL nResult

   nResult := ::Fetch( SQL_FETCH_LAST, 1 )
   if nResult == SQL_SUCCESS
     ::nRecno := ::nRecCount
   else
     //TODO: Error handling
   endif

RETURN nResult
todbc.prg637
TODBC:METHODMoveBy( nSteps ) CLASS TODBC
METHOD MoveBy( nSteps ) CLASS TODBC

   LOCAL nResult

   //TODO: Check if nSteps goes beyond eof
   nResult := ::Fetch( SQL_FETCH_RELATIVE, nSteps )
   if nResult == SQL_SUCCESS
     ::nRecno := ::nRecNo + nSteps
   else
     //TODO: Error handling
   endif

RETURN nResult
todbc.prg653
TODBC:METHODGOTO( nRecNo ) CLASS TODBC
METHOD GOTO( nRecNo ) CLASS TODBC

   LOCAL nResult

   nResult := ::Fetch( SQL_FETCH_ABSOLUTE, nRecNo )
   if nResult == SQL_SUCCESS
     ::nRecno := nRecNo
   else
     //TODO: Error handling
   endif

RETURN nResult
todbc.prg670
TODBC:METHODSKIP() CLASS TODBC
METHOD SKIP() CLASS TODBC

RETURN ::Next()
todbc.prg686
TODBC:METHODeof() CLASS TODBC
METHOD eof() CLASS TODBC

   LOCAL lResult := .F.

   // Do we have any data in recordset?
   
   if ::nRecCount > 0
      lResult := ( ::nRecNo > ::nRecCount )
   else
      lResult := .T.
   endif
   
RETURN lResult
todbc.prg694
TODBC:METHODbof() CLASS TODBC
METHOD bof() CLASS TODBC

RETURN ::lBof
todbc.prg711
TODBC:METHODRecNo() CLASS TODBC
METHOD RecNo() CLASS TODBC

RETURN ::nRecNo
todbc.prg718
TODBC:METHODLastrec() CLASS TODBC
METHOD Lastrec() CLASS TODBC

RETURN ::nRecCount
todbc.prg725
TODBC:METHODRecCount() CLASS TODBC
METHOD RecCount() CLASS TODBC

RETURN ::nRecCount
todbc.prg732
TODBC:METHODLoadData(nPos) CLASS TODBC
METHOD LoadData(nPos) CLASS TODBC

   LOCAL uData
   LOCAL i
   local nType

   FOR i := 1 TO len( ::Fields )

     uData := space( 64 )
     IF ::lCacheRS .AND. ::Active
        IF nPos > 0 .and. nPos <= ::nRecCount
          uData := ::aRecordSet[ nPos,i ]
        ENDIF
     ELSE
     
        SQLGetData( ::hStmt, ::Fields[ i ]:FieldID, SQL_CHAR, len( uData ), @uData)
        nType := ::Fields[ i ]:DataType


        do case
        case nType == SQL_LONGVARCHAR
           uData := AllTrim( uData )

        case nType == SQL_CHAR .or. nType == SQL_VARCHAR .or. nType == SQL_NVARCHAR
           uData := PadR( uData, ::Fields[ i ]:DataSize )

        case nType == SQL_TIMESTAMP .or. nType == SQL_DATE
           uData := stod( substr(uData,1,4) + substr(uData,6,2) + substr(uData,9,2) )

        case nType == SQL_BIT
           uData := Val( uData ) == 1

        case nType == SQL_NUMERIC;
         .or. nType == SQL_DECIMAL;
         .or. nType == SQL_DOUBLE;
         .or. nType == SQL_TINYINT;
         .or. nType == SQL_SMALLINT;
         .or. nType == SQL_INTEGER;
         .or. nType == SQL_FLOAT;
         .or. nType == SQL_REAL
            IF VALTYPE(uData) =="C" 
               uData := strtran(uData,",",".")
               uData := Round( Val(uData), ::Fields[ i ]:DataSize )
            ENDIF      
            uData := SetNumLen( uData, ::Fields[ i ]:DataSize ,::Fields[ i ]:DataDecs   )
       
        endcase

     ENDIF
     
     ::Fields[ i ]:Value := uData
   
   next
   

RETURN NIL
todbc.prg739

Page url: http://www.yourdomain.com/help/index.html?hbodbc.htm