diff --git a/ChangeLog.txt b/ChangeLog.txt index a8695a27d0..52ae9170a8 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,29 @@ Entries may not always be in chronological/commit order. See license at the end of file. */ +2019-04-11 17:23 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * include/dbinfo.ch + * src/rdd/dbf1.c + + added DB_SETHEADER_EOL flag, it's used to force setting EOL marker + when header is written. In Harbour's DBF* RDDs is set in CLOSE() + method so just like in Clipper when DBF is closed and header has to + be updated the EOL() marker is set. + As side effect reducing header updates to minimal level (in such + case DBF header is not updated after APPEND what is safe for Harbour, + Clipper and compatible RDDs because they use file size to calculate + number of records but some other DBF drivers may be confused) + increase the APPEND speed and also forces EOL setting in all cases + when CLOSE() method is called. Header updates can be reduce to minimal + level by: + hb_rddInfo( RDDI_SETHEADER, DB_SETHEADER_MINIMAL ) + + * src/rdd/usrrdd/usrrdd.c + ! fixed GPF in UsrRDD redirector for DROP(), EXISTS() and RENAME() methods + + * src/vm/cmdarg.c + * use HB_MEM_STATISTICS instead of HB_MEM_USEDMAX to check if memory + statistic module is enabled in //info message + 2019-03-27 18:27 UTC-0300 Lailton Fernando Mariano (lailton/at/harbour.com.br) * config/android/libs.mk * utils/hbmk2/hbmk2.prg diff --git a/include/dbinfo.ch b/include/dbinfo.ch index 4c407c57c5..ab6c936492 100644 --- a/include/dbinfo.ch +++ b/include/dbinfo.ch @@ -390,12 +390,14 @@ #endif /* DBF HEADER UPDATING */ -#define DB_SETHEADER_CLOSE 0 /* update in CLOSE method - it always happens if necessary */ -#define DB_SETHEADER_COMMIT 1 /* update in FLUSH method */ -#define DB_SETHEADER_WRITE 2 /* update in GOCOLD method */ -#define DB_SETHEADER_APPEND 0 /* record append sets update header flag (always enabled) */ -#define DB_SETHEADER_REPLACE 4 /* record modification sets update header flag */ -#define DB_SETHEADER_YYEAR 16 /* store year() % 100 instead of year - 1900, FoxPro compatibility */ +#define DB_SETHEADER_CLOSE 0x00 /* update in CLOSE method - it always happens if necessary */ +#define DB_SETHEADER_COMMIT 0x01 /* update in FLUSH method */ +#define DB_SETHEADER_WRITE 0x02 /* update in GOCOLD method */ +#define DB_SETHEADER_APPEND 0x00 /* record append sets update header flag (always enabled) */ +#define DB_SETHEADER_REPLACE 0x04 /* record modification sets update header flag */ +#define DB_SETHEADER_YYEAR 0x10 /* store year() % 100 instead of year - 1900, FoxPro compatibility */ +#define DB_SETHEADER_EOL 0x20 /* set EOL when header is written, enabled in CLOSE method if header has to be updated */ +#define DB_SETHEADER_MASK 0x37 /* bits used in DB_SETHEADER_* flags */ /* update in CLOSE after append only */ #define DB_SETHEADER_MINIMAL DB_SETHEADER_CLOSE diff --git a/src/rdd/dbf1.c b/src/rdd/dbf1.c index 961c6c1c82..78d79878ce 100644 --- a/src/rdd/dbf1.c +++ b/src/rdd/dbf1.c @@ -2067,7 +2067,7 @@ static HB_ERRCODE hb_dbfFlush( DBFAREAP pArea ) errCode = SELF_WRITEDBHEADER( &pArea->area ); } - if( hb_setGetHardCommit() && errCode == HB_SUCCESS ) + if( errCode == HB_SUCCESS && hb_setGetHardCommit() ) { if( pArea->fDataFlush ) { @@ -3018,7 +3018,10 @@ static HB_ERRCODE hb_dbfClose( DBFAREAP pArea ) /* Update header */ if( pArea->fUpdateHeader ) + { + pArea->uiSetHeader |= DB_SETHEADER_EOL; SELF_WRITEDBHEADER( &pArea->area ); + } /* It's not Clipper compatible but it reduces the problem with buggy Windows network setting */ @@ -3796,7 +3799,7 @@ static HB_ERRCODE hb_dbfInfo( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem if( HB_IS_NUMERIC( pItem ) ) { int iMode = hb_itemGetNI( pItem ); - if( ( iMode & ~0xFF ) == 0 ) + if( ( iMode & ~DB_SETHEADER_MASK ) == 0 ) pArea->uiSetHeader = iMode; } hb_itemPutNI( pItem, uiSetHeader ); @@ -4113,7 +4116,7 @@ static HB_ERRCODE hb_dbfNewArea( DBFAREAP pArea ) pArea->bTableType = ( HB_BYTE ) hb_itemGetNI( pItem ); hb_itemClear( pItem ); if( SELF_RDDINFO( SELF_RDDNODE( &pArea->area ), RDDI_SETHEADER, 0, pItem ) == HB_SUCCESS ) - pArea->uiSetHeader = ( HB_BYTE ) hb_itemGetNI( pItem ); + pArea->uiSetHeader = ( HB_UINT ) hb_itemGetNI( pItem ); hb_itemRelease( pItem ); } @@ -5630,6 +5633,7 @@ static HB_ERRCODE hb_dbfZap( DBFAREAP pArea ) if( SELF_WRITEDBHEADER( &pArea->area ) != HB_SUCCESS ) return HB_FAILURE; + if( SELF_GOTO( &pArea->area, 0 ) != HB_SUCCESS ) return HB_FAILURE; @@ -6319,23 +6323,26 @@ static HB_ERRCODE hb_dbfWriteDBHeader( DBFAREAP pArea ) } pArea->ulRecCount = hb_dbfCalcRecCount( pArea ); } - else - { - /* Exclusive mode */ - /* write eof mark */ - HB_FOFFSET nOffset = ( HB_FOFFSET ) pArea->uiHeaderLen + - ( HB_FOFFSET ) pArea->uiRecordLen * - ( HB_FOFFSET ) pArea->ulRecCount; - hb_fileWriteAt( pArea->pDataFile, "\032", 1, nOffset ); - hb_fileTruncAt( pArea->pDataFile, nOffset + 1 ); - } HB_PUT_LE_UINT32( pArea->dbfHeader.ulRecCount, pArea->ulRecCount ); HB_PUT_LE_UINT16( pArea->dbfHeader.uiHeaderLen, pArea->uiHeaderLen ); HB_PUT_LE_UINT16( pArea->dbfHeader.uiRecordLen, pArea->uiRecordLen ); if( hb_fileWriteAt( pArea->pDataFile, &pArea->dbfHeader, sizeof( DBFHEADER ), 0 ) == sizeof( DBFHEADER ) ) + { errCode = HB_SUCCESS; + if( ! pArea->fShared || ( pArea->uiSetHeader & DB_SETHEADER_EOL ) != 0 ) + { + /* write eof mark */ + HB_FOFFSET nOffset = ( HB_FOFFSET ) pArea->uiHeaderLen + + ( HB_FOFFSET ) pArea->uiRecordLen * + ( HB_FOFFSET ) pArea->ulRecCount; + if( hb_fileWriteAt( pArea->pDataFile, "\032", 1, nOffset ) == 1 ) + hb_fileTruncAt( pArea->pDataFile, nOffset + 1 ); + else + errCode = HB_FAILURE; + } + } else errCode = HB_FAILURE; @@ -6708,7 +6715,7 @@ static HB_ERRCODE hb_dbfRddInfo( LPRDDNODE pRDD, HB_USHORT uiIndex, HB_ULONG ulC if( HB_IS_NUMERIC( pItem ) ) { int iMode = hb_itemGetNI( pItem ); - if( ( iMode & ~0xFF ) == 0 ) + if( ( iMode & ~DB_SETHEADER_MASK ) == 0 ) pData->uiSetHeader = ( HB_USHORT ) iMode; } hb_itemPutNI( pItem, uiSetHeader ); diff --git a/src/rdd/usrrdd/usrrdd.c b/src/rdd/usrrdd/usrrdd.c index a1e39d8351..7aeee62d07 100644 --- a/src/rdd/usrrdd/usrrdd.c +++ b/src/rdd/usrrdd/usrrdd.c @@ -2528,8 +2528,14 @@ static HB_ERRCODE hb_usrDrop( LPRDDNODE pRDD, PHB_ITEM pTable, PHB_ITEM pIndex, return SUPER_DROP( pRDD, pTable, pIndex, ulConnection ); hb_vmPushInteger( pRDD->rddID ); - hb_vmPush( pTable ); - hb_vmPush( pIndex ); + if( pTable ) + hb_vmPush( pTable ); + else + hb_vmPushNil(); + if( pIndex ) + hb_vmPush( pIndex ); + else + hb_vmPushNil(); hb_vmPushLong( ulConnection ); hb_vmDo( 4 ); @@ -2544,8 +2550,14 @@ static HB_ERRCODE hb_usrExists( LPRDDNODE pRDD, PHB_ITEM pTable, PHB_ITEM pIndex return SUPER_EXISTS( pRDD, pTable, pIndex, ulConnection ); hb_vmPushInteger( pRDD->rddID ); - hb_vmPush( pTable ); - hb_vmPush( pIndex ); + if( pTable ) + hb_vmPush( pTable ); + else + hb_vmPushNil(); + if( pIndex ) + hb_vmPush( pIndex ); + else + hb_vmPushNil(); hb_vmPushLong( ulConnection ); hb_vmDo( 4 ); @@ -2560,9 +2572,18 @@ static HB_ERRCODE hb_usrRename( LPRDDNODE pRDD, PHB_ITEM pTable, PHB_ITEM pIndex return SUPER_RENAME( pRDD, pTable, pIndex, pNewName, ulConnection ); hb_vmPushInteger( pRDD->rddID ); - hb_vmPush( pTable ); - hb_vmPush( pIndex ); - hb_vmPush( pNewName ); + if( pTable ) + hb_vmPush( pTable ); + else + hb_vmPushNil(); + if( pIndex ) + hb_vmPush( pIndex ); + else + hb_vmPushNil(); + if( pNewName ) + hb_vmPush( pNewName ); + else + hb_vmPushNil(); hb_vmPushLong( ulConnection ); hb_vmDo( 5 ); diff --git a/src/vm/cmdarg.c b/src/vm/cmdarg.c index 23daad5333..8628514b4e 100644 --- a/src/vm/cmdarg.c +++ b/src/vm/cmdarg.c @@ -843,7 +843,7 @@ void hb_cmdargProcess( void ) #if defined( HB_CLP_STRICT ) hb_snprintf( buffer, sizeof( buffer ), "DS avail=%" HB_PFS "uKB OS avail=%" HB_PFS "uKB EMM avail=%" HB_PFS "uKB", hb_xquery( HB_MEM_BLOCK ), hb_xquery( HB_MEM_VM ), hb_xquery( HB_MEM_EMS ) ); #else - hb_snprintf( buffer, sizeof( buffer ), "DS avail=%" HB_PFS "uKB OS avail=%" HB_PFS "uKB EMM avail=%" HB_PFS "uKB MemStat:%s MT:%s", hb_xquery( HB_MEM_BLOCK ), hb_xquery( HB_MEM_VM ), hb_xquery( HB_MEM_EMS ), hb_xquery( HB_MEM_USEDMAX ) ? "On" : "Off", hb_vmIsMt() ? "On" : "Off" ); + hb_snprintf( buffer, sizeof( buffer ), "DS avail=%" HB_PFS "uKB OS avail=%" HB_PFS "uKB EMM avail=%" HB_PFS "uKB MemStat:%s MT:%s", hb_xquery( HB_MEM_BLOCK ), hb_xquery( HB_MEM_VM ), hb_xquery( HB_MEM_EMS ), hb_xquery( HB_MEM_STATISTICS ) ? "On" : "Off", hb_vmIsMt() ? "On" : "Off" ); #endif hb_conOutErr( buffer, 0 ); hb_conOutErr( hb_conNewLine(), 0 );