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

* contrib/sddfb/core.c
  * contrib/sddmy/core.c
  * contrib/sddoci/core.c
  * contrib/sddodbc/core.c
  * contrib/sddpg/core.c
  * contrib/sddsqlt3/core.c
    ! clear dbFieldInfo structure before use - it resolves problems with
      random field flags caused by uninitialized uiFlags member
    * minor cleanup in variable names
    * use hb_xgrabz()

  * contrib/sddodbc/core.c
    + added support for NULLABLE, UNICODE and BINARY field flags
    + added support for SQL_BINARY fields
    ! fixed SQL_TIME mapping to Harbour field types.
      It was mapped as HB_FT_DATE instead of HB_FT_TIME.
    ! fixed extracting integer values on on platforms where long int is
      64 bit integer (in practice all 64bit *nixes). SQL_C_LONG should be
      used with SQLINTEGER not 'long int'.

  * contrib/hbodbc/odbc.c
    + add support for different data types in SQLGetData()
      The original version was returning different types in their binary
      representation. Current implementation is based on similar one from
      Viktor's branch (2014-07-06 16:40 UTC+0200 Viktor Szakats) with
      small but important fixes.
    ! modified hb_odbcNumSetLen() to not break 64bit integers by casting
      to double value

  * contrib/hbodbc/sql.ch
    + added SQL_WCHAR

  * contrib/hbodbc/todbc.prg
    + use extended SQLGetData() and hb_odbcNumSetLen() functionality to
      extract ODBC data
    % few small optimization and casing usually based on Viktor's branch
      BTW pre incrementations/decrementations used in PUSH context are
      faster then post ones.
This commit is contained in:
Przemysław Czerpak
2015-02-24 17:49:04 +01:00
parent 0abd7da585
commit 0198c7a729
10 changed files with 504 additions and 326 deletions

View File

@@ -10,6 +10,46 @@
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
*/
2015-02-24 17:49 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/sddfb/core.c
* contrib/sddmy/core.c
* contrib/sddoci/core.c
* contrib/sddodbc/core.c
* contrib/sddpg/core.c
* contrib/sddsqlt3/core.c
! clear dbFieldInfo structure before use - it resolves problems with
random field flags caused by uninitialized uiFlags member
* minor cleanup in variable names
* use hb_xgrabz()
* contrib/sddodbc/core.c
+ added support for NULLABLE, UNICODE and BINARY field flags
+ added support for SQL_BINARY fields
! fixed SQL_TIME mapping to Harbour field types.
It was mapped as HB_FT_DATE instead of HB_FT_TIME.
! fixed extracting integer values on on platforms where long int is
64 bit integer (in practice all 64bit *nixes). SQL_C_LONG should be
used with SQLINTEGER not 'long int'.
* contrib/hbodbc/odbc.c
+ add support for different data types in SQLGetData()
The original version was returning different types in their binary
representation. Current implementation is based on similar one from
Viktor's branch (2014-07-06 16:40 UTC+0200 Viktor Szakats) with
small but important fixes.
! modified hb_odbcNumSetLen() to not break 64bit integers by casting
to double value
* contrib/hbodbc/sql.ch
+ added SQL_WCHAR
* contrib/hbodbc/todbc.prg
+ use extended SQLGetData() and hb_odbcNumSetLen() functionality to
extract ODBC data
% few small optimization and casing usually based on Viktor's branch
BTW pre incrementations/decrementations used in PUSH context are
faster then post ones.
2015-02-24 11:14 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* src/rtl/gtxwc/gtxwc.c
! fixed GPF when empty window title is set and then retrieve - thanks

View File

