From 625e5a6a13efdb58fc0fa26d471b506582ed220a Mon Sep 17 00:00:00 2001 From: "Alexander S.Kresin" Date: Thu, 15 Mar 2001 17:44:00 +0000 Subject: [PATCH] 2001-03-15 20:40 GMT+3 Alexander Kresin --- harbour/ChangeLog | 11 ++ harbour/include/hbapirdd.h | 35 +++- harbour/include/hbrdddbf.h | 5 + harbour/include/hbrddwrk.h | 5 + harbour/source/rdd/dbcmd.c | 366 +++++++++++++++++++++++++++++++++++-- harbour/source/rdd/dbf1.c | 36 +++- 6 files changed, 439 insertions(+), 19 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d6dbb21448..589f83d747 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,14 @@ +2001-03-15 20:40 GMT+3 Alexander Kresin + files posted by Juan Agustin Barriga + * source/rdd/dbcmd.c + * source/rdd/dbf1.c + * include/hbapirdd.h + * include/hbrdddbf.h + * include/hbrddwrk.h + * Implementation of DBAPPEND and DBCOPY is finished. + + Added: DBEXIT (for RDD cleanup), DBDROP (for table + deleting) and DBEXISTS (for table/index verification). + 2001-03-14 04:55 UTC-0800 Ron Pinkas * source/vm/classes.c ! Fixed hb_param() to hb_stackItemFromBase() (posted by José F. Giménez) diff --git a/harbour/include/hbapirdd.h b/harbour/include/hbapirdd.h index f04d557b42..44c0e2d29f 100644 --- a/harbour/include/hbapirdd.h +++ b/harbour/include/hbapirdd.h @@ -231,7 +231,7 @@ extern void hb_rddShutDown( void ); */ struct _RDDFUNCS; struct _AREA; - +struct _RDDNODE; /* @@ -616,7 +616,6 @@ typedef AREA * LPAREA; #endif - /*--------------------* Virtual Method Table *----------------------*/ typedef USHORT ( * DBENTRYP_V )( AREAP area ); @@ -657,6 +656,11 @@ typedef USHORT ( * DBENTRYP_VPL )( AREAP area, void * p1, LONG p2); typedef USHORT ( * DBENTRYP_VPLP )( AREAP area, void * p1, LONG * p2); typedef USHORT ( * DBENTRYP_LSP )( AREAP area, LONG p1, USHORT * p2); +/* this methods DO USE take a Workarea but an RDDNODE */ + +typedef USHORT ( * DBENTRYP_I0 )( void ); +typedef USHORT ( * DBENTRYP_I1 )( PHB_ITEM p1); +typedef USHORT ( * DBENTRYP_I2 )( PHB_ITEM p1, PHB_ITEM p2); /*--------------------* Virtual Method Table *----------------------*/ typedef struct _RDDFUNCS @@ -793,6 +797,11 @@ typedef struct _RDDFUNCS DBENTRYP_V writeDBHeader; + /* non WorkArea functions */ + DBENTRYP_I0 exit; + DBENTRYP_I1 drop; + DBENTRYP_I2 exists; + /* Special and reserved methods */ DBENTRYP_SVP whoCares; @@ -803,6 +812,17 @@ typedef RDDFUNCS * PRDDFUNCS; #define RDDFUNCSCOUNT ( sizeof( RDDFUNCS ) / sizeof( DBENTRYP_V ) ) +/* RDD Node structure */ +typedef struct _RDDNODE +{ + char szName[ HARBOUR_MAX_RDD_DRIVERNAME_LENGTH + 1 ]; /* Name of RDD */ + USHORT uiType; /* Type of RDD */ + RDDFUNCS pTable; /* Table of functions */ + USHORT uiAreaSize; /* Size of the WorkArea */ + struct _RDDNODE * pNext; /* Next RDD in the list */ +} RDDNODE; + +typedef RDDNODE * LPRDDNODE; /*--------------------* SELF Methods *------------------------*/ @@ -957,6 +977,12 @@ typedef RDDFUNCS * PRDDFUNCS; #define SELF_TABLEEXT(w, fp) ((*(w)->lprfsHost->info)(w, DBI_TABLEEXT, fp)) + /* non WorkArea functions */ +#define SELF_EXIT(r) ((*(r)->pTable.exit)()) +#define SELF_DROP(r, i) ((*(r)->pTable.drop)(i)) +#define SELF_EXISTS(r, it, ii) ((*(r)->pTable.exists)(it,ii)) + + /*--------------------* SUPER Methods *------------------------*/ @@ -1109,7 +1135,10 @@ typedef RDDFUNCS * PRDDFUNCS; #define SUPER_GETDELIM(w, fp) ((*(SUPERTABLE)->info)(w, DBI_GETDELIMITER, fp)) #define SUPER_TABLEEXT(w, fp) ((*(SUPERTABLE)->info)(w, DBI_TABLEEXT, fp)) - + /* non WorkArea functions */ +#define SUPER_EXIT() ((*(SUPERTABLE)->exit)()) +#define SUPER_DROP(i) ((*(SUPERTABLE)->drop)(i)) +#define SUPER_EXISTS(it, ii) ((*(SUPERTABLE)->exists)(it, ii)) /* * PROTOTYPES diff --git a/harbour/include/hbrdddbf.h b/harbour/include/hbrdddbf.h index 76c6664f54..9a02a1c091 100644 --- a/harbour/include/hbrdddbf.h +++ b/harbour/include/hbrdddbf.h @@ -250,6 +250,11 @@ extern ERRCODE hb_dbfOpenMemFile( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ); #define hb_dbfPutValueFile NULL extern ERRCODE hb_dbfReadDBHeader( DBFAREAP pArea ); extern ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ); + +#define hb_dbfExit NULL +extern ERRCODE hb_dbfDrop( PHB_ITEM pItemTable ); +extern BOOL hb_dbfExists( PHB_ITEM pItemTable, PHB_ITEM pItemIndex ); + #define hb_dbfWhoCares NULL #if defined(HB_EXTERN_C) diff --git a/harbour/include/hbrddwrk.h b/harbour/include/hbrddwrk.h index 7ea7bcf078..529b4ceb43 100644 --- a/harbour/include/hbrddwrk.h +++ b/harbour/include/hbrddwrk.h @@ -138,6 +138,11 @@ extern ERRCODE hb_waEvalBlock( AREAP pArea, PHB_ITEM pBlock ); #define hb_waPutValueFile ( DBENTRYP_SVP ) hb_waUnsupported #define hb_waReadDBHeader hb_waUnsupported #define hb_waWriteDBHeader hb_waUnsupported + +#define hb_rddExit (DBENTRYP_I0) NULL +#define hb_rddDrop (DBENTRYP_I1) hb_waUnsupported +#define hb_rddExists (DBENTRYP_I2) hb_waUnsupported + #define hb_waWhoCares ( DBENTRYP_SVP ) hb_waUnsupported #if defined(HB_EXTERN_C) diff --git a/harbour/source/rdd/dbcmd.c b/harbour/source/rdd/dbcmd.c index 712233d9b7..4934a2a539 100644 --- a/harbour/source/rdd/dbcmd.c +++ b/harbour/source/rdd/dbcmd.c @@ -44,19 +44,6 @@ l * #include "hbrddwrk.h" -typedef struct _RDDNODE -{ - char szName[ HARBOUR_MAX_RDD_DRIVERNAME_LENGTH + 1 ]; /* Name of RDD */ - USHORT uiType; /* Type of RDD */ - RDDFUNCS pTable; /* Table of functions */ - USHORT uiAreaSize; /* Size of the WorkArea */ - struct _RDDNODE * pNext; /* Next RDD in the list */ -} RDDNODE; - -typedef RDDNODE * LPRDDNODE; - - - typedef struct _AREANODE { void * pArea; /* WorkAreas with different sizes */ @@ -208,6 +195,9 @@ static RDDFUNCS waTable = { hb_waBof, hb_waPutValueFile, hb_waReadDBHeader, hb_waWriteDBHeader, + hb_rddExit, + hb_rddDrop, + hb_rddExists, hb_waWhoCares }; @@ -880,6 +870,8 @@ void hb_rddShutDown( void ) { pRddNode = s_pRddList; s_pRddList = s_pRddList->pNext; + if ( pRddNode->pTable.exit != NULL ) + SELF_EXIT( pRddNode ); hb_xfree( pRddNode ); } } @@ -1914,9 +1906,11 @@ HB_FUNC( DBUSEAREA ) /* Open file */ if( SELF_OPEN( ( AREAP ) s_pCurrArea->pArea, &pInfo ) == FAILURE ) { + hb_xfree( pInfo.abName ); hb_rddReleaseCurrentArea(); return; } + hb_xfree( szFileName ); } HB_FUNC( __DBZAP ) @@ -3202,4 +3196,348 @@ HB_FUNC( DBFILEPUT ) } #endif -#include "rddcpy.c" +/*******************************************/ +/* here we have the NEW Database level functions DBDROP & DBEXISTS */ +HB_FUNC( DBDROP ) +{ + PHB_ITEM pFileName; + PHB_ITEM pDriverName; + LPRDDNODE pRDDNode; + USHORT uiRddID; + char *szDriver; + + if ( ISCHAR( 2 ) ) /* we have a VIA RDD parameter */ + szDriver = hb_parc( 2 ); + else + szDriver = s_szDefDriver; + pRDDNode = hb_rddFindNode( szDriver, &uiRddID ); // find the RDD + + if ( !pRDDNode ) + { + hb_errRT_DBCMD( EG_ARG, EDBCMD_EVAL_BADPARAMETER, NULL, "DBDROP" ); + return; + } + if ( SELF_DROP( pRDDNode, hb_param( 1, HB_IT_STRING )) == 0 ) + hb_retl( TRUE ); + else + hb_retl( FALSE ); +} + +HB_FUNC( DBEXISTS ) +{ + PHB_ITEM pFileName; + PHB_ITEM pDriverName; + LPRDDNODE pRDDNode; + USHORT uiRddID; + char * szDriver, * szFileName, * szIndexName; + + if ( ISCHAR( 3 ) ) /* we have a VIA RDD parameter */ + szDriver = hb_parc( 3 ); + else + szDriver = s_szDefDriver; + pRDDNode = hb_rddFindNode( szDriver, &uiRddID ); // find the RDD + + if ( !pRDDNode ) + { + hb_errRT_DBCMD( EG_ARG, EDBCMD_EVAL_BADPARAMETER, NULL, "DBDROP" ); + return; + } + + if ( SELF_EXISTS( pRDDNode, + ISCHAR( 1 ) ? hb_param( 1, HB_IT_STRING ) : NULL, + ISCHAR( 2 ) ? hb_param( 2, HB_IT_STRING ) : NULL )) + hb_retl( TRUE ); + else + hb_retl( FALSE ); +} + +/*******************************************/ +// as we are in C, the code is upside down, +// find __SBAPP & __DBCOPY at the bottom + +// create a new AREANODE and open it's Area +// If the file exists it will be deteted & a new one created +static LPAREANODE GetTheOtherArea( char *szDriver, char * szFileName, BOOL createIt ) +{ + LPAREANODE pAreaNode; + LPRDDNODE pRDDNode; + PHB_ITEM tableItem, pFileExt; + USHORT uiRddID; + PHB_FNAME pFileName; + DBOPENINFO pInfo; + + pRDDNode = hb_rddFindNode( szDriver, &uiRddID ); // find the RDD + + if ( !pRDDNode ) + { + hb_errRT_DBCMD( EG_ARG, EDBCMD_EVAL_BADPARAMETER, NULL, "DBAPP" ); + return NULL; + } + +/* Fill pInfo structure */ + memset( &pInfo, 0, sizeof(DBOPENINFO) ); + pInfo.uiArea = uiRddID; + pInfo.abName = ( BYTE * ) hb_xgrab( _POSIX_PATH_MAX + 1 ); + strcpy( ( char * ) pInfo.abName, szFileName ); + pInfo.atomAlias = ( BYTE * ) "__TMPAREA"; + pInfo.fShared = !hb_set.HB_SET_EXCLUSIVE; + pInfo.fReadonly = FALSE; + +/* get the new area node */ + pAreaNode = hb_rddNewAreaNode( pRDDNode, uiRddID ); + +/* check the extension */ + pFileName = hb_fsFNameSplit( szFileName ); + if( !pFileName->szExtension ) + { + pFileExt = hb_itemPutC( NULL, "" ); + SELF_INFO( ( AREAP ) pAreaNode->pArea, DBI_TABLEEXT, pFileExt ); + strncat( pInfo.abName, hb_itemGetCPtr( pFileExt ), _POSIX_PATH_MAX - + strlen( pInfo.abName ) ); + hb_itemRelease( pFileExt ); + } + hb_xfree( pFileName ); + + if ( createIt ) + { + PHB_ITEM pFieldArray, pItem, pData; + USHORT uiFields, uiCount; + +/* get the table structure */ + pFieldArray = hb_itemNew( NULL ); + SELF_FIELDCOUNT( ( AREAP ) s_pCurrArea->pArea, &uiFields ); + hb_arrayNew( pFieldArray, 0 ); + pData = hb_itemNew( NULL ); + pItem = hb_itemNew( NULL ); + for( uiCount = 1; uiCount <= uiFields; uiCount++ ) + { + hb_arrayNew( pItem, 4 ); + SELF_FIELDINFO( ( AREAP ) s_pCurrArea->pArea, uiCount, DBS_NAME, pData ); + hb_arraySet( pItem, 1, pData ); + SELF_FIELDINFO( ( AREAP ) s_pCurrArea->pArea, uiCount, DBS_TYPE, pData ); + hb_arraySet( pItem, 2, pData ); + SELF_FIELDINFO( ( AREAP ) s_pCurrArea->pArea, uiCount, DBS_LEN, pData ); + hb_arraySet( pItem, 3, pData ); + SELF_FIELDINFO( ( AREAP ) s_pCurrArea->pArea, uiCount, DBS_DEC, pData ); + hb_arraySet( pItem, 4, pData ); + hb_arrayAdd( pFieldArray, pItem ); + } + hb_itemRelease( pItem ); + hb_itemRelease( pData ); + +/* check for table existence and if true, drop it */ + tableItem = hb_itemNew( NULL ); + hb_itemPutCL( tableItem, szFileName, strlen(szFileName) ); + if( SELF_EXISTS( pRDDNode, tableItem, NULL )) + SELF_DROP( pRDDNode, tableItem ); + hb_itemRelease( tableItem ); + +/* now create a new table based on the current Area's record layout */ + ( ( AREAP ) pAreaNode->pArea )->atomAlias = hb_dynsymGet( ( char * ) pInfo.atomAlias ); + if( SELF_CREATEFIELDS( ( AREAP ) pAreaNode->pArea, pFieldArray ) == FAILURE ) + { + SELF_RELEASE( ( AREAP ) pAreaNode->pArea ); + hb_xfree( pInfo.abName ); + hb_xfree( pAreaNode ); + hb_errRT_DBCMD( EG_ARG, EDBCMD_BADPARAMETER, NULL, "DBAPP" ); + return NULL; + } + + if( SELF_CREATE( ( AREAP ) pAreaNode->pArea, &pInfo ) == FAILURE ) + { + SELF_RELEASE( ( AREAP ) pAreaNode->pArea ); + hb_xfree( pInfo.abName ); + hb_xfree( pAreaNode ); + hb_errRT_DBCMD( EG_ARG, EDBCMD_BADPARAMETER, NULL, "DBAPP" ); + return NULL; + } + hb_itemRelease( pFieldArray ); + SELF_CLOSE( ( AREAP ) pAreaNode->pArea ); + SELF_RELEASE( ( AREAP ) pAreaNode->pArea ); + hb_xfree( pAreaNode ); + +/* get a new area node for this AREA */ + pAreaNode = hb_rddNewAreaNode( pRDDNode, uiRddID ); + } + +/* open it */ + if( SELF_OPEN( ( AREAP ) pAreaNode->pArea, &pInfo ) == FAILURE ) + { + SELF_RELEASE( ( AREAP ) pAreaNode->pArea ); + hb_xfree( pInfo.abName ); + hb_xfree( pAreaNode ); + hb_errRT_DBCMD( EG_OPEN, 0, NULL, "DBAPP" ); // Could not open it + return NULL; + } + hb_xfree( pInfo.abName ); + return pAreaNode; +} + +// check if the field is on the Fields Array +static BOOL IsFieldIn( char * fieldName, PHB_ITEM pFields ) +{ + USHORT i, uiFields = ( USHORT ) hb_arrayLen( pFields ); + for ( i=0; iitem.asArray.value->pItems + i; + if ( strcmp( fieldName, (char *)pField->item.asString.value ) == 0 ) + return TRUE; + } + return FALSE; +} + +// move the Field Data between areas by name +static void rddMoveFields( AREAP pAreaFrom, AREAP pAreaTo, PHB_ITEM pFields ) +{ + USHORT i; + PHB_ITEM fieldValue; + + fieldValue = hb_itemNew( NULL ); + for ( i=0 ; iuiFieldCount; i++ ) + { + // list or field in the list? + if ( !pFields || IsFieldIn( (( PHB_DYNS )(pAreaFrom->lpFields + i)->sym )->pSymbol->szName, pFields )) + { + SELF_GETVALUE( pAreaFrom, i+1, fieldValue ); + SELF_PUTVALUE( pAreaTo, i+1, fieldValue ); + } + } + hb_itemRelease( fieldValue ); +} + +// move the records filtering if apropiate +static ERRCODE rddMoveRecords( char *cAreaFrom, char *cAreaTo, PHB_ITEM pFields, + PHB_ITEM pFor, PHB_ITEM pWhile, LONG lNext, + ULONG lRec, BOOL bRest, char *cDriver ) +{ + char * szFileName, * szDriver; + LONG toGo=lNext; + BOOL bFor, bWhile; + BOOL keepGoing=TRUE; + AREAP pAreaFrom; + AREAP pAreaTo; + DBEVALINFO pEvalInfo; + LPAREANODE pAreaRelease=NULL; + LPAREANODE s_pCurrAreaSaved=s_pCurrArea; + + HB_SYMBOL_UNUSED( bRest ); + + if ( !s_pCurrArea ) // We need a current Area to APPEND TO or FROM + { + hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, "DBAPP" ); + return EG_NOTABLE; + } + + // get the RDD Driver to use for the "other" Area + if( cDriver ) + szDriver = cDriver; + else + szDriver = s_szDefDriver; + + if( !cAreaFrom && ! cAreaTo ) // File is needed + { + hb_errRT_DBCMD( EG_ARG, EDBCMD_EVAL_BADPARAMETER, NULL, "DBAPP" ); + return EG_ARG; + } + + if ( cAreaTo ) // it's a COPY TO + { + pAreaRelease = GetTheOtherArea( szDriver, cAreaTo, TRUE ); + pAreaTo = (AREAP) pAreaRelease->pArea; + } + else + pAreaTo = (AREAP) s_pCurrArea->pArea; + + + if ( cAreaFrom ) // it's an APPEND FROM + { // make it current + pAreaRelease = s_pCurrArea = GetTheOtherArea( szDriver, cAreaFrom, FALSE ); + pAreaFrom = (AREAP) pAreaRelease->pArea; + } + else + pAreaFrom = (AREAP) s_pCurrArea->pArea; + + // or one or the other but necer none + if ( !pAreaRelease ) // We need another Area to APPEND TO + { + hb_errRT_DBCMD( EG_NOTABLE, EDBCMD_NOTABLE, NULL, "DBAPP" ); + return EG_NOTABLE; + } + + if ( lRec > 0 ) // only one record + SELF_GOTO( pAreaFrom, lRec ); // go there + + // move those records assuming we are positioned on one. + while( keepGoing ) + { + keepGoing = FALSE; + if( !pAreaFrom->fEof ) // until eof or an evaluation failed + { + if( pWhile ) + bWhile = hb_itemGetL( hb_vmEvalBlock( pWhile ) ); + else + bWhile = TRUE; + + if( pFor ) + bFor = hb_itemGetL( hb_vmEvalBlock( pFor ) ); + else + bFor = TRUE; + + if( bWhile && bFor && (!lNext || toGo > 0 )) // candidate? + { + PHB_ITEM lpFields = pFields ? pFields->item.asArray.value->ulLen ? pFields : NULL : NULL; + SELF_APPEND( ( AREAP ) pAreaTo, FALSE ); // put a new one on TO Area + rddMoveFields( pAreaFrom, pAreaTo, lpFields ); // move the data + if ( lRec == 0 ) // only one record? + keepGoing = TRUE; + else + continue; + } + toGo--; // one less to go + SELF_SKIP( pAreaFrom, 1L ); // get the next one + } + } + + s_pCurrArea = s_pCurrAreaSaved; // set current WorkArea to initial state + + // Close the File + SELF_CLOSE( ( AREAP ) pAreaRelease->pArea ); + SELF_RELEASE( ( AREAP ) pAreaRelease->pArea ); + hb_xfree( pAreaRelease ); + + return SUCCESS; +} + +HB_FUNC( __DBAPP ) +{ + if( ISCHAR( 1 ) ) + { + rddMoveRecords( hb_parc( 1 ), /* File From */ + NULL, /* TO current area */ + hb_param( 2, HB_IT_ARRAY ), /* Fields */ + hb_param( 3, HB_IT_BLOCK ), /* For */ + hb_param( 4, HB_IT_BLOCK ), /* While */ + hb_parnl( 5 ), /* Next */ /* Defaults to zero on bad type */ + hb_parnl( 6 ), /* Record */ /* Defaults to zero on bad type */ + hb_parl( 7 ), /* Rest */ /* Defaults to zero on bad type */ + ISCHAR( 8 ) ? hb_parc( 8 ) : NULL ); /* RDD */ + } +} + +HB_FUNC( __DBCOPY ) +{ + if( ISCHAR( 1 ) ) + { + rddMoveRecords( NULL, /* fro CURRENT Area */ + hb_parc( 1 ), /* To File */ + hb_param( 2, HB_IT_ARRAY ), /* Fields */ + hb_param( 3, HB_IT_BLOCK ), /* For */ + hb_param( 4, HB_IT_BLOCK ), /* While */ + hb_parnl( 5 ), /* Next */ /* Defaults to zero on bad type */ + hb_parnl( 6 ), /* Record */ /* Defaults to zero on bad type */ + hb_parl( 7 ), /* Rest */ /* Defaults to zero on bad type */ + ISCHAR( 8 ) ? hb_parc( 8 ) : NULL ); /* RDD */ + } +} + + diff --git a/harbour/source/rdd/dbf1.c b/harbour/source/rdd/dbf1.c index 38b7de3001..ca03249bde 100644 --- a/harbour/source/rdd/dbf1.c +++ b/harbour/source/rdd/dbf1.c @@ -162,6 +162,9 @@ static RDDFUNCS dbfTable = { ( DBENTRYP_BP ) hb_dbfBof, ( DBENTRYP_SVP ) hb_dbfPutValueFile, ( DBENTRYP_V ) hb_dbfReadDBHeader, ( DBENTRYP_V ) hb_dbfWriteDBHeader, + ( DBENTRYP_I0 ) hb_dbfExit, + ( DBENTRYP_I1 ) hb_dbfDrop, + ( DBENTRYP_I2 ) hb_dbfExists, ( DBENTRYP_SVP ) hb_dbfWhoCares }; @@ -1419,6 +1422,7 @@ ERRCODE hb_dbfClose( DBFAREAP pArea ) hb_xfree( pArea->szMemoFileName ); pArea->szMemoFileName = NULL; } + return SUCCESS; } @@ -1435,7 +1439,8 @@ ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) HB_TRACE(HB_TR_DEBUG, ("hb_dbfCreate(%p, %p)", pArea, pCreateInfo)); - pArea->szDataFileName = ( char * ) pCreateInfo->abName; + pArea->szDataFileName = hb_xgrab( strlen(pCreateInfo->abName)+1 ); + strcpy( pArea->szDataFileName, ( char * ) pCreateInfo->abName ); uiSize = pArea->uiFieldCount * sizeof( DBFFIELD ); pBuffer = ( DBFFIELD * ) hb_xgrab( uiSize ); pArea->uiRecordLen = 1; @@ -1649,7 +1654,8 @@ ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) HB_TRACE(HB_TR_DEBUG, ("hb_dbfOpen(%p, %p)", pArea, pOpenInfo)); - pArea->szDataFileName = ( char * ) pOpenInfo->abName; + pArea->szDataFileName = hb_xgrab( strlen(pOpenInfo->abName)+1 ); + strcpy( pArea->szDataFileName, ( char * ) pOpenInfo->abName ); pArea->atomAlias = hb_dynsymGet( ( char * ) pOpenInfo->atomAlias ); if( ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) { @@ -2472,6 +2478,32 @@ ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ) return SUCCESS; } +ERRCODE hb_dbfDrop( PHB_ITEM pItemTable ) +{ + BYTE * pBuffer; + char szFileName[ _POSIX_PATH_MAX + 1 ]; + + pBuffer = hb_itemGetCPtr( pItemTable ); + strcpy( szFileName, pBuffer ); + if ( !strchr( szFileName, '.' )) + strcat( szFileName, DBF_TABLEEXT ); + return hb_fsDelete( szFileName ); +} + +/* returns 1 if exists, 0 else */ +BOOL hb_dbfExists( PHB_ITEM pItemTable, PHB_ITEM pItemIndex ) +{ + char szFileName[ _POSIX_PATH_MAX + 1 ]; + BYTE * pBuffer; + + pBuffer = hb_itemGetCPtr( pItemIndex != NULL ? pItemIndex : pItemTable ); + strcpy( szFileName, pBuffer ); + if ( pItemTable && !strchr( szFileName, '.' )) + strcat( szFileName, DBF_TABLEEXT ); + return hb_fsFile( szFileName ); +} + + HB_FUNC( _DBFC ) { }