Форум » [x]Harbour » Может кому надо ? » Ответить

Может кому надо ?

Pasha: В связи с тем, что я пока обхожусь без волшебного мира ms dos, мне потребовалась замена моему старенькому dbview Я начал ее делать, естественно на харборе Но мне нужны операции с файлом на физическом уровне, которые стандартный rdd не поддерживает: физическое удаление произвольной записи, быстрая вставка записи в середине файла. У rdd есть только 2 операции на физическом уровне: pack и zap Я для себя написал еще 3 функции: dbInsert(<nRec>, <nCount>) - вставить nCount записей перед записью nRec dbDelRecord(<nRec>, <nCount>) - удалить nCount записей после записи nRec dbTruncate(<nRec>, <nCount>) - удалить все записи после nRec Естественно, все функции работают только при монопольном открытии файла Если надо, выложу

Ответов - 3

gfilatov2002: Pasha пишет: Если надо, выложу Конечно, выкладывай! Это интересно

Andrey: gfilatov2002 пишет: Конечно, выкладывай! Это интересно Присоединяюсь !!!

Pasha: Ниже привожу сырцы этих функций. Их можно включить в prg с помощью #pragma BEGINDUMP, или оформить в виде отдельного c модуля. Эти функции не обновляют индекс, так что при их использовании индекс открывать не надо. Для всех функций если первый параметр опушен - используется текущая запись Для первых 2-х функций количество записей по умолчанию равно 1 [pre]#pragma BEGINDUMP #include "hbapi.h" #include "hbapiitm.h" #include "hbapirdd.h" #include "hbrdddbf.h" HB_FUNC( DBINSERT ) { DBFAREAP pArea = ( DBFAREAP ) hb_rddGetCurrentWorkAreaPointer(); BOOL bOk = TRUE; if( pArea && ! pArea->fReadonly && ! pArea->fShared ) { ULONG ulRec, ulCount = ISNUM(2) ? hb_parnl(2) : 1; if( ISNUM(1) ) ulRec = hb_parnl(1); else SELF_RECNO( ( AREAP ) pArea, &ulRec ); if( ulRec == 0 || ulRec > pArea->ulRecCount ) bOk = FALSE; if( bOk && SELF_GOCOLD( ( AREAP ) pArea ) != SUCCESS ) bOk = FALSE; else { char pData; ULONG ulIndex; for( ulIndex = 0; ulIndex < ulCount; ulIndex ++) SELF_APPEND( ( AREAP ) pArea, TRUE ); SELF_FLUSH( ( AREAP ) pArea ); if( bOk ) { ULONG ulLen = (pArea->ulRecCount - ulRec) * pArea->uiRecordLen; ULONG ulLen1 = ulCount*pArea->uiRecordLen; ULONG ulRecNo; char * pData = hb_xgrab( ulLen + 1 ); char * pZero = hb_xgrab( ulLen1 + 1 ); hb_fsSeekLarge( pArea->hDataFile, ( HB_FOFFSET ) pArea->uiHeaderLen + ( HB_FOFFSET ) pArea->uiRecordLen * ( HB_FOFFSET ) (ulRec - 1), FS_SET ); hb_fsReadLarge( pArea->hDataFile, pData, ulLen ); hb_fsSeekLarge( pArea->hDataFile, ( HB_FOFFSET ) pArea->uiHeaderLen + ( HB_FOFFSET ) pArea->uiRecordLen * ( HB_FOFFSET ) (pArea->ulRecCount - ulCount), FS_SET ); hb_fsReadLarge( pArea->hDataFile, pZero, ulLen1 ); hb_fsSeekLarge( pArea->hDataFile, ( HB_FOFFSET ) pArea->uiHeaderLen + ( HB_FOFFSET ) pArea->uiRecordLen * ( HB_FOFFSET ) (ulRec - 1), FS_SET ); hb_fsWriteLarge( pArea->hDataFile, pZero, ulLen1 ); hb_fsSeekLarge( pArea->hDataFile, ( HB_FOFFSET ) pArea->uiHeaderLen + ( HB_FOFFSET ) pArea->uiRecordLen * ( HB_FOFFSET ) (ulRec + ulCount - 1), FS_SET ); hb_fsWriteLarge( pArea->hDataFile, pData, ulLen ); hb_xfree( pData ); hb_xfree( pZero ); SELF_GOTO( ( AREAP ) pArea, ulRec ); } } if( bOk && SELF_GOTO( ( AREAP ) pArea, ulRec ) != SUCCESS ) bOk = FALSE; } hb_retl( bOk ); } HB_FUNC( DBDELRECORD ) { DBFAREAP pArea = ( DBFAREAP ) hb_rddGetCurrentWorkAreaPointer(); BOOL bOk = TRUE; if( pArea && ! pArea->fReadonly && ! pArea->fShared ) { ULONG ulRec, ulCount = ISNUM(2) ? hb_parnl(2) : 1; if( ISNUM(1) ) ulRec = hb_parnl(1); else SELF_RECNO( ( AREAP ) pArea, &ulRec ); if( ulRec == 0 || (ulRec + ulCount - 1) > pArea->ulRecCount ) bOk = FALSE; if( bOk && SELF_GOCOLD( ( AREAP ) pArea ) != SUCCESS ) bOk = FALSE; else { char pData; if( (ulRec + ulCount - 1) < pArea->ulRecCount ) { ULONG ulLen = (pArea->ulRecCount - (ulRec + ulCount - 1)) * pArea->uiRecordLen; char * pData = hb_xgrab( ulLen + 1 ); hb_fsSeekLarge( pArea->hDataFile, ( HB_FOFFSET ) pArea->uiHeaderLen + ( HB_FOFFSET ) pArea->uiRecordLen * ( HB_FOFFSET ) (ulRec + ulCount - 1), FS_SET ); hb_fsReadLarge( pArea->hDataFile, pData, ulLen ); hb_fsSeekLarge( pArea->hDataFile, ( HB_FOFFSET ) pArea->uiHeaderLen + ( HB_FOFFSET ) pArea->uiRecordLen * ( HB_FOFFSET ) (ulRec - 1), FS_SET ); hb_fsWriteLarge( pArea->hDataFile, pData, ulLen ); hb_xfree( pData ); } pArea->fUpdateHeader = TRUE; pArea->ulRecCount -= ulCount; } if( bOk && SELF_WRITEDBHEADER( ( AREAP ) pArea ) != SUCCESS ) bOk = FALSE; if( bOk && SELF_GOTO( ( AREAP ) pArea, ulRec ) != SUCCESS ) bOk = FALSE; } hb_retl( bOk ); } HB_FUNC( DBTRUNCATE ) { DBFAREAP pArea = ( DBFAREAP ) hb_rddGetCurrentWorkAreaPointer(); BOOL bOk = TRUE; ULONG ulRec = hb_parnl(1); if( pArea && ! pArea->fReadonly && ! pArea->fShared ) { if( ISNUM(1) ) ulRec = hb_parnl(1); else SELF_RECNO( ( AREAP ) pArea, &ulRec ); if( ulRec == 0 || ulRec > pArea->ulRecCount ) bOk = FALSE; if( bOk && SELF_GOCOLD( ( AREAP ) pArea ) != SUCCESS ) bOk = FALSE; else { pArea->fUpdateHeader = TRUE; pArea->ulRecCount = ulRec; } if( bOk && SELF_WRITEDBHEADER( ( AREAP ) pArea ) != SUCCESS ) bOk = FALSE; if( bOk && SELF_GOTO( ( AREAP ) pArea, ulRec ) != SUCCESS ) bOk = FALSE; } hb_retl( bOk ); } #pragma ENDDUMP[/pre]




полная версия страницы