@@ -72,6 +72,7 @@
#include "hbapierr.h"
#include "hbapistr.h"
#include "hbset.h"
#include "hbdate.h"
/* NOTE: This code using pointer items is a little bit more complicated
then it has to be.
@@ -118,6 +119,15 @@
typedef unsigned char SQLTCHAR;
typedef long SQLLEN;
typedef unsigned long SQLULEN;
# ifndef SQL_WCHAR
# define SQL_WCHAR (-8)
# endif
# ifndef SQL_WVARCHAR
# define SQL_WVARCHAR (-9)
# endif
# ifndef SQL_WLONGVARCHAR
# define SQL_WLONGVARCHAR (-10)
# endif
# endif
#endif
@@ -575,53 +585,195 @@ HB_FUNC( SQLFETCH ) /* hStmt --> nRetCode */
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
HB_FUNC( SQLGETDATA ) /* hStmt, nField, nType, nLen, @cBuffer --> nRetCode */
HB_FUNC( SQLGETDATA ) /* hStmt, nField, nType, [nMaxLen], @xValue --> nRetCode */
{
SQLHSTMT hStmt = hb_SQLHSTMT_par( 1 );
if( hStmt )
{
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;
SQLUSMALLINT uiField = ( SQLUSMALLINT ) hb_parni( 2 );
SQLSMALLINT iType = ( SQLSMALLINT ) hb_parnidef( 3, SQL_BINARY );
SQLLEN nLen = 0;
SQLRETURN res = SQL_ERROR;
/* 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 );
result = SQLGetData( hStmt, uiColumn, iType, ( SQLPOINTER ) buffer,
nLen, &nLen );
if( result == SQL_SUCCESS_WITH_INFO )
switch( iType )
{
if( nLen > nInitBuff )
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
{
/* 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( nLen == nInitBuff )
result = SQL_SUCCESS;
}
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;
O_HB_CHAR * val = NULL;
O_HB_CHAR buffer[ 1 ];
#if defined( UNICODE )
SQLSMALLINT iTargetType = SQL_C_WCHAR;
#else
SQLSMALLINT iTargetType = SQL_C_CHAR;
#endif
if( buffer )
hb_xfree( buffer );
hb_retni( result );
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, iTargetType, buffer, 0, &nLen ) ) )
{
if( nLen > 0 )
{
SQLLEN nMaxLen = ( SQLLEN ) hb_parnint( 4 );
#if defined( UNICODE )
nMaxLen <<= 1;
#endif
if( nMaxLen > 0 && nMaxLen < nLen )
nLen = nMaxLen;
val = ( O_HB_CHAR * ) hb_xgrab( nLen + sizeof( O_HB_CHAR ) );
if( ! SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, iTargetType, val, nLen + sizeof( O_HB_CHAR ), &nLen ) ) )
{
hb_xfree( val );
val = NULL;
}
#if defined( UNICODE )
else
nLen >>= 1;
#endif
}
}
if( val != NULL )
{
O_HB_STORSTRLEN( val, ( HB_SIZE ) nLen, 5 );
hb_xfree( val );
}
else
hb_storc( NULL, 5 );
break;
}
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
{
char * val = NULL;
char buffer[ 1 ];
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_BINARY, buffer, 0, &nLen ) ) )
{
if( nLen > 0 )
{
SQLLEN nMaxLen = ( SQLLEN ) hb_parnint( 4 );
if( nMaxLen > 0 && nMaxLen < nLen )
nLen = nMaxLen;
val = ( char * ) hb_xgrab( nLen + 1 );
if( ! SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_BINARY, val, nLen + 1, &nLen ) ) )
{
hb_xfree( val );
val = NULL;
}
}
}
if( val )
{
if( ! hb_storclen_buffer( val, ( HB_SIZE ) nLen, 5 ) )
hb_xfree( val );
}
else
hb_storc( NULL, 5 );
break;
}
case SQL_BIGINT:
#if ODBCVER >= 0x0300
{
HB_I64 val = 0;
/* NOTE: SQL_C_SBIGINT not available before ODBC 3.0 */
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_SBIGINT, &val, sizeof( val ), &nLen ) ) )
hb_stornint( val, 5 );
else
hb_stornint( 0, 5 );
break;
}
#endif
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
{
SQLINTEGER val = 0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_LONG, &val, sizeof( val ), &nLen ) ) )
hb_stornint( val, 5 );
else
hb_stornint( 0, 5 );
break;
}
case SQL_DECIMAL:
case SQL_NUMERIC:
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE:
{
double val = 0.0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_DOUBLE, &val, sizeof( val ), &nLen ) ) )
hb_stornd( val, 5 );
else
hb_stornd( 0.0, 5 );
break;
}
case SQL_BIT:
{
unsigned char val = 0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_BIT, &val, sizeof( val ), &nLen ) ) )
hb_storl( val != 0, 5 );
else
hb_storl( HB_FALSE, 5 );
break;
}
case SQL_DATE:
#if ODBCVER >= 0x0300
case SQL_TYPE_DATE:
#endif
{
DATE_STRUCT val = { 0, 0, 0 };
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_DATE, &val, sizeof( val ), &nLen ) ) )
hb_stordl( hb_dateEncode( val.year, val.month, val.day ), 5 );
else
hb_stordl( 0, 5 );
break;
}
case SQL_TIME:
#if ODBCVER >= 0x0300
case SQL_TYPE_TIME:
#endif
{
TIME_STRUCT val = { 0, 0, 0 };
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_TIME, &val, sizeof( val ), &nLen ) ) )
hb_stortdt( 0, hb_timeEncode( val.hour, val.minute, val.second, 0 ), 5 );
else
hb_stortdt( 0, 0, 5 );
break;
}
/* SQL_DATETIME = SQL_DATE = 9 */
case SQL_TIMESTAMP:
#if ODBCVER >= 0x0300
case SQL_TYPE_TIMESTAMP:
#endif
{
TIMESTAMP_STRUCT val = { 0, 0, 0, 0, 0, 0, 0 };
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, uiField, SQL_C_TIMESTAMP, &val, sizeof( val ), &nLen ) ) )
hb_stortdt( hb_dateEncode( val.year, val.month, val.day ),
hb_timeEncode( val.hour, val.minute, val.second, val.fraction / 1000000 ), 5 );
else
hb_stortdt( 0, 0, 5 );
break;
}
default:
hb_stor( 5 );
break;
}
hb_retni( res );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
@@ -1066,7 +1218,14 @@ HB_FUNC( HB_ODBCSTOD )
HB_FUNC( HB_ODBCNUMSETLEN ) /* nValue, nSize, nDecimals --> nValue (nSize, nDec) */
{
hb_retnlen( hb_parnd( 1 ), hb_parni( 2 ), hb_parni( 3 ) );
PHB_ITEM pValue = hb_param( 1, HB_IT_NUMERIC );
int iLen = hb_parni( 2 );
int iDec = hb_parni( 3 );
if( pValue != NULL && HB_IS_NUMINT( pValue ) && iDec == 0 )
hb_retnintlen( hb_itemGetNInt( pValue ), iLen );
else
hb_retnlen( hb_itemGetND( pValue ), iLen, iDec );
}
HB_FUNC( HB_ODBCVER )

View File

@@ -70,16 +70,16 @@
#define SQL_TIME 10
#define SQL_TIMESTAMP 11
#define SQL_VARCHAR 12
#define SQL_BIT -7
#define SQL_LONGVARCHAR -1
#define SQL_LONGVARBINARY -4
#define SQL_BIGINT -5
#define SQL_TINYINT -6
#define SQL_BIT -7
#define SQL_WCHAR -8
#define SQL_NVARCHAR -9
#define SQL_TYPE_NULL 0
#define SQL_TYPE_MIN SQL_BIT
#define SQL_TYPE_MIN SQL_NVARCHAR
#define SQL_TYPE_MAX SQL_VARCHAR
#define SQL_ALL_TYPES 0

View File

