diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d8ad04a496..c687791038 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,17 @@ +2000-09-28 14:20 GMT+3 Alexander Kresin + * include/hbapirdd.h + * contrib/rdd_ads/rddads.h + * contrib/rdd_ads/ads1.c + * contrib/rdd_ads/adsfunc.c + * Fixed handling of ADT tables + + Added implementation of SQL support in ADS RDD ( beginning ) + + Added functions: + adsConnect() + adsCreateSqlStatement() + adsExecuteSqlDirect() + adsCopyTable() + adsConvertTable() + 2000-09-27 10:15 GMT+3 Alexander Kresin * source/rdd/dbcmd.c * source/rdd/workarea.c diff --git a/harbour/contrib/rdd_ads/ads1.c b/harbour/contrib/rdd_ads/ads1.c index 97b67b3608..b723cc306b 100644 --- a/harbour/contrib/rdd_ads/ads1.c +++ b/harbour/contrib/rdd_ads/ads1.c @@ -256,7 +256,7 @@ static ERRCODE adsGoTo( ADSAREAP pArea, ULONG ulRecNo ) pArea->fValidBuffer = FALSE; AdsGotoRecord( pArea->hTable, ulRecNo ); hb_adsCheckBofEof( pArea ); -HB_TRACE(HB_TR_ALWAYS, ("afterCheckBE: %lu %lu ", pArea->ulRecNo, ulRecNo )); + // HB_TRACE(HB_TR_ALWAYS, ("afterCheckBE: %lu %lu ", pArea->ulRecNo, ulRecNo )); return SUCCESS; } @@ -455,6 +455,8 @@ static ERRCODE adsFlush( ADSAREAP pArea ) return SUCCESS; } +#define adsGetRec NULL +/* static ERRCODE adsGetRec( ADSAREAP pArea, BYTE ** pBuffer ) { UNSIGNED32 pulLen = pArea->uiRecordLen; @@ -465,12 +467,16 @@ static ERRCODE adsGetRec( ADSAREAP pArea, BYTE ** pBuffer ) * pBuffer = pArea->pRecord; return SUCCESS; } +*/ static ERRCODE adsGetValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { - LPFIELD pField; - BYTE * pBuffer; - char szBuffer[ 21 ]; + LPFIELD pField; + BYTE * pBuffer = pArea->pRecord; + // char szBuffer[ 21 ]; + UNSIGNED8 szName[ HARBOUR_MAX_RDD_FIELDNAME_LENGTH + 1 ]; + UNSIGNED16 pusBufLen = HARBOUR_MAX_RDD_FIELDNAME_LENGTH; + UNSIGNED32 pulLength; HB_TRACE(HB_TR_DEBUG, ("adsGetValue(%p, %hu, %p)", pArea, uiIndex, pItem)); @@ -480,40 +486,69 @@ static ERRCODE adsGetValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) if( pArea->fEof ) { int i; - pBuffer = pArea->pRecord; - for( i=0; i < pArea->uiRecordLen; i++ ) + for( i=0; i < pArea->maxFieldLen; i++ ) *( pBuffer+i ) = ' '; + *( pBuffer + ( int ) pField->uiLen ) = '\0'; } - else if( !pArea->fValidBuffer ) - adsGetRec( pArea, &pBuffer ); +// else if( !pArea->fValidBuffer ) +// adsGetRec( pArea, &pBuffer ); pField = pArea->lpFields + uiIndex - 1; + AdsGetFieldName( pArea->hTable, uiIndex, szName, &pusBufLen ); switch( pField->uiType ) { case HB_IT_STRING: - hb_itemPutCL( pItem, ( char * ) pBuffer + pArea->pFieldOffset[ uiIndex - 1 ], - pField->uiLen ); +// hb_itemPutCL( pItem, ( char * ) pBuffer + pArea->pFieldOffset[ uiIndex - 1 ], +// pField->uiLen ); + if( !pArea->fEof ) + { + pulLength = pArea->maxFieldLen; + AdsGetField( pArea->hTable, szName, pBuffer, &pulLength, ADS_NONE ); + } + hb_itemPutCL( pItem, ( char * ) pBuffer, pField->uiLen ); break; case HB_IT_LONG: - memcpy( szBuffer, pBuffer + pArea->pFieldOffset[ uiIndex - 1 ], - pField->uiLen ); - szBuffer[ pField->uiLen ] = 0; +// memcpy( szBuffer, pBuffer + pArea->pFieldOffset[ uiIndex - 1 ], +// pField->uiLen ); +// szBuffer[ pField->uiLen ] = 0; + if( !pArea->fEof ) + { + pulLength = pArea->maxFieldLen; + AdsGetField( pArea->hTable, szName, pBuffer, &pulLength, ADS_NONE ); + } if( pField->uiDec ) - hb_itemPutNDLen( pItem, atof( szBuffer ), + hb_itemPutNDLen( pItem, atof( pBuffer ), ( int ) pField->uiLen - ( ( int ) pField->uiDec + 1 ), ( int ) pField->uiDec ); else - hb_itemPutNLLen( pItem, atol( szBuffer ), ( int ) pField->uiLen ); + hb_itemPutNLLen( pItem, atol( pBuffer ), ( int ) pField->uiLen ); break; case HB_IT_DATE: - memcpy( szBuffer, pBuffer + pArea->pFieldOffset[ uiIndex - 1 ], 8 ); - szBuffer[ 8 ] = 0; - hb_itemPutDS( pItem, szBuffer ); +// memcpy( szBuffer, pBuffer + pArea->pFieldOffset[ uiIndex - 1 ], 8 ); +// szBuffer[ 8 ] = 0; + { + UNSIGNED8 pucFormat[ 11 ]; + UNSIGNED16 pusLen = 10; + AdsGetDateFormat ( pucFormat, &pusLen ); + AdsSetDateFormat ( (UCHAR*)"YYYYMMDD" ); + if( !pArea->fEof ) + { + pulLength = pArea->maxFieldLen; + AdsGetField( pArea->hTable, szName, pBuffer, &pulLength, ADS_NONE ); + } + hb_itemPutDS( pItem, pBuffer ); + AdsSetDateFormat ( pucFormat ); break; + } case HB_IT_LOGICAL: + if( !pArea->fEof ) + { + pulLength = pArea->maxFieldLen; + AdsGetField( pArea->hTable, szName, pBuffer, &pulLength, ADS_NONE ); + } hb_itemPutL( pItem, pArea->pRecord[ pArea->pFieldOffset[ uiIndex - 1 ] ] == 'T' || pArea->pRecord[ pArea->pFieldOffset[ uiIndex - 1 ] ] == 't' || pArea->pRecord[ pArea->pFieldOffset[ uiIndex - 1 ] ] == 'Y' || @@ -522,14 +557,11 @@ static ERRCODE adsGetValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) case HB_IT_MEMO: { - UNSIGNED8 szName[ HARBOUR_MAX_RDD_FIELDNAME_LENGTH + 1 ]; - UNSIGNED16 pusBufLen = HARBOUR_MAX_RDD_FIELDNAME_LENGTH; UNSIGNED8 *pucBuf; UNSIGNED32 pulLen; - AdsGetFieldName( pArea->hTable, uiIndex, szName, &pusBufLen ); - if ( AdsGetMemoLength( pArea->hTable, szName, &pulLen ) == - AE_NO_CURRENT_RECORD ) + if ( pArea->fEof || + AdsGetMemoLength( pArea->hTable, szName, &pulLen ) == AE_NO_CURRENT_RECORD ) hb_itemPutC( pItem, "" ); else { @@ -587,8 +619,6 @@ static ERRCODE adsPutValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) if( pArea->uiParents ) { -// AdsGetRecordNum( pArea->hTable, ADS_IGNOREFILTERS, -// (UNSIGNED32 *)&(pArea->ulRecNo) ); hb_adsCheckBofEof( pArea ); // xxx can't call this here-- it may skip!!! } @@ -597,7 +627,8 @@ static ERRCODE adsPutValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) return FAILURE; pField = pArea->lpFields + uiIndex - 1; - szText = pArea->pRecord + pArea->pFieldOffset[ uiIndex - 1 ]; + // szText = pArea->pRecord + pArea->pFieldOffset[ uiIndex - 1 ]; + szText = pArea->pRecord; bError = TRUE; AdsGetFieldName( pArea->hTable, uiIndex, szName, &pusBufLen ); @@ -609,8 +640,8 @@ static ERRCODE adsPutValue( ADSAREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) uiCount = ( USHORT ) hb_itemGetCLen( pItem ); if( uiCount > pField->uiLen ) uiCount = pField->uiLen; - memcpy( szText, hb_itemGetCPtr( pItem ), uiCount ); - memset( szText + uiCount, ' ', pField->uiLen - uiCount ); + // memcpy( szText, hb_itemGetCPtr( pItem ), uiCount ); + // memset( szText + uiCount, ' ', pField->uiLen - uiCount ); AdsSetString( pArea->hTable, szName, (UCHAR*)hb_itemGetCPtr( pItem ), uiCount ); bError = FALSE; } @@ -730,8 +761,13 @@ static ERRCODE adsClose( ADSAREAP pArea ) HB_TRACE(HB_TR_DEBUG, ("adsClose(%p)", pArea)); - AdsCloseTable ( pArea->hTable ); - uiError = SUPER_CLOSE( (AREAP)pArea ); + if( pArea->hTable ) + { + AdsCloseTable ( pArea->hTable ); + uiError = SUPER_CLOSE( (AREAP)pArea ); + } + if( pArea->hStatement ) + AdsCloseSQLStatement( pArea->hStatement ); /* Free field offset array */ if( pArea->pFieldOffset ) @@ -896,35 +932,40 @@ static ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo ) UNSIGNED16 pusBufLen, pusType; DBFIELDINFO dbFieldInfo; - HB_TRACE(HB_TR_DEBUG, ("adsReadHeader(%p)", pArea)); + HB_TRACE(HB_TR_DEBUG, ("adsOpen(%p)", pArea)); - pArea->szDataFileName = ( char * ) pOpenInfo->abName; - pArea->atomAlias = hb_dynsymGet( ( char * ) pOpenInfo->atomAlias ); - if( ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) + if( pOpenInfo->atomAlias ) { - hb_errRT_DBCMD( EG_DUPALIAS, EDBCMD_DUPALIAS, NULL, ( char * ) pOpenInfo->atomAlias ); - return FAILURE; - } - ( ( PHB_DYNS ) pArea->atomAlias )->hArea = pOpenInfo->uiArea; + pArea->atomAlias = hb_dynsymGet( ( char * ) pOpenInfo->atomAlias ); + if( ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) + { + hb_errRT_DBCMD( EG_DUPALIAS, EDBCMD_DUPALIAS, NULL, ( char * ) pOpenInfo->atomAlias ); + return FAILURE; + } + ( ( PHB_DYNS ) pArea->atomAlias )->hArea = pOpenInfo->uiArea; + pArea->szDataFileName = ( char * ) pOpenInfo->abName; + pArea->hStatement = 0; + pArea->hOrdCurrent = 0; - ulRetVal = AdsOpenTable ( 0, pOpenInfo->abName, NULL, + ulRetVal = AdsOpenTable ( 0, pOpenInfo->abName, NULL, adsFileType, adsCharType, adsLockType, adsRights, ( (pOpenInfo->fShared) ? ADS_SHARED : ADS_EXCLUSIVE ) | ( (pOpenInfo->fReadonly) ? ADS_READONLY : ADS_DEFAULT ), &hTable); - if( ulRetVal != AE_SUCCESS ) - { - commonError( pArea, EG_OPEN, ( USHORT ) ulRetVal, ( char * ) pOpenInfo->abName ); - return FAILURE; + if( ulRetVal != AE_SUCCESS ) + { + commonError( pArea, EG_OPEN, ( USHORT ) ulRetVal, ( char * ) pOpenInfo->abName ); + return FAILURE; + } + pArea->hTable = hTable; } - pArea->hTable = hTable; - pArea->hOrdCurrent = 0; SELF_FIELDCOUNT( ( AREAP ) pArea, &uiFields ); SELF_SETFIELDEXTENT( ( AREAP ) pArea, uiFields ); /* Size for deleted flag */ pArea->uiRecordLen = 1; + pArea->maxFieldLen = 0; for( uiCount = 1; uiCount <= uiFields; uiCount++ ) { @@ -935,6 +976,7 @@ static ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo ) AdsGetFieldType ( pArea->hTable, szName, &pusType ); AdsGetFieldLength( pArea->hTable, szName, &pulLength ); dbFieldInfo.uiLen = ( USHORT ) pulLength; + if( pulLength > pArea->maxFieldLen ) pArea->maxFieldLen = pulLength; dbFieldInfo.uiDec = 0; switch( pusType ) { @@ -943,6 +985,8 @@ static ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo ) break; case ADS_NUMERIC: + case ADS_DOUBLE: + case ADS_INTEGER: dbFieldInfo.uiType = HB_IT_LONG; AdsGetFieldDecimals( pArea->hTable, szName, ( UNSIGNED16 * ) &pulLength ); dbFieldInfo.uiDec = ( USHORT ) pulLength; @@ -964,7 +1008,7 @@ static ERRCODE adsOpen( ADSAREAP pArea, LPDBOPENINFO pOpenInfo ) } /* Alloc buffer */ - pArea->pRecord = ( BYTE * ) hb_xgrab( pArea->uiRecordLen ); + pArea->pRecord = ( BYTE * ) hb_xgrab( pArea->maxFieldLen + 1 ); pArea->fValidBuffer = FALSE; return SELF_GOTOP( ( AREAP ) pArea ); } @@ -1513,5 +1557,5 @@ HB_FUNC( ADS_GETFUNCTABLE ) if( pTable ) hb_retni( hb_rddInherit( pTable, &adsTable, &adsSuper, 0 ) ); else - hb_retni( FAILURE ); + hb_retni( FAILURE ); } diff --git a/harbour/contrib/rdd_ads/adsfunc.c b/harbour/contrib/rdd_ads/adsfunc.c index 1c9a09fb40..da60292a16 100644 --- a/harbour/contrib/rdd_ads/adsfunc.c +++ b/harbour/contrib/rdd_ads/adsfunc.c @@ -50,6 +50,7 @@ int adsFileType = ADS_CDX; int adsLockType = ADS_PROPRIETARY_LOCKING; int adsRights = 1; int adsCharType = ADS_ANSI; +ADSHANDLE adsConnectHandle = 0; HB_FUNC( ADSSETFILETYPE ) { @@ -577,4 +578,159 @@ HB_FUNC( ADSISTABLEENCRYPTED ) } else hb_errRT_DBCMD( EG_NOTABLE, 2001, NULL, " ADSISTABLEENCRYPTED" ); +} + +HB_FUNC( ADSCONNECT ) +{ + UNSIGNED32 ulRetVal; + + if( hb_pcount() > 0 && ISCHAR( 1 ) ) + { + ulRetVal = AdsConnect ( (UNSIGNED8*) hb_parc( 1 ), &adsConnectHandle ); + if ( ulRetVal == AE_SUCCESS ) + hb_retl( 1 ); + else + hb_retl( 0 ); + } + else + hb_retl( 0 ); +} + +HB_FUNC( ADSCREATESQLSTATEMENT ) +{ + UNSIGNED32 ulRetVal; + ADSAREAP pArea; + ADSHANDLE adsStatementHandle; + char szAlias[ HARBOUR_MAX_RDD_ALIAS_LENGTH + 1 ]; + UNSIGNED16 usTableType; + + if( adsConnectHandle ) + { + ulRetVal = AdsCreateSQLStatement( adsConnectHandle, &adsStatementHandle ); + if( ulRetVal == AE_SUCCESS ) + { + if( !hb_rddInsertAreaNode( "ADS" ) ) + { + AdsCloseSQLStatement( adsStatementHandle ); + hb_retl( 0 ); + } + else + { + pArea = (ADSAREAP) hb_rddGetCurrentWorkAreaPointer(); + if( ISCHAR( 1 ) ) + strncpy( szAlias, hb_parc( 1 ), HARBOUR_MAX_RDD_ALIAS_LENGTH ); + else + strcpy( szAlias, "ADSSQL" ); + pArea->atomAlias = hb_dynsymGet( szAlias ); + if( ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) + { + hb_errRT_DBCMD( EG_DUPALIAS, EDBCMD_DUPALIAS, NULL, szAlias ); + hb_retl( 0 ); + } + ( ( PHB_DYNS ) pArea->atomAlias )->hArea = hb_rddGetCurrentWorkAreaNumber(); + if( ISNUM( 2 ) ) + { + usTableType = hb_parni( 2 ); + if( usTableType == ADS_CDX ) + AdsStmtSetTableType( adsStatementHandle, ADS_CDX ); + } + pArea->uiArea = hb_rddGetCurrentWorkAreaNumber(); + pArea = (ADSAREAP) hb_rddGetCurrentWorkAreaPointer(); + pArea->hStatement = adsStatementHandle; + pArea->hTable = 0; + pArea->hOrdCurrent = 0; + hb_retl( 1 ); + } + } + else + hb_retl( 0 ); + } + else + hb_retl( 0 ); +} + +HB_FUNC( ADSEXECUTESQLDIRECT ) +{ + UNSIGNED32 ulRetVal; + ADSHANDLE hCursor = 0; + ADSAREAP pArea; + DBOPENINFO pInfo; + + if( adsConnectHandle && ( pArea = (ADSAREAP) hb_rddGetCurrentWorkAreaPointer() ) != 0 + && pArea->hStatement && ISCHAR( 1 ) ) + { + ulRetVal = AdsExecuteSQLDirect( pArea->hStatement, hb_parc( 1 ), &hCursor ); + if( ulRetVal == AE_SUCCESS ) + { + if( hCursor ) + { + pInfo.atomAlias = NULL; + pArea->hTable = hCursor; + SELF_OPEN( ( AREAP ) pArea, &pInfo ); + } + hb_retl( 1 ); + } + else + { + UNSIGNED32 pulErrCode; + UNSIGNED8 pucBuf[160]; + UNSIGNED16 pusBufLen = 160; + AdsGetLastError( &pulErrCode, &pucBuf, &pusBufLen); + printf( "\nDirect 4: %d %s",pulErrCode,pucBuf ); + hb_retl( 0 ); + } + } + else + hb_retl( 0 ); +} + +HB_FUNC( ADSCOPYTABLE ) +{ + ADSAREAP pArea; + + pArea = (ADSAREAP) hb_rddGetCurrentWorkAreaPointer(); + if( pArea ) + { + if( ISCHAR( 1 ) ) + { + AdsCopyTable( pArea->hTable, ADS_IGNOREFILTERS, hb_parc( 1 ) ); + } + else + { + hb_errRT_DBCMD( EG_ARG, 1014, NULL, "ADSCOPYTABLE" ); + return; + } + } + else + hb_errRT_DBCMD( EG_NOTABLE, 2001, NULL, " ADSCOPYTABLE" ); + +} + +HB_FUNC( ADSCONVERTTABLE ) +{ + ADSAREAP pArea; + UNSIGNED16 usTableType = ADS_ADT; + + pArea = (ADSAREAP) hb_rddGetCurrentWorkAreaPointer(); + if( pArea ) + { + if( ISCHAR( 1 ) ) + { + if( ISNUM( 2 ) ) + { + usTableType = hb_parni( 2 ); + if( usTableType < 1 || usTableType > 3 ) + usTableType = ADS_ADT; + } + AdsConvertTable( pArea->hTable, ADS_IGNOREFILTERS, hb_parc( 1 ), usTableType ); + } + else + { + hb_errRT_DBCMD( EG_ARG, 1014, NULL, "ADSCONVERTTABLE" ); + return; + } + } + else + hb_errRT_DBCMD( EG_NOTABLE, 2001, NULL, " ADSCONVERTTABLE" ); + } \ No newline at end of file diff --git a/harbour/contrib/rdd_ads/rddads.h b/harbour/contrib/rdd_ads/rddads.h index 1da53278b6..7becf46d8b 100644 --- a/harbour/contrib/rdd_ads/rddads.h +++ b/harbour/contrib/rdd_ads/rddads.h @@ -86,6 +86,7 @@ typedef struct _ADSAREA_ BYTE bDay; USHORT * pFieldOffset; /* Pointer to field offset array */ BYTE * pRecord; /* Buffer of record data */ + ULONG maxFieldLen; BOOL fValidBuffer; /* State of buffer */ BOOL fRecordChanged; /* Record changed */ BOOL fShared; /* Shared file */ @@ -93,6 +94,7 @@ typedef struct _ADSAREA_ BOOL fFLocked; /* TRUE if file is locked */ ADSHANDLE hTable; ADSHANDLE hOrdCurrent; + ADSHANDLE hStatement; } ADSAREA; typedef ADSAREA * ADSAREAP; \ No newline at end of file diff --git a/harbour/include/hbapirdd.h b/harbour/include/hbapirdd.h index 690f3dab45..459ec0092e 100644 --- a/harbour/include/hbapirdd.h +++ b/harbour/include/hbapirdd.h @@ -50,6 +50,7 @@ extern "C" { /* RDD virtual machine integration functions */ +extern USHORT hb_rddInsertAreaNode( char *szDriver ); extern int hb_rddGetCurrentWorkAreaNumber( void ); void * hb_rddGetCurrentWorkAreaPointer( void ); extern ERRCODE hb_rddSelectWorkAreaAlias( char * szAlias );