diff --git a/harbour/ChangeLog b/harbour/ChangeLog index f22ed189b5..f1cff6ffb2 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,8 @@ +2000-12-09 14:09 UTC-0800 Brian Hays + * source/rdd/dbfntx/dbfntx1.c + * More fixes by Alexander + Index creation works now + 2000-12-10 15:50 GMT -3 Luiz Rafael Culik *makefile.bc hb_slex.bc diff --git a/harbour/include/hbrddntx.h b/harbour/include/hbrddntx.h index 5fd0821851..d15983308d 100644 --- a/harbour/include/hbrddntx.h +++ b/harbour/include/hbrddntx.h @@ -64,6 +64,14 @@ extern "C" { #define NTX_MEMOEXT ".dbt" #define NTX_INDEXEXT ".ntx" +/* DBFNTX constants declarations */ +#define TOP_RECORD 1 +#define BTTM_RECORD 2 +#define PREV_RECORD 3 +#define NEXT_RECORD 4 +#define NTX_MAX_REC_NUM 0x7FFFFFFFL +#define NTX_IGNORE_REC_NUM -1 + /* forward declarations */ struct _RDDFUNCS; @@ -94,14 +102,6 @@ typedef struct HB_PAGEINFO_STRU BOOL ChkBOF; BOOL ChkEOF; BYTE PageType; - LONG RNMask; - BYTE ReqByte; - BYTE RNBits; - BYTE DCBits; - BYTE TCBits; - BYTE DCMask; - BYTE TCMask; - USHORT Space; LPKEYINFO pKeys; USHORT uiKeys; SHORT CurKey; @@ -149,7 +149,6 @@ typedef struct _NTXINDEX struct _NTXAREA * Owner; FHANDLE DiskFile; LPTAGINFO CompoundTag; - LPTAGINFO TagList; struct _NTXINDEX * pNext; /* The next index in the list */ } NTXINDEX; @@ -234,6 +233,7 @@ typedef struct _NTXAREA * example. */ + USHORT uiOrder; /* Number of current order */ LPNTXINDEX lpNtxIndex; /* Pointer to indexes array */ @@ -255,11 +255,11 @@ typedef NTXAREA * LPNTXAREA; #define ntxBof NULL #define ntxEof NULL #define ntxFound NULL -#define ntxGoBottom NULL +static ERRCODE ntxGoBottom( NTXAREAP pArea ); #define ntxGoTo NULL #define ntxGoToId NULL -#define ntxGoTop NULL -#define ntxSeek NULL +static ERRCODE ntxGoTop( NTXAREAP pArea ); +static ERRCODE ntxSeek( NTXAREAP pArea, BOOL bSoftSeek, PHB_ITEM pKey, BOOL bFindLast ); #define ntxSkip NULL #define ntxSkipFilter NULL #define ntxSkipRaw NULL @@ -318,7 +318,7 @@ static ERRCODE ntxOrderListAdd( NTXAREAP pArea, LPDBORDERINFO pOrderInfo ); static ERRCODE ntxOrderListClear( NTXAREAP pArea ); /* Close all indexes */ #define ntxOrderListDelete NULL -#define ntxOrderListFocus NULL +static ERRCODE ntxOrderListFocus( NTXAREAP pArea, LPDBORDERINFO pOrderInfo ); #define ntxOrderListRebuild NULL #define ntxOrderCondition NULL static ERRCODE ntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo ); diff --git a/harbour/source/rdd/dbfntx/dbfntx1.c b/harbour/source/rdd/dbfntx/dbfntx1.c index d27fb68924..0c172350c5 100644 --- a/harbour/source/rdd/dbfntx/dbfntx1.c +++ b/harbour/source/rdd/dbfntx/dbfntx1.c @@ -113,6 +113,7 @@ static void hb_ntxPageDump( LPPAGEINFO pPage ); #endif /* Internal functions */ +static LPNTXINDEX ntxFindCurrentIndex( NTXAREAP pArea ); static ERRCODE hb_ntxHeaderLoad( LPNTXINDEX pIndex , char * ITN ); /* Load NTX header an fill structures pIndex */ static void hb_ntxHeaderSave( LPNTXINDEX pIndex ); @@ -130,8 +131,6 @@ static LPTAGINFO hb_ntxTagNew( LPNTXINDEX PIF, char * ITN, char *szKeyExpr, PHB_ITEM pForExp, BOOL fAscendKey, BOOL fUnique ); /* Create Compound Tag with information about index */ -static LPPAGEINFO hb_ntxIndexRootPageLoad( LPNTXINDEX pIndex ); - /* Load root page of index */ static LPPAGEINFO hb_ntxPageNew(LPTAGINFO pParentTag, LPPAGEINFO pParentPage ); /* Allocate space for new page */ static void hb_ntxPageFree( LPPAGEINFO pPage ); @@ -144,8 +143,8 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level); /* Add key to page */ static ERRCODE hb_ntxPageKeyInsert( LPPAGEINFO pPage, PHB_ITEM pKey, int pos ); /* Insert page in position pos */ -static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2 ); - /* Compare 2 Keys (They mus be keys !!! */ +static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2, BOOL Exact ); + /* Compare 2 Keys (They must be keys !!! */ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level, int pos ); /* Implementation of functions for debug this module */ @@ -181,7 +180,7 @@ static void hb_ntxIndexDump( LPNTXINDEX pIndex ) { LPPAGEINFO pPage; - pPage = hb_ntxIndexRootPageLoad( pIndex ); + pPage = hb_ntxPageLoad( NULL,0 ); if( pPage ) { hb_ntxPageDump( pPage ); @@ -199,10 +198,262 @@ static void backcpy( BYTE* dest, BYTE* src, long mlen ) /* Implementation of internal functions */ -static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2 ) +static LPKEYINFO hb_ntxKeyNew( void ) { - int iLimit, iResult; - int EndPos = 0; + LPKEYINFO pKey; + + pKey = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) ); + pKey->pItem = hb_itemNew( NULL ); + pKey->Tag = pKey->Xtra = 0; + pKey->pNext = NULL; + return pKey; +} + +static void hb_ntxKeyFree( LPKEYINFO pKey ) +{ + hb_itemRelease( pKey->pItem ); + hb_xfree( pKey ); +} + +static int hb_ntxPageSeekKey( LPPAGEINFO pPage, LONG lBlock, LPKEYINFO pKey, BOOL bExact ) +{ + int k = 1, kChild; + LPKEYINFO p; + LPPAGEINFO pChildPage; + + bExact = ( bExact || pPage->TagParent->KeyType != 'C' ); + pPage->CurKey = 0; + if( pPage->uiKeys > 0 ) + { + while( k > 0 && pPage->CurKey < pPage->uiKeys ) + { + p = pPage->pKeys + pPage->CurKey; + k = hb_ntxItemCompare( pKey->pItem, p->pItem, bExact ); + if( !pPage->TagParent->AscendKey ) + k = -k; + if( k == 0 && lBlock == NTX_MAX_REC_NUM ) + k = 1; + if( k == 0 && lBlock != NTX_IGNORE_REC_NUM ) + { + if( lBlock > p->Xtra ) + k = 1; + else if( lBlock < p->Xtra ) + k = -1; + } + if( k <= 0 || pPage->CurKey == pPage->uiKeys - 1 ) /* pKey <= p */ + { + if( k == 0 ) + pKey->Xtra = p->Xtra; + if( p->Tag ) + { + pChildPage = hb_ntxPageLoad( pPage, p->Tag ); + kChild = hb_ntxPageSeekKey( pChildPage, lBlock, pKey, bExact ); + if( k != 0 || kChild == 0 ) + k = kChild; + } + else if( k == 0 && lBlock != NTX_IGNORE_REC_NUM ) + { + if( lBlock > p->Tag ) + k = 1; + else if( lBlock < p->Tag ) + k = -1; + } + } + if( k > 0 ) + pPage->CurKey++; + } + } + hb_ntxPageFree( pPage ); + return k; +} + +static LONG hb_ntxTagKeyFind( LPTAGINFO pTag, LPKEYINFO pKey ) +{ + int K; + LPKEYINFO stot; + + pTag->CurKeyInfo->Tag = 0; + stot = hb_ntxKeyNew(); + hb_itemCopy( stot->pItem, pKey->pItem ); + stot->Tag = pKey->Tag; + stot->Xtra = pKey->Xtra; + if( pTag->KeyType == 'C' ) + { + while( stot->pItem->item.asString.length > 0 && + stot->pItem->item.asString.value[ stot->pItem->item.asString.length - 1 ] == ' ' ) + stot->pItem->item.asString.length--; + stot->pItem->item.asString.value[ stot->pItem->item.asString.length ] = 0; + } + pTag->TagBOF = pTag->TagEOF = FALSE; + K = hb_ntxPageSeekKey( hb_ntxPageLoad( 0,0 ), stot->Tag, stot, FALSE ); + if( K == 0 ) + { + if( pTag->pForItem == NULL ) + { + K = stot->Xtra; + hb_ntxKeyFree( stot ); + return K; + } + else + /* TODO: test for expression */ + pTag->TagEOF = TRUE; + } + else if( K < 0 ) + { + if( pTag->pForItem != NULL ) + /* TODO: test for expression */ + pTag->TagEOF = TRUE; + } + else + pTag->TagEOF = TRUE; + hb_ntxKeyFree( stot ); + return 0; +} + +static BOOL hb_ntxPageReadTopKey( LPPAGEINFO pPage, ULONG ulOffset ) +{ + LPPAGEINFO pChildPage; + LPKEYINFO pKey; + + pChildPage = hb_ntxPageLoad( pPage, ulOffset ); + if( pPage ) + hb_ntxPageFree( pPage ); + if( pChildPage != NULL ) + { + pKey = pChildPage->pKeys; + ulOffset = pKey->Tag; + if( ulOffset ) + return hb_ntxPageReadTopKey( pChildPage,ulOffset ); + else + { + hb_itemCopy( pChildPage->TagParent->CurKeyInfo->pItem, pKey->pItem ); + pChildPage->TagParent->CurKeyInfo->Xtra = pKey->Xtra; + hb_ntxPageFree( pChildPage ); + return TRUE; + } + } + else + return FALSE; +} + +static BOOL hb_ntxPageReadBottomKey( LPPAGEINFO pPage, ULONG ulOffset ) +{ + LPPAGEINFO pChildPage; + LPKEYINFO pKey; + + pChildPage = hb_ntxPageLoad( pPage, ulOffset ); + if( pPage ) + hb_ntxPageFree( pPage ); + if( pChildPage != NULL ) + { + pKey = pChildPage->pKeys + pChildPage->uiKeys; + ulOffset = pKey->Tag; + if( ulOffset ) + return hb_ntxPageReadBottomKey( pChildPage,ulOffset ); + else + { + pKey -= 1; + hb_itemCopy( pChildPage->TagParent->CurKeyInfo->pItem, pKey->pItem ); + pChildPage->TagParent->CurKeyInfo->Xtra = pKey->Xtra; + hb_ntxPageFree( pChildPage ); + return TRUE; + } + } + else + return FALSE; +} + + +static void hb_ntxTagKeyRead( LPTAGINFO pTag, BYTE bTypRead ) +{ + pTag->CurKeyInfo->Tag = 0; + if( !pTag->AscendKey ) + { + switch( bTypRead ) + { + case TOP_RECORD: + bTypRead = BTTM_RECORD; + break; + + case BTTM_RECORD: + bTypRead = TOP_RECORD; + break; + + case NEXT_RECORD: + bTypRead = PREV_RECORD; + break; + + case PREV_RECORD: + bTypRead = NEXT_RECORD; + break; + } + } + pTag->TagBOF = pTag->TagEOF = FALSE; + switch( bTypRead ) + { + case TOP_RECORD: + if( pTag->pForItem != NULL ) + printf( "hb_ntxTagKeyRead()" ); + else + pTag->TagBOF = !hb_ntxPageReadTopKey( NULL,0 ); + if( pTag->pForItem != NULL ) + printf( "hb_ntxTagTestRange()" ); + if( pTag->TagEOF ) + pTag->TagBOF = TRUE; + pTag->TagEOF = pTag->TagBOF; + break; + + case BTTM_RECORD: + if( pTag->pForItem != NULL ) + printf( "hb_ntxTagKeyRead()" ); + else + pTag->TagEOF = !hb_ntxPageReadBottomKey( NULL,0 ); + if( pTag->pForItem != NULL ) + printf( "hb_ntxTagTestRange()" ); + if( pTag->TagBOF ) + pTag->TagEOF = TRUE; + pTag->TagBOF = pTag->TagEOF; + break; + + case NEXT_RECORD: + while( TRUE ) + { + /* pTag->TagEOF = !hb_ntxPageReadNextKey( pTag->RootPage ); */ + if( pTag->pForItem != NULL ) + printf( "hb_ntxTagKeyRead()" ); + else + break; + } + break; + + case PREV_RECORD: + while( TRUE ) + { + /* pTag->TagBOF = !hb_ntxPageReadPrevKey( pTag->RootPage ); */ + if( pTag->pForItem != NULL ) + printf( "hb_ntxTagKeyRead()" ); + else + break; + } + break; + + } + if( pTag->TagBOF || pTag->TagEOF ) + { + if( !pTag->AscendKey ) + { + pTag->CurKeyInfo->Xtra = pTag->TagEOF; + pTag->TagEOF = pTag->TagBOF; + pTag->TagBOF = ( BOOL ) pTag->CurKeyInfo->Xtra; + } + pTag->CurKeyInfo->Xtra = 0; + } +} + +static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2, BOOL Exact ) +{ + int iLimit, iResult, i; + USHORT EndPos = 0; if( pKey2 == NULL || pKey2->item.asString.length == 0 ) return 1; @@ -219,14 +470,35 @@ static int hb_ntxItemCompare( PHB_ITEM pKey1, PHB_ITEM pKey2 ) { iResult = pKey1->item.asString.value[ EndPos ] - pKey2->item.asString.value[ EndPos ]; - EndPos += 1; + EndPos++; } while( iResult == 0 && EndPos < iLimit ); if( iResult == 0 ) { - iResult = pKey1->item.asString.length - - pKey2->item.asString.length; + EndPos++; + if( ( iResult = pKey1->item.asString.length - + pKey2->item.asString.length ) != 0 ) + { + if( iResult > 0 ) + { + i = pKey1->item.asString.length; + while( i > iLimit && + pKey1->item.asString.value[ i - 1 ] == ' ' ) + i--; + } + else + { + i = pKey2->item.asString.length; + while( i > iLimit && + pKey2->item.asString.value[ i - 1 ] == ' ' ) + i--; + } + if( i == iLimit ) + iResult = 0; + } } + if( iResult < 0 && EndPos > pKey1->item.asString.length && !Exact ) + iResult = 0; break; default: iResult = 0; @@ -252,10 +524,13 @@ static void hb_ntxPageSave( LPPAGEINFO pPage ) pKey = pPage->pKeys; itemlist = ( LPNTXBUFFER ) buffer; itemlist->item_count = pPage->uiKeys; + for( i = 0; i < pPage->uiKeys; i++ ) { itemlist->item_offset[i] = 2 + 2 * ( pPage->TagParent->MaxKeys + 1 ) + i * ( pPage->TagParent->KeyLength + 8 ); + + item=(NTXITEM *)(buffer+itemlist->item_offset[i]); item->page = pKey[i].Tag; item->rec_no = pKey[i].Xtra; @@ -274,23 +549,44 @@ static LPPAGEINFO hb_ntxPageLoad( LPPAGEINFO pParentPage, ULONG ulOffset ) { char buffer[NTXBLOCKSIZE]; int i, uiCount; + NTXAREAP pArea; + LPNTXINDEX pIndex; LPNTXBUFFER itemlist; LPNTXITEM item; LPPAGEINFO pPage; /* printf( "\nntxPageLoad - 0" ); */ - hb_fsSeek( pParentPage->TagParent->Owner->DiskFile, ulOffset, FS_SET ); - uiCount = hb_fsRead( pParentPage->TagParent->Owner->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE ); + if( !pParentPage ) + { + pArea = (NTXAREAP) hb_rddGetCurrentWorkAreaPointer(); + pIndex = ntxFindCurrentIndex( pArea ); + hb_fsSeek( pIndex->DiskFile, pIndex->CompoundTag->RootBlock, FS_SET ); + uiCount = hb_fsRead( pIndex->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE ); + } + else + { + hb_fsSeek( pParentPage->TagParent->Owner->DiskFile, ulOffset, FS_SET ); + uiCount = hb_fsRead( pParentPage->TagParent->Owner->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE ); + } if( uiCount != NTXBLOCKSIZE ) { return NULL; } pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) ); memset( pPage , 0 ,sizeof( HB_PAGEINFO ) ); - pPage->TagParent = pParentPage->TagParent; - pPage->Owner = pParentPage; + if( !pParentPage ) + { + pPage->TagParent = pIndex->CompoundTag; + pPage->Owner = NULL; + pPage->Page = pIndex->CompoundTag->RootBlock; + } + else + { + pPage->TagParent = pParentPage->TagParent; + pPage->Owner = pParentPage; + pPage->Page = ulOffset; + } pPage->CurKey = -1; - pPage->Page = ulOffset; pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) ); memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) ); @@ -365,7 +661,7 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev if( pos > pPage->TagParent->MaxKeys ) { memmove( pNewPage->pKeys , pPage->pKeys, - ( pPage->uiKeys ) * sizeof( KEYINFO ) + sizeof( pPage->pKeys->Tag ) ); + ( pPage->uiKeys + 1 ) * sizeof( KEYINFO ) ); pNewPage->uiKeys = pPage->uiKeys; pPage->uiKeys = 1; pPage->pKeys[0].Tag = pNewPage->Page; @@ -374,6 +670,7 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev /* printf( "\nntxPageAddPageKeyAdd - 2( %s %d %d )", hb_itemGetCPtr( pKey ),level,pos ); */ } else + { nBegin = pos; nCount = 0; @@ -413,9 +710,8 @@ static ERRCODE hb_ntxPageAddPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int lev static ERRCODE hb_ntxPageKeyInsert( LPPAGEINFO pPage, PHB_ITEM pKey, int pos ) { - int i; /* printf( "\nntxPageKeyInsert ( %d %s )", pos,hb_itemGetCPtr( pKey ) ); */ - backcpy( pPage->pKeys + pos + 1 , pPage->pKeys + pos , + backcpy( (BYTE*)(pPage->pKeys + pos + 1) , (BYTE*)(pPage->pKeys + pos) , ( pPage->uiKeys - pos + 1 ) * sizeof( KEYINFO ) ); pPage->uiKeys++; pPage->Changed = TRUE; @@ -442,7 +738,7 @@ static ERRCODE hb_ntxPageKeyAdd( LPPAGEINFO pPage, PHB_ITEM pKey, int level) } while( i < pPage->uiKeys ) { - cmp = hb_ntxItemCompare( pPage->pKeys[ i ].pItem , pKey ); + cmp = hb_ntxItemCompare( pPage->pKeys[ i ].pItem , pKey, TRUE ); if( cmp > 0 ) { if( pPage->uiKeys == pPage->TagParent->MaxKeys && pPage->pKeys[i].Tag == 0 ) @@ -517,8 +813,10 @@ static ERRCODE hb_ntxTagKeyAdd( LPTAGINFO pTag, PHB_ITEM pKey) return SUCCESS; } + static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex ) { + ULONG ulRecNo, ulRecCount; USHORT uiCurLen; NTXAREAP pArea; @@ -530,6 +828,7 @@ static ERRCODE hb_ntxIndexCreate( LPNTXINDEX pIndex ) LPPAGEINFO pPage; ulRecCount = ( pIndex->Owner->ulRecCount > 200 ) ? 200 : + pIndex->Owner->ulRecCount; #else ulRecCount = pIndex->Owner->ulRecCount; @@ -623,6 +922,7 @@ static void hb_ntxHeaderSave( LPNTXINDEX pIndex ) Header.next_page = pIndex->NextAvail; Header.item_size = pIndex->CompoundTag->KeyLength+8; + Header.key_size = pIndex->CompoundTag->KeyLength; Header.key_dec = 0; Header.max_item = pIndex->CompoundTag->MaxKeys; @@ -641,9 +941,10 @@ static LPTAGINFO hb_ntxTagNew( LPNTXINDEX PIF, char * ITN, char *szKeyExpr, PHB_ pTag = ( LPTAGINFO ) hb_xgrab( sizeof( TAGINFO ) ); memset( pTag, 0, sizeof( TAGINFO ) ); - // pTag->TagName = (char *) hb_xgrab( strlen( ITN ) + 1 ); - - // hb_strncpyUpper( pTag->TagName, ITN, strlen( ITN ) + 1 ); + /* + pTag->TagName = (char *) hb_xgrab( strlen( ITN ) + 1 ); + hb_strncpyUpper( pTag->TagName, ITN, strlen( ITN ) + 1 ); + */ pTag->TagName = ITN; if( szKeyExpr ) { @@ -663,6 +964,7 @@ static LPTAGINFO hb_ntxTagNew( LPNTXINDEX PIF, char * ITN, char *szKeyExpr, PHB_ pTag->KeyLength = uiKeyLen; pTag->Owner = PIF; pTag->MaxKeys = (NTXBLOCKSIZE-6)/(uiKeyLen+10) - 1; + pTag->CurKeyInfo = hb_ntxKeyNew(); return pTag; } @@ -711,9 +1013,14 @@ static void hb_ntxIndexFree( LPNTXINDEX pIndex ) if( pTag->ForExpr != NULL ) hb_xfree( pTag->ForExpr ); if( pTag->pKeyItem != NULL ) + { + if( hb_itemType( pTag->pKeyItem ) != HB_IT_BLOCK ) + hb_macroDelete( ( HB_MACRO_PTR ) hb_itemGetPtr( pTag->pKeyItem ) ); hb_itemRelease( pTag->pKeyItem ); + } if( pTag->pForItem != NULL ) hb_itemRelease( pTag->pForItem ); + hb_ntxKeyFree( pTag->CurKeyInfo ); hb_xfree( pTag ); hb_xfree( pIndex->IndexName ); hb_xfree( pIndex ); @@ -738,7 +1045,7 @@ static ERRCODE hb_ntxHeaderLoad( LPNTXINDEX pIndex , char *ITN) pIndex->NextAvail = Header.next_page; pTag->RootBlock = Header.root; pTag->TagName = (char *) hb_xgrab( strlen( ITN ) + 1 ); - hb_strncpyUpper( pTag->TagName, ITN, strlen( ITN ) + 1 ); + hb_strncpyUpper( pTag->TagName, ITN, strlen( ITN ) ); pTag->KeyExpr = (char *) hb_xgrab( NTX_MAX_KEY ); strcpy( pTag->KeyExpr, Header.key_expr ); pTag->pKeyItem = pExpr; @@ -748,56 +1055,16 @@ static ERRCODE hb_ntxHeaderLoad( LPNTXINDEX pIndex , char *ITN) pTag->KeyLength = Header.key_size; pTag->Owner = pIndex; pTag->MaxKeys = Header.max_item; + pTag->CurKeyInfo = hb_ntxKeyNew(); return SUCCESS; } -static LPPAGEINFO hb_ntxIndexRootPageLoad( LPNTXINDEX pIndex ) -{ - char buffer[NTXBLOCKSIZE]; - int uiCount; - int i; - LPNTXBUFFER itemlist; - - LPNTXITEM item; - LPPAGEINFO pPage; - - - hb_fsSeek( pIndex->DiskFile, pIndex->CompoundTag->RootBlock, FS_SET ); - uiCount = hb_fsRead( pIndex->DiskFile, ( BYTE * ) buffer, NTXBLOCKSIZE ); - if( uiCount != NTXBLOCKSIZE ) - { - return NULL; - } - pPage = ( LPPAGEINFO ) hb_xgrab( sizeof( HB_PAGEINFO ) ); - memset( pPage , 0 ,sizeof( HB_PAGEINFO ) ); - pPage->TagParent = pIndex->CompoundTag; - pPage->Owner = NULL; - pPage->CurKey = -1; - pPage->Page = pIndex->CompoundTag->RootBlock; - pPage->pKeys = ( LPKEYINFO ) hb_xgrab( sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) ); - memset( pPage->pKeys, 0, sizeof( KEYINFO ) * ( pPage->TagParent->MaxKeys + 1 ) ); - itemlist = ( LPNTXBUFFER ) buffer; - pPage->uiKeys = itemlist->item_count; - - for( i = 0; i < itemlist->item_count; i++ ) - { - item=(NTXITEM *)(buffer+itemlist->item_offset[i]); - pPage->pKeys[i].Xtra = item->rec_no; - pPage->pKeys[i].Tag = item->page; - pPage->pKeys[i].pItem = hb_itemNew( NULL ); - hb_itemPutCL( pPage->pKeys[i].pItem, item->key, pPage->TagParent->KeyLength ); - } - item=(NTXITEM *)(buffer+itemlist->item_offset[i]); - pPage->pKeys[i].Tag = item->page; - return pPage; -} - static LPNTXINDEX ntxFindIndex( NTXAREAP pArea , PHB_ITEM lpOrder ) { LPNTXINDEX start, current; start = pArea->lpNtxIndex; - current=start; + current = start; if( hb_itemType( lpOrder ) == HB_IT_STRING ) { do @@ -819,8 +1086,123 @@ static LPNTXINDEX ntxFindIndex( NTXAREAP pArea , PHB_ITEM lpOrder ) return NULL; } +static LPNTXINDEX ntxFindCurrentIndex( NTXAREAP pArea ) +{ + LPNTXINDEX pIndex; + + if ( !pArea->uiOrder || !pArea->lpNtxIndex ) + return NULL; + + pIndex = pArea->lpNtxIndex; + do + { + if( pIndex->TagRoot == pArea->uiOrder ) + break; + pIndex = pIndex->pNext; + } while( pIndex ); + return pIndex; +} + /* Implementation of exported functions */ +static ERRCODE ntxGoBottom( NTXAREAP pArea ) +{ + HB_TRACE(HB_TR_DEBUG, ("ntxGoBottom(%p)", pArea)); + + if ( !pArea->uiOrder || !pArea->lpNtxIndex ) + SUPER_GOBOTTOM( ( AREAP ) pArea ); + else + { + LPTAGINFO pTag; + + pTag = pArea->lpNtxIndex->CompoundTag; + hb_ntxTagKeyRead( pTag, BTTM_RECORD ); + SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ); + } + return SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); +} + +static ERRCODE ntxGoTop( NTXAREAP pArea ) +{ + HB_TRACE(HB_TR_DEBUG, ("ntxGoTop(%p)", pArea)); + + if ( !pArea->uiOrder || !pArea->lpNtxIndex ) + SUPER_GOTOP( ( AREAP ) pArea ); + else + { + LPTAGINFO pTag; + + pTag = pArea->lpNtxIndex->CompoundTag; + hb_ntxTagKeyRead( pTag, TOP_RECORD ); + SELF_GOTO( ( AREAP ) pArea, pTag->CurKeyInfo->Xtra ); + } + return SELF_SKIPFILTER( ( AREAP ) pArea, 1 ); +} + +static ERRCODE ntxSeek( NTXAREAP pArea, BOOL bSoftSeek, PHB_ITEM pKey, BOOL bFindLast ) +{ + PHB_ITEM pError; + ERRCODE retvalue; + HB_TRACE(HB_TR_DEBUG, ("ntxSeek(%p, %d, %p, %d)", pArea, bSoftSeek, pKey, bFindLast)); + + if ( ! pArea->lpNtxIndex ) + { + pError = hb_errNew(); + hb_errPutGenCode( pError, EG_NOORDER ); + hb_errPutSubCode( pError, 1020 ); + hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_NOORDER ) ); + hb_errPutFlags( pError, EF_CANDEFAULT ); + SELF_ERROR( ( AREAP ) pArea, pError ); + hb_errRelease( pError ); + return FAILURE; + } + else + { + LONG lRecno; + LPKEYINFO pKey2; + LPTAGINFO pTag = pArea->lpNtxIndex->CompoundTag; + USHORT uiOrder; + ERRCODE result; + + pKey2 = hb_ntxKeyNew(); + hb_itemCopy( pKey2->pItem, pKey ); + if ( bFindLast ) + pKey2->Tag = NTX_MAX_REC_NUM; + else + pKey2->Tag = NTX_IGNORE_REC_NUM; + pKey2->Xtra = 0; + + lRecno = hb_ntxTagKeyFind( pTag, pKey2 ); + pArea->fEof = pTag->TagEOF; + pArea->fBof = pTag->TagBOF; + hb_ntxKeyFree( pKey2 ); + if ( lRecno > 0 ) + { + retvalue = SELF_GOTO( ( AREAP ) pArea, lRecno ); + pArea->fFound = TRUE; + return retvalue; + } + else + { + pArea->fFound = FALSE; + if ( bSoftSeek && !pTag->TagEOF ) + { + return SELF_GOTO( ( AREAP ) pArea, lRecno ); + } + else + { + uiOrder = pArea->uiOrder; + pArea->uiOrder = 0; + SELF_GOBOTTOM( ( AREAP ) pArea ); + result = SELF_SKIPRAW( ( AREAP ) pArea, 1 ); + pArea->uiOrder = uiOrder; + return result; + } + } + } + return SUCCESS; +} + /* * Retrieve the size of the WorkArea structure. */ @@ -848,6 +1230,7 @@ static ERRCODE ntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo ) HB_TRACE(HB_TR_DEBUG, ("ntxOrderCreate(%p, %p)", pArea, pOrderInfo)); + SELF_ORDLSTCLEAR( ( AREAP ) pArea ); if( SELF_GOCOLD( ( AREAP ) pArea ) == FAILURE ) return FAILURE; @@ -1024,7 +1407,6 @@ static ERRCODE ntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo ) pIndex->IndexName = szFileName; pArea->lpNtxIndex = pIndex; pTag = hb_ntxTagNew( pIndex, szTagName, pOrderInfo->abExpr->item.asString.value, - pKeyExp, bType, uiLen, (char *) ( pArea->lpdbOrdCondInfo ? pArea->lpdbOrdCondInfo->abFor : NULL ), pForExp, pArea->lpdbOrdCondInfo ? !pArea->lpdbOrdCondInfo->fDescending : TRUE, pOrderInfo->fUnique ); @@ -1047,6 +1429,7 @@ static ERRCODE ntxOrderCreate( NTXAREAP pArea, LPDBORDERCREATEINFO pOrderInfo ) { return FAILURE; } + pArea->uiOrder = 1; SELF_ORDSETCOND( ( AREAP ) pArea, NULL ); return SELF_GOTOP( ( AREAP ) pArea ); @@ -1156,9 +1539,10 @@ static ERRCODE ntxOrderListAdd( NTXAREAP pArea, LPDBORDERINFO pOrderInfo ) else { pArea->lpNtxIndex = pIndex; - pIndex->pNext = pIndex; } - pArea->lpNtxIndex = pIndex; + if( !pArea->uiOrder ) + pArea->uiOrder = 1; + hb_xfree( szFileName ); hb_xfree( pFileName ); return SUCCESS; } @@ -1176,6 +1560,28 @@ static ERRCODE ntxOrderListClear( NTXAREAP pArea ) hb_ntxIndexFree( pIndex ); } pArea->lpNtxIndex = NULL; + pArea->uiOrder = 0; + return SUCCESS; +} + +static ERRCODE ntxOrderListFocus( NTXAREAP pArea, LPDBORDERINFO pOrderInfo ) +{ + LPNTXINDEX pIndex; + + HB_TRACE(HB_TR_DEBUG, ("ntxOrderListFocus(%p, %p)", pArea, pOrderInfo)); + + hb_itemPutNI( pOrderInfo->itmResult, pArea->uiOrder ); + + if( hb_itemType( pOrderInfo->itmOrder ) != HB_IT_STRING && + hb_itemGetNI( pOrderInfo->itmOrder ) == 0 ) + pArea->uiOrder = 0; + else + { + pIndex = ntxFindIndex( pArea, pOrderInfo->itmOrder ); + if( pIndex ) + pArea->uiOrder = pIndex->TagRoot; + } + return SUCCESS; } @@ -1190,11 +1596,11 @@ static ERRCODE ntxClose( NTXAREAP pArea ) static RDDFUNCS ntxTable = { ntxBof, ntxEof, ntxFound, - ntxGoBottom, + ( DBENTRYP_V ) ntxGoBottom, ntxGoTo, ntxGoToId, - ntxGoTop, - ntxSeek, + ( DBENTRYP_V ) ntxGoTop, + ( DBENTRYP_BIB ) ntxSeek, ntxSkip, ntxSkipFilter, ntxSkipRaw, @@ -1235,6 +1641,7 @@ static RDDFUNCS ntxTable = { ntxBof, ntPackRec, ntxSort, ntxTrans, + ntxTransRec, ntxZap, ntxchildEnd, @@ -1250,7 +1657,7 @@ static RDDFUNCS ntxTable = { ntxBof, ( DBENTRYP_OI ) ntxOrderListAdd, ( DBENTRYP_V ) ntxOrderListClear, ntxOrderListDelete, - ntxOrderListFocus, + ( DBENTRYP_OI ) ntxOrderListFocus, ntxOrderListRebuild, ntxOrderCondition, ( DBENTRYP_VOC ) ntxOrderCreate, @@ -1298,4 +1705,5 @@ HB_FUNC( DBFNTX_GETFUNCTABLE ) hb_retni( hb_rddInherit( pTable, &ntxTable, &ntxSuper, ( BYTE * ) "DBF" ) ); else hb_retni( FAILURE ); + } \ No newline at end of file