@@ -129,15 +129,15 @@ CREATE CLASS TODBC
METHOD Next()
METHOD Prior()
METHOD First()
METHOD last()
METHOD Last()
METHOD MoveBy( nSteps )
METHOD GoTo( nRecNo )
METHOD Skip()
METHOD Eof()
METHOD Bof()
METHOD RecNo()
METHOD RecCount()
METHOD LastRec()
METHOD RecNo()
METHOD SQLErrorMessage()
@@ -497,12 +497,11 @@ METHOD Next() CLASS TODBC
LOCAL nResult := ::Fetch( SQL_FETCH_NEXT, 1 )
IF nResult == SQL_SUCCESS
::nRecno := ::nRecno + 1
IF ::nRecNo > ::nRecCount
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
++::nRecNo
ELSE
// TODO: Error handling
ENDIF
@@ -515,9 +514,9 @@ METHOD Prior() CLASS TODBC
LOCAL nResult := ::Fetch( SQL_FETCH_PRIOR, 1 )
IF nResult == SQL_SUCCESS
::nRecno := ::nRecno - 1
--::nRecNo
ELSEIF nResult == SQL_NO_DATA_FOUND .AND. ::nRecNo == 1 // permit skip-1 on first row, so that Bof() can work properly
::nRecno := ::nRecno - 1
--::nRecNo
::Next()
::lBof := .T.
ELSE
@@ -532,7 +531,7 @@ METHOD First() CLASS TODBC
LOCAL nResult := ::Fetch( SQL_FETCH_FIRST, 1 )
IF nResult == SQL_SUCCESS
::nRecno := 1
::nRecNo := 1
ELSE
// TODO: Error handling
ENDIF
@@ -540,12 +539,12 @@ METHOD First() CLASS TODBC
RETURN nResult
// Moves to the last record on DataSet
METHOD last() CLASS TODBC
METHOD Last() CLASS TODBC
LOCAL nResult := ::Fetch( SQL_FETCH_LAST, 1 )
IF nResult == SQL_SUCCESS
::nRecno := ::nRecCount
::nRecNo := ::nRecCount
ELSE
// TODO: Error handling
ENDIF
@@ -559,7 +558,7 @@ METHOD MoveBy( nSteps ) CLASS TODBC
LOCAL nResult := ::Fetch( SQL_FETCH_RELATIVE, nSteps )
IF nResult == SQL_SUCCESS
::nRecno := ::nRecNo + nSteps
::nRecNo += nSteps
ELSE
// TODO: Error handling
ENDIF
@@ -572,7 +571,7 @@ METHOD GoTo( nRecNo ) CLASS TODBC
LOCAL nResult := ::Fetch( SQL_FETCH_ABSOLUTE, nRecNo )
IF nResult == SQL_SUCCESS
::nRecno := nRecNo
::nRecNo := nRecNo
ELSE
// TODO: Error handling
ENDIF
@@ -588,17 +587,8 @@ METHOD Skip() CLASS TODBC
// NOTE: Current implementation usable only with drivers that report number of records in last select
METHOD Eof() CLASS TODBC
LOCAL lResult
RETURN ::nRecCount == 0 .OR. ::nRecNo > ::nRecCount
// Do we have any data in recordset?
IF ::nRecCount > 0
lResult := ( ::nRecNo > ::nRecCount )
ELSE
lResult := .T.
ENDIF
RETURN lResult
// Checks for Begining of File
METHOD Bof() CLASS TODBC
@@ -611,73 +601,48 @@ METHOD RecNo() CLASS TODBC
RETURN ::nRecNo
// Returns number of rows ( if that function is supported by ODBC driver )
METHOD LastRec() CLASS TODBC
METHOD RecCount() CLASS TODBC
RETURN ::nRecCount
// Returns number of rows ( if that function is supported by ODBC driver )
METHOD RecCount() CLASS TODBC
METHOD LastRec() CLASS TODBC
RETURN ::nRecCount
// Loads current record data into the Fields collection
METHOD LoadData( nPos ) CLASS TODBC
LOCAL uData
LOCAL i
FOR i := 1 TO Len( ::Fields )
uData := ""
LOCAL xValue
LOCAL oField
FOR EACH oField IN ::Fields
IF ::lCacheRS .AND. ::Active
IF nPos > 0 .AND. nPos <= ::nRecCount
uData := ::aRecordSet[ nPos, i ]
ENDIF
xValue := iif( nPos > 0 .AND. nPos <= ::nRecCount, ;
::aRecordSet[ nPos, oField:__enumIndex() ], NIL )
ELSE
SQLGetData( ::hStmt, oField:FieldID, oField:DataType,, @xValue )
SQLGetData( ::hStmt, ::Fields[ i ]:FieldID, SQL_CHAR, 256, @uData )
SWITCH ::Fields[ i ]:DataType
CASE SQL_LONGVARCHAR
uData := AllTrim( uData )
EXIT
SWITCH oField:DataType
CASE SQL_CHAR
CASE SQL_VARCHAR
CASE SQL_NVARCHAR
uData := PadR( uData, ::Fields[ i ]:DataSize )
CASE SQL_WCHAR
xValue := PadR( xValue, oField:DataSize )
EXIT
CASE SQL_TIMESTAMP
CASE SQL_DATE
uData := hb_odbcSToD( uData )
EXIT
CASE SQL_BIT
uData := Val( uData ) == 1
EXIT
CASE SQL_NUMERIC
CASE SQL_DECIMAL
CASE SQL_DOUBLE
CASE SQL_FLOAT
CASE SQL_REAL
CASE SQL_TINYINT
CASE SQL_SMALLINT
CASE SQL_BIGINT
CASE SQL_INTEGER
CASE SQL_FLOAT
CASE SQL_REAL
uData := hb_odbcNumSetLen( Val( StrTran( uData, ",", "." ) ), ;
::Fields[ i ]:DataSize, ;
::Fields[ i ]:DataDecs )
xValue := hb_odbcNumSetLen( xValue, oField:DataSize, oField:DataDecs )
EXIT
ENDSWITCH
ENDIF
::Fields[ i ]:Value := uData
oField:Value := xValue
NEXT
RETURN NIL

View File

