diff --git a/harbour/ChangeLog b/harbour/ChangeLog index efc9252e85..2d465158ad 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,10 @@ +19990824-11:07 GMT+1 Bruno Cantero + * funclist.txt + include/rddapi.h + source/rdd/dbcmd.c + source/rdd/dbf1.c + + Added RLOCK, DBRLOCK and DBRUNLOCK functions + 19990824-03:50 GMT+1 Victor Szel * tests/working/fileio.prg + Rewritten to check more functions in more situations, displaying all diff --git a/harbour/funclist.txt b/harbour/funclist.txt index 17cbfd4463..b7446b873a 100644 --- a/harbour/funclist.txt +++ b/harbour/funclist.txt @@ -200,7 +200,7 @@ RECSIZE ;N; REPLICATE ;R; RESTSCREEN ;S; RIGHT ;R; -RLOCK ;N; +RLOCK ;R; ROUND ;R; ROW ;R; RTRIM ;R; @@ -238,9 +238,9 @@ VERSION ;S; WORD ;N; YEAR ;R; ; RDD DRIVER SYSTEM -DBRLOCK ;N; -DBRLOCKLIST ;N; -DBRUNLOCK ;N; +DBRLOCK ;R; +DBRLOCKLIST ;R; +DBRUNLOCK ;R; ORDBAGEXT ;N; ORDBAGNAME ;N; ORDCREATE ;N; diff --git a/harbour/include/rddapi.h b/harbour/include/rddapi.h index 4fdeebaa96..76cd5f60d5 100644 --- a/harbour/include/rddapi.h +++ b/harbour/include/rddapi.h @@ -115,10 +115,12 @@ typedef USHORT ERRCODE; #define APPEND_LOCK 7 #define APPEND_UNLOCK 8 - typedef struct _FILEINFO { FHANDLE hFile; + LONG * pLocksPos; /* List of records locked */ + LONG lNumLocksPos; /* Number of records locked */ + BOOL fFileLocked; /* TRUE if entire file is locked */ struct _FILEINFO * pNext; /* The next file in the list */ } FILEINFO; @@ -158,7 +160,6 @@ typedef struct BYTE * atomAlias; /* The logical name of the data store */ BOOL fShared; /* Share mode of the data store */ BOOL fReadonly; /* Readonly mode of the data store */ - void * lpdbHeader; /* Pointer to a header of the data store */ } DBOPENINFO; @@ -180,7 +181,6 @@ typedef struct BOOL fHasMemo; /* Work Area with Memo fields */ PHB_ITEM pRecNo; /* Current record */ BOOL fExclusive; /* Share the Work Area */ - BOOL fFileLocked; /* File Locked */ } DBEXTENDINFO; typedef DBEXTENDINFO * LPDBEXTENDINFO; @@ -208,13 +208,11 @@ typedef struct _DBORDERCONDINFO BOOL fDescending; BOOL fScoped; BOOL fAll; - BOOL fAdditive; BOOL fUseCurrent; BOOL fCustom; BOOL fNoOptimize; void * lpvCargo; - } DBORDERCONDINFO; typedef DBORDERCONDINFO * LPDBORDERCONDINFO; @@ -234,8 +232,6 @@ typedef struct BYTE * atomBagName; /* Name of the Order */ PHB_ITEM itmOrder; BOOL fUnique; /* Flag to determine if all keys are unique */ - /* las claves con £nicas */ - PHB_ITEM itmCobExpr; /* Code block containing the KEY expression */ PHB_ITEM abExpr; /* String containing the KEY expression */ } DBORDERCREATEINFO; @@ -254,13 +250,9 @@ typedef struct { PHB_ITEM atomBagName; /* Name of the Order Bag */ PHB_ITEM itmOrder; /* Name or Number of the Order */ - PHB_ITEM itmCobExpr; /* Code block containing the KEY expression */ - PHB_ITEM itmResult; /* Operation result */ - - BOOL fAllTags; /* Indicador de todos los tags a abrir */ - + BOOL fAllTags; /* Open all tags */ } DBORDERINFO; typedef DBORDERINFO * LPDBORDERINFO; @@ -282,12 +274,10 @@ typedef struct PHB_ITEM lNext; /* NEXT record */ PHB_ITEM itmRecID; PHB_ITEM fRest; /* TRUE if start from the current record */ - BOOL fIgnoreFilter; BOOL fIncludeDeleted; BOOL fLast; BOOL fIgnoreDuplicates; - } DBSCOPEINFO; typedef DBSCOPEINFO * LPDBSCOPEINFO; @@ -321,12 +311,9 @@ typedef struct _DBRELINFO { PHB_ITEM itmCobExpr; /* Block representation of the relational SEEK key */ PHB_ITEM abKey; /* String representation of the relational SEEK key */ - struct _AREA *lpaParent; /* The parent of this relation */ struct _AREA *lpaChild; /* The parents children */ - struct _DBRELINFO *lpdbriNext; /* Next child or parent */ - } DBRELINFO; typedef DBRELINFO * LPDBRELINFO; @@ -385,9 +372,7 @@ typedef struct struct _AREA *lpaSource; /* Pointer to source work area */ struct _AREA *lpaDest; /* Pointer to dest work area */ DBSCOPEINFO dbsci; /* Scope to limit transfer */ - USHORT uiFlags; /* Transfer attributes */ - USHORT uiItemCount; /* Number of items below */ LPDBTRANSITEM lpTransItems; /* Array of items */ } DBTRANSINFO; @@ -436,10 +421,8 @@ typedef DBSORTITEM * LPDBSORTITEM; typedef struct { DBTRANSINFO dbtri; /* Destination workarea transfer information */ - LPDBSORTITEM lpdbsItem; /* Fields which compose the key values for the sort */ USHORT uiItemCount; /* The number of fields above */ - } DBSORTINFO; typedef DBSORTINFO * LPDBSORTINFO; @@ -481,9 +464,7 @@ typedef struct _FIELD USHORT uiDec; /* Decimal length */ USHORT uiArea; /* Area this field resides in */ void * sym; /* Symbol that represents the field */ - struct _FIELD *lpfNext; /* The next field in the list */ - } FIELD; typedef FIELD * LPFIELD; @@ -504,40 +485,28 @@ struct _RDDFUNCS; /* forward declaration */ typedef struct _AREA { struct _RDDFUNCS * lprfsHost; /* Virtual method table for this workarea */ - USHORT uiArea; /* The number assigned to this workarea */ void * atomAlias; /* Pointer to the alias symbol for this workarea */ - USHORT uiFieldExtent; /* Total number of fields allocated */ USHORT uiFieldCount; /* Total number of fields used */ LPFIELD lpFields; /* Pointer to an array of fields */ - void * lpFieldExtents; /* Void ptr for additional field properties */ - PHB_ITEM valResult; /* All purpose result holder */ - BOOL fTop; /* TRUE if "top" */ BOOL fBottom; /* TRUE if "bottom" */ BOOL fBof; /* TRUE if "bof" */ BOOL fEof; /* TRUE if "eof" */ BOOL fFound; /* TRUE if "found" */ - DBSCOPEINFO dbsi; /* Info regarding last LOCATE */ DBFILTERINFO dbfi; /* Filter in effect */ - LPDBORDERCONDINFO lpdbOrdCondInfo; - LPDBRELINFO lpdbRelations; /* Parent/Child relationships used */ USHORT uiParents; /* Number of parents for this area */ - USHORT heap; USHORT heapSize; - USHORT rddID; - LPFILEINFO lpFileInfo; /* Files used by this workarea */ LPDBEXTENDINFO lpExtendInfo; /* Additional properties */ - } AREA; typedef AREA * LPAREA; diff --git a/harbour/source/rdd/dbcmd.c b/harbour/source/rdd/dbcmd.c index 1df67083eb..36456ebead 100644 --- a/harbour/source/rdd/dbcmd.c +++ b/harbour/source/rdd/dbcmd.c @@ -73,6 +73,9 @@ HARBOUR HB_DBGOBOTTOM( void ); HARBOUR HB_DBGOTO( void ); HARBOUR HB_DBGOTOP( void ); HARBOUR HB_DBRECALL( void ); +HARBOUR HB_DBRLOCK( void ); +HARBOUR HB_DBRLOCKLIST( void ); +HARBOUR HB_DBRUNLOCK( void ); HARBOUR HB_DBSELECTAREA( void ); HARBOUR HB_DBSETDRIVER( void ); HARBOUR HB_DBSKIP( void ); @@ -94,6 +97,7 @@ HARBOUR HB_RDDSETDEFAULT( void ); HARBOUR HB_RDDSHUTDOWN( void ); HARBOUR HB_RECCOUNT( void ); HARBOUR HB_RECNO( void ); +HARBOUR HB_RLOCK( void ); HARBOUR HB_SELECT( void ); HARBOUR HB_USED( void ); @@ -109,6 +113,9 @@ HB_INIT_SYMBOLS_BEGIN( dbCmd__InitSymbols ) { "DBGOTO", FS_PUBLIC, HB_DBGOTO, 0 }, { "DBGOTOP", FS_PUBLIC, HB_DBGOTOP, 0 }, { "DBRECALL", FS_PUBLIC, HB_DBRECALL, 0 }, +{ "DBRLOCK", FS_PUBLIC, HB_DBRLOCK, 0 }, +{ "DBRLOCKLIST", FS_PUBLIC, HB_DBRLOCKLIST, 0 }, +{ "DBRUNLOCK", FS_PUBLIC, HB_DBRUNLOCK, 0 }, { "DBSELECTAREA", FS_PUBLIC, HB_DBSELECTAREA, 0 }, { "DBSETDRIVER", FS_PUBLIC, HB_DBSETDRIVER, 0 }, { "DBSKIP", FS_PUBLIC, HB_DBSKIP, 0 }, @@ -130,6 +137,7 @@ HB_INIT_SYMBOLS_BEGIN( dbCmd__InitSymbols ) { "RDDSHUTDOWN", FS_PUBLIC, HB_RDDSHUTDOWN, 0 }, { "RECCOUNT", FS_PUBLIC, HB_RECCOUNT, 0 }, { "RECNO", FS_PUBLIC, HB_RECNO, 0 }, +{ "RLOCK", FS_PUBLIC, HB_RLOCK, 0 }, { "SELECT", FS_PUBLIC, HB_SELECT, 0 }, { "USED", FS_PUBLIC, HB_USED, 0 } HB_INIT_SYMBOLS_END( dbCmd__InitSymbols ) @@ -275,8 +283,8 @@ static ERRCODE Info( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) static ERRCODE NewArea( AREAP pArea ) { pArea->lpFileInfo = ( LPFILEINFO ) hb_xgrab( sizeof( FILEINFO ) ); + memset( pArea->lpFileInfo, 0, sizeof( FILEINFO ) ); pArea->lpFileInfo->hFile = FS_ERROR; - pArea->lpFileInfo->pNext = 0; pArea->lpExtendInfo = ( LPDBEXTENDINFO ) hb_xgrab( sizeof( DBEXTENDINFO ) ); memset( pArea->lpExtendInfo, 0, sizeof( DBEXTENDINFO ) ); pArea->lpExtendInfo->pRecNo = hb_itemNew( NULL ); @@ -285,8 +293,6 @@ static ERRCODE NewArea( AREAP pArea ) static ERRCODE Open( AREAP pArea, LPDBOPENINFO pOpenInfo ) { - USHORT uiFlags; - pArea->atomAlias = hb_dynsymFind( ( char * ) pOpenInfo->atomAlias ); if( pArea->atomAlias && ( ( PHB_DYNS ) pArea->atomAlias )->hArea ) { @@ -686,7 +692,7 @@ HARBOUR HB_BOF( void ) { BOOL bBof = TRUE; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_BOF( ( AREAP ) pCurrArea->pArea, &bBof ); hb_retl( bBof ); } @@ -721,7 +727,7 @@ HARBOUR HB_DBCLOSEAREA( void ) HARBOUR HB_DBCOMMIT( void ) { - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_FLUSH( ( AREAP ) pCurrArea->pArea ); else hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBCOMMIT" ); @@ -814,7 +820,7 @@ HARBOUR HB_DBCREATE( void ) HARBOUR HB_DBDELETE( void ) { - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_DELETE( ( AREAP ) pCurrArea->pArea ); else hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBDELETE" ); @@ -822,7 +828,7 @@ HARBOUR HB_DBDELETE( void ) HARBOUR HB_DBGOBOTTOM( void ) { - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_GOBOTTOM( ( AREAP ) pCurrArea->pArea ); else hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBGOBOTTOM" ); @@ -832,7 +838,7 @@ HARBOUR HB_DBGOTO( void ) { PHB_ITEM pItem; - if( !pCurrArea || !( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( !pCurrArea ) { hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBGOTOP" ); return; @@ -847,7 +853,7 @@ HARBOUR HB_DBGOTO( void ) HARBOUR HB_DBGOTOP( void ) { - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_GOTOP( ( AREAP ) pCurrArea->pArea ); else hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBGOTOP" ); @@ -855,12 +861,57 @@ HARBOUR HB_DBGOTOP( void ) HARBOUR HB_DBRECALL( void ) { - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_RECALL( ( AREAP ) pCurrArea->pArea ); else hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBRECALL" ); } +HARBOUR HB_DBRLOCK( void ) +{ + DBLOCKINFO pLockInfo; + + pLockInfo.fResult = FALSE; + if( pCurrArea ) + { + pLockInfo.itmRecID = hb_parnl( 1 ); + pLockInfo.uiMethod = REC_LOCK; + SELF_LOCK( ( AREAP ) pCurrArea->pArea, &pLockInfo ); + } + else + hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBRLOCK" ); + + hb_retl( pLockInfo.fResult ); +} + +HARBOUR HB_DBRLOCKLIST( void ) +{ + PHB_ITEM pList; + + pList = hb_itemArrayNew( 0 ); + if( pCurrArea ) + SELF_INFO( ( AREAP ) pCurrArea->pArea, DBI_GETLOCKARRAY, pList ); + else + hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBRLOCKLIST" ); + + hb_itemReturn( pList ); + hb_itemRelease( pList ); +} + +HARBOUR HB_DBRUNLOCK( void ) +{ + DBLOCKINFO pLockInfo; + + if( pCurrArea ) + { + pLockInfo.itmRecID = hb_parnl( 1 ); + pLockInfo.uiMethod = REC_UNLOCK; + SELF_LOCK( ( AREAP ) pCurrArea->pArea, &pLockInfo ); + } + else + hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "DBRUNLOCK" ); +} + HARBOUR HB_DBSELECTAREA( void ) { USHORT uiNewArea; @@ -909,7 +960,7 @@ HARBOUR HB_DBSKIP( void ) PHB_ITEM pItem; LONG lToSkip = 1; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) { pItem = hb_param( 1, IT_NUMERIC ); if( pItem ) @@ -1127,7 +1178,7 @@ HARBOUR HB_DELETED( void ) { BOOL bDeleted = FALSE; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_DELETED( ( AREAP ) pCurrArea->pArea, &bDeleted ); hb_retl( bDeleted ); } @@ -1136,7 +1187,7 @@ HARBOUR HB_EOF( void ) { BOOL bEof = TRUE; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_EOF( ( AREAP ) pCurrArea->pArea, &bEof ); hb_retl( bEof ); } @@ -1145,7 +1196,7 @@ HARBOUR HB_FCOUNT( void ) { USHORT uiFields = 0; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_FIELDCOUNT( ( AREAP ) pCurrArea->pArea, &uiFields ); hb_retni( uiFields ); } @@ -1158,7 +1209,7 @@ HARBOUR HB_FIELDGET( void ) pItem = hb_itemNew( 0 ); uiField = hb_parni( 1 ); - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost && uiField ) + if( pCurrArea && uiField ) SELF_GETVALUE( ( AREAP ) pCurrArea->pArea, uiField, pItem ); hb_itemReturn( pItem ); @@ -1170,7 +1221,7 @@ HARBOUR HB_FIELDNAME( void ) USHORT uiFields, uiIndex; char * szName; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) { uiIndex = hb_parni( 1 ); if( SELF_FIELDCOUNT( ( AREAP ) pCurrArea->pArea, &uiFields ) == SUCCESS ) @@ -1195,7 +1246,7 @@ HARBOUR HB_FIELDPOS( void ) char * szName; LPFIELD pField; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) { szName = hb_parc( 1 ); hb_strUpper( szName, strlen( szName ) ); @@ -1221,7 +1272,7 @@ HARBOUR HB_FIELDPUT( void ) PHB_ITEM pItem; uiIndex = hb_parni( 1 ); - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost && uiIndex ) + if( pCurrArea && uiIndex ) { pItem = hb_param( 2, IT_ANY ); if( SELF_PUTVALUE( ( AREAP ) pCurrArea->pArea, uiIndex, pItem ) == SUCCESS ) @@ -1237,7 +1288,7 @@ HARBOUR HB_FOUND( void ) { BOOL bFound = FALSE; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_FOUND( ( AREAP ) pCurrArea->pArea, &bFound ); hb_retl( bFound ); } @@ -1271,7 +1322,7 @@ HARBOUR HB_RDDNAME( void ) { char * pBuffer; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) { pBuffer = ( char * ) hb_xgrab( HARBOUR_MAX_RDD_DRIVERNAME_LENGTH + 1 ); pBuffer[ 0 ] = '\0'; @@ -1343,7 +1394,7 @@ HARBOUR HB_RECCOUNT( void ) { LONG ulRecCount = 0; - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_RECCOUNT( ( AREAP ) pCurrArea->pArea, &ulRecCount ); hb_retnl( ulRecCount ); } @@ -1353,11 +1404,30 @@ HARBOUR HB_RECNO( void ) PHB_ITEM pRecNo; pRecNo = hb_itemPutNL( NULL, 0 ); - if( pCurrArea && ( ( AREAP ) pCurrArea->pArea )->lprfsHost ) + if( pCurrArea ) SELF_RECNO( ( AREAP ) pCurrArea->pArea, pRecNo ); hb_itemReturn( pRecNo ); } +HARBOUR HB_RLOCK( void ) +{ + DBLOCKINFO pLockInfo; + PHB_ITEM pRecNo; + + pLockInfo.fResult = FALSE; + if( pCurrArea ) + { + SELF_RECNO( ( AREAP ) pCurrArea->pArea, pRecNo ); + pLockInfo.itmRecID = pRecNo->item.asLong.value; + pLockInfo.uiMethod = REC_LOCK; + SELF_LOCK( ( AREAP ) pCurrArea->pArea, &pLockInfo ); + } + else + hb_errRT_DBCMD( EG_NOTABLE, 2001, 0, "RLOCK" ); + + hb_retl( pLockInfo.fResult ); +} + HARBOUR HB_SELECT( void ) { char * szAlias; @@ -1376,4 +1446,3 @@ HARBOUR HB_USED( void ) else hb_retl( 0 ); } - diff --git a/harbour/source/rdd/dbf1.c b/harbour/source/rdd/dbf1.c index 410bafcefd..7f9635d034 100644 --- a/harbour/source/rdd/dbf1.c +++ b/harbour/source/rdd/dbf1.c @@ -77,7 +77,144 @@ HB_INIT_SYMBOLS_END( dbf1__InitSymbols ) #pragma startup dbf1__InitSymbols #endif -static ERRCODE ReadBuffer( AREAP pArea, LONG lRecNo ); +#define LOCK_START 0x40000000L + +static BOOL hb_rddIsLocked( AREAP pArea, LONG lLockPos ) +{ + LONG lNumLocksPos; + + lNumLocksPos = pArea->lpFileInfo->lNumLocksPos; + while( lNumLocksPos > 0 ) + { + if( pArea->lpFileInfo->pLocksPos[ lNumLocksPos - 1 ] == lLockPos ) + return TRUE; + lNumLocksPos--; + } + + return FALSE; +} + +static BOOL hb_rddLockRecord( AREAP pArea, LONG lRecNum ) +{ + LPFILEINFO pFileInfo; + + if( pArea->lpExtendInfo->fExclusive || pArea->lpFileInfo->fFileLocked ) + return TRUE; + + pFileInfo = pArea->lpFileInfo; + if( hb_rddIsLocked( pArea, lRecNum ) ) + return TRUE; + + if( !hb_fsLock( pArea->lpFileInfo->hFile, LOCK_START + lRecNum, 1, FL_LOCK ) ) + return FALSE; + + if( pFileInfo->lNumLocksPos == 0 ) /* Create the list */ + { + pFileInfo->pLocksPos = ( LONG * ) hb_xgrab( sizeof( LONG ) ); + pFileInfo->pLocksPos[ 0 ] = lRecNum; + } + else /* Resize the list */ + { + pFileInfo->pLocksPos = ( LONG * ) + hb_xrealloc( pFileInfo->pLocksPos, + ( pFileInfo->lNumLocksPos + 1 ) * + sizeof( LONG ) ); + pFileInfo->pLocksPos[ pFileInfo->lNumLocksPos ] = lRecNum; + } + pFileInfo->lNumLocksPos++; + + return TRUE; +} + +static BOOL hb_rddUnLockRecord( AREAP pArea, LONG lRecNum ) +{ + LPFILEINFO pFileInfo; + LONG lLockPos, * pList; + + if( pArea->lpExtendInfo->fExclusive || pArea->lpFileInfo->fFileLocked ) + return TRUE; + + pFileInfo = pArea->lpFileInfo; + if( !hb_rddIsLocked( pArea, lRecNum ) ) + return TRUE; + + if( !hb_fsLock( pArea->lpFileInfo->hFile, LOCK_START + lRecNum, 1, FL_UNLOCK ) ) + return FALSE; + + if( pFileInfo->lNumLocksPos == 1 ) /* Delete the list */ + { + hb_xfree( pFileInfo->pLocksPos ); + pFileInfo->lNumLocksPos = 0; + } + else /* Resize the list */ + { + /* Search de locked record */ + for( lLockPos = 0; lLockPos < pFileInfo->lNumLocksPos; lLockPos++ ) + { + if( pFileInfo->pLocksPos[ lLockPos ] == lRecNum ) + { + pList = pFileInfo->pLocksPos + lLockPos; + memmove( pList, pList + 1, + ( pFileInfo->lNumLocksPos - lLockPos - 1 ) * + sizeof( LONG ) ); + pFileInfo->pLocksPos = ( LONG * ) + hb_xrealloc( pFileInfo->pLocksPos, + ( pFileInfo->lNumLocksPos - 1 ) * + sizeof( LONG ) ); + pFileInfo->lNumLocksPos--; + return TRUE; + } + } + } + + return TRUE; +} + +static BOOL hb_rddUnLockAllRecords( AREAP pArea ) +{ + LPFILEINFO pFileInfo; + LONG lPosLocked; + BOOL bUnLocked = TRUE; + + if( pArea->lpExtendInfo->fExclusive ) + return TRUE; + + pFileInfo = pArea->lpFileInfo; + for( lPosLocked = 0; lPosLocked < pFileInfo->lNumLocksPos; lPosLocked++ ) + if( !hb_fsLock( pArea->lpFileInfo->hFile, LOCK_START + + pFileInfo->pLocksPos[ lPosLocked ], 1, FL_UNLOCK ) ) + bUnLocked = FALSE; + + if( pFileInfo->lNumLocksPos > 1 ) + hb_xfree( pFileInfo->pLocksPos ); + pFileInfo->pLocksPos = 0; + pFileInfo->lNumLocksPos = 0; + + return bUnLocked; +} + +static void hb_rddGetLockArray( AREAP pArea, PHB_ITEM pItem ) +{ + LONG lLockPos; + + for( lLockPos = 1; lLockPos <= pArea->lpFileInfo->lNumLocksPos; lLockPos++ ) + hb_arrayAdd( pItem, + hb_itemPutNL( NULL, pArea->lpFileInfo->pLocksPos[ lLockPos - 1 ] ) ); +} + +static ERRCODE hb_rddReadBuffer( AREAP pArea, LONG lRecNo ) +{ + hb_fsSeek( pArea->lpFileInfo->hFile, pArea->lpExtendInfo->uiHeaderLen + + ( lRecNo - 1 ) * pArea->lpExtendInfo->uiRecordLen, FS_SET ); + if( hb_fsRead( pArea->lpFileInfo->hFile, pArea->lpExtendInfo->bRecord, + pArea->lpExtendInfo->uiRecordLen ) != pArea->lpExtendInfo->uiRecordLen ) + { + memset( pArea->lpExtendInfo->bRecord, ' ', pArea->lpExtendInfo->uiRecordLen ); + pArea->lpExtendInfo->bRecord[ pArea->lpExtendInfo->uiRecordLen ] = 0; + return FAILURE; + } + return SUCCESS; +} static RDDFUNCS dbfSuper = { 0 }; @@ -88,7 +225,10 @@ static RDDFUNCS dbfSuper = { 0 }; static ERRCODE Close( AREAP pArea ) { if( pArea->lpFileInfo->hFile != FS_ERROR ) + { + hb_rddUnLockAllRecords( pArea ); hb_fsClose( pArea->lpFileInfo->hFile ); + } pArea->lpFileInfo->hFile = FS_ERROR; return SUPER_CLOSE( pArea ); @@ -114,10 +254,8 @@ static ERRCODE Create( AREAP pArea, LPDBOPENINFO pCreateInfo ) static ERRCODE Deleted( AREAP pArea, BOOL * pDeleted ) { - if( pArea->lpExtendInfo->bRecord[ 0 ] == '*' ) - * pDeleted = TRUE; - else - * pDeleted = FALSE; + * pDeleted = ( pArea->lpExtendInfo->bRecord[ 0 ] == '*' ); + return SUCCESS; } @@ -225,7 +363,7 @@ static ERRCODE GoTo( AREAP pArea, LONG lRecNo ) } hb_itemPutNL( pArea->lpExtendInfo->pRecNo, lRecNo ); if( lRecCount > 0 ) - return ReadBuffer( pArea, lRecNo ); + return hb_rddReadBuffer( pArea, lRecNo ); else return SUCCESS; } @@ -245,19 +383,30 @@ static ERRCODE GoTop( AREAP pArea ) static ERRCODE Info( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) { - HB_SYMBOL_UNUSED( pArea ); - switch( uiIndex ) { case DBI_TABLEEXT: hb_itemPutC( pItem, ".DBF" ); break; + + case DBI_GETLOCKARRAY: + hb_rddGetLockArray( pArea, pItem ); + break; } return SUCCESS; } static ERRCODE Lock( AREAP pArea, LPDBLOCKINFO pLockInfo ) { + if( pLockInfo->itmRecID == 0) /* UnLock all records */ + { + hb_rddUnLockAllRecords( pArea ); + if( pLockInfo->uiMethod == REC_UNLOCK ) + return SUCCESS; + + /* Get current record */ + pLockInfo->itmRecID = pArea->lpExtendInfo->pRecNo->item.asLong.value; + } if( SELF_RAWLOCK( pArea, pLockInfo->uiMethod, pLockInfo->itmRecID ) == SUCCESS ) pLockInfo->fResult = TRUE; else @@ -305,7 +454,7 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) if( uiIndex > pArea->uiFieldCount ) return FAILURE; - if( !pArea->lpExtendInfo->fExclusive && !pArea->lpExtendInfo->fFileLocked ) + if( !pArea->lpExtendInfo->fExclusive && !pArea->lpFileInfo->fFileLocked ) { pError = hb_errNew(); hb_errPutGenCode( pError, EG_UNLOCKED ); @@ -406,25 +555,19 @@ static ERRCODE PutValue( AREAP pArea, USHORT uiIndex, PHB_ITEM pItem ) static ERRCODE RawLock( AREAP pArea, USHORT uiAction, LONG lRecNo ) { - HB_SYMBOL_UNUSED( pArea ); HB_SYMBOL_UNUSED( lRecNo ); switch( uiAction ) { - } - return SUCCESS; -} + case REC_LOCK: + if( !hb_rddLockRecord( pArea, lRecNo ) ) + return FAILURE; + break; -static ERRCODE ReadBuffer( AREAP pArea, LONG lRecNo ) -{ - hb_fsSeek( pArea->lpFileInfo->hFile, pArea->lpExtendInfo->uiHeaderLen + - ( lRecNo - 1 ) * pArea->lpExtendInfo->uiRecordLen, FS_SET ); - if( hb_fsRead( pArea->lpFileInfo->hFile, pArea->lpExtendInfo->bRecord, - pArea->lpExtendInfo->uiRecordLen ) != pArea->lpExtendInfo->uiRecordLen ) - { - memset( pArea->lpExtendInfo->bRecord, ' ', pArea->lpExtendInfo->uiRecordLen ); - pArea->lpExtendInfo->bRecord[ pArea->lpExtendInfo->uiRecordLen ] = 0; - return FAILURE; + case REC_UNLOCK: + if( !hb_rddUnLockRecord( pArea, lRecNo ) ) + return FAILURE; + break; } return SUCCESS; } @@ -682,5 +825,4 @@ HARBOUR HB_DBF_GETFUNCTABLE( void ) hb_retni( hb_rddInherit( pTable, &dbfTable, &dbfSuper, 0 ) ); else hb_retni( FAILURE ); -} - +} \ No newline at end of file diff --git a/harbour/source/rdd/delim1.c b/harbour/source/rdd/delim1.c index b569d63d50..a0e4b25e6f 100644 --- a/harbour/source/rdd/delim1.c +++ b/harbour/source/rdd/delim1.c @@ -65,3 +65,4 @@ HARBOUR HB_DELIM_GETFUNCTABLE( void ) else hb_retni( FAILURE ); } +