diff --git a/harbour/ChangeLog b/harbour/ChangeLog index d8e787da6b..5c018325fa 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,13 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-03-01 13:42 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/rdd/dbfntx/dbfntx1.c + * harbour/src/rdd/dbfnsx/dbfnsx1.c + * harbour/src/rdd/dbfcdx/dbfcdx1.c + ! make linear scan in template tags to detect position of current + record in tag after GOTO() operation - SIX3 compatible behavior + 2010-03-01 08:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/src/vm/hvm.c ! added missing HB_STACK_TLS_PRELOAD diff --git a/harbour/src/rdd/dbfcdx/dbfcdx1.c b/harbour/src/rdd/dbfcdx/dbfcdx1.c index 94618ec52e..9deb70d752 100644 --- a/harbour/src/rdd/dbfcdx/dbfcdx1.c +++ b/harbour/src/rdd/dbfcdx/dbfcdx1.c @@ -5201,6 +5201,16 @@ static HB_BOOL hb_cdxCurKeyRefresh( CDXAREAP pArea, LPCDXTAG pTag ) if( memcmp( buf, pKey->val, pKey->len ) != 0 ) hb_cdxTagKeyFind( pTag, pKey ); } + if( pTag->CurKey->rec != pArea->dbfarea.ulRecNo && pTag->Template ) + { + hb_cdxTagGoTop( pTag ); + while( !pTag->TagBOF && !pTag->TagEOF && hb_cdxBottomScope( pTag ) ) + { + if( pTag->CurKey->rec == pArea->dbfarea.ulRecNo ) + break; + hb_cdxTagSkipNext( pTag ); + } + } } hb_cdxKeyFree( pKey ); return ( pTag->CurKey->rec != 0 && pTag->CurKey->rec == pArea->dbfarea.ulRecNo ); diff --git a/harbour/src/rdd/dbfnsx/dbfnsx1.c b/harbour/src/rdd/dbfnsx/dbfnsx1.c index 2621ad8a11..dc14377225 100644 --- a/harbour/src/rdd/dbfnsx/dbfnsx1.c +++ b/harbour/src/rdd/dbfnsx/dbfnsx1.c @@ -1650,6 +1650,17 @@ static HB_ULONG hb_nsxPageGetFree( LPTAGINFO pTag ) return ulPage; } +/* + * SIX3 compatible template index expression detection + */ +static HB_BOOL hb_nsxIsTemplateFunc( const char * szKeyExpr ) +{ + return hb_strnicmp( szKeyExpr, "sxChar(", 7 ) == 0 || + hb_strnicmp( szKeyExpr, "sxDate(", 7 ) == 0 || + hb_strnicmp( szKeyExpr, "sxNum(", 6 ) == 0 || + hb_strnicmp( szKeyExpr, "sxLog(", 6 ) == 0; +} + /* * create the new tag structure */ @@ -3417,61 +3428,6 @@ static HB_BOOL hb_nsxTagKeyDel( LPTAGINFO pTag, LPKEYINFO pKey ) /* ************************************************************************* */ -/* - * refresh CurKey value and set proper path from RootPage to LeafPage - */ -static HB_BOOL hb_nsxCurKeyRefresh( LPTAGINFO pTag ) -{ - NSXAREAP pArea = pTag->pIndex->pArea; - - if( pArea->dbfarea.lpdbPendingRel ) - SELF_FORCEREL( ( AREAP ) pArea ); - - if( !pArea->dbfarea.fPositioned ) - { - pTag->stackLevel = 0; - pTag->TagBOF = pTag->TagEOF = HB_TRUE; - pTag->CurKeyInfo->rec = 0; - return HB_FALSE; - } - else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo ) - { - HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer; - HB_BYTE buf[ NSX_MAXKEYLEN ]; - HB_BOOL fBuf = HB_FALSE; - LPKEYINFO pKey = NULL; - /* Try to find previous if it's key for the same record */ - if( pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo ) - { - fBuf = HB_TRUE; - memcpy( buf, pTag->CurKeyInfo->val, pTag->KeyLength ); - pKey = hb_nsxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength ); - hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength ); - } - if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo ) - { - /* not found, create new key from DBF and if differs seek again */ - pKey = hb_nsxEvalKey( pKey, pTag ); - if( !fBuf || memcmp( buf, pKey->val, pTag->KeyLength ) != 0 ) - hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength ); - /* not found, if key was generated from DBF buffer then force to - * update it, create the new key and if differs seek again */ - if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo && fValidBuf ) - { - SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo ); - memcpy( buf, pKey->val, pTag->KeyLength ); - pKey = hb_nsxEvalKey( pKey, pTag ); - if( memcmp( buf, pKey->val, pTag->KeyLength ) != 0 ) - hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength ); - } - } - hb_nsxKeyFree( pKey ); - return pTag->CurKeyInfo->rec != 0 && pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo; - } - pTag->TagBOF = pTag->TagEOF = HB_FALSE; - return HB_TRUE; -} - /* * Skip in tag respecting record filter only */ @@ -3709,6 +3665,71 @@ static void hb_nsxTagGoToRelKeyPos( LPTAGINFO pTag, double dPos ) hb_nsxTagPrevKey( pTag ); } +/* + * refresh CurKey value and set proper path from RootPage to LeafPage + */ +static HB_BOOL hb_nsxCurKeyRefresh( LPTAGINFO pTag ) +{ + NSXAREAP pArea = pTag->pIndex->pArea; + + if( pArea->dbfarea.lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + if( !pArea->dbfarea.fPositioned ) + { + pTag->stackLevel = 0; + pTag->TagBOF = pTag->TagEOF = HB_TRUE; + pTag->CurKeyInfo->rec = 0; + return HB_FALSE; + } + else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo ) + { + HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer; + HB_BYTE buf[ NSX_MAXKEYLEN ]; + HB_BOOL fBuf = HB_FALSE; + LPKEYINFO pKey = NULL; + /* Try to find previous if it's key for the same record */ + if( pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo ) + { + fBuf = HB_TRUE; + memcpy( buf, pTag->CurKeyInfo->val, pTag->KeyLength ); + pKey = hb_nsxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength ); + hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength ); + } + if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo ) + { + /* not found, create new key from DBF and if differs seek again */ + pKey = hb_nsxEvalKey( pKey, pTag ); + if( !fBuf || memcmp( buf, pKey->val, pTag->KeyLength ) != 0 ) + hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength ); + /* not found, if key was generated from DBF buffer then force to + * update it, create the new key and if differs seek again */ + if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo && fValidBuf ) + { + SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo ); + memcpy( buf, pKey->val, pTag->KeyLength ); + pKey = hb_nsxEvalKey( pKey, pTag ); + if( memcmp( buf, pKey->val, pTag->KeyLength ) != 0 ) + hb_nsxTagKeyFind( pTag, pKey, pTag->KeyLength ); + } + if( pTag->CurKeyInfo->rec != pArea->dbfarea.ulRecNo && pTag->Template ) + { + hb_nsxTagGoTop( pTag ); + while( !pTag->TagEOF ) + { + if( pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo ) + break; + hb_nsxTagSkipNext( pTag ); + } + } + } + hb_nsxKeyFree( pKey ); + return pTag->CurKeyInfo->rec != 0 && pTag->CurKeyInfo->rec == pArea->dbfarea.ulRecNo; + } + pTag->TagBOF = pTag->TagEOF = HB_FALSE; + return HB_TRUE; +} + /* * free pages allocated by tag */ @@ -6900,6 +6921,7 @@ static HB_ERRCODE hb_nsxOrderCreate( NSXAREAP pArea, LPDBORDERCREATEINFO pOrderI szKey, pKeyExp, bType, ( HB_USHORT ) iLen, bTrail, szFor, pForExp, fAscend, pOrderInfo->fUnique, fCustom ); + pTag->Template = hb_nsxIsTemplateFunc( pTag->KeyExpr ); pTag->Partial = ( pArea->dbfarea.area.lpdbOrdCondInfo && !pArea->dbfarea.area.lpdbOrdCondInfo->fAll ); if( fNewFile ) diff --git a/harbour/src/rdd/dbfntx/dbfntx1.c b/harbour/src/rdd/dbfntx/dbfntx1.c index b3de5a46b4..725b68784c 100644 --- a/harbour/src/rdd/dbfntx/dbfntx1.c +++ b/harbour/src/rdd/dbfntx/dbfntx1.c @@ -3194,63 +3194,6 @@ static HB_BOOL hb_ntxTagKeyDel( LPTAGINFO pTag, LPKEYINFO pKey ) return HB_TRUE; } -/* - * refresh CurKey value and set proper path from RootPage to LeafPage - */ -static HB_BOOL hb_ntxCurKeyRefresh( LPTAGINFO pTag ) -{ - NTXAREAP pArea = pTag->Owner->Owner; - - if( pArea->dbfarea.lpdbPendingRel ) - SELF_FORCEREL( ( AREAP ) pArea ); - - if( !pArea->dbfarea.fPositioned ) - { - pTag->stackLevel = 0; - pTag->TagBOF = pTag->TagEOF = HB_TRUE; - pTag->CurKeyInfo->Xtra = 0; - return HB_FALSE; - } - else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo ) - { - HB_BYTE buf[ NTX_MAX_KEY ]; - HB_BOOL fBuf = HB_FALSE; - LPKEYINFO pKey = NULL; - /* Try to find previous if it's key for the same record */ - if( pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo ) - { - fBuf = HB_TRUE; - memcpy( buf, pTag->CurKeyInfo->key, pTag->KeyLength ); - pKey = hb_ntxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength ); - hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ); - } - if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo ) - { - HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer; - /* not found, create new key from DBF and if differs seek again */ - pKey = hb_ntxEvalKey( pKey, pTag ); - if( !fBuf || memcmp( buf, pKey->key, pTag->KeyLength ) != 0 ) - { - hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ); - } - /* not found, if key was generated from DBF buffer then force to - * update it, create the new key and if differs seek again */ - if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo && fValidBuf ) - { - SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo ); - memcpy( buf, pKey->key, pTag->KeyLength ); - pKey = hb_ntxEvalKey( pKey, pTag ); - if( memcmp( buf, pKey->key, pTag->KeyLength ) != 0 ) - hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ); - } - } - hb_ntxKeyFree( pKey ); - return pTag->CurKeyInfo->Xtra != 0 && pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo; - } - pTag->TagBOF = pTag->TagEOF = HB_FALSE; - return HB_TRUE; -} - /* * Skip in tag respecting record filter only */ @@ -3474,6 +3417,73 @@ static void hb_ntxTagGoToRelKeyPos( LPTAGINFO pTag, double dPos ) hb_ntxTagPrevKey( pTag ); } +/* + * refresh CurKey value and set proper path from RootPage to LeafPage + */ +static HB_BOOL hb_ntxCurKeyRefresh( LPTAGINFO pTag ) +{ + NTXAREAP pArea = pTag->Owner->Owner; + + if( pArea->dbfarea.lpdbPendingRel ) + SELF_FORCEREL( ( AREAP ) pArea ); + + if( !pArea->dbfarea.fPositioned ) + { + pTag->stackLevel = 0; + pTag->TagBOF = pTag->TagEOF = HB_TRUE; + pTag->CurKeyInfo->Xtra = 0; + return HB_FALSE; + } + else if( pTag->stackLevel == 0 || pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo ) + { + HB_BYTE buf[ NTX_MAX_KEY ]; + HB_BOOL fBuf = HB_FALSE; + LPKEYINFO pKey = NULL; + /* Try to find previous if it's key for the same record */ + if( pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo ) + { + fBuf = HB_TRUE; + memcpy( buf, pTag->CurKeyInfo->key, pTag->KeyLength ); + pKey = hb_ntxKeyCopy( pKey, pTag->CurKeyInfo, pTag->KeyLength ); + hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ); + } + if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo ) + { + HB_BOOL fValidBuf = pArea->dbfarea.fValidBuffer; + /* not found, create new key from DBF and if differs seek again */ + pKey = hb_ntxEvalKey( pKey, pTag ); + if( !fBuf || memcmp( buf, pKey->key, pTag->KeyLength ) != 0 ) + { + hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ); + } + /* not found, if key was generated from DBF buffer then force to + * update it, create the new key and if differs seek again */ + if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo && fValidBuf ) + { + SELF_GOTO( ( AREAP ) pArea, pArea->dbfarea.ulRecNo ); + memcpy( buf, pKey->key, pTag->KeyLength ); + pKey = hb_ntxEvalKey( pKey, pTag ); + if( memcmp( buf, pKey->key, pTag->KeyLength ) != 0 ) + hb_ntxTagKeyFind( pTag, pKey, pTag->KeyLength ); + } + if( pTag->CurKeyInfo->Xtra != pArea->dbfarea.ulRecNo && pTag->Template ) + { + hb_ntxTagGoTop( pTag ); + while( !pTag->TagEOF ) + { + if( pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo ) + break; + hb_ntxTagSkipNext( pTag ); + } + } + } + hb_ntxKeyFree( pKey ); + return pTag->CurKeyInfo->Xtra != 0 && pTag->CurKeyInfo->Xtra == pArea->dbfarea.ulRecNo; + } + pTag->TagBOF = pTag->TagEOF = HB_FALSE; + return HB_TRUE; +} + /* * free pages allocated by tag */