@@ -212,7 +212,6 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
XSQLDA ISC_FAR * pSqlda;
XSQLVAR * pVar;
PHB_ITEM pItemEof, pItem;
DBFIELDINFO pFieldInfo;
HB_BOOL bError;
HB_USHORT uiFields, uiCount;
int iType;
@@ -293,15 +292,16 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
bError = HB_FALSE;
for( uiCount = 0, pVar = pSqlda->sqlvar; uiCount < uiFields; uiCount++, pVar++ )
{
DBFIELDINFO dbFieldInfo;
/* FIXME: if pVar->sqlname is ended with 0 byte then this hb_strndup()
* and hb_xfree() bewlow is redundant and
* pFieldInfo.atomName = pVar->sqlname;
* dbFieldInfo.atomName = pVar->sqlname;
* is enough.
*/
char * szOurName = hb_strndup( pVar->sqlname, pVar->sqlname_length );
pFieldInfo.atomName = szOurName;
pFieldInfo.uiDec = 0;
memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) );
dbFieldInfo.atomName = szOurName;
iType = pVar->sqltype & ~1;
switch( iType )
@@ -310,12 +310,12 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
{
char * pStr;
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = pVar->sqllen;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( char ) * pVar->sqllen + 2 );
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = pVar->sqllen;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( char ) * pVar->sqllen + 2 );
pStr = ( char * ) memset( hb_xgrab( pFieldInfo.uiLen ), ' ', pFieldInfo.uiLen );
pItem = hb_itemPutCL( NULL, pStr, pFieldInfo.uiLen );
pStr = ( char * ) memset( hb_xgrab( dbFieldInfo.uiLen ), ' ', dbFieldInfo.uiLen );
pItem = hb_itemPutCL( NULL, pStr, dbFieldInfo.uiLen );
hb_xfree( pStr );
break;
}
@@ -325,13 +325,13 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
{
char * pStr;
pFieldInfo.uiType = HB_FT_VARLENGTH;
pFieldInfo.uiLen = pVar->sqllen;
dbFieldInfo.uiType = HB_FT_VARLENGTH;
dbFieldInfo.uiLen = pVar->sqllen;
/* pVar->sqltype = SQL_TEXT; Coercing */
pVar->sqldata = ( char * ) hb_xgrab( sizeof( char ) * pVar->sqllen + 2 );
pStr = ( char * ) memset( hb_xgrab( pFieldInfo.uiLen ), ' ', pFieldInfo.uiLen );
pItem = hb_itemPutCL( NULL, pStr, pFieldInfo.uiLen );
pStr = ( char * ) memset( hb_xgrab( dbFieldInfo.uiLen ), ' ', dbFieldInfo.uiLen );
pItem = hb_itemPutCL( NULL, pStr, dbFieldInfo.uiLen );
hb_xfree( pStr );
break;
}
@@ -339,16 +339,16 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
case SQL_SHORT:
if( pVar->sqlscale < 0 )
{
pFieldInfo.uiType = HB_FT_LONG;
pFieldInfo.uiLen = 7;
pFieldInfo.uiDec = -pVar->sqlscale;
dbFieldInfo.uiType = HB_FT_LONG;
dbFieldInfo.uiLen = 7;
dbFieldInfo.uiDec = -pVar->sqlscale;
pItem = hb_itemPutNDLen( NULL, 0.0, 6 - pFieldInfo.uiDec, ( int ) pFieldInfo.uiDec );
pItem = hb_itemPutNDLen( NULL, 0.0, 6 - dbFieldInfo.uiDec, ( int ) dbFieldInfo.uiDec );
}
else
{
pFieldInfo.uiType = HB_FT_INTEGER;
pFieldInfo.uiLen = 2;
dbFieldInfo.uiType = HB_FT_INTEGER;
dbFieldInfo.uiLen = 2;
pItem = hb_itemPutNILen( NULL, 0, 6 );
}
@@ -358,16 +358,16 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
case SQL_LONG:
if( pVar->sqlscale < 0 )
{
pFieldInfo.uiType = HB_FT_LONG;
pFieldInfo.uiLen = 12;
pFieldInfo.uiDec = -pVar->sqlscale;
dbFieldInfo.uiType = HB_FT_LONG;
dbFieldInfo.uiLen = 12;
dbFieldInfo.uiDec = -pVar->sqlscale;
pItem = hb_itemPutNDLen( NULL, 0.0, 11 - pFieldInfo.uiDec, ( int ) pFieldInfo.uiDec );
pItem = hb_itemPutNDLen( NULL, 0.0, 11 - dbFieldInfo.uiDec, ( int ) dbFieldInfo.uiDec );
}
else
{
pFieldInfo.uiType = HB_FT_INTEGER;
pFieldInfo.uiLen = 4;
dbFieldInfo.uiType = HB_FT_INTEGER;
dbFieldInfo.uiLen = 4;
pItem = hb_itemPutNLLen( NULL, 0, 11 );
}
@@ -375,36 +375,33 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
break;
case SQL_FLOAT:
pFieldInfo.uiType = HB_FT_DOUBLE;
pFieldInfo.uiLen = 8;
pFieldInfo.uiDec = -pVar->sqlscale;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( float ) );
dbFieldInfo.uiType = HB_FT_DOUBLE;
dbFieldInfo.uiLen = 8;
dbFieldInfo.uiDec = -pVar->sqlscale;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( float ) );
pItem = hb_itemPutNDLen( NULL, *( float * ) pVar->sqldata, 20 - pFieldInfo.uiDec, pFieldInfo.uiDec );
pItem = hb_itemPutNDLen( NULL, *( float * ) pVar->sqldata, 20 - dbFieldInfo.uiDec, dbFieldInfo.uiDec );
break;
case SQL_DOUBLE:
pFieldInfo.uiType = HB_FT_DOUBLE;
pFieldInfo.uiLen = 8;
pFieldInfo.uiDec = -pVar->sqlscale;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( double ) );
dbFieldInfo.uiType = HB_FT_DOUBLE;
dbFieldInfo.uiLen = 8;
dbFieldInfo.uiDec = -pVar->sqlscale;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( double ) );
pItem = hb_itemPutNDLen( NULL, *( float * ) pVar->sqldata, 20 - pFieldInfo.uiDec, pFieldInfo.uiDec );
pItem = hb_itemPutNDLen( NULL, *( float * ) pVar->sqldata, 20 - dbFieldInfo.uiDec, dbFieldInfo.uiDec );
break;
case SQL_TIMESTAMP:
pFieldInfo.uiType = HB_FT_TIMESTAMP;
pFieldInfo.uiLen = 8;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( ISC_TIMESTAMP ) );
dbFieldInfo.uiType = HB_FT_TIMESTAMP;
dbFieldInfo.uiLen = 8;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( ISC_TIMESTAMP ) );
pItem = hb_itemPutTDT( NULL, 0, 0 );
break;
default: /* other fields as binary string */
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = pVar->sqllen;
pVar->sqldata = ( char * ) hb_xgrab( sizeof( char ) * pVar->sqllen );
pVar->sqldata = ( char * ) hb_xgrab( sizeof( char ) * pVar->sqllen );
pItem = hb_itemNew( NULL );
bError = HB_TRUE;
break;
@@ -417,7 +414,7 @@ static HB_ERRCODE fbOpen( SQLBASEAREAP pArea )
hb_itemRelease( pItem );
if( ! bError )
bError = ( SELF_ADDFIELD( &pArea->area, &pFieldInfo ) == HB_FAILURE );
bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE );
hb_xfree( szOurName );

View File

@@ -238,7 +238,6 @@ static HB_ERRCODE mysqlOpen( SQLBASEAREAP pArea )
HB_USHORT uiFields, uiCount;
HB_ERRCODE errCode = 0;
HB_BOOL bError;
DBFIELDINFO pFieldInfo;
MYSQL_FIELD * pMyField;
void ** pRow;
@@ -267,59 +266,61 @@ static HB_ERRCODE mysqlOpen( SQLBASEAREAP pArea )
bError = HB_FALSE;
for( uiCount = 0; uiCount < uiFields; uiCount++ )
{
DBFIELDINFO dbFieldInfo;
pMyField = mysql_fetch_field_direct( pSDDData->pResult, uiCount );
pFieldInfo.atomName = pMyField->name;
pFieldInfo.uiLen = ( HB_USHORT ) pMyField->length;
pFieldInfo.uiDec = 0;
memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) );
dbFieldInfo.atomName = pMyField->name;
dbFieldInfo.uiLen = ( HB_USHORT ) pMyField->length;
switch( pMyField->type )
{
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
pFieldInfo.uiType = HB_FT_INTEGER;
dbFieldInfo.uiType = HB_FT_INTEGER;
break;
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_INT24:
pFieldInfo.uiType = HB_FT_LONG;
dbFieldInfo.uiType = HB_FT_LONG;
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
pFieldInfo.uiType = HB_FT_DOUBLE;
pFieldInfo.uiDec = ( HB_USHORT ) pMyField->decimals;
dbFieldInfo.uiType = HB_FT_DOUBLE;
dbFieldInfo.uiDec = ( HB_USHORT ) pMyField->decimals;
break;
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_ENUM:
pFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiType = HB_FT_STRING;
break;
case MYSQL_TYPE_DATE:
pFieldInfo.uiType = HB_FT_DATE;
dbFieldInfo.uiType = HB_FT_DATE;
break;
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
pFieldInfo.uiType = HB_FT_MEMO;
dbFieldInfo.uiType = HB_FT_MEMO;
break;
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME:
pFieldInfo.uiType = HB_FT_TIMESTAMP;
pFieldInfo.uiLen = 8;
dbFieldInfo.uiType = HB_FT_TIMESTAMP;
dbFieldInfo.uiLen = 8;
break;
case MYSQL_TYPE_TIME:
pFieldInfo.uiType = HB_FT_TIME;
pFieldInfo.uiLen = 4;
dbFieldInfo.uiType = HB_FT_TIME;
dbFieldInfo.uiLen = 4;
break;
/*
@@ -332,23 +333,22 @@ static HB_ERRCODE mysqlOpen( SQLBASEAREAP pArea )
default:
bError = HB_TRUE;
errCode = ( HB_ERRCODE ) pMyField->type;
pFieldInfo.uiType = 0;
break;
}
if( ! bError )
{
switch( pFieldInfo.uiType )
switch( dbFieldInfo.uiType )
{
case HB_FT_STRING:
{
char * pStr;
pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 );
memset( pStr, ' ', pFieldInfo.uiLen );
pStr[ pFieldInfo.uiLen ] = '\0';
pStr = ( char * ) hb_xgrab( dbFieldInfo.uiLen + 1 );
memset( pStr, ' ', dbFieldInfo.uiLen );
pStr[ dbFieldInfo.uiLen ] = '\0';
pItem = hb_itemPutCL( NULL, pStr, pFieldInfo.uiLen );
pItem = hb_itemPutCL( NULL, pStr, dbFieldInfo.uiLen );
hb_xfree( pStr );
break;
}
@@ -387,12 +387,12 @@ static HB_ERRCODE mysqlOpen( SQLBASEAREAP pArea )
hb_arraySetForward( pItemEof, uiCount + 1, pItem );
hb_itemRelease( pItem );
/* if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER )
pFieldInfo.uiType = HB_IT_LONG;
/* if( dbFieldInfo.uiType == HB_IT_DOUBLE || dbFieldInfo.uiType == HB_IT_INTEGER )
dbFieldInfo.uiType = HB_IT_LONG;
*/
if( ! bError )
bError = ( SELF_ADDFIELD( &pArea->area, &pFieldInfo ) == HB_FAILURE );
bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE );
}
if( bError )

