2015-02-23 17:47 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)

* contrib/hbodbc/odbc.c
    * rewritten function SQLGetData() - new code is much simpler and
      fixes few bugs

  * contrib/hbodbc/todbc.prg
    % eliminated unnecessary AAdd() when final array size is already known
    ! do not round numbers read number to default number of decimal places
This commit is contained in:
Przemysław Czerpak
2015-02-23 17:47:54 +01:00
parent 86d8fd5915
commit 0bcc223b14
3 changed files with 55 additions and 66 deletions

View File

@@ -10,6 +10,15 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2015-02-23 17:47 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbodbc/odbc.c
* rewritten function SQLGetData() - new code is much simpler and
fixes few bugs
* contrib/hbodbc/todbc.prg
% eliminated unnecessary AAdd() when final array size is already known
! do not round numbers read number to default number of decimal places
2015-02-21 15:33 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* ChangeLog.txt
* src/compiler/hbmain.c

View File

@@ -581,68 +581,46 @@ HB_FUNC( SQLGETDATA ) /* hStmt, nField, nType, nLen, @cBuffer --> nRetCode */
if( hStmt )
{
SQLLEN nLen;
SQLLEN nInitBuff;
SQLLEN nBuffLen = 0;
char * buffer;
char * outbuf = NULL;
SQLSMALLINT iType = ( SQLSMALLINT ) hb_parnidef( 3, SQL_BINARY );
int iReallocs = 0;
SQLRETURN result;
SQLUSMALLINT uiColumn = ( SQLUSMALLINT ) hb_parni( 2 );
SQLSMALLINT iType = ( SQLSMALLINT ) hb_parnidef( 3, SQL_BINARY );
SQLLEN nLen = ( SQLLEN ) hb_parnint( 4 );
SQLLEN nInitBuff;
char * buffer;
SQLRETURN result;
nLen = ( SQLLEN ) hb_parnint( 4 );
if( nLen <= 0 )
/* driver does not check the nLen parameter for fixed length types
so caller has to provide enough space */
if( nLen < 64 )
nLen = 64;
nInitBuff = nLen;
buffer = ( char * ) hb_xgrab( ( HB_SIZE ) nLen + 1 );
buffer = ( char * ) hb_xgrab( ( HB_SIZE ) nLen + 1 );
result = ! SQL_NO_DATA;
while( result != SQL_NO_DATA )
result = SQLGetData( hStmt, uiColumn, iType, ( SQLPOINTER ) buffer,
nLen, &nLen );
if( result == SQL_SUCCESS_WITH_INFO )
{
result = SQLGetData( hStmt,
( SQLUSMALLINT ) hb_parni( 2 ),
( SQLSMALLINT ) iType,
( SQLPOINTER ) buffer,
( SQLLEN ) nLen,
( SQLLEN * ) &nLen );
if( result == SQL_SUCCESS && iReallocs == 0 )
if( nLen > nInitBuff )
{
hb_storclen( buffer, ( HB_SIZE ) ( nLen < 0 ? 0 : ( nLen < ( SQLLEN ) hb_parnint( 4 ) ? nLen : ( SQLLEN ) hb_parnint( 4 ) ) ), 5 );
break;
/* data right truncated! */
buffer = ( char * ) hb_xrealloc( buffer, ( HB_SIZE ) nLen + 1 );
result = SQLGetData( hStmt, uiColumn, iType,
( SQLPOINTER ) ( buffer + nInitBuff ),
nLen - nInitBuff, &nInitBuff );
if( result == SQL_SUCCESS_WITH_INFO )
result = SQL_SUCCESS;
}
else if( result == SQL_SUCCESS_WITH_INFO && iReallocs == 0 )
{
/* Perhaps a data truncation */
if( nLen >= nInitBuff )
{
/* data right truncated! */
nBuffLen = nLen;
outbuf = ( char * ) hb_xgrab( ( HB_SIZE ) nBuffLen + 1 );
hb_strncpy( outbuf, buffer, nLen );
nLen = nLen - nInitBuff + 2;
buffer = ( char * ) hb_xrealloc( buffer, ( HB_SIZE ) nLen );
iReallocs++;
}
else
{
hb_storclen( buffer, ( HB_SIZE ) ( nLen < 0 ? 0 : ( nLen < ( SQLLEN ) hb_parnint( 4 ) ? nLen : ( SQLLEN ) hb_parnint( 4 ) ) ), 5 );
break;
}
}
else if( ( result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO ) && iReallocs > 0 )
{
hb_strncat( outbuf, buffer, nBuffLen );
hb_storclen( outbuf, ( HB_SIZE ) ( nLen + nInitBuff - 1 ), 5 );
else if( nLen == nInitBuff )
result = SQL_SUCCESS;
break;
}
else
break;
}
hb_xfree( buffer );
if( outbuf )
hb_xfree( outbuf );
if( result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO )
nLen = 0;
if( nInitBuff - nLen > 32 )
hb_storclen( buffer, ( HB_SIZE ) ( nLen < 0 ? 0 : nLen ), 5 );
else if( hb_storclen_buffer( buffer, nLen, 5 ) )
buffer = NULL;
if( buffer )
hb_xfree( buffer );
hb_retni( result );
}
else

View File

@@ -270,6 +270,7 @@ METHOD Open() CLASS TODBC
LOCAL nNul
LOCAL nResult
LOCAL aCurRow
LOCAL oField
DO WHILE .T.
@@ -309,20 +310,20 @@ METHOD Open() CLASS TODBC
::nRecCount := nRows
ENDIF
::Fields := {}
::Fields := Array( nCols )
FOR i := 1 TO nCols
SQLDescribeCol( ::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 )
::Fields[ i ] := oField := TODBCField():New()
oField:FieldID := i
oField:FieldName := cColName
oField:DataSize := nColsize
oField:DataType := nDataType
oField:DataDecs := nDecimals
oField:AllowNull := ( nNul != 0 )
NEXT
@@ -331,9 +332,9 @@ METHOD Open() CLASS TODBC
::aRecordSet := {}
DO WHILE ::Fetch( SQL_FETCH_NEXT, 1 ) == SQL_SUCCESS
aCurRow := {}
aCurRow := Array( nCols )
FOR i := 1 TO nCols
AAdd( aCurRow, ::Fields[ i ]:value )
aCurRow[ i ] := ::Fields[ i ]:value
NEXT
AAdd( ::aRecordSet, aCurRow )
ENDDO
@@ -650,7 +651,7 @@ METHOD LoadData( nPos ) CLASS TODBC
CASE SQL_TIMESTAMP
CASE SQL_DATE
uData := hb_SToD( SubStr( uData, 1, 4 ) + SubStr( uData, 6, 2 ) + SubStr( uData, 9, 2 ) )
uData := hb_odbcSToD( uData )
EXIT
CASE SQL_BIT
@@ -666,8 +667,9 @@ METHOD LoadData( nPos ) CLASS TODBC
CASE SQL_INTEGER
CASE SQL_FLOAT
CASE SQL_REAL
uData := Round( Val( StrTran( uData, ",", "." ) ), ::Fields[ i ]:DataDecs )
uData := hb_odbcNumSetLen( uData, ::Fields[ i ]:DataSize, ::Fields[ i ]:DataDecs )
uData := hb_odbcNumSetLen( Val( StrTran( uData, ",", "." ) ), ;
::Fields[ i ]:DataSize, ;
::Fields[ i ]:DataDecs )
EXIT
ENDSWITCH