View File

@@ -343,7 +343,7 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea )
bError = HB_FALSE;
for( uiIndex = 0; uiIndex < uiFields; ++uiIndex )
{
DBFIELDINFO pFieldInfo;
DBFIELDINFO dbFieldInfo;
PHB_ITEM pName;
@@ -365,8 +365,9 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea )
return HB_FAILURE;
}
memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) );
pName = D_HB_ITEMPUTSTR( NULL, OCI_ColumnGetName( col ) );
pFieldInfo.atomName = hb_itemGetCPtr( pName );
dbFieldInfo.atomName = hb_itemGetCPtr( pName );
uiDataType = OCI_ColumnGetType( col );
uiSize = OCI_ColumnGetSize( col );
@@ -374,44 +375,44 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea )
bNullable = ( HB_BOOL ) OCI_ColumnGetNullable( col );
if( bNullable )
pFieldInfo.uiFlags |= HB_FF_NULLABLE;
dbFieldInfo.uiFlags |= HB_FF_NULLABLE;
pFieldInfo.uiLen = ( HB_USHORT ) uiSize;
pFieldInfo.uiDec = ( HB_USHORT ) iDec;
dbFieldInfo.uiLen = ( HB_USHORT ) uiSize;
dbFieldInfo.uiDec = ( HB_USHORT ) iDec;
#if 0
HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d dec=%d nullable=%d %d %d %d %d", pFieldInfo.atomName, uiDataType, uiSize, iDec, bNullable, OCI_ColumnGetScale( col ), OCI_ColumnGetPrecision( col ), OCI_ColumnGetFractionalPrecision( col ), OCI_ColumnGetLeadingPrecision( col ) ) );
HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d dec=%d nullable=%d %d %d %d %d", dbFieldInfo.atomName, uiDataType, uiSize, iDec, bNullable, OCI_ColumnGetScale( col ), OCI_ColumnGetPrecision( col ), OCI_ColumnGetFractionalPrecision( col ), OCI_ColumnGetLeadingPrecision( col ) ) );
#endif
switch( uiDataType )
{
case OCI_CDT_TEXT:
pFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiType = HB_FT_STRING;
break;
case OCI_CDT_NUMERIC:
pFieldInfo.uiType = HB_FT_LONG;
dbFieldInfo.uiType = HB_FT_LONG;
/* For plain 'NUMERIC', precision is zero and scale is -127 */
if( OCI_ColumnGetPrecision( col ) > 0 )
pFieldInfo.uiLen = ( HB_USHORT ) OCI_ColumnGetPrecision( col );
dbFieldInfo.uiLen = ( HB_USHORT ) OCI_ColumnGetPrecision( col );
if( OCI_ColumnGetScale( col ) >= 0 )
pFieldInfo.uiDec = ( HB_USHORT ) OCI_ColumnGetScale( col );
dbFieldInfo.uiDec = ( HB_USHORT ) OCI_ColumnGetScale( col );
else
pFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals();
dbFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals();
break;
case OCI_CDT_LONG:
pFieldInfo.uiType = HB_FT_VARLENGTH;
dbFieldInfo.uiType = HB_FT_VARLENGTH;
break;
case OCI_CDT_RAW:
pFieldInfo.uiType = HB_FT_BLOB;
dbFieldInfo.uiType = HB_FT_BLOB;
break;
case OCI_CDT_DATETIME:
case OCI_CDT_TIMESTAMP:
case OCI_CDT_INTERVAL:
pFieldInfo.uiType = HB_FT_TIME;
dbFieldInfo.uiType = HB_FT_TIME;
break;
default:
@@ -420,22 +421,20 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea )
#endif
bError = HB_TRUE;
errCode = ( HB_ERRCODE ) uiDataType;
pFieldInfo.uiType = 0;
pFieldInfo.uiType = HB_FT_STRING;
break;
}
if( ! bError )
{
switch( pFieldInfo.uiType )
switch( dbFieldInfo.uiType )
{
case HB_FT_STRING:
{
char * pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pFieldInfo.uiLen + 1 );
memset( pStr, ' ', pFieldInfo.uiLen );
pStr[ pFieldInfo.uiLen ] = '\0';
char * pStr = ( char * ) hb_xgrab( ( HB_SIZE ) dbFieldInfo.uiLen + 1 );
memset( pStr, ' ', dbFieldInfo.uiLen );
pStr[ dbFieldInfo.uiLen ] = '\0';
hb_itemPutCLPtr( pItem, pStr, pFieldInfo.uiLen );
hb_itemPutCLPtr( pItem, pStr, dbFieldInfo.uiLen );
break;
}
case HB_FT_MEMO:
@@ -449,14 +448,14 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea )
break;
case HB_FT_LONG:
if( pFieldInfo.uiDec == 0 )
hb_itemPutNLLen( pItem, 0, pFieldInfo.uiLen );
if( dbFieldInfo.uiDec == 0 )
hb_itemPutNLLen( pItem, 0, dbFieldInfo.uiLen );
else
hb_itemPutNDLen( pItem, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec );
hb_itemPutNDLen( pItem, 0.0, dbFieldInfo.uiLen, dbFieldInfo.uiDec );
break;
case HB_FT_DOUBLE:
hb_itemPutNDLen( pItem, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec );
hb_itemPutNDLen( pItem, 0.0, dbFieldInfo.uiLen, dbFieldInfo.uiDec );
break;
case HB_FT_LOGICAL:
@@ -480,7 +479,7 @@ static HB_ERRCODE ocilibOpen( SQLBASEAREAP pArea )
hb_arraySetForward( pItemEof, uiIndex + 1, pItem );
if( ! bError )
bError = ( SELF_ADDFIELD( &pArea->area, &pFieldInfo ) == HB_FAILURE );
bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE );
}
hb_itemRelease( pName );

View File

@@ -120,7 +120,7 @@ static HB_ERRCODE odbcClose( SQLBASEAREAP pArea );
static HB_ERRCODE odbcGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo );
static SDDNODE odbcdd =
static SDDNODE s_odbcdd =
{
NULL,
"ODBC",
@@ -139,7 +139,7 @@ static void hb_odbcdd_init( void * cargo )
{
HB_SYMBOL_UNUSED( cargo );
if( ! hb_sddRegister( &odbcdd ) )
if( ! hb_sddRegister( &s_odbcdd ) )
hb_errInternal( HB_EI_RDDINVALID, NULL, NULL, NULL );
}
@@ -441,7 +441,7 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
bError = HB_FALSE;
for( uiIndex = 0; uiIndex < uiFields; uiIndex++ )
{
DBFIELDINFO pFieldInfo;
DBFIELDINFO dbFieldInfo;
PHB_ITEM pName;
@@ -463,8 +463,10 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
return HB_FAILURE;
}
memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) );
pName = O_HB_ITEMPUTSTRLEN( NULL, ( O_HB_CHAR * ) cName, iNameLen );
pFieldInfo.atomName = hb_itemGetCPtr( pName );
dbFieldInfo.atomName = hb_itemGetCPtr( pName );
/*
We do mapping of many SQL types to one Harbour field type here, so, we need store
@@ -475,12 +477,14 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
or introduce our own unsigned SQL types.
[Mindaugas]
*/
pFieldInfo.uiTypeExtended = ( HB_USHORT ) iDataType;
pFieldInfo.uiLen = ( HB_USHORT ) uiSize;
pFieldInfo.uiDec = iDec;
dbFieldInfo.uiTypeExtended = ( HB_USHORT ) iDataType;
dbFieldInfo.uiLen = ( HB_USHORT ) uiSize;
dbFieldInfo.uiDec = iDec;
if( iNull == SQL_NULLABLE )
dbFieldInfo.uiFlags |= HB_FF_NULLABLE;
#if 0
HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d dec=%d null=%d", pFieldInfo.atomName, iDataType, uiSize, iDec, iNull ) );
HB_TRACE( HB_TR_ALWAYS, ( "field: name=%s type=%d len=%d dec=%d null=%d", dbFieldInfo.atomName, iDataType, uiSize, iDec, iNull ) );
#endif
switch( iDataType )
@@ -488,52 +492,57 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
case SQL_CHAR:
case SQL_VARCHAR:
case SQL_LONGVARCHAR:
dbFieldInfo.uiType = HB_FT_STRING;
break;
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
pFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiFlags |= HB_FF_UNICODE;
break;
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiFlags = HB_FF_BINARY;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiFlags |= HB_FF_BINARY;
break;
case SQL_TINYINT:
case SQL_SMALLINT:
case SQL_INTEGER:
case SQL_BIGINT:
pFieldInfo.uiType = HB_FT_INTEGER;
dbFieldInfo.uiType = HB_FT_INTEGER;
break;
case SQL_DECIMAL:
case SQL_NUMERIC:
pFieldInfo.uiType = HB_FT_LONG;
dbFieldInfo.uiType = HB_FT_LONG;
break;
case SQL_REAL:
case SQL_FLOAT:
case SQL_DOUBLE:
pFieldInfo.uiType = HB_FT_DOUBLE;
dbFieldInfo.uiType = HB_FT_DOUBLE;
break;
case SQL_BIT:
pFieldInfo.uiType = HB_FT_LOGICAL;
dbFieldInfo.uiType = HB_FT_LOGICAL;
break;
case SQL_DATE:
#if ODBCVER >= 0x0300
case SQL_TYPE_DATE:
#endif
pFieldInfo.uiType = HB_FT_DATE;
dbFieldInfo.uiType = HB_FT_DATE;
break;
case SQL_TIME:
#if ODBCVER >= 0x0300
case SQL_TYPE_TIME:
#endif
pFieldInfo.uiType = HB_FT_DATE;
dbFieldInfo.uiType = HB_FT_TIME;
break;
/* SQL_DATETIME = SQL_DATE = 9 */
@@ -541,7 +550,7 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
#if ODBCVER >= 0x0300
case SQL_TYPE_TIMESTAMP:
#endif
pFieldInfo.uiType = HB_FT_TIMESTAMP;
dbFieldInfo.uiType = HB_FT_TIMESTAMP;
break;
default:
@@ -550,24 +559,22 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
#endif
bError = HB_TRUE;
errCode = ( HB_ERRCODE ) iDataType;
pFieldInfo.uiType = 0;
pFieldInfo.uiType = HB_FT_STRING;
break;
}
if( ! bError )
{
switch( pFieldInfo.uiType )
switch( dbFieldInfo.uiType )
{
case HB_FT_STRING:
{
char * pStr;
pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pFieldInfo.uiLen + 1 );
memset( pStr, ' ', pFieldInfo.uiLen );
pStr[ pFieldInfo.uiLen ] = '\0';
pStr = ( char * ) hb_xgrab( ( HB_SIZE ) dbFieldInfo.uiLen + 1 );
memset( pStr, ' ', dbFieldInfo.uiLen );
pStr[ dbFieldInfo.uiLen ] = '\0';
pItem = hb_itemPutCL( NULL, pStr, pFieldInfo.uiLen );
pItem = hb_itemPutCL( NULL, pStr, dbFieldInfo.uiLen );
hb_xfree( pStr );
break;
}
@@ -581,14 +588,14 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
break;
case HB_FT_LONG:
if( pFieldInfo.uiDec == 0 )
pItem = hb_itemPutNLLen( NULL, 0, pFieldInfo.uiLen );
if( dbFieldInfo.uiDec == 0 )
pItem = hb_itemPutNLLen( NULL, 0, dbFieldInfo.uiLen );
else
pItem = hb_itemPutNDLen( NULL, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec );
pItem = hb_itemPutNDLen( NULL, 0.0, dbFieldInfo.uiLen, dbFieldInfo.uiDec );
break;
case HB_FT_DOUBLE:
pItem = hb_itemPutNDLen( NULL, 0.0, pFieldInfo.uiLen, pFieldInfo.uiDec );
pItem = hb_itemPutNDLen( NULL, 0.0, dbFieldInfo.uiLen, dbFieldInfo.uiDec );
break;
case HB_FT_LOGICAL:
@@ -617,7 +624,7 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
hb_itemRelease( pItem );
if( ! bError )
bError = ( SELF_ADDFIELD( &pArea->area, &pFieldInfo ) == HB_FAILURE );
bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE );
}
hb_itemRelease( pName );
@@ -641,10 +648,8 @@ static HB_ERRCODE odbcOpen( SQLBASEAREAP pArea )
pArea->ulRecCount = 0;
pArea->ulRecMax = SQLDD_ROWSET_INIT;
pArea->pRow = ( void ** ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( void * ) );
memset( pArea->pRow, 0, SQLDD_ROWSET_INIT * sizeof( void * ) );
pArea->pRowFlags = ( HB_BYTE * ) hb_xgrab( SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) );
memset( pArea->pRowFlags, 0, SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) );
pArea->pRow = ( void ** ) hb_xgrabz( SQLDD_ROWSET_INIT * sizeof( void * ) );
pArea->pRowFlags = ( HB_BYTE * ) hb_xgrabz( SQLDD_ROWSET_INIT * sizeof( HB_BYTE ) );
pArea->pRow[ 0 ] = pItemEof;
pArea->pRowFlags[ 0 ] = SQLDD_FLAG_CACHED;
@@ -701,35 +706,50 @@ static HB_ERRCODE odbcGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo )
switch( pField->uiType )
{
case HB_FT_STRING:
{
SQLSMALLINT iTargetType;
char buffer[ 2 ];
iLen = 0;
#if defined( UNICODE )
iTargetType = SQL_C_WCHAR;
#else
iTargetType = SQL_C_CHAR;
#endif
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, iTargetType, buffer, 0, &iLen ) ) )
if( pField->uiType & HB_FF_BINARY )
{
if( iLen >= 0 )
char buffer[ 1 ];
iLen = 0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_BINARY, buffer, 0, &iLen ) ) )
{
SQLPOINTER * val = ( SQLPOINTER * ) hb_xgrab( iLen + sizeof( O_HB_CHAR ) );
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, iTargetType, val, iLen + sizeof( O_HB_CHAR ), &iLen ) ) )
if( iLen >= 0 )
{
#if defined( UNICODE )
iLen /= 2;
#endif
pItem = O_HB_ITEMPUTSTRLEN( NULL, ( O_HB_CHAR * ) val, ( HB_SIZE ) iLen );
char * val = ( char * ) hb_xgrab( iLen + 1 );
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_BINARY, val, iLen + 1, &iLen ) ) )
pItem = hb_itemPutCLPtr( NULL, val, ( HB_SIZE ) iLen );
else
hb_xfree( val );
}
}
}
else
{
O_HB_CHAR buffer[ 1 ];
#if defined( UNICODE )
SQLSMALLINT iTargetType = SQL_C_WCHAR;
#else
SQLSMALLINT iTargetType = SQL_C_CHAR;
#endif
iLen = 0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, iTargetType, buffer, 0, &iLen ) ) )
{
if( iLen >= 0 )
{
O_HB_CHAR * val = ( O_HB_CHAR * ) hb_xgrab( iLen + sizeof( O_HB_CHAR ) );
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, iTargetType, val, iLen + sizeof( O_HB_CHAR ), &iLen ) ) )
{
#if defined( UNICODE )
iLen >>= 1;
#endif
pItem = O_HB_ITEMPUTSTRLEN( NULL, val, ( HB_SIZE ) iLen );
}
hb_xfree( val );
}
hb_xfree( val );
}
}
break;
}
case HB_FT_INTEGER:
#if ODBCVER >= 0x0300
@@ -743,16 +763,16 @@ static HB_ERRCODE odbcGoTo( SQLBASEAREAP pArea, HB_ULONG ulRecNo )
else
#endif
{
long int val = 0;
SQLINTEGER val = 0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_LONG, &val, sizeof( val ), &iLen ) ) )
pItem = hb_itemPutNLLen( NULL, val, pField->uiLen );
}
break;
case HB_FT_LONG:
if( pField->uiDec == 0 )
if( pField->uiDec == 0 && pField->uiLen < 10 )
{
long int val = 0;
SQLINTEGER val = 0;
if( SQL_SUCCEEDED( res = SQLGetData( hStmt, ui, SQL_C_LONG, &val, sizeof( val ), &iLen ) ) )
pItem = hb_itemPutNLLen( NULL, val, pField->uiLen );
}

View File

@@ -246,7 +246,6 @@ static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea )
PHB_ITEM pItemEof, pItem;
HB_USHORT uiFields, uiCount;
HB_BOOL bError;
DBFIELDINFO pFieldInfo;
pArea->pSDDData = memset( hb_xgrab( sizeof( SDDDATA ) ), 0, sizeof( SDDDATA ) );
pSDDData = ( SDDDATA * ) pArea->pSDDData;
@@ -277,134 +276,133 @@ static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea )
bError = HB_FALSE;
for( uiCount = 0; uiCount < uiFields; uiCount++ )
{
pFieldInfo.atomName = PQfname( pResult, ( int ) uiCount );
pFieldInfo.uiDec = 0;
DBFIELDINFO dbFieldInfo;
memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) );
dbFieldInfo.atomName = PQfname( pResult, ( int ) uiCount );
switch( PQftype( pResult, ( int ) uiCount ) )
{
case BPCHAROID:
case VARCHAROID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = ( HB_USHORT ) PQfmod( pResult, uiCount ) - 4;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = ( HB_USHORT ) PQfmod( pResult, uiCount ) - 4;
break;
case TEXTOID:
pFieldInfo.uiType = HB_FT_MEMO;
pFieldInfo.uiLen = 10;
dbFieldInfo.uiType = HB_FT_MEMO;
dbFieldInfo.uiLen = 10;
break;
case NUMERICOID:
pFieldInfo.uiType = HB_FT_DOUBLE;
pFieldInfo.uiLen = ( PQfmod( pResult, uiCount ) - 4 ) >> 16;
pFieldInfo.uiDec = ( PQfmod( pResult, uiCount ) - 4 ) & 0xFFFF;
dbFieldInfo.uiType = HB_FT_DOUBLE;
dbFieldInfo.uiLen = ( PQfmod( pResult, uiCount ) - 4 ) >> 16;
dbFieldInfo.uiDec = ( PQfmod( pResult, uiCount ) - 4 ) & 0xFFFF;
break;
case INT2OID:
pFieldInfo.uiType = HB_FT_INTEGER;
pFieldInfo.uiLen = 6;
dbFieldInfo.uiType = HB_FT_INTEGER;
dbFieldInfo.uiLen = 6;
break;
case INT4OID:
pFieldInfo.uiType = HB_FT_INTEGER;
pFieldInfo.uiLen = 11;
dbFieldInfo.uiType = HB_FT_INTEGER;
dbFieldInfo.uiLen = 11;
break;
case INT8OID:
case OIDOID:
pFieldInfo.uiType = HB_FT_LONG;
pFieldInfo.uiLen = 20;
dbFieldInfo.uiType = HB_FT_LONG;
dbFieldInfo.uiLen = 20;
break;
case FLOAT4OID:
case FLOAT8OID:
case CASHOID: /* TODO: ??? */
pFieldInfo.uiType = HB_FT_DOUBLE;
pFieldInfo.uiLen = 16;
pFieldInfo.uiDec = 2; /* TODO: hb_set.SET_DECIMALS ??? */
dbFieldInfo.uiType = HB_FT_DOUBLE;
dbFieldInfo.uiLen = 16;
dbFieldInfo.uiDec = 2; /* TODO: hb_set.SET_DECIMALS ??? */
break;
case BOOLOID:
pFieldInfo.uiType = HB_FT_LOGICAL;
pFieldInfo.uiLen = 1;
dbFieldInfo.uiType = HB_FT_LOGICAL;
dbFieldInfo.uiLen = 1;
break;
case DATEOID:
pFieldInfo.uiType = HB_FT_DATE;
pFieldInfo.uiLen = 8;
dbFieldInfo.uiType = HB_FT_DATE;
dbFieldInfo.uiLen = 8;
break;
case INETOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 29;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 29;
break;
case CIDROID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 32;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 32;
break;
case MACADDROID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 17;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 17;
break;
case BITOID:
case VARBITOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = ( HB_USHORT ) PQfsize( pResult, uiCount );
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = ( HB_USHORT ) PQfsize( pResult, uiCount );
break;
case TIMEOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 12;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 12;
break;
case TIMESTAMPOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 23;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 23;
break;
case TIMETZOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 15;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 15;
break;
case TIMESTAMPTZOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 26;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 26;
break;
case NAMEOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 63;
dbFieldInfo.uiType = HB_FT_STRING;
dbFieldInfo.uiLen = 63;
break;
case BYTEAOID:
pFieldInfo.uiType = HB_FT_STRING;
pFieldInfo.uiLen = 0;
dbFieldInfo.uiType = HB_FT_STRING;
break;
default:
pFieldInfo.uiType = 0;
pFieldInfo.uiLen = 0;
bError = HB_TRUE;
break;
}
/* printf( "field:%s \ttype:%d \tsize:%d \tformat:%d \tmod:%d err=%d\n", pFieldInfo.atomName, PQftype( pResult, ( int ) uiCount ), PQfsize( pResult, uiCount ), PQfformat( pResult, uiCount ) , PQfmod( pResult, uiCount ), bError ); */
/* printf( "field:%s \ttype:%d \tsize:%d \tformat:%d \tmod:%d err=%d\n", dbFieldInfo.atomName, PQftype( pResult, ( int ) uiCount ), PQfsize( pResult, uiCount ), PQfformat( pResult, uiCount ) , PQfmod( pResult, uiCount ), bError ); */
if( ! bError )
{
switch( pFieldInfo.uiType )
switch( dbFieldInfo.uiType )
{
case HB_FT_STRING:
{
char * pStr;
pStr = ( char * ) hb_xgrab( pFieldInfo.uiLen + 1 );
memset( pStr, ' ', pFieldInfo.uiLen );
pStr[ pFieldInfo.uiLen ] = '\0';
pStr = ( char * ) hb_xgrab( dbFieldInfo.uiLen + 1 );
memset( pStr, ' ', dbFieldInfo.uiLen );
pStr[ dbFieldInfo.uiLen ] = '\0';
hb_itemPutCL( pItem, pStr, pFieldInfo.uiLen );
hb_itemPutCL( pItem, pStr, dbFieldInfo.uiLen );
hb_xfree( pStr );
break;
}
@@ -441,12 +439,12 @@ static HB_ERRCODE pgsqlOpen( SQLBASEAREAP pArea )
hb_arraySetForward( pItemEof, uiCount + 1, pItem );
/* if( pFieldInfo.uiType == HB_IT_DOUBLE || pFieldInfo.uiType == HB_IT_INTEGER )
pFieldInfo.uiType = HB_IT_LONG;
/* if( dbFieldInfo.uiType == HB_IT_DOUBLE || dbFieldInfo.uiType == HB_IT_INTEGER )
dbFieldInfo.uiType = HB_IT_LONG;
*/
if( ! bError )
bError = ( SELF_ADDFIELD( &pArea->area, &pFieldInfo ) == HB_FAILURE );
bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE );
}
if( bError )

View File

@@ -344,45 +344,45 @@ static HB_ERRCODE sqlite3Open( SQLBASEAREAP pArea )
pItemEof = hb_itemArrayNew( uiFields );
for( uiIndex = 0; uiIndex < uiFields; ++uiIndex )
{
DBFIELDINFO pFieldInfo;
DBFIELDINFO dbFieldInfo;
memset( &pFieldInfo, 0, sizeof( pFieldInfo ) );
memset( &dbFieldInfo, 0, sizeof( dbFieldInfo ) );
pName = S_HB_ITEMPUTSTR( pName, sqlite3_column_name( st, uiIndex ) );
pFieldInfo.atomName = hb_itemGetCPtr( pName );
pFieldInfo.uiType = sqlite3DeclType( st, uiIndex );
dbFieldInfo.atomName = hb_itemGetCPtr( pName );
dbFieldInfo.uiType = sqlite3DeclType( st, uiIndex );
pItem = hb_arrayGetItemPtr( pItemEof, uiIndex + 1 );
switch( pFieldInfo.uiType )
switch( dbFieldInfo.uiType )
{
case HB_FT_STRING:
{
int iSize = sqlite3_column_bytes( st, uiIndex );
char * pStr;
pFieldInfo.uiLen = ( HB_USHORT ) HB_MAX( iSize, 10 );
pStr = ( char * ) hb_xgrab( ( HB_SIZE ) pFieldInfo.uiLen + 1 );
memset( pStr, ' ', pFieldInfo.uiLen );
hb_itemPutCLPtr( pItem, pStr, pFieldInfo.uiLen );
dbFieldInfo.uiLen = ( HB_USHORT ) HB_MAX( iSize, 10 );
pStr = ( char * ) hb_xgrab( ( HB_SIZE ) dbFieldInfo.uiLen + 1 );
memset( pStr, ' ', dbFieldInfo.uiLen );
hb_itemPutCLPtr( pItem, pStr, dbFieldInfo.uiLen );
break;
}
case HB_FT_BLOB:
pFieldInfo.uiLen = 4;
dbFieldInfo.uiLen = 4;
hb_itemPutC( pItem, NULL );
break;
case HB_FT_INTEGER:
pFieldInfo.uiLen = 8;
dbFieldInfo.uiLen = 8;
hb_itemPutNInt( pItem, 0 );
break;
case HB_FT_LONG:
pFieldInfo.uiLen = 20;
pFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals();
hb_itemPutNDDec( pItem, 0.0, pFieldInfo.uiDec );
dbFieldInfo.uiLen = 20;
dbFieldInfo.uiDec = ( HB_USHORT ) hb_setGetDecimals();
hb_itemPutNDDec( pItem, 0.0, dbFieldInfo.uiDec );
break;
case HB_FT_ANY:
pFieldInfo.uiLen = 6;
dbFieldInfo.uiLen = 6;
break;
default:
@@ -390,7 +390,7 @@ static HB_ERRCODE sqlite3Open( SQLBASEAREAP pArea )
}
if( ! bError )
bError = ( SELF_ADDFIELD( &pArea->area, &pFieldInfo ) == HB_FAILURE );
bError = ( SELF_ADDFIELD( &pArea->area, &dbFieldInfo ) == HB_FAILURE );
if( bError )
break;