From 8a0e15bf889c5426bf1b8fd4f651c03b7b2b6c60 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Sat, 11 Dec 2010 22:32:25 +0000 Subject: [PATCH] 2010-12-11 23:31 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * examples/hbbtree/hb_btree.h * examples/hbbtree/hb_btree.c * Reformatted to Harbour standard using uncrustify tool. - examples/hbsqlit2 - Deleted. --- harbour/ChangeLog | 8 + harbour/examples/hbbtree/hb_btree.c | 2619 +++++++++--------- harbour/examples/hbbtree/hb_btree.h | 13 +- harbour/examples/hbsqlit2/TODO.txt | 26 - harbour/examples/hbsqlit2/hbsqlit2.c | 241 -- harbour/examples/hbsqlit2/hbsqlit2.ch | 90 - harbour/examples/hbsqlit2/hbsqlit2.hbc | 9 - harbour/examples/hbsqlit2/hbsqlit2.hbp | 21 - harbour/examples/hbsqlit2/readme.txt | 127 - harbour/examples/hbsqlit2/tests/example.db | Bin 77824 -> 0 bytes harbour/examples/hbsqlit2/tests/hbmk.hbm | 7 - harbour/examples/hbsqlit2/tests/hbsqlite.prg | 1157 -------- 12 files changed, 1381 insertions(+), 2937 deletions(-) delete mode 100644 harbour/examples/hbsqlit2/TODO.txt delete mode 100644 harbour/examples/hbsqlit2/hbsqlit2.c delete mode 100644 harbour/examples/hbsqlit2/hbsqlit2.ch delete mode 100644 harbour/examples/hbsqlit2/hbsqlit2.hbc delete mode 100644 harbour/examples/hbsqlit2/hbsqlit2.hbp delete mode 100644 harbour/examples/hbsqlit2/readme.txt delete mode 100644 harbour/examples/hbsqlit2/tests/example.db delete mode 100644 harbour/examples/hbsqlit2/tests/hbmk.hbm delete mode 100644 harbour/examples/hbsqlit2/tests/hbsqlite.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 2d9fd19085..740ad34bbb 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,14 @@ The license applies to all entries newer than 2009-04-28. */ +2010-12-11 23:31 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) + * examples/hbbtree/hb_btree.h + * examples/hbbtree/hb_btree.c + * Reformatted to Harbour standard using uncrustify tool. + + - examples/hbsqlit2 + - Deleted. + 2010-12-11 23:22 UTC+0200 Viktor Szakats (harbour.01 syenar.hu) * config/hbc.cfg + Enabled alignment of PP definitions. diff --git a/harbour/examples/hbbtree/hb_btree.c b/harbour/examples/hbbtree/hb_btree.c index 6d3a8264ff..b700854db9 100644 --- a/harbour/examples/hbbtree/hb_btree.c +++ b/harbour/examples/hbbtree/hb_btree.c @@ -1,6 +1,6 @@ /* - $Id$ -*/ + $Id$ + */ /* * Harbour Project source code: @@ -34,7 +34,7 @@ */ /* -TODO: + TODO: - determine how to handle page buffers in a multi-user environment - replace some of the for..next loops through the key/branches that move them around with memmove() @@ -55,11 +55,11 @@ TODO: - read page input buffer then split it - make MT safe -TOFIX: + TOFIX: - remove UNION's as they hide 32/64 size problems - use HB_U32 as the standard data type of file reading/writing - in-memory btree's cause a fatal error; this is a work in progress -*/ + */ #include "hbvm.h" #include "hbapi.h" @@ -72,10 +72,10 @@ TOFIX: HB_EXTERN_BEGIN -#if !defined( DEBUG ) && !defined( NDEBUG ) +#if ! defined( DEBUG ) && ! defined( NDEBUG ) #define NDEBUG #else - #define PrintCRLF() hb_conOutStd( hb_conNewLine(), strlen( hb_conNewLine() ) ) + #define PrintCRLF() hb_conOutStd( hb_conNewLine(), strlen( hb_conNewLine() ) ) #endif #if defined( __GNUC__ ) @@ -86,67 +86,71 @@ HB_EXTERN_BEGIN #define SRCLINENO __FUNCTION__ " (" STRINGIFY_1( __LINE__ ) ")" #define FILESRCLINENO __FILE__ "." SRCLINENO #elif 0 - #define SRCLINENO __FUNCTION__ + #define SRCLINENO __FUNCTION__ #else - #define SRCLINENO "%s (%d)", __FUNCTION__, __LINE__ + #define SRCLINENO "%s (%d)", __FUNCTION__, __LINE__ #endif #else /* - #define STRINGIFY_2( n ) #n - #define STRINGIFY_1( n ) STRINGIFY_2( n ) - #define SRCLINENO ( __FILE__ " (" STRINGIFY_1( __LINE__ ) ")" ) -*/ - #define SRCLINENO "" + #define STRINGIFY_2( n ) #n + #define STRINGIFY_1( n ) STRINGIFY_2( n ) + #define SRCLINENO ( __FILE__ " (" STRINGIFY_1( __LINE__ ) ")" ) + */ + #define SRCLINENO "" #endif -#define HEADER_ID "BTR\x10" +#define HEADER_ID "BTR\x10" -#define NULLPAGE 0L +#define NULLPAGE 0L -#define BTREENODEISNULL( pBTree, node ) ( HB_BOOL )( ( node ) == NULLPAGE ) -#define READPAGE_IF_NEEDED( pBTree, node ) if ( node != pBTree->ioBuffer->xPage.ulPage ) ioBufferScan( pBTree, node ) -#define CLEARKEYDATA( pBTree ) ( ( pBTree )->pThisKeyData->szKey[ 0 ] = '\0', \ - ( pBTree )->pThisKeyData->xData.lData = 0, \ - ( pBTree )->pThisKeyData->xData.pData = NULL ) +#define BTREENODEISNULL( pBTree, node ) ( HB_BOOL ) ( ( node ) == NULLPAGE ) +#define READPAGE_IF_NEEDED( pBTree, node ) if( node != \ + pBTree->ioBuffer->xPage.ulPage ) ioBufferScan( \ + pBTree, node ) +#define CLEARKEYDATA( pBTree ) ( ( pBTree )->pThisKeyData->szKey[ 0 ] = '\0', \ + ( pBTree )->pThisKeyData->xData.lData = 0, \ + ( pBTree )->pThisKeyData->xData.pData = NULL ) #undef HB_BTREE_HEADERSIZE -#define HB_BTREE_HEADERSIZE 2048 +#define HB_BTREE_HEADERSIZE 2048 typedef struct stack_item { - HB_ULONG ulNode; - int iPosition; + HB_ULONG ulNode; + int iPosition; } BTreeStackItem; typedef struct stack_tag { - HB_USHORT usCount; - BTreeStackItem items[ 1 ]; + HB_USHORT usCount; + BTreeStackItem items[ 1 ]; } BTreeStack; -#define STACKNODE( pStack ) ( *pStack )->items[ ( *pStack )->usCount - 1 ].ulNode -#define STACKPOSITION( pStack ) ( *pStack )->items[ ( *pStack )->usCount - 1 ].iPosition +#define STACKNODE( pStack ) ( *pStack )->items[ ( *pStack )->usCount - 1 ].ulNode +#define STACKPOSITION( pStack ) ( *pStack )->items[ ( *pStack )->usCount - 1 ].iPosition /* TODO: create two structs, one for in-memory, one for files */ typedef struct ioBuffer_tag { - struct ioBuffer_tag *prev, *next; - union { - HB_ULONG ulPage; /* not in-memory */ - struct ioBuffer_tag * pPage; /* in-memory */ - } xPage; - HB_BOOL IsDirty; + struct ioBuffer_tag * prev, * next; + union + { + HB_ULONG ulPage; /* not in-memory */ + struct ioBuffer_tag * pPage; /* in-memory */ + } xPage; + HB_BOOL IsDirty; - /* was: Buffer_T pBuffer; */ - HB_ULONG * pulPageCount; /* TODO: use LE get macro to retrieve this; better yet, dont use this */ - HB_ULONG * pulBranch; - union { - HB_LONG * plData; /* not in-memory */ - PHB_ITEM * ppData; /* in-memory */ - } xData; - HB_BYTE * szKey; - HB_BYTE Buffer[ 1 ]; + /* was: Buffer_T pBuffer; */ + HB_ULONG * pulPageCount; /* TODO: use LE get macro to retrieve this; better yet, dont use this */ + HB_ULONG * pulBranch; + union + { + HB_LONG * plData; /* not in-memory */ + PHB_ITEM * ppData; /* in-memory */ + } xData; + HB_BYTE * szKey; + HB_BYTE Buffer[ 1 ]; } ioBuffer_T; typedef int hb_BTreeFlags_T; @@ -170,431 +174,457 @@ typedef int hb_BTreeFlags_T; #define IsMultiBuffers ( 1 << 18 ) #define IsOptimized ( 1 << 19 ) -#define GETFLAG( pBTree, flag ) ( HB_BOOL )( ( ( int ) ( pBTree )->ulFlags & ( flag ) ) == ( flag ) ) -#define SETFLAG( pBTree, flag ) ( ( pBTree )->ulFlags |= ( flag ) ) -#define RESETFLAG( pBTree, flag ) ( ( pBTree )->ulFlags &= ~( flag ) ) +#define GETFLAG( pBTree, flag ) ( HB_BOOL ) ( ( ( int ) ( pBTree )->ulFlags & ( flag ) ) == \ + ( flag ) ) +#define SETFLAG( pBTree, flag ) ( ( pBTree )->ulFlags |= ( flag ) ) +#define RESETFLAG( pBTree, flag ) ( ( pBTree )->ulFlags &= ~( flag ) ) /* TODO: if 64 bit the size of the union may be different so this code will fail to work as expected */ typedef struct hb_KeyData_Tag { - union { - HB_LONG lData; /* lData is placed first for alignment, thought it is secondary */ - PHB_ITEM pData; - } xData; - HB_BYTE szKey[ 1 ]; + union + { + HB_LONG lData; /* lData is placed first for alignment, thought it is secondary */ + PHB_ITEM pData; + } xData; + HB_BYTE szKey[ 1 ]; } hb_KeyData_T; -typedef int ( * BTreeCmpFunc )( const char * l, const char * r, size_t n ); +typedef int ( *BTreeCmpFunc )( const char * l, const char * r, size_t n ); struct hb_BTree { - char * szFileName; - HB_FHANDLE hFile; - HB_ULONG ulRootPage; - HB_ULONG ulFreePage; - HB_USHORT usPageSize; - HB_USHORT usKeySize; - HB_USHORT usMaxKeys; - HB_USHORT usMinKeys; - hb_BTreeFlags_T ulFlags; - HB_ULONG ulKeyCount; - hb_KeyData_T * pThisKeyData; - BTreeStack * pStack; - ioBuffer_T * ioBuffer; - void * BufferEnd; - HB_BOOL IsDirtyFlagAssignment; /* replaces const TRUE, and !GETFLAG( pBTree, IsInMemory ) */ + char * szFileName; + HB_FHANDLE hFile; + HB_ULONG ulRootPage; + HB_ULONG ulFreePage; + HB_USHORT usPageSize; + HB_USHORT usKeySize; + HB_USHORT usMaxKeys; + HB_USHORT usMinKeys; + hb_BTreeFlags_T ulFlags; + HB_ULONG ulKeyCount; + hb_KeyData_T * pThisKeyData; + BTreeStack * pStack; + ioBuffer_T * ioBuffer; + void * BufferEnd; + HB_BOOL IsDirtyFlagAssignment; /* replaces const TRUE, and !GETFLAG( pBTree, IsInMemory ) */ - BTreeCmpFunc pStrCompare; + BTreeCmpFunc pStrCompare; }; -#if !defined( DEBUG ) && !defined( NDEBUG ) - HB_BOOL IsDebugging = HB_FALSE; +#if ! defined( DEBUG ) && ! defined( NDEBUG ) +HB_BOOL IsDebugging = HB_FALSE; #else #define IsDebugging HB_FALSE #endif -static struct hb_BTree **s_BTree_List = NULL; -static int s_BTree_List_Count = 0; +static struct hb_BTree ** s_BTree_List = NULL; +static int s_BTree_List_Count = 0; /* forward declarations */ static HB_USHORT CountGet( struct hb_BTree * pBTree, HB_ULONG ulNode ); -static hb_KeyData_T *KeyGet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, hb_KeyData_T *buffer ); +static hb_KeyData_T * KeyGet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, + hb_KeyData_T * buffer ); static HB_ULONG BranchGet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ); /* end of forward declarations */ -static void raiseError( HB_ULONG ulGenCode, HB_ULONG ulSubCode, const char * szDescription, const char * szOperation, int uiArguments ) +static void raiseError( HB_ULONG ulGenCode, HB_ULONG ulSubCode, const char * szDescription, + const char * szOperation, + int uiArguments ) { - PHB_ITEM pErr = hb_errRT_New( - ES_ERROR /* HB_USHORT uiSeverity */, - "HB_BTREE" /* const char * szSubSystem */, - ulGenCode /* HB_ULONG ulGenCode */, - ulSubCode /* HB_ULONG ulSubCode */, - szDescription /* const char * szDescription */, - szOperation /* const char * szOperation */, - 0 /* HB_ERRCODE uiOsCode */, - EF_NONE /* HB_USHORT uiFlags */ - ); + PHB_ITEM pErr = hb_errRT_New( + ES_ERROR /* HB_USHORT uiSeverity */, + "HB_BTREE" /* const char * szSubSystem */, + ulGenCode /* HB_ULONG ulGenCode */, + ulSubCode /* HB_ULONG ulSubCode */, + szDescription /* const char * szDescription */, + szOperation /* const char * szOperation */, + 0 /* HB_ERRCODE uiOsCode */, + EF_NONE /* HB_USHORT uiFlags */ + ); - if ( uiArguments > 0 ) - { - hb_errPutArgs( pErr, uiArguments, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( 3 ), hb_paramError( 4 ), hb_paramError( 5 ) ); - } + if( uiArguments > 0 ) + { + hb_errPutArgs( pErr, uiArguments, hb_paramError( 1 ), hb_paramError( 2 ), hb_paramError( + 3 ), hb_paramError( 4 ), hb_paramError( 5 ) ); + } - hb_errLaunch( pErr ); - hb_errRelease( pErr ); + hb_errLaunch( pErr ); + hb_errRelease( pErr ); } -static void * BufferRealloc( void *buffer, HB_ULONG size ) +static void * BufferRealloc( void * buffer, HB_ULONG size ) { - void *tmpBuffer = hb_xgrab( size ); + void * tmpBuffer = hb_xgrab( size ); - if ( buffer ) - { - hb_xmemcpy( tmpBuffer, buffer, size ); - hb_xfree( buffer ); - } + if( buffer ) + { + hb_xmemcpy( tmpBuffer, buffer, size ); + hb_xfree( buffer ); + } /* else hb_xmemset( tmpBuffer, '\0', size );*/ - return tmpBuffer; + return tmpBuffer; } -#define BufferAlloc( n ) BufferRealloc( NULL, ( n ) ) -#define BufferRelease( b ) hb_xfree( b ) +#define BufferAlloc( n ) BufferRealloc( NULL, ( n ) ) +#define BufferRelease( b ) hb_xfree( b ) -static ioBuffer_T * ioOneBufferAlloc( struct hb_BTree * pBTree, ioBuffer_T * prev, ioBuffer_T * next ) +static ioBuffer_T * ioOneBufferAlloc( struct hb_BTree * pBTree, ioBuffer_T * prev, + ioBuffer_T * next ) { - ioBuffer_T * thisptr; + ioBuffer_T * thisptr; - thisptr = ( ioBuffer_T * ) BufferAlloc( sizeof( ioBuffer_T ) + pBTree->usPageSize ); - hb_xmemset( thisptr, '\0', sizeof( ioBuffer_T ) + pBTree->usPageSize ); + thisptr = ( ioBuffer_T * ) BufferAlloc( sizeof( ioBuffer_T ) + pBTree->usPageSize ); + hb_xmemset( thisptr, '\0', sizeof( ioBuffer_T ) + pBTree->usPageSize ); - thisptr->pulPageCount = ( HB_ULONG * )( thisptr->Buffer ); - thisptr->pulBranch = ( HB_ULONG * )&thisptr->pulPageCount[ 1 ]; + thisptr->pulPageCount = ( HB_ULONG * ) ( thisptr->Buffer ); + thisptr->pulBranch = ( HB_ULONG * ) &thisptr->pulPageCount[ 1 ]; - if ( GETFLAG( pBTree, IsInMemory ) ) - { - thisptr->xData.ppData = ( PHB_ITEM * )&thisptr->pulBranch[ pBTree->usMaxKeys + 1 ]; - thisptr->szKey = ( HB_BYTE * )&thisptr->xData.ppData[ pBTree->usMaxKeys ]; - } - else - { - thisptr->xData.plData = ( HB_LONG * )&thisptr->pulBranch[ pBTree->usMaxKeys + 1 ]; - thisptr->szKey = ( HB_BYTE * )&thisptr->xData.plData[ pBTree->usMaxKeys ]; - } + if( GETFLAG( pBTree, IsInMemory ) ) + { + thisptr->xData.ppData = ( PHB_ITEM * ) &thisptr->pulBranch[ pBTree->usMaxKeys + 1 ]; + thisptr->szKey = ( HB_BYTE * ) &thisptr->xData.ppData[ pBTree->usMaxKeys ]; + } + else + { + thisptr->xData.plData = ( HB_LONG * ) &thisptr->pulBranch[ pBTree->usMaxKeys + 1 ]; + thisptr->szKey = ( HB_BYTE * ) &thisptr->xData.plData[ pBTree->usMaxKeys ]; + } - thisptr->xPage.ulPage = NULLPAGE; - thisptr->xPage.pPage = 0; - thisptr->IsDirty = HB_FALSE; + thisptr->xPage.ulPage = NULLPAGE; + thisptr->xPage.pPage = 0; + thisptr->IsDirty = HB_FALSE; - thisptr->prev = prev; - thisptr->next = next; + thisptr->prev = prev; + thisptr->next = next; - return thisptr; + return thisptr; } /* a link list 'most recently access' page buffering system */ static void ioBufferAlloc( struct hb_BTree * pBTree, HB_ULONG ulBuffers ) { - ioBuffer_T *thisptr = NULL, *last = NULL; + ioBuffer_T * thisptr = NULL, * last = NULL; - if ( ulBuffers == 0 ) - ulBuffers = 1; + if( ulBuffers == 0 ) + ulBuffers = 1; - if ( ulBuffers > 1 || GETFLAG( pBTree, IsInMemory ) ) - { - SETFLAG( pBTree, IsMultiBuffers ); - } - else - { - RESETFLAG( pBTree, IsMultiBuffers ); - } + if( ulBuffers > 1 || GETFLAG( pBTree, IsInMemory ) ) + { + SETFLAG( pBTree, IsMultiBuffers ); + } + else + { + RESETFLAG( pBTree, IsMultiBuffers ); + } - while ( ulBuffers-- > 0 ) - { - thisptr = ioOneBufferAlloc( pBTree, NULL, last ); - if ( last ) last->prev = thisptr; - last = thisptr; - } + while( ulBuffers-- > 0 ) + { + thisptr = ioOneBufferAlloc( pBTree, NULL, last ); + if( last ) + last->prev = thisptr; + last = thisptr; + } - pBTree->ioBuffer = thisptr; + pBTree->ioBuffer = thisptr; } -static void ioBufferWrite( struct hb_BTree * pBTree, ioBuffer_T *thisptr ) +static void ioBufferWrite( struct hb_BTree * pBTree, ioBuffer_T * thisptr ) { - hb_fsSeek( pBTree->hFile, thisptr->xPage.ulPage, FS_SET ); - if ( hb_fsWrite( pBTree->hFile, thisptr->Buffer, pBTree->usPageSize ) != pBTree->usPageSize ) - { - raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "ioBufferWrite*", 0 ); - } - thisptr->IsDirty = HB_FALSE; + hb_fsSeek( pBTree->hFile, thisptr->xPage.ulPage, FS_SET ); + if( hb_fsWrite( pBTree->hFile, thisptr->Buffer, pBTree->usPageSize ) != pBTree->usPageSize ) + { + raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "ioBufferWrite*", 0 ); + } + thisptr->IsDirty = HB_FALSE; } static void ioBufferRead( struct hb_BTree * pBTree, HB_ULONG ulNode ) { - ioBuffer_T *thisptr = pBTree->ioBuffer; + ioBuffer_T * thisptr = pBTree->ioBuffer; - if ( thisptr->IsDirty ) - { - ioBufferWrite( pBTree, thisptr ); - thisptr->IsDirty = HB_FALSE; - } - thisptr->xPage.ulPage = ulNode; - hb_fsSeek( pBTree->hFile, thisptr->xPage.ulPage, FS_SET ); - hb_fsRead( pBTree->hFile, thisptr->Buffer, pBTree->usPageSize ); + if( thisptr->IsDirty ) + { + ioBufferWrite( pBTree, thisptr ); + thisptr->IsDirty = HB_FALSE; + } + thisptr->xPage.ulPage = ulNode; + hb_fsSeek( pBTree->hFile, thisptr->xPage.ulPage, FS_SET ); + hb_fsRead( pBTree->hFile, thisptr->Buffer, pBTree->usPageSize ); } static void ioBufferRelease( struct hb_BTree * pBTree ) { - ioBuffer_T *next, *thisptr; - HB_ULONG n; + ioBuffer_T * next, * thisptr; + HB_ULONG n; - for ( thisptr = pBTree->ioBuffer; thisptr; thisptr = next ) - { - next = thisptr->next; - if ( thisptr->IsDirty ) /* cannot be in-memory in this case */ - { - ioBufferWrite( pBTree, thisptr ); - } - else if ( GETFLAG( pBTree, IsInMemory ) ) - { - for ( n = 0; n < *thisptr->pulPageCount; n++ ) - { -/* { printf( "%p", thisptr->xData.ppData[ n ] ); PrintCRLF(); }*/ - hb_itemRelease( thisptr->xData.ppData[ n ] ); - } - } - BufferRelease( thisptr ); - } - pBTree->ioBuffer = NULL; + for( thisptr = pBTree->ioBuffer; thisptr; thisptr = next ) + { + next = thisptr->next; + if( thisptr->IsDirty ) /* cannot be in-memory in this case */ + { + ioBufferWrite( pBTree, thisptr ); + } + else if( GETFLAG( pBTree, IsInMemory ) ) + { + for( n = 0; n < *thisptr->pulPageCount; n++ ) + { +/* { printf( "%p", thisptr->xData.ppData[ n ] ); PrintCRLF(); }*/ + hb_itemRelease( thisptr->xData.ppData[ n ] ); + } + } + BufferRelease( thisptr ); + } + pBTree->ioBuffer = NULL; } #if 0 /* keep just in case, but its functionality is built into ioBufferRelease */ - static void ioBufferFlush( struct hb_BTree * pBTree ) - { - ioBuffer_T *thisptr; +static void ioBufferFlush( struct hb_BTree * pBTree ) +{ + ioBuffer_T * thisptr; - for ( thisptr = pBTree->ioBuffer; thisptr; thisptr = thisptr->next ) - { - if ( thisptr->IsDirty ) ioBufferWrite( pBTree, thisptr ); - } - } + for( thisptr = pBTree->ioBuffer; thisptr; thisptr = thisptr->next ) + { + if( thisptr->IsDirty ) + ioBufferWrite( pBTree, thisptr ); + } +} #endif static void ioBufferScan( struct hb_BTree * pBTree, HB_ULONG page ) { - ioBuffer_T *thisptr; - ioBuffer_T *thisnext, *thisprev; + ioBuffer_T * thisptr; + ioBuffer_T * thisnext, * thisprev; - /* locate either the buffer the page is in, the first empty buffer, - or the last buffer in the list */ - for ( thisptr = pBTree->ioBuffer; - thisptr && !BTREENODEISNULL( pBTree, thisptr->xPage.ulPage ) && thisptr->xPage.ulPage != page && thisptr->next; - thisptr = thisptr->next ) {} + /* locate either the buffer the page is in, the first empty buffer, + or the last buffer in the list */ + for( thisptr = pBTree->ioBuffer; + thisptr && + ! BTREENODEISNULL( pBTree, + thisptr->xPage.ulPage ) && thisptr->xPage.ulPage != page && + thisptr->next; + thisptr = thisptr->next ) + { + } - /* only shuffle the buffers if the target buffer is not the root buffer */ - if ( thisptr != pBTree->ioBuffer ) - { - /* minimize writes */ - if ( thisptr->xPage.ulPage != page && thisptr->IsDirty ) - { + /* only shuffle the buffers if the target buffer is not the root buffer */ + if( thisptr != pBTree->ioBuffer ) + { + /* minimize writes */ + if( thisptr->xPage.ulPage != page && thisptr->IsDirty ) + { + ioBufferWrite( pBTree, thisptr ); + } + + thisprev = thisptr->prev; + thisnext = thisptr->next; + + if( thisnext ) + thisnext->prev = thisprev; + if( thisprev ) + thisprev->next = thisnext; + + thisptr->prev = NULL; + thisptr->next = pBTree->ioBuffer; + pBTree->ioBuffer->prev = thisptr; + pBTree->ioBuffer = thisptr; + } + else if( thisptr->IsDirty ) ioBufferWrite( pBTree, thisptr ); - } - thisprev = thisptr->prev; - thisnext = thisptr->next; - - if ( thisnext ) thisnext->prev = thisprev; - if ( thisprev ) thisprev->next = thisnext; - - thisptr->prev = NULL; - thisptr->next = pBTree->ioBuffer; - pBTree->ioBuffer->prev = thisptr; - pBTree->ioBuffer = thisptr; - } - else if ( thisptr->IsDirty ) - ioBufferWrite( pBTree, thisptr ); - - /* Grow() will call this with a null page, to flush & shuffle buffers */ - if ( !BTREENODEISNULL( pBTree, page ) && thisptr->xPage.ulPage != page && !GETFLAG( pBTree, IsInMemory ) ) - { - ioBufferRead( pBTree, page ); - } + /* Grow() will call this with a null page, to flush & shuffle buffers */ + if( ! BTREENODEISNULL( pBTree, + page ) && thisptr->xPage.ulPage != page && ! GETFLAG( pBTree, IsInMemory ) ) + { + ioBufferRead( pBTree, page ); + } } -static void StackNew( BTreeStack **pStack ) +static void StackNew( BTreeStack ** pStack ) { - *pStack = ( BTreeStack * )BufferRealloc( *pStack, sizeof( **pStack ) ); - ( *pStack )->usCount = 0; + *pStack = ( BTreeStack * ) BufferRealloc( *pStack, sizeof( **pStack ) ); + ( *pStack )->usCount = 0; } -static void StackPush( BTreeStack **pStack, HB_ULONG ulNode, int iPosition ) +static void StackPush( BTreeStack ** pStack, HB_ULONG ulNode, int iPosition ) { - *pStack = ( BTreeStack * )BufferRealloc( *pStack, sizeof( **pStack ) + ( ( *pStack )->usCount + 1 ) * sizeof( ( *pStack )->items[ 0 ] ) ); - ( *pStack )->items[ ( *pStack )->usCount ].ulNode = ulNode; - ( *pStack )->items[ ( *pStack )->usCount ].iPosition = iPosition; - ( *pStack )->usCount++; + *pStack = + ( BTreeStack * ) BufferRealloc( + *pStack, sizeof( **pStack ) + + ( ( *pStack )->usCount + 1 ) * sizeof( ( *pStack )->items[ 0 ] ) ); + ( *pStack )->items[ ( *pStack )->usCount ].ulNode = ulNode; + ( *pStack )->items[ ( *pStack )->usCount ].iPosition = iPosition; + ( *pStack )->usCount++; } -static void StackPop( BTreeStack **pStack, HB_ULONG *pulNode, int *piPosition ) +static void StackPop( BTreeStack ** pStack, HB_ULONG * pulNode, int * piPosition ) { - if ( ( *pStack )->usCount ) - { - ( *pStack )->usCount--; - *pulNode = ( *pStack )->items[ ( *pStack )->usCount ].ulNode; - *piPosition = ( *pStack )->items[ ( *pStack )->usCount ].iPosition; - *pStack = ( BTreeStack * )BufferRealloc( *pStack, sizeof( **pStack ) + ( ( *pStack )->usCount + 1 ) * sizeof( ( *pStack )->items[ 0 ] ) ); - } + if( ( *pStack )->usCount ) + { + ( *pStack )->usCount--; + *pulNode = ( *pStack )->items[ ( *pStack )->usCount ].ulNode; + *piPosition = ( *pStack )->items[ ( *pStack )->usCount ].iPosition; + *pStack = + ( BTreeStack * ) BufferRealloc( + *pStack, sizeof( **pStack ) + + ( ( *pStack )->usCount + 1 ) * sizeof( ( *pStack )->items[ 0 ] ) ); + } } -static void StackPeek( BTreeStack **pStack, HB_ULONG *pulNode, int *piPosition ) +static void StackPeek( BTreeStack ** pStack, HB_ULONG * pulNode, int * piPosition ) { - if ( ( *pStack )->usCount ) - { - *pulNode = ( *pStack )->items[ ( *pStack )->usCount - 1 ].ulNode; - *piPosition = ( *pStack )->items[ ( *pStack )->usCount - 1 ].iPosition; - } - else - { - *pulNode = 0; - *piPosition = 0; - } + if( ( *pStack )->usCount ) + { + *pulNode = ( *pStack )->items[ ( *pStack )->usCount - 1 ].ulNode; + *piPosition = ( *pStack )->items[ ( *pStack )->usCount - 1 ].iPosition; + } + else + { + *pulNode = 0; + *piPosition = 0; + } } -static HB_LONG StackSkip( struct hb_BTree * pBTree, BTreeStack **pStack, HB_LONG records ) +static HB_LONG StackSkip( struct hb_BTree * pBTree, BTreeStack ** pStack, HB_LONG records ) { - HB_ULONG ulNode; - int iPosition; - HB_LONG recordsskipped = 0; + HB_ULONG ulNode; + int iPosition; + HB_LONG recordsskipped = 0; - if ( ( *pStack )->usCount == 0 ) - { - /* todo: raise an error? */ - raiseError( EG_CORRUPTION, HB_BTREE_EC_STACKSKIP, "internal stack skip error", "StackSkip*", 0 ); - } + if( ( *pStack )->usCount == 0 ) + { + /* todo: raise an error? */ + raiseError( EG_CORRUPTION, HB_BTREE_EC_STACKSKIP, "internal stack skip error", "StackSkip*", + 0 ); + } - if ( records == 0 ) - { - StackPeek( pStack, &ulNode, &iPosition ); - } - else if ( records > 0 ) - { - while ( records-- > 0 ) - { - ulNode = BranchGet( pBTree, STACKNODE( pStack ), STACKPOSITION( pStack ) ); - if ( !BTREENODEISNULL( pBTree, ulNode ) ) + if( records == 0 ) + { + StackPeek( pStack, &ulNode, &iPosition ); + } + else if( records > 0 ) + { + while( records-- > 0 ) { - StackPush( pStack, ulNode, STACKPOSITION( pStack ) ); - while ( !BTREENODEISNULL( pBTree, ( ulNode = BranchGet( pBTree, ulNode, 0 ) ) ) ) - { + ulNode = BranchGet( pBTree, STACKNODE( pStack ), STACKPOSITION( pStack ) ); + if( ! BTREENODEISNULL( pBTree, ulNode ) ) + { + StackPush( pStack, ulNode, STACKPOSITION( pStack ) ); + while( ! BTREENODEISNULL( pBTree, ( ulNode = BranchGet( pBTree, ulNode, 0 ) ) ) ) + { /* StackPush( pStack, BranchGet( pBTree, ulNode, 0 ), 0 );*/ - StackPush( pStack, ulNode, 0 ); - } - STACKPOSITION( pStack ) = 1; - recordsskipped++; + StackPush( pStack, ulNode, 0 ); + } + STACKPOSITION( pStack ) = 1; + recordsskipped++; + } + else if( STACKPOSITION( pStack ) < CountGet( pBTree, STACKNODE( pStack ) ) ) + { + STACKPOSITION( pStack )++; + recordsskipped++; + } + else + { + StackPop( pStack, &ulNode, &iPosition ); + if( ( *pStack )->usCount == 0 ) + { + break; + } + else if( STACKPOSITION( pStack ) < CountGet( pBTree, STACKNODE( pStack ) ) ) + { + STACKPOSITION( pStack )++; + recordsskipped++; + } + else + { + STACKPOSITION( pStack )++; + records++; /* force the loop to retry */ + } + } } - else if ( STACKPOSITION( pStack ) < CountGet( pBTree, STACKNODE( pStack ) ) ) + StackPeek( pStack, &ulNode, &iPosition ); + } + else /*if ( records < 0 )*/ + { + while( records++ < 0 ) { - STACKPOSITION( pStack )++; - recordsskipped++; + if( STACKPOSITION( pStack ) > 0 ) + ulNode = BranchGet( pBTree, STACKNODE( pStack ), --STACKPOSITION( pStack ) ); + else + ulNode = NULLPAGE; + if( ! BTREENODEISNULL( pBTree, ulNode ) ) + { + StackPush( pStack, ulNode, CountGet( pBTree, ulNode ) ); + while( ! BTREENODEISNULL( pBTree, + ( ulNode = + BranchGet( pBTree, ulNode, CountGet( pBTree, ulNode ) ) ) ) ) + { + StackPush( pStack, ulNode, CountGet( pBTree, ulNode ) ); + } + recordsskipped--; + } + else if( STACKPOSITION( pStack ) > 0 ) + { + recordsskipped--; + } + else + { + StackPop( pStack, &ulNode, &iPosition ); + if( ( *pStack )->usCount == 0 ) + { + break; + } + else if( STACKPOSITION( pStack ) > 0 ) + { + recordsskipped--; + } + else + { + records--; /* force the loop to retry */ + } + } } - else - { - StackPop( pStack, &ulNode, &iPosition ); - if ( ( *pStack )->usCount == 0 ) - { - break; - } - else if ( STACKPOSITION( pStack ) < CountGet( pBTree, STACKNODE( pStack ) ) ) - { - STACKPOSITION( pStack )++; - recordsskipped++; - } - else - { - STACKPOSITION( pStack )++; - records++; /* force the loop to retry */ - } - } - } - StackPeek( pStack, &ulNode, &iPosition ); - } - else /*if ( records < 0 )*/ - { - while ( records++ < 0 ) - { - if ( STACKPOSITION( pStack ) > 0 ) - ulNode = BranchGet( pBTree, STACKNODE( pStack ), --STACKPOSITION( pStack ) ); - else - ulNode = NULLPAGE; - if ( !BTREENODEISNULL( pBTree, ulNode ) ) - { - StackPush( pStack, ulNode, CountGet( pBTree, ulNode ) ); - while ( !BTREENODEISNULL( pBTree, ( ulNode = BranchGet( pBTree, ulNode, CountGet( pBTree, ulNode ) ) ) ) ) - { - StackPush( pStack, ulNode, CountGet( pBTree, ulNode ) ); - } - recordsskipped--; - } - else if ( STACKPOSITION( pStack ) > 0 ) - { - recordsskipped--; - } - else - { - StackPop( pStack, &ulNode, &iPosition ); - if ( ( *pStack )->usCount == 0 ) - { - break; - } - else if ( STACKPOSITION( pStack ) > 0 ) - { - recordsskipped--; - } - else - { - records--; /* force the loop to retry */ - } - } - } - StackPeek( pStack, &ulNode, &iPosition ); - } + StackPeek( pStack, &ulNode, &iPosition ); + } - if ( ulNode == 0 && iPosition == 0 ) - CLEARKEYDATA( pBTree ); - else - KeyGet( pBTree, ulNode, iPosition, pBTree->pThisKeyData ); + if( ulNode == 0 && iPosition == 0 ) + CLEARKEYDATA( pBTree ); + else + KeyGet( pBTree, ulNode, iPosition, pBTree->pThisKeyData ); - return recordsskipped; + return recordsskipped; } -static void StackRelease( BTreeStack **pStack ) +static void StackRelease( BTreeStack ** pStack ) { - if ( *pStack ) - { - BufferRelease( *pStack ); - *pStack = NULL; - } + if( *pStack ) + { + BufferRelease( *pStack ); + *pStack = NULL; + } } static void HeaderWrite( struct hb_BTree * pBTree ) { - HB_BYTE TmpHeader[ HB_BTREE_HEADERSIZE ]; - HB_BYTE * pHeader = &TmpHeader[ 0 ]; - HB_U32 uiHeaderSize = HB_BTREE_HEADERSIZE; + HB_BYTE TmpHeader[ HB_BTREE_HEADERSIZE ]; + HB_BYTE * pHeader = &TmpHeader[ 0 ]; + HB_U32 uiHeaderSize = HB_BTREE_HEADERSIZE; - /* - header [4 bytes] - ulFreePage [4 bytes, little endian] - usPageSize [2 bytes, little endian] - usKeySize [2 bytes, little endian] - ulRootPage [4 bytes, little endian] - ulFlags [4 bytes, little endian] - ulKeyCount [4 bytes, little endian] - */ + /* + header [4 bytes] + ulFreePage [4 bytes, little endian] + usPageSize [2 bytes, little endian] + usKeySize [2 bytes, little endian] + ulRootPage [4 bytes, little endian] + ulFlags [4 bytes, little endian] + ulKeyCount [4 bytes, little endian] + */ hb_xmemset( TmpHeader, '\0', sizeof( TmpHeader ) ); @@ -612,158 +642,169 @@ static void HeaderWrite( struct hb_BTree * pBTree ) HB_PUT_LE_UINT32( pHeader, pBTree->ulKeyCount ); hb_fsSeek( pBTree->hFile, 0, FS_SET ); - if ( hb_fsWrite( pBTree->hFile, TmpHeader, sizeof( TmpHeader ) ) != sizeof( TmpHeader ) ) + if( hb_fsWrite( pBTree->hFile, TmpHeader, sizeof( TmpHeader ) ) != sizeof( TmpHeader ) ) { - raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "HeaderWrite*", 0 ); + raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "HeaderWrite*", 0 ); } } static HB_ULONG Grow( struct hb_BTree * pBTree ) { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( GETFLAG( pBTree, IsInMemory ) ) - { - ioBuffer_T * thisptr; + if( GETFLAG( pBTree, IsInMemory ) ) + { + ioBuffer_T * thisptr; - thisptr = ioOneBufferAlloc( pBTree, NULL, pBTree->ioBuffer ); - thisptr->xPage.pPage = thisptr; - if ( pBTree->ioBuffer ) pBTree->ioBuffer->prev = thisptr; - pBTree->ioBuffer = thisptr; - } - else - { - /* locate a page to use */ - ioBufferScan( pBTree, NULLPAGE ); + thisptr = ioOneBufferAlloc( pBTree, NULL, pBTree->ioBuffer ); + thisptr->xPage.pPage = thisptr; + if( pBTree->ioBuffer ) + pBTree->ioBuffer->prev = thisptr; + pBTree->ioBuffer = thisptr; + } + else + { + /* locate a page to use */ + ioBufferScan( pBTree, NULLPAGE ); - if ( BTREENODEISNULL( pBTree, pBTree->ulFreePage ) ) - { - HB_BYTE *buffer = pBTree->ioBuffer->Buffer; - - pBTree->ioBuffer->xPage.ulPage = hb_fsSeek( pBTree->hFile, 0, FS_END ); - hb_xmemset( buffer, '\0', pBTree->usPageSize ); - if ( pBTree->usPageSize != hb_fsWrite( pBTree->hFile, buffer, pBTree->usPageSize ) ) + if( BTREENODEISNULL( pBTree, pBTree->ulFreePage ) ) { - raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "Grow*", 0 ); - } - } - else - { - char buffer[ sizeof( pBTree->ulFreePage ) ]; - pBTree->ioBuffer->xPage.ulPage = hb_fsSeek( pBTree->hFile, pBTree->ulFreePage, FS_SET ); - hb_fsRead( pBTree->hFile, buffer, sizeof( pBTree->ulFreePage ) ); - pBTree->ulFreePage = HB_GET_LE_UINT32( buffer ); - } - pBTree->ioBuffer->IsDirty = HB_TRUE; - } + HB_BYTE * buffer = pBTree->ioBuffer->Buffer; - return pBTree->ioBuffer->xPage.ulPage; + pBTree->ioBuffer->xPage.ulPage = hb_fsSeek( pBTree->hFile, 0, FS_END ); + hb_xmemset( buffer, '\0', pBTree->usPageSize ); + if( pBTree->usPageSize != hb_fsWrite( pBTree->hFile, buffer, pBTree->usPageSize ) ) + { + raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "Grow*", 0 ); + } + } + else + { + char buffer[ sizeof( pBTree->ulFreePage ) ]; + pBTree->ioBuffer->xPage.ulPage = hb_fsSeek( pBTree->hFile, pBTree->ulFreePage, FS_SET ); + hb_fsRead( pBTree->hFile, buffer, sizeof( pBTree->ulFreePage ) ); + pBTree->ulFreePage = HB_GET_LE_UINT32( buffer ); + } + pBTree->ioBuffer->IsDirty = HB_TRUE; + } + + return pBTree->ioBuffer->xPage.ulPage; } static void Prune( struct hb_BTree * pBTree, HB_ULONG ulNode ) { - if ( GETFLAG( pBTree, IsInMemory ) ) - { - ioBuffer_T * thisptr; - HB_ULONG n; + if( GETFLAG( pBTree, IsInMemory ) ) + { + ioBuffer_T * thisptr; + HB_ULONG n; - for ( thisptr = pBTree->ioBuffer; thisptr && thisptr->xPage.ulPage != ulNode; thisptr = thisptr->next ) {} + for( thisptr = pBTree->ioBuffer; thisptr && thisptr->xPage.ulPage != ulNode; + thisptr = thisptr->next ) + { + } - if ( thisptr->prev ) thisptr->prev->next = thisptr->next; - if ( thisptr->next ) thisptr->next->prev = thisptr->prev; + if( thisptr->prev ) + thisptr->prev->next = thisptr->next; + if( thisptr->next ) + thisptr->next->prev = thisptr->prev; - if ( thisptr == pBTree->ioBuffer ) /* root page */ - pBTree->ioBuffer = thisptr->next; + if( thisptr == pBTree->ioBuffer ) /* root page */ + pBTree->ioBuffer = thisptr->next; - for ( n = 0; n < *thisptr->pulPageCount; n++ ) - { - hb_itemRelease( thisptr->xData.ppData[ n ] ); - } - hb_xfree( thisptr ); - } - else - { - char buffer[ sizeof( pBTree->ulFreePage ) ]; - hb_fsSeek( pBTree->hFile, ulNode, FS_SET ); - HB_PUT_LE_UINT32( buffer, pBTree->ulFreePage ); - if ( hb_fsWrite( pBTree->hFile, buffer, sizeof( pBTree->ulFreePage ) ) != sizeof( pBTree->ulFreePage ) ) - { - raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "Prune*", 0 ); - } - pBTree->ulFreePage = ulNode; - } + for( n = 0; n < *thisptr->pulPageCount; n++ ) + { + hb_itemRelease( thisptr->xData.ppData[ n ] ); + } + hb_xfree( thisptr ); + } + else + { + char buffer[ sizeof( pBTree->ulFreePage ) ]; + hb_fsSeek( pBTree->hFile, ulNode, FS_SET ); + HB_PUT_LE_UINT32( buffer, pBTree->ulFreePage ); + if( hb_fsWrite( pBTree->hFile, buffer, + sizeof( pBTree->ulFreePage ) ) != sizeof( pBTree->ulFreePage ) ) + { + raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "write error", "Prune*", 0 ); + } + pBTree->ulFreePage = ulNode; + } } static HB_USHORT CountGet( struct hb_BTree * pBTree, HB_ULONG ulNode ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); - return ( HB_USHORT )( *pBTree->ioBuffer->pulPageCount ); + READPAGE_IF_NEEDED( pBTree, ulNode ); + return ( HB_USHORT ) ( *pBTree->ioBuffer->pulPageCount ); } static void CountSet( struct hb_BTree * pBTree, HB_ULONG ulNode, HB_ULONG newPageCount ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); - *pBTree->ioBuffer->pulPageCount = newPageCount; - pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; + READPAGE_IF_NEEDED( pBTree, ulNode ); + *pBTree->ioBuffer->pulPageCount = newPageCount; + pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; } static HB_USHORT CountAdj( struct hb_BTree * pBTree, HB_ULONG ulNode, HB_LONG adjPageCount ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); + READPAGE_IF_NEEDED( pBTree, ulNode ); - *pBTree->ioBuffer->pulPageCount += adjPageCount; - pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; + *pBTree->ioBuffer->pulPageCount += adjPageCount; + pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; - return ( HB_USHORT )*pBTree->ioBuffer->pulPageCount; + return ( HB_USHORT ) *pBTree->ioBuffer->pulPageCount; } -static void NodeCopy( struct hb_BTree * pBTree, HB_ULONG toNode, int toPosition, HB_ULONG fromNode, int fromPosition, hb_KeyData_T *buffer ) +static void NodeCopy( struct hb_BTree * pBTree, HB_ULONG toNode, int toPosition, HB_ULONG fromNode, + int fromPosition, + hb_KeyData_T * buffer ) { - HB_ULONG ulBranch; - HB_LONG lData = 0; - PHB_ITEM pData = NULL; + HB_ULONG ulBranch; + HB_LONG lData = 0; + PHB_ITEM pData = NULL; - READPAGE_IF_NEEDED( pBTree, fromNode ); - ulBranch = pBTree->ioBuffer->pulBranch[ fromPosition ]; + READPAGE_IF_NEEDED( pBTree, fromNode ); + ulBranch = pBTree->ioBuffer->pulBranch[ fromPosition ]; - if ( GETFLAG( pBTree, IsInMemory ) ) - { - pData = pBTree->ioBuffer->xData.ppData[ fromPosition - 1 ]; - } - else - { - lData = pBTree->ioBuffer->xData.plData[ fromPosition - 1 ]; - } + if( GETFLAG( pBTree, IsInMemory ) ) + { + pData = pBTree->ioBuffer->xData.ppData[ fromPosition - 1 ]; + } + else + { + lData = pBTree->ioBuffer->xData.plData[ fromPosition - 1 ]; + } - hb_xmemcpy( buffer->szKey, pBTree->ioBuffer->szKey + ( fromPosition - 1 ) * pBTree->usKeySize, pBTree->usKeySize ); - buffer->szKey[ pBTree->usKeySize ] = '\0'; + hb_xmemcpy( buffer->szKey, pBTree->ioBuffer->szKey + ( fromPosition - 1 ) * pBTree->usKeySize, + pBTree->usKeySize ); + buffer->szKey[ pBTree->usKeySize ] = '\0'; - READPAGE_IF_NEEDED( pBTree, toNode ); - pBTree->ioBuffer->pulBranch[ toPosition ] = ulBranch; - if ( GETFLAG( pBTree, IsInMemory ) ) - { - pBTree->ioBuffer->xData.ppData[ toPosition - 1 ] = pData; - } - else - { - pBTree->ioBuffer->xData.plData[ toPosition - 1 ] = lData; - } - hb_xmemcpy( pBTree->ioBuffer->szKey + ( toPosition - 1 ) * pBTree->usKeySize, buffer->szKey, pBTree->usKeySize ); - pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; + READPAGE_IF_NEEDED( pBTree, toNode ); + pBTree->ioBuffer->pulBranch[ toPosition ] = ulBranch; + if( GETFLAG( pBTree, IsInMemory ) ) + { + pBTree->ioBuffer->xData.ppData[ toPosition - 1 ] = pData; + } + else + { + pBTree->ioBuffer->xData.plData[ toPosition - 1 ] = lData; + } + hb_xmemcpy( pBTree->ioBuffer->szKey + ( toPosition - 1 ) * pBTree->usKeySize, buffer->szKey, + pBTree->usKeySize ); + pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; } static HB_ULONG BranchGet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); - return pBTree->ioBuffer->pulBranch[ iPosition ]; + READPAGE_IF_NEEDED( pBTree, ulNode ); + return pBTree->ioBuffer->pulBranch[ iPosition ]; } #if defined( DEBUG ) static void Chk4Loop( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, HB_ULONG ulBranch ) { /* - int i; - for ( i = 0; i < CountGet( pBTree, ulNode ); i++ ) + int i; + for ( i = 0; i < CountGet( pBTree, ulNode ); i++ ) if ( i != iPosition && pBTree->ioBuffer->pulBranch[ i ] == ulBranch && ulBranch ) { HB_TRACE( HB_TR_ERROR, "Chk4Loop( nbranch %ld exists in page %ld (position %d, found at %d, count %d) )", @@ -773,1185 +814,1255 @@ static void Chk4Loop( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, ( int )i, CountGet( pBTree, ulNode ) ); } -*/ - if ( ulBranch > filelength( pBTree->hFile ) ) - HB_TRACE( HB_TR_ERROR, "Chk4Loop( nbranch %ld exceeds file size in page %ld (position %d, count %d) )", - ( long )ulBranch, - ( long )ulNode, - ( int )iPosition, - ( int )CountGet( pBTree, ulNode ) ); + */ + if( ulBranch > filelength( pBTree->hFile ) ) + HB_TRACE( HB_TR_ERROR, + "Chk4Loop( nbranch %ld exceeds file size in page %ld (position %d, count %d) )", + ( long ) ulBranch, + ( long ) ulNode, + ( int ) iPosition, + ( int ) CountGet( pBTree, + ulNode ) ); } #endif static void BranchSet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, HB_ULONG ulBranch ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); + READPAGE_IF_NEEDED( pBTree, ulNode ); /* - if ( ulBranch > filelength( pBTree->hFile ) ) + if ( ulBranch > filelength( pBTree->hFile ) ) HB_TRACE( HB_TR_ERROR, "BranchSet( nbranch set %ld exceeds file size in page %ld (position %d, count %d) )", ( long )ulBranch, ( long )ulNode, ( int )iPosition, CountGet( pBTree, ulNode ) ); -*/ + */ - pBTree->ioBuffer->pulBranch[ iPosition ] = ulBranch; - pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; + pBTree->ioBuffer->pulBranch[ iPosition ] = ulBranch; + pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; } /* if the parameter is null, allocate a buffer - it is the */ /* callers responsibility to release the buffer */ -static hb_KeyData_T *KeyGet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, hb_KeyData_T *buffer ) +static hb_KeyData_T * KeyGet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, + hb_KeyData_T * buffer ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); + READPAGE_IF_NEEDED( pBTree, ulNode ); - if ( buffer == NULL ) - buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + if( buffer == NULL ) + buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - hb_xmemcpy( buffer->szKey, pBTree->ioBuffer->szKey + ( iPosition - 1 ) * pBTree->usKeySize, pBTree->usKeySize ); - buffer->szKey[ pBTree->usKeySize ] = '\0'; - if ( GETFLAG( pBTree, IsInMemory ) ) - { - buffer->xData.pData = pBTree->ioBuffer->xData.ppData[ iPosition - 1 ]; - } - else - { - buffer->xData.lData = pBTree->ioBuffer->xData.plData[ iPosition - 1 ]; - } + hb_xmemcpy( buffer->szKey, pBTree->ioBuffer->szKey + ( iPosition - 1 ) * pBTree->usKeySize, + pBTree->usKeySize ); + buffer->szKey[ pBTree->usKeySize ] = '\0'; + if( GETFLAG( pBTree, IsInMemory ) ) + { + buffer->xData.pData = pBTree->ioBuffer->xData.ppData[ iPosition - 1 ]; + } + else + { + buffer->xData.lData = pBTree->ioBuffer->xData.plData[ iPosition - 1 ]; + } - return buffer; + return buffer; } -static void KeySet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, hb_KeyData_T *key ) +static void KeySet( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition, hb_KeyData_T * key ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); + READPAGE_IF_NEEDED( pBTree, ulNode ); /* if ( pBTree->ioBuffer->szKey + ( iPosition - 1 ) * pBTree->usKeySize + pBTree->usKeySize > pBTree->ioBuffer->Buffer + pBTree->usPageSize ) */ - hb_xmemcpy( pBTree->ioBuffer->szKey + ( iPosition - 1 ) * pBTree->usKeySize, key->szKey, pBTree->usKeySize ); - if ( GETFLAG( pBTree, IsInMemory ) ) - { - pBTree->ioBuffer->xData.ppData[ iPosition - 1 ] = key->xData.pData; - } - else - { - pBTree->ioBuffer->xData.plData[ iPosition - 1 ] = key->xData.lData; - } - pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; + hb_xmemcpy( pBTree->ioBuffer->szKey + ( iPosition - 1 ) * pBTree->usKeySize, key->szKey, + pBTree->usKeySize ); + if( GETFLAG( pBTree, IsInMemory ) ) + { + pBTree->ioBuffer->xData.ppData[ iPosition - 1 ] = key->xData.pData; + } + else + { + pBTree->ioBuffer->xData.plData[ iPosition - 1 ] = key->xData.lData; + } + pBTree->ioBuffer->IsDirty = pBTree->IsDirtyFlagAssignment; } -static HB_LONG KeyCompare( struct hb_BTree * pBTree, hb_KeyData_T *left, hb_KeyData_T *right ) +static HB_LONG KeyCompare( struct hb_BTree * pBTree, hb_KeyData_T * left, hb_KeyData_T * right ) { /* HB_LONG lResults = strnicmp( left->szKey, right->szKey, pBTree->usKeySize );*/ - HB_LONG lResults = ( pBTree->pStrCompare )( ( const char * ) left->szKey, ( const char * ) right->szKey, pBTree->usKeySize ); + HB_LONG lResults = + ( pBTree->pStrCompare )( ( const char * ) left->szKey, ( const char * ) right->szKey, + pBTree->usKeySize ); - if ( lResults == 0 && GETFLAG( pBTree, IsUnique ) ) - { - lResults = ( left->xData.lData - right->xData.lData ); - } + if( lResults == 0 && GETFLAG( pBTree, IsUnique ) ) + { + lResults = ( left->xData.lData - right->xData.lData ); + } - return lResults; + return lResults; } -static HB_BOOL SearchNode( struct hb_BTree * pBTree, hb_KeyData_T *target, HB_ULONG ulNode, int *iPosition ) +static HB_BOOL SearchNode( struct hb_BTree * pBTree, hb_KeyData_T * target, HB_ULONG ulNode, + int * iPosition ) { - HB_BOOL results; - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + HB_BOOL results; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - READPAGE_IF_NEEDED( pBTree, ulNode ); + READPAGE_IF_NEEDED( pBTree, ulNode ); - if ( KeyCompare( pBTree, target, KeyGet( pBTree, ulNode, 1, buffer ) ) < 0 ) - { - *iPosition = 0; - results = HB_FALSE; - } - else - { - *iPosition = CountGet( pBTree, ulNode ); - while ( KeyCompare( pBTree, target, KeyGet( pBTree, ulNode, *iPosition, buffer ) ) < 0 && *iPosition > 1 ) - ( *iPosition )--; + if( KeyCompare( pBTree, target, KeyGet( pBTree, ulNode, 1, buffer ) ) < 0 ) + { + *iPosition = 0; + results = HB_FALSE; + } + else + { + *iPosition = CountGet( pBTree, ulNode ); + while( KeyCompare( pBTree, target, + KeyGet( pBTree, ulNode, *iPosition, buffer ) ) < 0 && *iPosition > 1 ) + ( *iPosition )--; - results = ( HB_BOOL )( KeyCompare( pBTree, target, buffer ) == 0 ); + results = ( HB_BOOL ) ( KeyCompare( pBTree, target, buffer ) == 0 ); /* TODO: change the linear search (above) into a binary search */ #if 0 - if ( 1 || IsDebugging ) - { - short int lower_, upper_, middle_, results_; + if( 1 || IsDebugging ) + { + short int lower_, upper_, middle_, results_; - lower_ = 1; - upper_ = CountGet( pBTree, ulNode ); - do { - middle_ = ( upper_ + lower_ ) / 2; - results_ = KeyCompare( pBTree, target, KeyGet( pBTree, ulNode, middle_, buffer ) ); - if ( results_ < 0 ) - upper_ = middle_-1; - else if ( results_ > 0 ) - lower_ = middle_+1; - } while ( results_ != 0 && upper_ >= lower_ ); - if ( !( results == (HB_BOOL)( results_ == 0 ) && *iPosition != results_ == 0 ? middle_ : upper_ ) ) - HB_TRACE( HB_TR_ERROR, ( "SearchNode( results=%d results_=%d *iPosition=%d myposition=%d )", - results, (HB_BOOL)( results_ == 0 ), *iPosition, results_ == 0 ? middle_ : upper_ ) ); + lower_ = 1; + upper_ = CountGet( pBTree, ulNode ); + do + { + middle_ = ( upper_ + lower_ ) / 2; + results_ = KeyCompare( pBTree, target, KeyGet( pBTree, ulNode, middle_, buffer ) ); + if( results_ < 0 ) + upper_ = middle_ - 1; + else if( results_ > 0 ) + lower_ = middle_ + 1; + } + while( results_ != 0 && upper_ >= lower_ ); + if( ! ( results == + ( HB_BOOL ) ( results_ == + 0 ) && *iPosition != results_ == 0 ? middle_ : upper_ ) ) + HB_TRACE( HB_TR_ERROR, + ( "SearchNode( results=%d results_=%d *iPosition=%d myposition=%d )", + results, ( HB_BOOL ) ( results_ == 0 ), *iPosition, + results_ == 0 ? middle_ : upper_ ) ); - /* results = ( HB_BOOL )( results_ == 0 ); - *iPosition = results == 0 ? middle_ : upper_; */ - } + /* results = ( HB_BOOL )( results_ == 0 ); + *iPosition = results == 0 ? middle_ : upper_; */ + } #endif - } + } - BufferRelease( buffer ); - return results; + BufferRelease( buffer ); + return results; } -static HB_ULONG hb_BTreeSearch( struct hb_BTree * pBTree, hb_KeyData_T *target, int *targetpos, BTreeStack **pStack ) +static HB_ULONG hb_BTreeSearch( struct hb_BTree * pBTree, hb_KeyData_T * target, int * targetpos, + BTreeStack ** pStack ) { - HB_ULONG ulNode = pBTree->ulRootPage; + HB_ULONG ulNode = pBTree->ulRootPage; - while ( ulNode && !SearchNode( pBTree, target, ulNode, targetpos ) ) - { - if ( pStack && *pStack ) - { + while( ulNode && ! SearchNode( pBTree, target, ulNode, targetpos ) ) + { + if( pStack && *pStack ) + { + StackPush( pStack, ulNode, *targetpos ); + } + ulNode = BranchGet( pBTree, ulNode, *targetpos ); + } + + if( ulNode && pStack && *pStack ) + { StackPush( pStack, ulNode, *targetpos ); - } - ulNode = BranchGet( pBTree, ulNode, *targetpos ); - } + } - if ( ulNode && pStack && *pStack ) - { - StackPush( pStack, ulNode, *targetpos ); - } - - return ulNode; + return ulNode; } -static void PushIn( struct hb_BTree * pBTree, hb_KeyData_T *xkey, HB_ULONG xbranch, HB_ULONG ulNode, int iPosition ) +static void PushIn( struct hb_BTree * pBTree, hb_KeyData_T * xkey, HB_ULONG xbranch, + HB_ULONG ulNode, + int iPosition ) { - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - int i; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + int i; - for ( i = CountGet( pBTree, ulNode ); i > iPosition; i-- ) - { - NodeCopy( pBTree, ulNode, i + 1, ulNode, i, buffer ); - } + for( i = CountGet( pBTree, ulNode ); i > iPosition; i-- ) + { + NodeCopy( pBTree, ulNode, i + 1, ulNode, i, buffer ); + } - KeySet( pBTree, ulNode, iPosition + 1, xkey ); - BranchSet( pBTree, ulNode, iPosition + 1, xbranch ); - ( void )CountAdj( pBTree, ulNode, +1 ); - BufferRelease( buffer ); + KeySet( pBTree, ulNode, iPosition + 1, xkey ); + BranchSet( pBTree, ulNode, iPosition + 1, xbranch ); + ( void ) CountAdj( pBTree, ulNode, +1 ); + BufferRelease( buffer ); } -static void Split( struct hb_BTree * pBTree, hb_KeyData_T *xkey, HB_ULONG xbranch, HB_ULONG ulNode, int iPosition, hb_KeyData_T **ykey, HB_ULONG *ybranch ) +static void Split( struct hb_BTree * pBTree, hb_KeyData_T * xkey, HB_ULONG xbranch, HB_ULONG ulNode, + int iPosition, hb_KeyData_T ** ykey, + HB_ULONG * ybranch ) { - int i; - int median; - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + int i; + int median; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - if ( iPosition <= pBTree->usMinKeys ) - median = pBTree->usMinKeys; - else - median = pBTree->usMinKeys + 1; + if( iPosition <= pBTree->usMinKeys ) + median = pBTree->usMinKeys; + else + median = pBTree->usMinKeys + 1; - *ybranch = Grow( pBTree ); - for ( i = median + 1; i <= pBTree->usMaxKeys; i++ ) - { - NodeCopy( pBTree, *ybranch, i - median, ulNode, i, buffer ); - } + *ybranch = Grow( pBTree ); + for( i = median + 1; i <= pBTree->usMaxKeys; i++ ) + { + NodeCopy( pBTree, *ybranch, i - median, ulNode, i, buffer ); + } - CountSet( pBTree, *ybranch, pBTree->usMaxKeys - median ); - CountSet( pBTree, ulNode, median ); + CountSet( pBTree, *ybranch, pBTree->usMaxKeys - median ); + CountSet( pBTree, ulNode, median ); - if ( iPosition <= pBTree->usMinKeys ) - PushIn( pBTree, xkey, xbranch, ulNode, iPosition ); - else - PushIn( pBTree, xkey, xbranch, *ybranch, iPosition - median ); + if( iPosition <= pBTree->usMinKeys ) + PushIn( pBTree, xkey, xbranch, ulNode, iPosition ); + else + PushIn( pBTree, xkey, xbranch, *ybranch, iPosition - median ); /* hb_xmemcpy( *ykey, KeyGet( pBTree, ulNode, CountGet( pBTree, ulNode ), buffer ), pBTree->usKeySize ); */ - KeyGet( pBTree, ulNode, CountGet( pBTree, ulNode ), *ykey ); + KeyGet( pBTree, ulNode, CountGet( pBTree, ulNode ), *ykey ); /* *ykey = KeyGet( pBTree, ulNode, CountGet( pBTree, ulNode ) );*/ - BranchSet( pBTree, *ybranch, 0, BranchGet( pBTree, ulNode, CountGet( pBTree, ulNode ) ) ); - ( void )CountAdj( pBTree, ulNode, -1 ); - BufferRelease( buffer ); + BranchSet( pBTree, *ybranch, 0, BranchGet( pBTree, ulNode, CountGet( pBTree, ulNode ) ) ); + ( void ) CountAdj( pBTree, ulNode, -1 ); + BufferRelease( buffer ); } #ifdef DEBUG - static HB_ULONG sulMaxPushDownDepth = 0; +static HB_ULONG sulMaxPushDownDepth = 0; #endif -static HB_BOOL PushDown( struct hb_BTree * pBTree, hb_KeyData_T *newkey, HB_ULONG ulNode, hb_KeyData_T **xkey, HB_ULONG *xbranch ) +static HB_BOOL PushDown( struct hb_BTree * pBTree, hb_KeyData_T * newkey, HB_ULONG ulNode, + hb_KeyData_T ** xkey, + HB_ULONG * xbranch ) { - int iPosition; + int iPosition; #ifdef DEBUG - static HB_ULONG PushDownDepth = 0; + static HB_ULONG PushDownDepth = 0; - if( ++PushDownDepth > sulMaxPushDownDepth ) - { - sulMaxPushDownDepth = PushDownDepth; - } + if( ++PushDownDepth > sulMaxPushDownDepth ) + { + sulMaxPushDownDepth = PushDownDepth; + } #endif - if ( BTREENODEISNULL( pBTree, ulNode ) ) - { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - hb_xmemcpy( *xkey, newkey, sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 );/* *xkey = newkey;*/ - *xbranch = NULLPAGE; - return HB_TRUE; - } - else - { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( SearchNode( pBTree, newkey, ulNode, &iPosition ) ) - { - SETFLAG( pBTree, IsDuplicateKey ); - return HB_FALSE; /* error */ - } + if( BTREENODEISNULL( pBTree, ulNode ) ) + { + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + hb_xmemcpy( *xkey, newkey, sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); /* *xkey = newkey;*/ + *xbranch = NULLPAGE; + return HB_TRUE; + } + else + { + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( SearchNode( pBTree, newkey, ulNode, &iPosition ) ) + { + SETFLAG( pBTree, IsDuplicateKey ); + return HB_FALSE; /* error */ + } - if ( PushDown( pBTree, newkey, BranchGet( pBTree, ulNode, iPosition ), xkey, xbranch ) ) - { - if ( CountGet( pBTree, ulNode ) < pBTree->usMaxKeys ) + if( PushDown( pBTree, newkey, BranchGet( pBTree, ulNode, iPosition ), xkey, xbranch ) ) { - PushIn( pBTree, *xkey, *xbranch, ulNode, iPosition ); - return HB_FALSE; + if( CountGet( pBTree, ulNode ) < pBTree->usMaxKeys ) + { + PushIn( pBTree, *xkey, *xbranch, ulNode, iPosition ); + return HB_FALSE; + } + else + { + Split( pBTree, *xkey, *xbranch, ulNode, iPosition, xkey, xbranch ); + return HB_TRUE; + } } - else - { - Split( pBTree, *xkey, *xbranch, ulNode, iPosition, xkey, xbranch ); - return HB_TRUE; - } - } - return HB_FALSE; - } + return HB_FALSE; + } } HB_BOOL hb_BTreeInsert( struct hb_BTree * pBTree, const char * szKey, PHB_ITEM pData ) { - hb_KeyData_T *xkey = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - HB_ULONG xbranch; - HB_ULONG newnode; + hb_KeyData_T * xkey = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + HB_ULONG xbranch; + HB_ULONG newnode; - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - RESETFLAG( pBTree, IsDuplicateKey ); + RESETFLAG( pBTree, IsDuplicateKey ); - hb_xmemcpy( pBTree->pThisKeyData->szKey, szKey, pBTree->usKeySize ); - pBTree->pThisKeyData->szKey[ pBTree->usKeySize ] = '\0'; + hb_xmemcpy( pBTree->pThisKeyData->szKey, szKey, pBTree->usKeySize ); + pBTree->pThisKeyData->szKey[ pBTree->usKeySize ] = '\0'; - if ( GETFLAG( pBTree, IsInMemory ) ) - { - pBTree->pThisKeyData->xData.pData = hb_itemNew( pData ); + if( GETFLAG( pBTree, IsInMemory ) ) + { + pBTree->pThisKeyData->xData.pData = hb_itemNew( pData ); /*printf( "[%p %p] ", pBTree->pThisKeyData->xData.pData, pData );PrintCRLF();*/ - } - else - { - pBTree->pThisKeyData->xData.lData = hb_itemGetNL( pData ); - } + } + else + { + pBTree->pThisKeyData->xData.lData = hb_itemGetNL( pData ); + } - if ( PushDown( pBTree, pBTree->pThisKeyData, pBTree->ulRootPage, &xkey, &xbranch ) ) - { - newnode = Grow( pBTree ); - CountSet( pBTree, newnode, 1 ); - KeySet( pBTree, newnode, 1, xkey ); - BranchSet( pBTree, newnode, 0, pBTree->ulRootPage ); - BranchSet( pBTree, newnode, 1, xbranch ); - pBTree->ulRootPage = newnode; - } + if( PushDown( pBTree, pBTree->pThisKeyData, pBTree->ulRootPage, &xkey, &xbranch ) ) + { + newnode = Grow( pBTree ); + CountSet( pBTree, newnode, 1 ); + KeySet( pBTree, newnode, 1, xkey ); + BranchSet( pBTree, newnode, 0, pBTree->ulRootPage ); + BranchSet( pBTree, newnode, 1, xbranch ); + pBTree->ulRootPage = newnode; + } - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - BufferRelease( xkey ); - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + BufferRelease( xkey ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( !GETFLAG( pBTree, IsDuplicateKey ) ) - pBTree->ulKeyCount++; + if( ! GETFLAG( pBTree, IsDuplicateKey ) ) + pBTree->ulKeyCount++; - return !GETFLAG( pBTree, IsDuplicateKey ); + return ! GETFLAG( pBTree, IsDuplicateKey ); } static void MoveRight( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - int c; - HB_ULONG tmpnode; - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + int c; + HB_ULONG tmpnode; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - tmpnode = BranchGet( pBTree, ulNode, iPosition ); - for ( c = CountGet( pBTree, tmpnode ); c > 0; c-- ) - { - NodeCopy( pBTree, tmpnode, c + 1, tmpnode, c, buffer ); - } + tmpnode = BranchGet( pBTree, ulNode, iPosition ); + for( c = CountGet( pBTree, tmpnode ); c > 0; c-- ) + { + NodeCopy( pBTree, tmpnode, c + 1, tmpnode, c, buffer ); + } - BranchSet( pBTree, tmpnode, 1, BranchGet( pBTree, tmpnode, 0 ) ); - ( void )CountAdj( pBTree, tmpnode, +1 ); - KeySet( pBTree, tmpnode, 1, KeyGet( pBTree, ulNode, iPosition, buffer ) ); + BranchSet( pBTree, tmpnode, 1, BranchGet( pBTree, tmpnode, 0 ) ); + ( void ) CountAdj( pBTree, tmpnode, +1 ); + KeySet( pBTree, tmpnode, 1, KeyGet( pBTree, ulNode, iPosition, buffer ) ); - tmpnode = BranchGet( pBTree, ulNode, iPosition - 1 ); - KeySet( pBTree, ulNode, iPosition, KeyGet( pBTree, tmpnode, CountGet( pBTree, tmpnode ), buffer ) ); - BranchSet( pBTree, BranchGet( pBTree, ulNode, iPosition ), 0, BranchGet( pBTree, tmpnode, CountGet( pBTree, tmpnode ) ) ); - ( void )CountAdj( pBTree, tmpnode, -1 ); - BufferRelease( buffer ); + tmpnode = BranchGet( pBTree, ulNode, iPosition - 1 ); + KeySet( pBTree, ulNode, iPosition, + KeyGet( pBTree, tmpnode, CountGet( pBTree, tmpnode ), buffer ) ); + BranchSet( pBTree, + BranchGet( pBTree, ulNode, + iPosition ), 0, BranchGet( pBTree, tmpnode, CountGet( pBTree, tmpnode ) ) ); + ( void ) CountAdj( pBTree, tmpnode, -1 ); + BufferRelease( buffer ); } static void MoveLeft( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - int c, c_count; - HB_ULONG tmpnode; - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + int c, c_count; + HB_ULONG tmpnode; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - tmpnode = BranchGet( pBTree, ulNode, iPosition - 1 ); - c_count = CountAdj( pBTree, tmpnode, +1 ); - KeySet( pBTree, tmpnode, c_count, KeyGet( pBTree, ulNode, iPosition, buffer ) ); - BranchSet( pBTree, tmpnode, c_count, BranchGet( pBTree, BranchGet( pBTree, ulNode, iPosition ), 0 ) ); + tmpnode = BranchGet( pBTree, ulNode, iPosition - 1 ); + c_count = CountAdj( pBTree, tmpnode, +1 ); + KeySet( pBTree, tmpnode, c_count, KeyGet( pBTree, ulNode, iPosition, buffer ) ); + BranchSet( pBTree, tmpnode, c_count, + BranchGet( pBTree, BranchGet( pBTree, ulNode, iPosition ), 0 ) ); - tmpnode = BranchGet( pBTree, ulNode, iPosition ); - KeySet( pBTree, ulNode, iPosition, KeyGet( pBTree, tmpnode, 1, buffer ) ); - BranchSet( pBTree, tmpnode, 0, BranchGet( pBTree, tmpnode, 1 ) ); - c_count = CountAdj( pBTree, tmpnode, -1 ); + tmpnode = BranchGet( pBTree, ulNode, iPosition ); + KeySet( pBTree, ulNode, iPosition, KeyGet( pBTree, tmpnode, 1, buffer ) ); + BranchSet( pBTree, tmpnode, 0, BranchGet( pBTree, tmpnode, 1 ) ); + c_count = CountAdj( pBTree, tmpnode, -1 ); - for ( c = 1; c <= c_count; c++ ) - { - NodeCopy( pBTree, tmpnode, c, tmpnode, c + 1, buffer ); - } + for( c = 1; c <= c_count; c++ ) + { + NodeCopy( pBTree, tmpnode, c, tmpnode, c + 1, buffer ); + } - BufferRelease( buffer ); + BufferRelease( buffer ); } static void Combine( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - int c, c_count; - HB_ULONG tmpnode; - HB_ULONG leftnode; - HB_ULONG leftpagecount; - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + int c, c_count; + HB_ULONG tmpnode; + HB_ULONG leftnode; + HB_ULONG leftpagecount; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - tmpnode = BranchGet( pBTree, ulNode, iPosition ); - leftnode = BranchGet( pBTree, ulNode, iPosition - 1 ); - leftpagecount = CountAdj( pBTree, leftnode, +1 ); - KeySet( pBTree, leftnode, leftpagecount, KeyGet( pBTree, ulNode, iPosition, buffer ) ); - BranchSet( pBTree, leftnode, leftpagecount, BranchGet( pBTree, tmpnode, 0 ) ); + tmpnode = BranchGet( pBTree, ulNode, iPosition ); + leftnode = BranchGet( pBTree, ulNode, iPosition - 1 ); + leftpagecount = CountAdj( pBTree, leftnode, +1 ); + KeySet( pBTree, leftnode, leftpagecount, KeyGet( pBTree, ulNode, iPosition, buffer ) ); + BranchSet( pBTree, leftnode, leftpagecount, BranchGet( pBTree, tmpnode, 0 ) ); - c_count = CountGet( pBTree, tmpnode ); - for ( c = 1; c <= c_count; c++ ) - { - leftpagecount = CountAdj( pBTree, leftnode, +1 ); - NodeCopy( pBTree, leftnode, leftpagecount, tmpnode, c, buffer ); - } + c_count = CountGet( pBTree, tmpnode ); + for( c = 1; c <= c_count; c++ ) + { + leftpagecount = CountAdj( pBTree, leftnode, +1 ); + NodeCopy( pBTree, leftnode, leftpagecount, tmpnode, c, buffer ); + } - c_count = CountGet( pBTree, ulNode ); - for ( c = iPosition; c < c_count; c++ ) - { - NodeCopy( pBTree, ulNode, c, ulNode, c + 1, buffer ); - } - ( void )CountAdj( pBTree, ulNode, -1 ); + c_count = CountGet( pBTree, ulNode ); + for( c = iPosition; c < c_count; c++ ) + { + NodeCopy( pBTree, ulNode, c, ulNode, c + 1, buffer ); + } + ( void ) CountAdj( pBTree, ulNode, -1 ); - Prune( pBTree, tmpnode ); - BufferRelease( buffer ); + Prune( pBTree, tmpnode ); + BufferRelease( buffer ); } static void Restore( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - READPAGE_IF_NEEDED( pBTree, ulNode ); + READPAGE_IF_NEEDED( pBTree, ulNode ); - if ( iPosition == 0 ) /* left-most key */ - { - if ( CountGet( pBTree, BranchGet( pBTree, ulNode, 1 ) ) > pBTree->usMinKeys ) - { - MoveLeft( pBTree, ulNode, 1 ); - } - else - { - Combine( pBTree, ulNode, 1 ); - } - } - else if ( iPosition == CountGet( pBTree, ulNode ) ) /* right-most key */ - { - if ( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) > pBTree->usMinKeys ) - { + if( iPosition == 0 ) /* left-most key */ + { + if( CountGet( pBTree, BranchGet( pBTree, ulNode, 1 ) ) > pBTree->usMinKeys ) + { + MoveLeft( pBTree, ulNode, 1 ); + } + else + { + Combine( pBTree, ulNode, 1 ); + } + } + else if( iPosition == CountGet( pBTree, ulNode ) ) /* right-most key */ + { + if( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) > pBTree->usMinKeys ) + { + MoveRight( pBTree, ulNode, iPosition ); + } + else + { + Combine( pBTree, ulNode, iPosition ); + } + } + else if( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) > pBTree->usMinKeys ) + { MoveRight( pBTree, ulNode, iPosition ); - } - else - { + } + else if( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition + 1 ) ) > pBTree->usMinKeys ) + { + MoveLeft( pBTree, ulNode, iPosition + 1 ); + } + else Combine( pBTree, ulNode, iPosition ); - } - } - else if ( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) > pBTree->usMinKeys ) - { - MoveRight( pBTree, ulNode, iPosition ); - } - else if ( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition + 1 ) ) > pBTree->usMinKeys ) - { - MoveLeft( pBTree, ulNode, iPosition + 1 ); - } - else - Combine( pBTree, ulNode, iPosition ); } static void Remove( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - int c, c_count; - hb_KeyData_T *buffer = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + int c, c_count; + hb_KeyData_T * buffer = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - c_count = CountGet( pBTree, ulNode ); - for ( c = iPosition + 1; c <= c_count; c++ ) - { - NodeCopy( pBTree, ulNode, c - 1, ulNode, c, buffer ); - } - ( void )CountAdj( pBTree, ulNode, -1 ); - BufferRelease( buffer ); + c_count = CountGet( pBTree, ulNode ); + for( c = iPosition + 1; c <= c_count; c++ ) + { + NodeCopy( pBTree, ulNode, c - 1, ulNode, c, buffer ); + } + ( void ) CountAdj( pBTree, ulNode, -1 ); + BufferRelease( buffer ); } static void Successor( struct hb_BTree * pBTree, HB_ULONG ulNode, int iPosition ) { - HB_ULONG tmpnode; - hb_KeyData_T *buffer; + HB_ULONG tmpnode; + hb_KeyData_T * buffer; - for ( tmpnode = BranchGet( pBTree, ulNode, iPosition ); - !BTREENODEISNULL( pBTree, BranchGet( pBTree, tmpnode, 0 ) ); - tmpnode = BranchGet( pBTree, tmpnode, 0 ) ) {} + for( tmpnode = BranchGet( pBTree, ulNode, iPosition ); + ! BTREENODEISNULL( pBTree, BranchGet( pBTree, tmpnode, 0 ) ); + tmpnode = BranchGet( pBTree, tmpnode, 0 ) ) + { + } - KeySet( pBTree, ulNode, iPosition, ( buffer = KeyGet( pBTree, tmpnode, 1, NULL ) ) ); - BufferRelease( buffer ); + KeySet( pBTree, ulNode, iPosition, ( buffer = KeyGet( pBTree, tmpnode, 1, NULL ) ) ); + BufferRelease( buffer ); } #ifdef DEBUG - static HB_ULONG sulMaxRecDeleteDepth = 0; +static HB_ULONG sulMaxRecDeleteDepth = 0; #endif -static HB_BOOL RecDelete( struct hb_BTree * pBTree, hb_KeyData_T *target, HB_ULONG ulNode ) +static HB_BOOL RecDelete( struct hb_BTree * pBTree, hb_KeyData_T * target, HB_ULONG ulNode ) { #ifdef DEBUG - static HB_ULONG RecDeleteDepth = 0; + static HB_ULONG RecDeleteDepth = 0; #endif - int iPosition; - HB_BOOL found; + int iPosition; + HB_BOOL found; - if ( BTREENODEISNULL( pBTree, ulNode ) ) - { - /* todo: hitting an empty pBTree is an error */ - return HB_FALSE; - } - else - { + if( BTREENODEISNULL( pBTree, ulNode ) ) + { + /* todo: hitting an empty pBTree is an error */ + return HB_FALSE; + } + else + { #ifdef DEBUG - if( ++RecDeleteDepth > sulMaxRecDeleteDepth ) - { - sulMaxRecDeleteDepth = RecDeleteDepth; - if ( RecDeleteDepth > 10 ) { HB_TRACE( HB_TR_ERROR, ( "RecDelete( Exiting 2! )" ) ); exit(0); } - } -#endif - /* inline assignment & comparision was generating a Borland warning */ - found = SearchNode( pBTree, target, ulNode, &iPosition ); - if ( found ) - { - if ( !BTREENODEISNULL( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) ) + if( ++RecDeleteDepth > sulMaxRecDeleteDepth ) { - Successor( pBTree, ulNode, iPosition ); /* move successor to this iPosition */ - KeyGet( pBTree, ulNode, iPosition, target ); - found = RecDelete( pBTree, target, BranchGet( pBTree, ulNode, iPosition ) ); -#if 0 - if ( !found ) - error( "key not found" ); /* key exists, so this shouldn't occur*/ + sulMaxRecDeleteDepth = RecDeleteDepth; + if( RecDeleteDepth > 10 ) + { + HB_TRACE( HB_TR_ERROR, ( "RecDelete( Exiting 2! )" ) ); exit( 0 ); + } + } #endif + /* inline assignment & comparision was generating a Borland warning */ + found = SearchNode( pBTree, target, ulNode, &iPosition ); + if( found ) + { + if( ! BTREENODEISNULL( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) ) + { + Successor( pBTree, ulNode, iPosition ); /* move successor to this iPosition */ + KeyGet( pBTree, ulNode, iPosition, target ); + found = RecDelete( pBTree, target, BranchGet( pBTree, ulNode, iPosition ) ); +#if 0 + if( ! found ) + error( "key not found" ); /* key exists, so this shouldn't occur*/ +#endif + } + else + Remove( pBTree, ulNode, iPosition ); } else - Remove( pBTree, ulNode, iPosition ); - } - else - found = RecDelete( pBTree, target, BranchGet( pBTree, ulNode, iPosition ) ); + found = RecDelete( pBTree, target, BranchGet( pBTree, ulNode, iPosition ) ); - /* the recursive call has returned */ - if ( found && !BTREENODEISNULL( pBTree, BranchGet( pBTree, ulNode, iPosition ) ) ) - if ( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition ) ) < pBTree->usMinKeys ) - Restore( pBTree, ulNode, iPosition ); + /* the recursive call has returned */ + if( found && ! BTREENODEISNULL( pBTree, BranchGet( pBTree, ulNode, iPosition ) ) ) + if( CountGet( pBTree, BranchGet( pBTree, ulNode, iPosition ) ) < pBTree->usMinKeys ) + Restore( pBTree, ulNode, iPosition ); #ifdef DEBUG ---RecDeleteDepth; + --RecDeleteDepth; #endif - return found; - } + return found; + } } #if 0 - static HB_BOOL __RecDelete( struct hb_BTree * pBTree, hb_KeyData_T target, HB_ULONG ulNode ) - { - static HB_ULONG RecDeleteDepth = 0; - HB_BOOL found = HB_FALSE; +static HB_BOOL __RecDelete( struct hb_BTree * pBTree, hb_KeyData_T target, HB_ULONG ulNode ) +{ + static HB_ULONG RecDeleteDepth = 0; + HB_BOOL found = HB_FALSE; if( ++RecDeleteDepth > sulMaxRecDeleteDepth ) { - sulMaxRecDeleteDepth = RecDeleteDepth; + sulMaxRecDeleteDepth = RecDeleteDepth; } - if ( !BTREENODEISNULL( pBTree, ulNode ) ) + if( ! BTREENODEISNULL( pBTree, ulNode ) ) { int iPosition; - /* hb_KeyData_T tmpTarget; */ - /* */ - /* tmpTarget = BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); */ - /* hb_xmemcpy( tmpTarget, target, pBTree->usKeySize ); */ + /* hb_KeyData_T tmpTarget; */ + /* */ + /* tmpTarget = BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); */ + /* hb_xmemcpy( tmpTarget, target, pBTree->usKeySize ); */ #define tmpTarget target - /* inline assignment & comparision was generating a Borland warning */ - found = SearchNode( pBTree, tmpTarget, ulNode, &iPosition ) - if ( found ) - { - if ( !BTREENODEISNULL( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) ) - { - Successor( pBTree, ulNode, iPosition ); - hb_xmemcpy( tmpTarget, KeyGet( pBTree, ulNode, iPosition ), pBTree->usKeySize ); - /*if ( !( found =*/ RecDelete( pBTree, tmpTarget, BranchGet( pBTree, ulNode, iPosition ) );/*) )*/ - /* RESETFLAG( pBTree, IsRecordFound )*/ /*pBTree->bRecordNotFound = HB_TRUE*/; /* error */ - } - else - { - Remove( pBTree, ulNode, iPosition ); - } - } - else - { - if ( !( found = RecDelete( pBTree, tmpTarget, BranchGet( pBTree, ulNode, iPosition ) ) ) ) - RESETFLAG( pBTree, IsRecordFound ); /* error */ - } + /* inline assignment & comparision was generating a Borland warning */ + found = SearchNode( pBTree, tmpTarget, ulNode, &iPosition ) + if( found ) + { + if( ! BTREENODEISNULL( pBTree, BranchGet( pBTree, ulNode, iPosition - 1 ) ) ) + { + Successor( pBTree, ulNode, iPosition ); + hb_xmemcpy( tmpTarget, KeyGet( pBTree, ulNode, iPosition ), pBTree->usKeySize ); + /*if ( !( found =*/ RecDelete( pBTree, tmpTarget, BranchGet( pBTree, ulNode, iPosition ) ); /*) )*/ + /* RESETFLAG( pBTree, IsRecordFound )*/ /*pBTree->bRecordNotFound = HB_TRUE*/; /* error */ + } + else + { + Remove( pBTree, ulNode, iPosition ); + } + } + else + { + if( ! ( found = RecDelete( pBTree, tmpTarget, BranchGet( pBTree, ulNode, iPosition ) ) ) ) + RESETFLAG( pBTree, IsRecordFound ); /* error */ + } - /* if ( GETFLAG( pBTree, IsRecordFound )*/ /*!tree->bRecordNotFound )*/ - { - HB_ULONG tmpNode; + /* if ( GETFLAG( pBTree, IsRecordFound )*/ /*!tree->bRecordNotFound )*/ + { + HB_ULONG tmpNode; - tmpNode = BranchGet( pBTree, ulNode, iPosition ); - if ( !BTREENODEISNULL( pBTree, tmpNode ) ) - if ( CountGet( pBTree, tmpNode ) < pBTree->usMinKeys ) - Restore( pBTree, ulNode, iPosition ); - } + tmpNode = BranchGet( pBTree, ulNode, iPosition ); + if( ! BTREENODEISNULL( pBTree, tmpNode ) ) + if( CountGet( pBTree, tmpNode ) < pBTree->usMinKeys ) + Restore( pBTree, ulNode, iPosition ); + } - /*BufferRelease( tmpTarget );*/ + /*BufferRelease( tmpTarget );*/ #undef tmpTarget } else - RESETFLAG( pBTree, IsRecordFound ); /* error */ + RESETFLAG( pBTree, IsRecordFound ); /* error */ --RecDeleteDepth; return found; - } +} #endif -HB_BOOL hb_BTreeDelete( struct hb_BTree * pBTree, const char *target, HB_LONG lData ) +HB_BOOL hb_BTreeDelete( struct hb_BTree * pBTree, const char * target, HB_LONG lData ) { - HB_ULONG ulNode; - int iPosition; - hb_KeyData_T *tmpTarget; - HB_BOOL found = HB_FALSE; + HB_ULONG ulNode; + int iPosition; + hb_KeyData_T * tmpTarget; + HB_BOOL found = HB_FALSE; - SETFLAG( pBTree, IsRecordFound ); - CLEARKEYDATA( pBTree ); + SETFLAG( pBTree, IsRecordFound ); + CLEARKEYDATA( pBTree ); - tmpTarget = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - hb_xmemcpy( tmpTarget->szKey, target, pBTree->usKeySize ); - tmpTarget->xData.lData = lData; + tmpTarget = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + hb_xmemcpy( tmpTarget->szKey, target, pBTree->usKeySize ); + tmpTarget->xData.lData = lData; - if ( hb_BTreeSearch( pBTree, tmpTarget, &iPosition, NULL ) ) - { - if ( RecDelete( pBTree, tmpTarget, pBTree->ulRootPage ) ) - { - found = HB_TRUE; - if ( CountGet( pBTree, pBTree->ulRootPage ) == 0 ) + if( hb_BTreeSearch( pBTree, tmpTarget, &iPosition, NULL ) ) + { + if( RecDelete( pBTree, tmpTarget, pBTree->ulRootPage ) ) { - ulNode = pBTree->ulRootPage; - pBTree->ulRootPage = BranchGet( pBTree, pBTree->ulRootPage, 0 ); - Prune( pBTree, ulNode ); + found = HB_TRUE; + if( CountGet( pBTree, pBTree->ulRootPage ) == 0 ) + { + ulNode = pBTree->ulRootPage; + pBTree->ulRootPage = BranchGet( pBTree, pBTree->ulRootPage, 0 ); + Prune( pBTree, ulNode ); + } } - } #if 0 - else - {} /* error - key does not exist */ + else + { + } /* error - key does not exist */ #endif - } - else - RESETFLAG( pBTree, IsRecordFound ); + } + else + RESETFLAG( pBTree, IsRecordFound ); - BufferRelease( tmpTarget ); + BufferRelease( tmpTarget ); - if ( found ) - pBTree->ulKeyCount--; + if( found ) + pBTree->ulKeyCount--; - return found;/*!tree->bRecordNotFound;*/ + return found; /*!tree->bRecordNotFound;*/ } void hb_BTreeGoTop( struct hb_BTree * pBTree ) { - HB_ULONG ulNode; - HB_ULONG ulLastNode; + HB_ULONG ulNode; + HB_ULONG ulLastNode; - for ( ulLastNode = ulNode = pBTree->ulRootPage; !BTREENODEISNULL( pBTree, ulNode ); ulLastNode = ulNode, ulNode = BranchGet( pBTree, ulNode, 0 ) ) {} + for( ulLastNode = ulNode = pBTree->ulRootPage; ! BTREENODEISNULL( pBTree, ulNode ); + ulLastNode = ulNode, ulNode = BranchGet( pBTree, ulNode, 0 ) ) + { + } - if ( BTREENODEISNULL( pBTree, ulLastNode ) ) - CLEARKEYDATA( pBTree ); - else - KeyGet( pBTree, ulLastNode, 1, pBTree->pThisKeyData ); + if( BTREENODEISNULL( pBTree, ulLastNode ) ) + CLEARKEYDATA( pBTree ); + else + KeyGet( pBTree, ulLastNode, 1, pBTree->pThisKeyData ); } void hb_BTreeGoBottom( struct hb_BTree * pBTree ) { - HB_ULONG ulNode; - HB_ULONG ulLastNode; + HB_ULONG ulNode; + HB_ULONG ulLastNode; - for ( ulLastNode = ulNode = pBTree->ulRootPage; !BTREENODEISNULL( pBTree, ulNode ); ulLastNode = ulNode, ulNode = BranchGet( pBTree, ulNode, CountGet( pBTree, ulNode ) ) ) {} + for( ulLastNode = ulNode = pBTree->ulRootPage; ! BTREENODEISNULL( pBTree, ulNode ); + ulLastNode = ulNode, ulNode = BranchGet( pBTree, ulNode, CountGet( pBTree, ulNode ) ) ) + { + } - if ( BTREENODEISNULL( pBTree, ulLastNode ) ) - CLEARKEYDATA( pBTree ); - else - KeyGet( pBTree, ulLastNode, CountGet( pBTree, ulLastNode ), pBTree->pThisKeyData ); + if( BTREENODEISNULL( pBTree, ulLastNode ) ) + CLEARKEYDATA( pBTree ); + else + KeyGet( pBTree, ulLastNode, CountGet( pBTree, ulLastNode ), pBTree->pThisKeyData ); } HB_LONG hb_BTreeSkip( struct hb_BTree * pBTree, HB_LONG records ) { - HB_LONG results = 0; - int iPosition; - hb_KeyData_T *keydata; - BTreeStack *pStack = NULL; + HB_LONG results = 0; + int iPosition; + hb_KeyData_T * keydata; + BTreeStack * pStack = NULL; - if ( BTREENODEISNULL( pBTree, pBTree->ulRootPage ) ) - { - CLEARKEYDATA( pBTree ); - return 0; - } + if( BTREENODEISNULL( pBTree, pBTree->ulRootPage ) ) + { + CLEARKEYDATA( pBTree ); + return 0; + } - keydata = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - hb_xmemcpy( keydata->szKey, pBTree->pThisKeyData->szKey, pBTree->usKeySize ); - keydata->xData.lData = pBTree->pThisKeyData->xData.lData; + keydata = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + hb_xmemcpy( keydata->szKey, pBTree->pThisKeyData->szKey, pBTree->usKeySize ); + keydata->xData.lData = pBTree->pThisKeyData->xData.lData; - StackNew( &pStack ); - if ( !BTREENODEISNULL( pBTree, hb_BTreeSearch( pBTree, keydata, &iPosition, &pStack ) ) ) - { - results = StackSkip( pBTree, &pStack, records ); - } - else - { - CLEARKEYDATA( pBTree ); - } + StackNew( &pStack ); + if( ! BTREENODEISNULL( pBTree, hb_BTreeSearch( pBTree, keydata, &iPosition, &pStack ) ) ) + { + results = StackSkip( pBTree, &pStack, records ); + } + else + { + CLEARKEYDATA( pBTree ); + } - StackRelease( &pStack ); - BufferRelease( keydata ); + StackRelease( &pStack ); + BufferRelease( keydata ); - return results; + return results; } -HB_BOOL hb_BTreeSeek( struct hb_BTree * pBTree, const char *szKey, HB_LONG lData, HB_BOOL bSoftSeek ) +HB_BOOL hb_BTreeSeek( struct hb_BTree * pBTree, const char * szKey, HB_LONG lData, + HB_BOOL bSoftSeek ) { - HB_BOOL results = HB_FALSE; - int iPosition; - hb_KeyData_T *tmpTarget; - BTreeStack *pStack = NULL; + HB_BOOL results = HB_FALSE; + int iPosition; + hb_KeyData_T * tmpTarget; + BTreeStack * pStack = NULL; - tmpTarget = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - hb_xmemcpy( tmpTarget->szKey, szKey, pBTree->usKeySize ); - tmpTarget->xData.lData = lData; + tmpTarget = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + hb_xmemcpy( tmpTarget->szKey, szKey, pBTree->usKeySize ); + tmpTarget->xData.lData = lData; - StackNew( &pStack ); - if ( !BTREENODEISNULL( pBTree, hb_BTreeSearch( pBTree, tmpTarget, &iPosition, &pStack ) ) || + StackNew( &pStack ); + if( ! BTREENODEISNULL( pBTree, hb_BTreeSearch( pBTree, tmpTarget, &iPosition, &pStack ) ) || ( bSoftSeek && pStack->usCount > 0 && ( 1 == StackSkip( pBTree, &pStack, 1 ) ) ) ) - { - KeyGet( pBTree, STACKNODE( &pStack ), STACKPOSITION( &pStack ), pBTree->pThisKeyData ); - results = HB_TRUE; - } - else - { - CLEARKEYDATA( pBTree ); - } + { + KeyGet( pBTree, STACKNODE( &pStack ), STACKPOSITION( &pStack ), pBTree->pThisKeyData ); + results = HB_TRUE; + } + else + { + CLEARKEYDATA( pBTree ); + } - StackRelease( &pStack ); - BufferRelease( tmpTarget ); + StackRelease( &pStack ); + BufferRelease( tmpTarget ); - return results; + return results; } -static int hb_BTstrncmp( const char *s1, const char *s2, size_t n ) +static int hb_BTstrncmp( const char * s1, const char * s2, size_t n ) { return strncmp( s1, s2, n ); } /* allocate hb_BTree structure */ -struct hb_BTree * hb_BTreeNew( const char * FileName, HB_USHORT usPageSize, HB_USHORT usKeySize, HB_ULONG ulFlags, HB_ULONG ulBuffers ) +struct hb_BTree * hb_BTreeNew( const char * FileName, HB_USHORT usPageSize, HB_USHORT usKeySize, + HB_ULONG ulFlags, + HB_ULONG ulBuffers ) { - struct hb_BTree *pBTree = ( struct hb_BTree * ) BufferAlloc( sizeof( struct hb_BTree ) ); - int iFileIOmode; + struct hb_BTree * pBTree = ( struct hb_BTree * ) BufferAlloc( sizeof( struct hb_BTree ) ); + int iFileIOmode; - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - /* correct parameters to default values */ - if ( usKeySize < 8 ) usKeySize = 8; - if ( usPageSize % HB_BTREE_HEADERSIZE ) usPageSize -= ( usPageSize % HB_BTREE_HEADERSIZE ); - if ( usPageSize < HB_BTREE_HEADERSIZE ) usPageSize = HB_BTREE_HEADERSIZE; + /* correct parameters to default values */ + if( usKeySize < 8 ) + usKeySize = 8; + if( usPageSize % HB_BTREE_HEADERSIZE ) + usPageSize -= ( usPageSize % HB_BTREE_HEADERSIZE ); + if( usPageSize < HB_BTREE_HEADERSIZE ) + usPageSize = HB_BTREE_HEADERSIZE; - /* - number of keys is: - ( usPageSize - ( sizeof count + sizeof branch[0] ) ) / ( sizeof branch[0] + sizeof key ) - 1 - */ + /* + number of keys is: + ( usPageSize - ( sizeof count + sizeof branch[0] ) ) / ( sizeof branch[0] + sizeof key ) - 1 + */ /* this assumes that the count field and a branch field are HB_U32 */ #define MAXKEYS( pagesize, keysize, flags ) \ - ( ( ( pagesize ) - ( sizeof( HB_U32 ) + sizeof( HB_U32 ) ) ) / \ - ( sizeof( HB_U32 ) \ - + ( ( ( flags ) & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY \ - ? sizeof( PHB_ITEM * ) \ - : ( keysize ) ) ) - 1 \ - ) + ( ( ( pagesize ) - ( sizeof( HB_U32 ) + sizeof( HB_U32 ) ) ) / \ + ( sizeof( HB_U32 ) \ + + ( ( ( flags ) & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY \ + ? sizeof( PHB_ITEM * ) \ + : ( keysize ) ) ) - 1 \ + ) #define MINKEYS( maxkeys ) ( ( maxkeys + 1 ) / 2 - ( maxkeys % 2 ) ) - if ( ( ulFlags & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY ) - { - pBTree->hFile = 0; - pBTree->szFileName = NULL; - pBTree->IsDirtyFlagAssignment = HB_FALSE; /* replaces const value for assignment */ - } - else - { - pBTree->IsDirtyFlagAssignment = HB_TRUE; /* replaces const value for assignment */ + if( ( ulFlags & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY ) + { + pBTree->hFile = 0; + pBTree->szFileName = NULL; + pBTree->IsDirtyFlagAssignment = HB_FALSE; /* replaces const value for assignment */ + } + else + { + pBTree->IsDirtyFlagAssignment = HB_TRUE; /* replaces const value for assignment */ - if ( ( ulFlags & ( HB_BTREE_READONLY ) ) == HB_BTREE_READONLY ) - { - iFileIOmode = FC_READONLY; - ulFlags &= ~HB_BTREE_READONLY; - ulFlags &= ~HB_BTREE_SHARED; - } - else - { - iFileIOmode = FC_NORMAL; - } - - pBTree->hFile = hb_fsCreate( FileName, iFileIOmode ); - if ( pBTree->hFile == -1 ) - { - BufferRelease( pBTree ); - return NULL; - } - - if ( ( ulFlags & ( HB_BTREE_SHARED ) ) == HB_BTREE_SHARED ) - { - hb_fsClose( pBTree->hFile ); - pBTree->hFile = hb_fsOpen( FileName, FO_READWRITE | FO_SHARED ); - if ( pBTree->hFile == -1 ) + if( ( ulFlags & ( HB_BTREE_READONLY ) ) == HB_BTREE_READONLY ) { - BufferRelease( pBTree ); - return NULL; + iFileIOmode = FC_READONLY; + ulFlags &= ~HB_BTREE_READONLY; + ulFlags &= ~HB_BTREE_SHARED; + } + else + { + iFileIOmode = FC_NORMAL; } - } - pBTree->szFileName = hb_strdup( FileName ); - } + pBTree->hFile = hb_fsCreate( FileName, iFileIOmode ); + if( pBTree->hFile == -1 ) + { + BufferRelease( pBTree ); + return NULL; + } - pBTree->ulFreePage = NULLPAGE; - pBTree->ulRootPage = NULLPAGE; - pBTree->usPageSize = usPageSize; - pBTree->usKeySize = usKeySize; - pBTree->usMaxKeys = ( HB_USHORT ) MAXKEYS( usPageSize, usKeySize, ulFlags ); - pBTree->usMinKeys = ( HB_USHORT ) MINKEYS( pBTree->usMaxKeys ); - pBTree->ulFlags = ulFlags; - pBTree->ulKeyCount = 0; - pBTree->pStack = NULL; + if( ( ulFlags & ( HB_BTREE_SHARED ) ) == HB_BTREE_SHARED ) + { + hb_fsClose( pBTree->hFile ); + pBTree->hFile = hb_fsOpen( FileName, FO_READWRITE | FO_SHARED ); + if( pBTree->hFile == -1 ) + { + BufferRelease( pBTree ); + return NULL; + } + } + + pBTree->szFileName = hb_strdup( FileName ); + } + + pBTree->ulFreePage = NULLPAGE; + pBTree->ulRootPage = NULLPAGE; + pBTree->usPageSize = usPageSize; + pBTree->usKeySize = usKeySize; + pBTree->usMaxKeys = ( HB_USHORT ) MAXKEYS( usPageSize, usKeySize, ulFlags ); + pBTree->usMinKeys = ( HB_USHORT ) MINKEYS( pBTree->usMaxKeys ); + pBTree->ulFlags = ulFlags; + pBTree->ulKeyCount = 0; + pBTree->pStack = NULL; /* TODO: use stack optimization if flags warrant: if ( flag... ) StackNew( &pBTree->pStack ); */ - pBTree->pThisKeyData = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - CLEARKEYDATA( pBTree ); - ioBufferAlloc( pBTree, ulBuffers ); + pBTree->pThisKeyData = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + CLEARKEYDATA( pBTree ); + ioBufferAlloc( pBTree, ulBuffers ); - if ( GETFLAG( pBTree, IsCaseLess ) ) - { - pBTree->pStrCompare = ( BTreeCmpFunc ) hb_strnicmp; - } - else - { - pBTree->pStrCompare = ( BTreeCmpFunc ) hb_BTstrncmp; - } + if( GETFLAG( pBTree, IsCaseLess ) ) + { + pBTree->pStrCompare = ( BTreeCmpFunc ) hb_strnicmp; + } + else + { + pBTree->pStrCompare = ( BTreeCmpFunc ) hb_BTstrncmp; + } - if ( GETFLAG( pBTree, IsInMemory ) == HB_FALSE ) - { - HeaderWrite( pBTree ); - } - else /* IsInMemory == HB_TRUE */ - { - RESETFLAG( pBTree, HB_BTREE_UNIQUE ); /* clear this flag */ - } + if( GETFLAG( pBTree, IsInMemory ) == HB_FALSE ) + { + HeaderWrite( pBTree ); + } + else /* IsInMemory == HB_TRUE */ + { + RESETFLAG( pBTree, HB_BTREE_UNIQUE ); /* clear this flag */ + } - return pBTree; + return pBTree; } /* open an existing structure */ -struct hb_BTree *hb_BTreeOpen( const char *FileName, HB_ULONG ulFlags, HB_ULONG ulBuffers ) +struct hb_BTree * hb_BTreeOpen( const char * FileName, HB_ULONG ulFlags, HB_ULONG ulBuffers ) { - struct hb_BTree *pBTree = ( struct hb_BTree * ) BufferAlloc( sizeof( struct hb_BTree ) ); - HB_BYTE TmpHeader[ HB_BTREE_HEADERSIZE ]; - HB_BYTE * pHeader = &TmpHeader[ 0 ]; + struct hb_BTree * pBTree = ( struct hb_BTree * ) BufferAlloc( sizeof( struct hb_BTree ) ); + HB_BYTE TmpHeader[ HB_BTREE_HEADERSIZE ]; + HB_BYTE * pHeader = &TmpHeader[ 0 ]; - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - pBTree->szFileName = hb_strdup( FileName ); - pBTree->hFile = hb_fsOpen( pBTree->szFileName, ( ( ulFlags & HB_BTREE_READONLY ) ? FO_READ : FO_READWRITE ) ); - if ( pBTree->hFile == -1 ) - { - BufferRelease( pBTree ); - return NULL; - } + pBTree->szFileName = hb_strdup( FileName ); + pBTree->hFile = + hb_fsOpen( pBTree->szFileName, ( ( ulFlags & HB_BTREE_READONLY ) ? FO_READ : FO_READWRITE ) ); + if( pBTree->hFile == -1 ) + { + BufferRelease( pBTree ); + return NULL; + } - hb_fsRead( pBTree->hFile, TmpHeader, sizeof( TmpHeader ) ); - if ( memcmp( TmpHeader, HEADER_ID, sizeof( HEADER_ID ) ) != 0 ) - { - hb_fsClose( pBTree->hFile ); - BufferRelease( pBTree ); - return NULL; - } + hb_fsRead( pBTree->hFile, TmpHeader, sizeof( TmpHeader ) ); + if( memcmp( TmpHeader, HEADER_ID, sizeof( HEADER_ID ) ) != 0 ) + { + hb_fsClose( pBTree->hFile ); + BufferRelease( pBTree ); + return NULL; + } - pHeader += sizeof( HEADER_ID ) - 1; /* the trailing null byte */ - pHeader += sizeof( HB_U32 ); /* skip over the header size (HB_BTREE_HEADERSIZE) field */ - pBTree->usPageSize = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; - pBTree->usKeySize = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; - pBTree->usMaxKeys = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; - pBTree->usMinKeys = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; - pBTree->ulFlags = HB_GET_LE_UINT32( pHeader ) | ( ulFlags & HB_BTREE_READONLY ); + pHeader += sizeof( HEADER_ID ) - 1; /* the trailing null byte */ + pHeader += sizeof( HB_U32 ); /* skip over the header size (HB_BTREE_HEADERSIZE) field */ + pBTree->usPageSize = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; + pBTree->usKeySize = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; + pBTree->usMaxKeys = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; + pBTree->usMinKeys = ( HB_U16 ) HB_GET_LE_UINT32( pHeader ); pHeader += 4; + pBTree->ulFlags = HB_GET_LE_UINT32( pHeader ) | ( ulFlags & HB_BTREE_READONLY ); - pHeader = &TmpHeader[ 64 ]; - pBTree->ulRootPage = HB_GET_LE_UINT32( pHeader ); pHeader += 4; - pBTree->ulFreePage = HB_GET_LE_UINT32( pHeader ); pHeader += 4; - pBTree->ulKeyCount = HB_GET_LE_UINT32( pHeader ); + pHeader = &TmpHeader[ 64 ]; + pBTree->ulRootPage = HB_GET_LE_UINT32( pHeader ); pHeader += 4; + pBTree->ulFreePage = HB_GET_LE_UINT32( pHeader ); pHeader += 4; + pBTree->ulKeyCount = HB_GET_LE_UINT32( pHeader ); - pBTree->pThisKeyData = ( hb_KeyData_T * ) BufferAlloc( sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); - CLEARKEYDATA( pBTree ); - pBTree->pStack = NULL; + pBTree->pThisKeyData = ( hb_KeyData_T * ) BufferAlloc( + sizeof( hb_KeyData_T ) + pBTree->usKeySize + 1 ); + CLEARKEYDATA( pBTree ); + pBTree->pStack = NULL; /* TODO: use stack optimization if flags warrant: if ( flag... ) StackNew( &pBTree->pStack ); */ - ioBufferAlloc( pBTree, ulBuffers ); + ioBufferAlloc( pBTree, ulBuffers ); - RESETFLAG( pBTree, HB_BTREE_INMEMORY ); /* clear this flag */ - pBTree->IsDirtyFlagAssignment = HB_TRUE; /* replaces const value for assignment */ + RESETFLAG( pBTree, HB_BTREE_INMEMORY ); /* clear this flag */ + pBTree->IsDirtyFlagAssignment = HB_TRUE; /* replaces const value for assignment */ - if ( GETFLAG( pBTree, IsCaseLess ) ) - { - pBTree->pStrCompare = ( BTreeCmpFunc ) hb_strnicmp; - } - else - { - pBTree->pStrCompare = ( BTreeCmpFunc ) hb_BTstrncmp; - } + if( GETFLAG( pBTree, IsCaseLess ) ) + { + pBTree->pStrCompare = ( BTreeCmpFunc ) hb_strnicmp; + } + else + { + pBTree->pStrCompare = ( BTreeCmpFunc ) hb_BTstrncmp; + } - return pBTree; + return pBTree; } void hb_BTreeClose( struct hb_BTree * pBTree ) { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - ioBufferRelease( pBTree ); + ioBufferRelease( pBTree ); - if ( GETFLAG( pBTree, IsInMemory ) == HB_FALSE && + if( GETFLAG( pBTree, IsInMemory ) == HB_FALSE && GETFLAG( pBTree, IsReadOnly ) == HB_FALSE ) - { - HeaderWrite( pBTree ); - } + { + HeaderWrite( pBTree ); + } - if ( pBTree->hFile != 0 ) - { - hb_fsClose( pBTree->hFile ); - } + if( pBTree->hFile != 0 ) + { + hb_fsClose( pBTree->hFile ); + } - if ( pBTree->szFileName != NULL ) - { - BufferRelease( pBTree->szFileName ); - } + if( pBTree->szFileName != NULL ) + { + BufferRelease( pBTree->szFileName ); + } - StackRelease( &pBTree->pStack ); - BufferRelease( pBTree->pThisKeyData ); - BufferRelease( pBTree ); + StackRelease( &pBTree->pStack ); + BufferRelease( pBTree->pThisKeyData ); + BufferRelease( pBTree ); } const char * hb_BTreeKey( struct hb_BTree * pBTree ) { - return ( const char * )pBTree->pThisKeyData->szKey; + return ( const char * ) pBTree->pThisKeyData->szKey; } HB_LONG hb_BTreeData( struct hb_BTree * pBTree ) { - return pBTree->pThisKeyData->xData.lData; + return pBTree->pThisKeyData->xData.lData; } PHB_ITEM hb_BTreeDataItem( struct hb_BTree * pBTree ) { - return ( PHB_ITEM ) pBTree->pThisKeyData->xData.pData; + return ( PHB_ITEM ) pBTree->pThisKeyData->xData.pData; } static int BTree_SetTreeIndex( struct hb_BTree * pBTree ) { - int n; + int n; - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( pBTree == NULL ) - return -1; + if( pBTree == NULL ) + return -1; - for ( n = 0; n < s_BTree_List_Count && s_BTree_List[ n ] != NULL; n++ ) {} + for( n = 0; n < s_BTree_List_Count && s_BTree_List[ n ] != NULL; n++ ) + { + } - if ( n == s_BTree_List_Count ) - { - s_BTree_List = (struct hb_BTree **) BufferRealloc( s_BTree_List, ++s_BTree_List_Count * sizeof( s_BTree_List[ 0 ] ) ); - } + if( n == s_BTree_List_Count ) + { + s_BTree_List = ( struct hb_BTree ** ) BufferRealloc( + s_BTree_List, ++s_BTree_List_Count * sizeof( s_BTree_List[ 0 ] ) ); + } - s_BTree_List[ n ] = pBTree; + s_BTree_List[ n ] = pBTree; - return n + 1; + return n + 1; } -static struct hb_BTree *BTree_GetTreeIndex( const char * GetSource ) +static struct hb_BTree * BTree_GetTreeIndex( const char * GetSource ) { - int index; + int index; - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - index = hb_parni( 1 ); - if ( index < 1 || index > s_BTree_List_Count || s_BTree_List[ index - 1 ] == NULL ) \ - { - raiseError( EG_ARG, HB_BTREE_EC_TREEHANDLE, "Bad HB_BTree handle", GetSource, 1 ); - return NULL; - } - else - return s_BTree_List[ index - 1 ]; + index = hb_parni( 1 ); + if( index < 1 || index > s_BTree_List_Count || s_BTree_List[ index - 1 ] == NULL ) + { + raiseError( EG_ARG, HB_BTREE_EC_TREEHANDLE, "Bad HB_BTree handle", GetSource, 1 ); + return NULL; + } + else + return s_BTree_List[ index - 1 ]; } HB_FUNC( HB_BTREEOPEN ) /* hb_BTreeOpen( CHAR cFileName, HB_ULONG ulFlags [ , int nBuffers=1 ] ) -> hb_Btree_Handle */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( HB_ISCHAR( 1 ) && hb_parclen( 1 ) > 0 ) - { - hb_retni( BTree_SetTreeIndex( hb_BTreeOpen( hb_parc( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) ) ); - } - else - { - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); - hb_retni( 0 ); - } + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( HB_ISCHAR( 1 ) && hb_parclen( 1 ) > 0 ) + { + hb_retni( BTree_SetTreeIndex( hb_BTreeOpen( hb_parc( 1 ), hb_parnl( 2 ), hb_parnl( 3 ) ) ) ); + } + else + { + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); + hb_retni( 0 ); + } } HB_FUNC( HB_BTREENEW ) /* hb_BTreeNew( CHAR cFileName, int nPageSize, int nKeySize, [ HB_ULONG ulFlags ], [ int nBuffers=1 ] ) -> hb_Btree_Handle */ { - int iPageSize = hb_parni( 2 ); - int iKeySize = hb_parni( 3 ); + int iPageSize = hb_parni( 2 ); + int iKeySize = hb_parni( 3 ); HB_ULONG ulFlags = hb_parnl( 4 ); - int iMaxKeys = MAXKEYS( ( HB_U32 ) iPageSize, ( HB_U32 ) iKeySize, ulFlags ); - int iMinKeys = MINKEYS( iMaxKeys ); + int iMaxKeys = MAXKEYS( ( HB_U32 ) iPageSize, ( HB_U32 ) iKeySize, ulFlags ); + int iMinKeys = MINKEYS( iMaxKeys ); - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( ( ( ulFlags & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY || ( HB_ISCHAR( 1 ) && hb_parclen( 1 ) > 0 ) ) && - ( HB_ISNUM( 2 ) && iPageSize >= 1024 && iPageSize < ( int )USHRT_MAX ) && - ( ( ulFlags & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY || ( HB_ISNUM( 3 ) && iKeySize >= 4 && iMinKeys > 0 && iMaxKeys > 2 ) ) && + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( ( ( ulFlags & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY || + ( HB_ISCHAR( 1 ) && hb_parclen( 1 ) > 0 ) ) && + ( HB_ISNUM( 2 ) && iPageSize >= 1024 && iPageSize < ( int ) USHRT_MAX ) && + ( ( ulFlags & HB_BTREE_INMEMORY ) == HB_BTREE_INMEMORY || + ( HB_ISNUM( 3 ) && iKeySize >= 4 && iMinKeys > 0 && iMaxKeys > 2 ) ) && ( 1 == 1 ) ) - { - hb_retni( BTree_SetTreeIndex( hb_BTreeNew( hb_parc( 1 ), ( HB_USHORT ) iPageSize, ( HB_USHORT ) iKeySize, ulFlags, hb_parnl( 5 ) ) ) ); - } - else - { - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); - hb_retni( 0 ); - } + { + hb_retni( BTree_SetTreeIndex( hb_BTreeNew( hb_parc( 1 ), ( HB_USHORT ) iPageSize, + ( HB_USHORT ) iKeySize, ulFlags, hb_parnl( 5 ) ) ) ); + } + else + { + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); + hb_retni( 0 ); + } } HB_FUNC( HB_BTREECLOSE ) /* hb_BTreeClose( hb_BTree_Handle ) -> NIL */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - hb_BTreeClose( BTree_GetTreeIndex( "hb_btreeclose" ) ); - s_BTree_List[ hb_parni( 1 ) - 1 ] = NULL; + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + hb_BTreeClose( BTree_GetTreeIndex( "hb_btreeclose" ) ); + s_BTree_List[ hb_parni( 1 ) - 1 ] = NULL; } HB_FUNC( HB_BTREEINSERT ) /* hb_BTreeInsert( hb_BTree_Handle, CHAR cKey, HB_LONG lData | ANY xData ) -> lSuccess */ { - struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreeinsert" ); - /* PHB_ITEM pKeyCode = hb_param( 1, HB_IT_NUMERIC ); */ + struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreeinsert" ); - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( HB_ISNUM( 1 ) && HB_ISCHAR( 2 ) && ( hb_pcount() == 2 || GETFLAG( pBTree, IsInMemory ) || HB_ISNUM( 3 ) ) ) - { - if ( GETFLAG( pBTree, IsReadOnly ) == HB_FALSE ) - { - hb_retl( hb_BTreeInsert( pBTree, hb_parc( 2 ), hb_paramError( 3 ) ) ); - } - else - { - raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "Cannot insert into a read-only file", HB_ERR_FUNCNAME, hb_pcount() ); + /* PHB_ITEM pKeyCode = hb_param( 1, HB_IT_NUMERIC ); */ + + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( HB_ISNUM( 1 ) && HB_ISCHAR( 2 ) && + ( hb_pcount() == 2 || GETFLAG( pBTree, IsInMemory ) || HB_ISNUM( 3 ) ) ) + { + if( GETFLAG( pBTree, IsReadOnly ) == HB_FALSE ) + { + hb_retl( hb_BTreeInsert( pBTree, hb_parc( 2 ), hb_paramError( 3 ) ) ); + } + else + { + raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "Cannot insert into a read-only file", + HB_ERR_FUNCNAME, + hb_pcount() ); + hb_retl( HB_FALSE ); + } + } + else + { + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); hb_retl( HB_FALSE ); - } - } - else - { - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); - hb_retl( HB_FALSE ); - } + } } HB_FUNC( HB_BTREEDELETE ) /* hb_BTreeDelete( hb_BTree_Handle, CHAR cKey, HB_LONG lData ) -> lSuccess */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( HB_ISNUM( 1 ) && HB_ISCHAR( 2 ) && ( hb_pcount() == 2 || HB_ISNUM( 3 ) ) ) - { - struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreedelete" ); - if ( GETFLAG( pBTree, IsReadOnly ) == HB_FALSE ) - { - hb_retl( hb_BTreeDelete( pBTree, hb_parc( 2 ), hb_parnl( 3 ) ) ); - } - else - { - raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "Cannot delete from a read-only file", HB_ERR_FUNCNAME, hb_pcount() ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( HB_ISNUM( 1 ) && HB_ISCHAR( 2 ) && ( hb_pcount() == 2 || HB_ISNUM( 3 ) ) ) + { + struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreedelete" ); + if( GETFLAG( pBTree, IsReadOnly ) == HB_FALSE ) + { + hb_retl( hb_BTreeDelete( pBTree, hb_parc( 2 ), hb_parnl( 3 ) ) ); + } + else + { + raiseError( EG_WRITE, HB_BTREE_EC_WRITEERROR, "Cannot delete from a read-only file", + HB_ERR_FUNCNAME, + hb_pcount() ); + hb_retl( HB_FALSE ); + } + } + else + { + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); hb_retl( HB_FALSE ); - } - } - else - { - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); - hb_retl( HB_FALSE ); - } + } } HB_FUNC( HB_BTREEKEY ) /* hb_BTreeKey( hb_BTree_Handle ) -> CHAR cKey */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - hb_retc( ( char * ) BTree_GetTreeIndex( "hb_btreekey" )->pThisKeyData->szKey ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + hb_retc( ( char * ) BTree_GetTreeIndex( "hb_btreekey" )->pThisKeyData->szKey ); } HB_FUNC( HB_BTREEDATA ) /* hb_BtreeData( hb_BTree_Handle ) -> HB_LONG lOldData | xOldData */ { /*, [ HB_LONG lNewData | ANY xNewData ] ??? */ - struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreeinfo" ); - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( GETFLAG( pBTree, IsInMemory ) ) - { - if ( pBTree->pThisKeyData->xData.pData ) - { - hb_itemReturn( pBTree->pThisKeyData->xData.pData ); - } - else - { - hb_ret(); - } - } - else - { - hb_retnl( pBTree->pThisKeyData->xData.lData ); - } + struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreeinfo" ); + + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( GETFLAG( pBTree, IsInMemory ) ) + { + if( pBTree->pThisKeyData->xData.pData ) + { + hb_itemReturn( pBTree->pThisKeyData->xData.pData ); + } + else + { + hb_ret(); + } + } + else + { + hb_retnl( pBTree->pThisKeyData->xData.lData ); + } } HB_FUNC( HB_BTREEGOTOP ) /* hb_BTreeGoTop( hb_BTree_Handle ) --> NIL */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - hb_BTreeGoTop( BTree_GetTreeIndex( "hb_btreegotop" ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + hb_BTreeGoTop( BTree_GetTreeIndex( "hb_btreegotop" ) ); } HB_FUNC( HB_BTREEGOBOTTOM ) /* hb_BTreeGoBottom( hb_BTree_Handle ) --> NIL */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - hb_BTreeGoBottom( BTree_GetTreeIndex( "hb_btreegobottom" ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + hb_BTreeGoBottom( BTree_GetTreeIndex( "hb_btreegobottom" ) ); } HB_FUNC( HB_BTREESKIP ) /* hb_BTreeSkip( hb_BTree_Handle, HB_LONG nRecords ) -> HB_LONG nRecordsSkipped */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( HB_ISNUM( 1 ) && ( hb_pcount() == 1 || HB_ISNUM( 2 ) ) ) - { - HB_LONG nSkip = hb_pcount() == 1 ? 1 : hb_parnl( 2 ); - hb_retnl( hb_BTreeSkip( BTree_GetTreeIndex( "hb_btreeskip" ), nSkip ) ); - } - else - { - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); - hb_retnl( 0 ); - } + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( HB_ISNUM( 1 ) && ( hb_pcount() == 1 || HB_ISNUM( 2 ) ) ) + { + HB_LONG nSkip = hb_pcount() == 1 ? 1 : hb_parnl( 2 ); + hb_retnl( hb_BTreeSkip( BTree_GetTreeIndex( "hb_btreeskip" ), nSkip ) ); + } + else + { + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); + hb_retnl( 0 ); + } } HB_FUNC( HB_BTREESEEK ) /* hb_BTreeSeek( hb_BTree_Handle, CHAR cKey, HB_LONG lData, BOOL lSoftSeek ) -> lSuccess */ { - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( HB_ISNUM( 1 ) && HB_ISCHAR( 2 ) ) - hb_retl( hb_BTreeSeek( BTree_GetTreeIndex( "hb_btreeseek" ), hb_parc( 2 ), hb_parnl( 3 ), hb_parl( 4 ) ) ); - else - { - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); - hb_retl( HB_FALSE ); - } + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + if( HB_ISNUM( 1 ) && HB_ISCHAR( 2 ) ) + hb_retl( hb_BTreeSeek( BTree_GetTreeIndex( "hb_btreeseek" ), hb_parc( 2 ), hb_parnl( 3 ), + hb_parl( 4 ) ) ); + else + { + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); + hb_retl( HB_FALSE ); + } } HB_FUNC( HB_BTREEINFO ) /* hb_BTreeInfo( hb_BTree_Handle, [index] ) -> aResults | cResults | nResults */ { - struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreeinfo" ); + struct hb_BTree * pBTree = BTree_GetTreeIndex( "hb_btreeinfo" ); - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - if ( pBTree ) - switch ( hb_parni( 2 ) ) - { - case HB_BTREEINFO_FILENAME: hb_retc( pBTree->szFileName ); break; - case HB_BTREEINFO_PAGESIZE: hb_retni( pBTree->usPageSize ); break; - case HB_BTREEINFO_KEYSIZE: hb_retni( pBTree->usKeySize ); break; - case HB_BTREEINFO_MAXKEYS: hb_retni( pBTree->usMaxKeys ); break; - case HB_BTREEINFO_MINKEYS: hb_retni( pBTree->usMinKeys ); break; - case HB_BTREEINFO_FLAGS: hb_retnl( pBTree->ulFlags ); break; - case HB_BTREEINFO_KEYCOUNT: hb_retnl( pBTree->ulKeyCount ); break; - case HB_BTREEINFO_ALL: - default: /* build an array and store all elements from above into it */ + if( pBTree ) + switch( hb_parni( 2 ) ) { - PHB_ITEM info = hb_itemArrayNew( HB_BTREEINFO__SIZE ); + case HB_BTREEINFO_FILENAME: hb_retc( pBTree->szFileName ); break; + case HB_BTREEINFO_PAGESIZE: hb_retni( pBTree->usPageSize ); break; + case HB_BTREEINFO_KEYSIZE: hb_retni( pBTree->usKeySize ); break; + case HB_BTREEINFO_MAXKEYS: hb_retni( pBTree->usMaxKeys ); break; + case HB_BTREEINFO_MINKEYS: hb_retni( pBTree->usMinKeys ); break; + case HB_BTREEINFO_FLAGS: hb_retnl( pBTree->ulFlags ); break; + case HB_BTREEINFO_KEYCOUNT: hb_retnl( pBTree->ulKeyCount ); break; + case HB_BTREEINFO_ALL: + default: /* build an array and store all elements from above into it */ + { + PHB_ITEM info = hb_itemArrayNew( HB_BTREEINFO__SIZE ); - hb_arraySetC( info, HB_BTREEINFO_FILENAME, pBTree->szFileName ); - hb_arraySetNI( info, HB_BTREEINFO_PAGESIZE, pBTree->usPageSize ); - hb_arraySetNI( info, HB_BTREEINFO_KEYSIZE , pBTree->usKeySize ); - hb_arraySetNI( info, HB_BTREEINFO_MAXKEYS , pBTree->usMaxKeys ); - hb_arraySetNI( info, HB_BTREEINFO_MINKEYS , pBTree->usMinKeys ); - hb_arraySetNL( info, HB_BTREEINFO_FLAGS , pBTree->ulFlags ); - hb_arraySetNL( info, HB_BTREEINFO_KEYCOUNT, pBTree->ulKeyCount ); + hb_arraySetC( info, HB_BTREEINFO_FILENAME, pBTree->szFileName ); + hb_arraySetNI( info, HB_BTREEINFO_PAGESIZE, pBTree->usPageSize ); + hb_arraySetNI( info, HB_BTREEINFO_KEYSIZE, pBTree->usKeySize ); + hb_arraySetNI( info, HB_BTREEINFO_MAXKEYS, pBTree->usMaxKeys ); + hb_arraySetNI( info, HB_BTREEINFO_MINKEYS, pBTree->usMinKeys ); + hb_arraySetNL( info, HB_BTREEINFO_FLAGS, pBTree->ulFlags ); + hb_arraySetNL( info, HB_BTREEINFO_KEYCOUNT, pBTree->ulKeyCount ); - hb_itemReturnRelease( info ); + hb_itemReturnRelease( info ); + } } - } } #if 0 HB_FUNB( HB_BTREEEVAL ) /* hb_BTreeEval( hb_BTree_Handle, bBlock, [bForCondition], [bWhileCondition], [nNextRecords], [nRecord], [lRest] ) -- NIL */ { - if ( HB_ISNUM( 1 ) && HB_ISBLOCK( 2 ) ) - hb_BTreeEval( BTree_GetTreeIndex( "hb_btreeeval" ), 0 ); - else - raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); + if( HB_ISNUM( 1 ) && HB_ISBLOCK( 2 ) ) + hb_BTreeEval( BTree_GetTreeIndex( "hb_btreeeval" ), 0 ); + else + raiseError( EG_ARG, HB_BTREE_EC_INVALIDARG, "Bad argument(s)", HB_ERR_FUNCNAME, hb_pcount() ); } #endif static void hb_BTree_Initialize( void * cargo ) { - /* TODO: initialization code */ + /* TODO: initialization code */ - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - HB_SYMBOL_UNUSED( cargo ); + HB_SYMBOL_UNUSED( cargo ); } static void hb_BTree_Terminate( void * cargo ) { - /* TODO: termination (cleanup) code */ + /* TODO: termination (cleanup) code */ - int n; + int n; - HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); + HB_TRACE( HB_TR_DEBUG, ( SRCLINENO ) ); - HB_SYMBOL_UNUSED( cargo ); + HB_SYMBOL_UNUSED( cargo ); - for ( n = 0; n < s_BTree_List_Count; n++ ) - { - if ( s_BTree_List[ n ] ) hb_BTreeClose( s_BTree_List[ n ] ); - } + for( n = 0; n < s_BTree_List_Count; n++ ) + { + if( s_BTree_List[ n ] ) + hb_BTreeClose( s_BTree_List[ n ] ); + } - if ( s_BTree_List_Count > 0 ) - BufferRelease( s_BTree_List ); + if( s_BTree_List_Count > 0 ) + BufferRelease( s_BTree_List ); } HB_CALL_ON_STARTUP_BEGIN( _hb_BTree_Initialize_ ) - hb_vmAtInit( hb_BTree_Initialize, NULL ); - hb_vmAtExit( hb_BTree_Terminate, NULL ); +hb_vmAtInit( hb_BTree_Initialize, NULL ); +hb_vmAtExit( hb_BTree_Terminate, NULL ); HB_CALL_ON_STARTUP_END( _hb_BTree_Initialize_ ) #if defined( HB_PRAGMA_STARTUP ) #pragma startup _hb_BTree_Initialize_ #elif defined( HB_DATASEG_STARTUP ) - #define HB_DATASEG_BODY HB_DATASEG_FUNC( _hb_BTree_Initialize_ ) + #define HB_DATASEG_BODY HB_DATASEG_FUNC( _hb_BTree_Initialize_ ) #include "hbiniseg.h" #endif diff --git a/harbour/examples/hbbtree/hb_btree.h b/harbour/examples/hbbtree/hb_btree.h index 9e935d633c..554ba0f7f8 100644 --- a/harbour/examples/hbbtree/hb_btree.h +++ b/harbour/examples/hbbtree/hb_btree.h @@ -1,6 +1,6 @@ /* - $Id$ -*/ + $Id$ + */ /* * Harbour Project source code: @@ -42,14 +42,17 @@ HB_EXTERN_BEGIN struct hb_BTree; -struct hb_BTree * hb_BTreeNew( const char * FileName, HB_USHORT usPageSize, HB_USHORT usKeySize, HB_ULONG ulFlags, HB_ULONG ulBuffers ); -struct hb_BTree * hb_BTreeOpen( const char *FileName, HB_ULONG ulFlags, HB_ULONG ulBuffers ); +struct hb_BTree * hb_BTreeNew( const char * FileName, HB_USHORT usPageSize, HB_USHORT usKeySize, + HB_ULONG ulFlags, + HB_ULONG ulBuffers ); +struct hb_BTree * hb_BTreeOpen( const char * FileName, HB_ULONG ulFlags, HB_ULONG ulBuffers ); void hb_BTreeClose( struct hb_BTree * pBTree ); HB_BOOL hb_BTreeInsert( struct hb_BTree * pBTree, const char * szKey, PHB_ITEM pData ); HB_BOOL hb_BTreeDelete( struct hb_BTree * pBTree, const char * szKey, HB_LONG lData ); void hb_BTreeGoTop( struct hb_BTree * pBTree ); void hb_BTreeGoBottom( struct hb_BTree * pBTree ); -HB_BOOL hb_BTreeSeek( struct hb_BTree * pBTree, const char * szKey, HB_LONG lData, HB_BOOL bSoftSeek ); +HB_BOOL hb_BTreeSeek( struct hb_BTree * pBTree, const char * szKey, HB_LONG lData, + HB_BOOL bSoftSeek ); HB_LONG hb_BTreeSkip( struct hb_BTree * pBTree, HB_LONG records ); const char * hb_BTreeKey( struct hb_BTree * pBTree ); HB_LONG hb_BTreeData( struct hb_BTree * pBTree ); diff --git a/harbour/examples/hbsqlit2/TODO.txt b/harbour/examples/hbsqlit2/TODO.txt deleted file mode 100644 index e1f7d3930a..0000000000 --- a/harbour/examples/hbsqlit2/TODO.txt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * $Id$ - */ - -/* - *------------------------------------------------------------------------ - * HARBOUR INTERFACE for SQLITE - *------------------------------------------------------------------------ - * - * Copyright 2003 Alejandro de Garate - * - -There are many areas for improving HbSQLite; any of them are: - -- Mimic the REPLACE command from Clipper -- A better dataset manipulation -- Made available other SQLite commands, etc. -- Changing to OOP, so the harbour code would be more compatible and easy - to use among different SQL databases. -- Enhance the sql query edit window (maybe with memoedit). -- Changing the DOS console user interface with a GUI look and feel. -- Remove or hidden public vars - -put here what you want :) - -... diff --git a/harbour/examples/hbsqlit2/hbsqlit2.c b/harbour/examples/hbsqlit2/hbsqlit2.c deleted file mode 100644 index eea2a8f7ac..0000000000 --- a/harbour/examples/hbsqlit2/hbsqlit2.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * $Id$ - */ - -/* - *------------------------------------------------------------------------ - * HARBOUR INTERFACE for SQLITE - *------------------------------------------------------------------------ - * Copyright 2003 Alejandro de Garate - * License: General Public License (GNU) - * - * History: - * Ver 0.40 30 December 2003 Fixed an opening error not detected - * It seems is a problem with BCC compiler. - * If "xxFile" database is not found, an empty file is - * created with the same name, given an incorrect signal - * to FILE() function. File is empty but exists (Oh man...) - * I fix it from harbour code, when have more spare time - * I will look in depth. - * Ver 0.30 28 December 2003 Pick tables, fields and DB structure, - * you can import some dbf (not finish yet) - * Ver 0.20 5 December 2003 changes in design, A front end is started - * Shows database struc, table struct, field type - * Ver 0.10 26 November 2003 first intempts, open connection, list data - * close connection - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include "hbapi.h" -#include "hbapiitm.h" - -#include "sqlite.h" -#include "sqliteInt.h" - -/* Public vars */ -sqlite * hb_sqlite2_db = NULL; /* public by ale */ -char * hb_sqlite2_szErrMsg = NULL; -int hb_sqlite2_iDataRows = 0; /* records */ -int hb_sqlite2_iDataCols = 0; /* fields */ - -/* Returns information about current SQLite package */ -HB_FUNC( SQLITE_INFO ) -{ - hb_reta( 3 ); - hb_storc( SQLITE_VERSION , -1, 1 ); - hb_storc( sqlite_libversion() , -1, 2 ); - hb_storc( sqlite_libencoding(), -1, 3 ); -} - -/* Open a database file (in SQLite format) and set a public structure */ -HB_FUNC( SQLITE_OPEN ) -{ - if( hb_sqlite2_db ) - sqlite_close( hb_sqlite2_db ); - - hb_sqlite2_db = ( sqlite * ) sqlite_open( hb_parcx( 1 ), 0, &hb_sqlite2_szErrMsg ); - - hb_retni( hb_sqlite2_db == NULL ? 1 : 0 ); /* error: 1 */ -} - -/* Close currently open database */ -HB_FUNC( SQLITE_CLOSE ) -{ - if( hb_sqlite2_db ) - { - sqlite_close( hb_sqlite2_db ); - hb_sqlite2_db = NULL; - } -} - -/* Execute a statment (not a query) over the database */ -HB_FUNC( SQLITE_EXECUTE ) -{ - if( hb_sqlite2_db ) - hb_retni( sqlite_exec( hb_sqlite2_db, hb_parcx( 1 ), NULL, NULL, &hb_sqlite2_szErrMsg ) ); -} - -/* Execute a query over the passed table */ -HB_FUNC( SQLITE_QUERY ) -{ - const char * szSQLcom = hb_parcx( 1 ); - - if( hb_sqlite2_db && sqlite_exec( hb_sqlite2_db, szSQLcom, NULL, NULL, &hb_sqlite2_szErrMsg ) == SQLITE_OK ) - { - int iResRows = 0; - int iResCols = 0; - int iRec; - int iField; - char * pErrmsg; - char ** pResStr; - PHB_ITEM paRows; - int i; - - /* put here a routine to process results */ - sqlite_get_table( hb_sqlite2_db, /* An open database */ - szSQLcom, /* SQL to be executed */ - &pResStr, /* Result written to a char *[] that this points to */ - &iResRows, /* Number of result rows written here */ - &iResCols, /* Number of result columns written here */ - &pErrmsg /* Error msg written here */ - ); - - /* global results */ - hb_sqlite2_iDataRows = iResRows; /* set rows from last operation */ - hb_sqlite2_iDataCols = iResCols; /* set cols from last operation */ - - /* quiero devolver un array bidimensional donde la cantidad de filas - es rows +1 (ó reccords +1 ) y las columnas los campos - la primer fila contiene los encabezados de los campos */ - - /* dimension rows array */ - paRows = hb_itemArrayNew( iResRows + 1 ); - - for( iRec = 0, i = 0; iRec < iResRows + 1; iRec++ ) - { - if( iResCols > 1 ) /* if it's a multidimensional array */ - { - PHB_ITEM paCols = hb_itemArrayNew( iResCols ); - - /* for every field */ - for( iField = 0; iField < iResCols; iField++ ) - hb_arraySetC( paCols, iField + 1, pResStr[ i++ ] ); - - /* put data onto subarray of records */ - hb_itemArrayPut( paRows, iRec + 1, paCols ); - hb_itemRelease( paCols ); - } - else /* is an unidimensional array */ - hb_arraySetC( paRows, iRec + 1, pResStr[ i++ ] ); - } - - /* free memory allocated */ - sqlite_free_table( pResStr ); - - hb_itemReturnRelease( paRows ); - } - else - hb_reta( 0 ); -} - -/* Returns an unidimensional array with FIELD NAMES only */ -HB_FUNC( SQLITE_SYSCOLUMNS ) -{ - if( hb_sqlite2_db ) - { - struct Table * pTable = ( struct Table * ) sqliteFindTable( hb_sqlite2_db, ( const char * ) hb_parcx( 1 ), NULL ); - - if( pTable ) - { - /* dimension rows array: - 1 is table name - 2 is field number - 3 to n cols data */ - PHB_ITEM paRows = hb_itemArrayNew( 2 + pTable->nCol ); - int iField; - - /* the Table structure itself */ - hb_arraySetC( paRows, 1, pTable->zName ); /* save name of table */ - hb_arraySetNL( paRows, 2, pTable->nCol ); /* save number of cols/fields */ - - for( iField = 0; iField < pTable->nCol; iField++ ) - { - /* it's a multidimensional array */ - /* four data columns name, default, type, isprimarykey per field */ - PHB_ITEM paCols = hb_itemArrayNew( 4 ); - - hb_arraySetC( paCols, 1, pTable->aCol[ iField ].zName ); - hb_arraySetC( paCols, 2, pTable->aCol[ iField ].zDflt ); - hb_arraySetC( paCols, 3, pTable->aCol[ iField ].zType ); - hb_arraySetL( paCols, 4, pTable->aCol[ iField ].isPrimKey ); - - /* put data onto subarray of records */ - hb_itemArrayPut( paRows, 3 + iField, paCols ); - hb_itemRelease( paCols ); - } - - hb_itemReturnRelease( paRows ); - return; - } - } - - hb_reta( 0 ); -} - -/* Returns an unidimensional array with field names only */ -HB_FUNC( SQLITE_FIELDS ) -{ - if( hb_sqlite2_db ) - { - struct Table * pTable = ( struct Table * ) sqliteFindTable( hb_sqlite2_db, ( const char * ) hb_parcx( 1 ), NULL ); - - if( pTable ) - { - int i; - - /* the Table structure itself */ - hb_reta( pTable->nCol ); - - for( i = 0; i < pTable->nCol; i++ ) - hb_storc( pTable->aCol[ i ].zName, -1, 1 + i ); - - return; - } - } - - hb_reta( 0 ); -} - -/* Returns number of tables inside current open database (not table) */ -HB_FUNC( SQLITE_NUMOFTABLES ) -{ - hb_retni( hb_sqlite2_db ? hb_sqlite2_db->nTable - 2 : 0 ); -} - -/* Returns a string explaining last error */ -HB_FUNC( SQLITE_ERROR ) -{ - hb_retc( hb_sqlite2_szErrMsg ); -} - -/* Returns the number of rows resulting from last operation */ -HB_FUNC( SQLITE_GETROWS ) -{ - hb_retni( hb_sqlite2_iDataRows ); -} - -/* Returns the number of columns resulting from last operation */ -HB_FUNC( SQLITE_GETCOLS ) -{ - hb_retni( hb_sqlite2_iDataCols ); -} diff --git a/harbour/examples/hbsqlit2/hbsqlit2.ch b/harbour/examples/hbsqlit2/hbsqlit2.ch deleted file mode 100644 index 2c40450ce7..0000000000 --- a/harbour/examples/hbsqlit2/hbsqlit2.ch +++ /dev/null @@ -1,90 +0,0 @@ -/* - * $Id$ - */ - -/* - * Harbour Project source code: - * - * SQLite DBMS defines - * - * Copyright 2003 Alejandro de Garate - * www - http://harbour-project.org - * - */ - -#ifndef HBSQLIT2_CH_ -#define HBSQLIT2_CH_ - -/* Generic defines */ - -/* - * Return values for sqlite_exec() and sqlite_step() - */ -#define HB_SQLITE_OK 0 /* Successful result */ -#define HB_SQLITE_ERROR 1 /* SQL error or missing database */ -#define HB_SQLITE_INTERNAL 2 /* An internal logic error in SQLite */ -#define HB_SQLITE_PERM 3 /* Access permission denied */ -#define HB_SQLITE_ABORT 4 /* Callback routine requested an abort */ -#define HB_SQLITE_BUSY 5 /* The database file is locked */ -#define HB_SQLITE_LOCKED 6 /* A table in the database is locked */ -#define HB_SQLITE_NOMEM 7 /* A malloc() failed */ -#define HB_SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define HB_SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */ -#define HB_SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ -#define HB_SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define HB_SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */ -#define HB_SQLITE_FULL 13 /* Insertion failed because database is full */ -#define HB_SQLITE_CANTOPEN 14 /* Unable to open the database file */ -#define HB_SQLITE_PROTOCOL 15 /* Database lock protocol error */ -#define HB_SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */ -#define HB_SQLITE_SCHEMA 17 /* The database schema changed */ -#define HB_SQLITE_TOOBIG 18 /* Too much data for one row of a table */ -#define HB_SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */ -#define HB_SQLITE_MISMATCH 20 /* Data type mismatch */ -#define HB_SQLITE_MISUSE 21 /* Library used incorrectly */ -#define HB_SQLITE_NOLFS 22 /* Uses OS features not supported on host */ -#define HB_SQLITE_AUTH 23 /* Authorization denied */ -#define HB_SQLITE_FORMAT 24 /* Auxiliary database format error */ -#define HB_SQLITE_ROW 100 /* sqlite_step() has another row ready */ -#define HB_SQLITE_DONE 101 /* sqlite_step() has finished executing */ - -/* * SQLITE_COPY -** SQLITE_CREATE_INDEX -** SQLITE_CREATE_TABLE -** SQLITE_CREATE_TEMP_INDEX -** SQLITE_CREATE_TEMP_TABLE -** SQLITE_CREATE_TEMP_TRIGGER -** SQLITE_CREATE_TEMP_VIEW -** SQLITE_CREATE_TRIGGER -** SQLITE_CREATE_VIEW -** SQLITE_DELETE -** SQLITE_DROP_INDEX -** SQLITE_DROP_TABLE -** SQLITE_DROP_TEMP_INDEX -** SQLITE_DROP_TEMP_TABLE -** SQLITE_DROP_TEMP_TRIGGER -** SQLITE_DROP_TEMP_VIEW -** SQLITE_DROP_TRIGGER -** SQLITE_DROP_VIEW -** SQLITE_INSERT -** SQLITE_PRAGMA -** SQLITE_READ -** SQLITE_SELECT -** SQLITE_TRANSACTION -** SQLITE_UPDATE -*/ - -/* Harbour definitions */ - #define HB_HB4SQLITE_VER "0.40" - -/* SQLite tag - * we use the first part of the tag (defined at btree.c) to not exclude - * any version of the database - * "** This file contains an SQLite 2.1 database **" - */ -#define XSQLITE_TAG "** This file contains an SQLite " -#define XSQLITE_TAG_LEN LEN(XSQLITE_TAG) - -#endif - -/* End of hbsqlite.ch */ diff --git a/harbour/examples/hbsqlit2/hbsqlit2.hbc b/harbour/examples/hbsqlit2/hbsqlit2.hbc deleted file mode 100644 index 2aba39ccab..0000000000 --- a/harbour/examples/hbsqlit2/hbsqlit2.hbc +++ /dev/null @@ -1,9 +0,0 @@ -# -# $Id$ -# - -incpaths=. -libpaths=lib/${hb_plat}/${hb_comp} - -libs=${hb_name} -libs=sqlite2 diff --git a/harbour/examples/hbsqlit2/hbsqlit2.hbp b/harbour/examples/hbsqlit2/hbsqlit2.hbp deleted file mode 100644 index f9c44b384a..0000000000 --- a/harbour/examples/hbsqlit2/hbsqlit2.hbp +++ /dev/null @@ -1,21 +0,0 @@ -# -# $Id$ -# - --hblib --inc - --o${hb_name} - --w3 -es2 - -"-stop={dos}'${hb_name}' doesn't support MS-DOS platform." - --depkeyhead=sqlite2:sqlite.h --depcontrol=sqlite2:${HB_WITH_SQLITE2} --depincpath=sqlite2:/usr/include --depincpath=sqlite2:/boot/common/include - --instfile=inc:hbsqlit2.ch - -hbsqlit2.c diff --git a/harbour/examples/hbsqlit2/readme.txt b/harbour/examples/hbsqlit2/readme.txt deleted file mode 100644 index 97e04e638b..0000000000 --- a/harbour/examples/hbsqlit2/readme.txt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * $Id$ - */ - -/* - *------------------------------------------------------------------------ - * HARBOUR INTERFACE for SQLITE - *------------------------------------------------------------------------ - * - * Copyright 2003 Alejandro de Garate - * - * License: General Public License or for short GPL (GNU) - * - * Developed using: - * Harbour 0.42 or upper - * Borland C++ BCC 5.5.1 - * - */ - - Requirements - ------------ - Any windows platform W95, W98, W98SE or NT family - A C++ compiler, if you use other than Borland some minor changes could - be required. - - - The program - ----------- - The source program is quite small (about 50 Kbytes) and a litle basic, - but gives an easy way of accessing a SQL Database, like SQLite. - Inside the prg you can find several C functions used to connect to the - database, and Clipper/Harbour code used for calling C functions. - Most of the code is commented and is easy to follow. - Of course many enhancement would be done, I will do if I found spare - time :) - The library that come with the program it's based in the SQLite version - 2.8.6 - - - Purpose - ------- - To access a sqlite database using Clipper/Harbour language. - - - Use - --- - This program is mostly self-contained. - For using you needs: - 1- Borland C++ Compiler BCC 5.5 or upper (working) - 2- Harbour version 0.42 or upper (working) - 3- hbsqlite.prg (main program /front end) - 4- hbsqlite.ch (some defines) - 5- sqlite.lib (library builded for BCC55 and windows platform) - 6- sqlite.h (include file for sqlite code) - 7- sqliteInt.h (include file for sqlite code) - 8- example.db (a simple sqlite database for testings ) - - Steps: - 1.- Unzip the package to the target directory (ie.: \sqlite) - - 2.- Keep the zip file at safe place :) - - 3.- Add sqlite.lib to the list of libraries - You also needs to add sqlite.lib to the list of libraries inside - the build.bat file at harbour\bin directory. - - 4.- Move the static library sqlite.lib to the harbour\lib directory. - - 5.- If you have (1) & (2) working, just compile hbsqlite.prg using: - bld_b32 hbsqlite // without extension - - - Information about SQLITE - ------------------------ - 1. web site at www.sqlite.org - - 2. User list for sqlite (do not ask about harbour stuffs) - subscribe at: - (one by one) - - (digest mode) - - - What is inside the source package ? - ----------------------------------- - Inside the hbsqlite_src.zip file you will find: - - File Size Description - -------------------------------------------------------------------------- - 1- hbsqlite.prg 46.401 (main program /front end) - 2- hbsqlite.ch 3.369 (some defines) - 3- sqlite.lib 352.256 (lib builded for BCC55 and windows platform) - 4- sqlite.h 31.222 (include file for sqlite code) - 5- sqliteInt.h 53.893 (include file for sqlite code) - 6- gpl.txt 17.989 (a copy of GPL license) - 7- todo.txt (a list of pending things ) - 8- readme_en.txt (this readme) - - Note: - You may want also the sqlite manager and the sample database, in that - case you must download the binary package. - - - What is inside the binary package ? - ----------------------------------- - Inside the hbsqlite_bin.zip file you will find: - - File Size Description - -------------------------------------------------------------------------- - 1- hbsqlite.exe 741.376 (harbour front end to sqlite) - 2- sqlite.exe 285.444 (a comand-line Sqlite manager) - 3- example.db 77.824 (a simple sqlite database for testings) - 4- test.db (another sqlite database for testings) - 5- readme_en.txt (this readme) - - Final comments - -------------- - You can adapt the program to your needs, but if you made any - improvements, fixes or found any error, let me know so I can add it - to the program. - Anyway if you want to ask something, or think a feature is missing - send me a mail. - - Enjoy it! - - Alejandro - diff --git a/harbour/examples/hbsqlit2/tests/example.db b/harbour/examples/hbsqlit2/tests/example.db deleted file mode 100644 index deaac12f4f284a40b4a265fff65a42dfbb8e5325..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77824 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�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 diff --git a/harbour/examples/hbsqlit2/tests/hbmk.hbm b/harbour/examples/hbsqlit2/tests/hbmk.hbm deleted file mode 100644 index 003c47d377..0000000000 --- a/harbour/examples/hbsqlit2/tests/hbmk.hbm +++ /dev/null @@ -1,7 +0,0 @@ -# -# $Id$ -# - -../hbsqlit2.hbc - --w3 -es2 diff --git a/harbour/examples/hbsqlit2/tests/hbsqlite.prg b/harbour/examples/hbsqlit2/tests/hbsqlite.prg deleted file mode 100644 index b4d881858d..0000000000 --- a/harbour/examples/hbsqlit2/tests/hbsqlite.prg +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * $Id$ - */ - -/* - *------------------------------------------------------------------------ - * HARBOUR INTERFACE for SQLITE - *------------------------------------------------------------------------ - * - * Copyright 2003 Alejandro de Garate - * - * License: General Public License (GNU) - * - * Developed using: - * Harbour 0.42 or upper - * Borland C++ BCC 5.5.1 - * - * History: - * - * Ver 0.40 30 December 2003 Fixed an opening error not detected - * It seems is a problem with BCC compiler. - * If "xxFile" database is not found, an empty file is - * created with the same name, given an incorrect signal - * to FILE() function. File is empty but exists (Oh man...) - * I fix it from harbour code, when have more spare time - * I will look in depth. - * - * Ver 0.30 28 December 2003 Pick tables, fields and DB structure, - * you can import some dbf (not finish yet) - * - * Ver 0.20 5 December 2003 changes in design, A front end is started - * Shows database struc, table struct, field type - * - * Ver 0.10 26 November 2003 first intempts, open connection, list data - * close connection - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -MEMVAR cDatabase -MEMVAR cCurrTable -MEMVAR ins_on - -PROCEDURE MAIN() -*--------------------------------------------------------------------------- -* Main procedure -*--------------------------------------------------------------------------- - LOCAL nError, nOption - - LOCAL cDbase - LOCAL cDTable - - PUBLIC cDatabase // only one DB in use - PUBLIC cCurrTable // Table currently in use - PUBLIC ins_on := .F. // if Insert key is On - - #define CRLF CHR(13) + CHR(10) - #define cSpace " " - #define cQuote "'" - - #include "setcurs.ch" - #include "box.ch" - #include "inkey.ch" - #include "hbsqlit2.ch" // REQUIRED ! - - // basic setup - SET WRAP ON - SET CENTURY ON - SET DATE BRITISH - SET SCOREBOARD OFF - SET MESSAGE TO 23 CENTER - SET KEY K_F1 TO HELP() - SET KEY 22 TO INSERT - - - SETCOLOR("W+/BG,W+/N,N,N,N/W*") - CLS - @ 0,0 TO 24,79 DOUBLE - @ 22,0 TO 24,79 DOUBLE - @ 22, 0 SAY "Ì" - @ 22,79 SAY "¹" - @ 0,22 SAY " Harbour Interface for SQLite " + HB_HB4SQLITE_VER COLOR "GR+/BG" - - cDbase := PickSQLiteFile() - - cDatabase := IIF( ! EMPTY(cDbase), LOWER( cDbase ), "" ) // set public var - -* cDBase := "example.db" // sample database with a couple of tables -* cDbase := ChooseDB() - - IF EMPTY( cDbase ) - CLS - ? "Harbour for SQLite" - ? - ? "Database was not supplied" - ? - QUIT - ENDIF - - * Open SQLite database - nError := SQLITE_OPEN( cDbase ) - - IF nError > 0 - ALERT("Error number:" + STR( nError, 3) +; - ";Error when opening database: " + cDbase + ; - ";;Error explanation: ;" + SQLITE_ERROR() ) - QUIT - ENDIF - - DataBar("None") - - nOption := 1 - - -DO WHILE nOption != 0 - - @ 1,1 CLEAR TO 21,78 - - @ 2,2 PROMPT "See SQLite Version" MESSAGE; - "Take a look what version SQLite is" - - @ 4,2 PROMPT "See HbSQLite Info" MESSAGE; - "Take a look what version Harbour for SQLite is" - - @ 6,2 PROMPT "See ALL tables" MESSAGE; - "List ALL the tables inside the SQLite database" - - @ 8,2 PROMPT "See ALL Columns (Fields)" MESSAGE; - "List ALL Fields of the selected table inside the SQLite database" - - @ 10,2 PROMPT "See Table struct (Fields)" MESSAGE; - "Show table structure and list ALL Fields of the selected table " - - @ 12,2 PROMPT "Show data" MESSAGE; - "List some data from test table" - - @ 14,2 PROMPT "APPEND FROM DBF" MESSAGE; - "Create a table and append from an external DBF file " - - @ 16,2 PROMPT "DROP TABLE" MESSAGE; - "Erase a table from the database" - - @ 18,2 PROMPT "EXIT" MESSAGE; - "QUIT from Harbour Interface for SQLite" - MENU TO nOption - - @ 23,1 CLEAR TO 23,78 // clean msg area - - DO CASE - CASE nOption == 1 // See SQLite Version - ShowVersion() - - CASE nOption == 2 // See Hb4SQLite Info - SQLITE_HB4SQLITE() - - CASE nOption == 3 // See ALL tables - ShowTables(.F.) - - CASE nOption == 4 // See ALL Columns (Fields) - cDTable := ShowTables(.T.) - DataBar( cDTable ) // status bar - ShowFields( cDTable ) - - CASE nOption == 5 // See Table struct (Fields) - cDTable := ShowTables(.T.) - DataBar( cDTable ) // status bar - ShowCOLInfo( cDTable ) - - CASE nOption == 6 // Show data - cDTable := ShowTables(.T.) - DataBar( cDTable ) // status bar - ShowData( cDTable ) - - CASE nOption == 7 // APPEND FROM DBF - AppendFrom() - - CASE nOption == 8 // DROP TABLE - SQLITE_DROPTABLE() - - OTHERWISE - EXIT - ENDCASE - -ENDDO - - // close the connection - SQLITE_CLOSE() - - CLS - @ 2,1 SAY "Successfully quiting from Harbour for SQLite ..." - @ 23,1 SAY "." - SET COLOR TO - -RETURN // End Main - - -*------------------------------ - FUNCTION ShowCOLInfo( cTable ) -*--------------------------------------------------------------------------- -* Shows Information about fields... -*--------------------------------------------------------------------------- - LOCAL aResult, n, aBrowse := {}, nLen, cData - LOCAL nOldCursor, nOldRow, nOldCol, cOldScreen, cOldColor, cDflt - LOCAL nFrom, nTo - LOCAL cc, clen - #define FLD_NAME 1 - #define FLD_DFLT 2 - #define FLD_TYPE 3 -//#define FLD_LENGTH 3 // It's embebed in field type - #define FLD_PRIMKEY 4 - #define cDel SPACE(2) - - * save status - nOldRow := ROW() - nOldCol := COL() - nOldCursor := SETCURSOR( SC_NONE ) - cOldScreen := SAVESCREEN( 0, 0, MAXROW(), MAXCOL() ) - cOldColor := SETCOLOR() - - IF !( VALTYPE( cTable ) == "C" ) .OR. EMPTY( cTable ) .OR. cTable == NIL - RETURN "" - ENDIF - - aResult := SQLITE_SYSCOLUMNS( cTable ) - - nLen := 2 + aResult[ 2 ] - -FOR n := 3 TO nLen - cDflt := IIF( EMPTY( aResult[ n ][FLD_DFLT]) , ; - PADR( "SPACES", 12), PADR( aResult[ n ][FLD_DFLT], 12) ) - - * Try to get Lenght - cc := aResult[ n ][FLD_TYPE] - nFrom := AT( "(", cc ) + 1 - nTo := AT( ")", cc ) - - IF nFrom > 1 - cLen := PADL( SUBST( cc, nFrom, nTo - nFrom), 6) - ELSE - * Get length from special array of datatypes - cLen := STR( GetFldLen( UPPER( ALLTRIM(cc) ) ), 6) //SPACE(6) - ENDIF - - * build the display array - cData := STR( n-2, 2) + " "+; - PADR( aResult[ n ][FLD_NAME], 23 ) + cDel + ; - cDflt + " " + ; - PADR( aResult[ n ][FLD_TYPE], 12 ) + cDel + ; - cLen + SPACE(4) + ; - IIF( aResult[ n ][FLD_PRIMKEY], "TRUE ", "FALSE") - - AADD( aBrowse, cData) -NEXT - - SETCOLOR( "W+/BG,W+/B,N,N,N/W*" ) - DISPBOX( 2, 2, 21, 77, B_DOUBLE + ' ', "W+/BG,W+/B" ) // draw box - - @ 2,27 SAY " Table Structure Data " COLOR "GR+/BG" - @ 3, 4 SAY " Table Name: " + aResult[ 1 ] COLOR "W+/BG" - @ 4, 4 SAY "Number of fields: " + STR( aResult[2], 3) COLOR "W+/BG" - @ 5, 4 SAY "Number of reccds: " - @ 7, 2 SAY "Ì" + REPLIC( "Í", 74) + "¹" - @ 7,30 SAY " Field Data " COLOR "GR+/BG" - @ 8,03 SAY " Name" + SPACE(21) + "Default Val." + SPACE(3) + "Type" +; - SPACE(10) + "Len Primary Key" COLOR "N/W" - - ACHOICE( 9, 4, 20, 75, aBrowse ) - - * restore status - RESTSCREEN( 0, 0, MAXROW(), MAXCOL(), cOldScreen ) - SETCURSOR( nOldCursor ) - SETPOS( nOldRow, nOldCol ) - SETCOLOR( cOldColor ) - -RETURN 0 - - - -*---------------------------- - FUNCTION SQLITE_HB4SQLITE() -*---------------------------- -* Shows specific info -*--------------------------------------------------------------------------- - LOCAL aInfo [6], nWide := 60, dUpdate - #define this_UPDATE __DATE__ // constant from C compiler - - dUpdate := STOD( this_UPDATE ) // undocumented in Clipper - - aInfo [1] := " Version: " + HB_HB4SQLITE_VER - aInfo [2] := " Last Update: " + DTOC( dUpdate ) - aInfo [3] := " Harbour Build: " + VERSION() - aInfo [4] := " C++ Compiler: " + HB_COMPILER() - aInfo [5] := "Operat. System: " + OS() - aInfo [6] := " Author: Alejandro de Gárate" - - ALERT( "Harbour for SQlite;;" +; - PADR( aInfo [1], nWide ) + ";" +; - PADR( aInfo [2], nWide ) + ";" +; - PADR( aInfo [3], nWide ) + ";" +; - PADR( aInfo [4], nWide ) + ";" +; - PADR( aInfo [5], nWide ) + ";" ,; - NIL, "1/15") - -RETURN 0 - - -*------------------------ - FUNCTION SQLITE_TABLES() -*--------------------------------------------------------------------------- -* Uses a (special) master table where the names of all tables are stored -* Returns an array with names of tables inside of the database -*--------------------------------------------------------------------------- -LOCAL aTables, cStatment, nLen - /* execte a query - if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){ - char **azResult; - int nRow, rc; - char *zErrMsg; - open_db(p); - if( nArg==1 ) - rc = sqlite_get_table(p->db, - "SELECT name FROM sqlite_master " - "WHERE type IN ('table','view') " - "UNION ALL " - "SELECT name FROM sqlite_temp_master " - "WHERE type IN ('table','view') " - "ORDER BY 1", - &azResult, &nRow, 0, &zErrMsg - ); - */ - -cStatment := "SELECT name FROM sqlite_master " +; - "WHERE type IN ('table','view') " +; - "UNION ALL " +; - "SELECT name FROM sqlite_temp_master " +; - "WHERE type IN ('table','view') " +; - "ORDER BY 1;" - -aTables := SQLITE_QUERY( cStatment ) // query master table -nlen := LEN( aTables ) -ADEL( aTables, 1) // delete field title -ASIZE( aTables, nLen-1 ) // resize array according delete -RETURN aTables - - -*--------------------------------------------------------------------------- -* ===> H E L P E R F U N C T I O N S <=== -*--------------------------------------------------------------------------- - -*------------------------------ - FUNCTION CreatefromDBF( cSQL ) -*--------------------------------------------------------------------------- -* *** UNDER DEVELOPMENT *** -*--------------------------------------------------------------------------- -LOCAL aStruct, cData := "", cDBase, n, cFlist := "" -LOCAL nFields -LOCAL cField_Def -LOCAL cHeader -#include "dbstruct.ch" - -*COPY STRUCTURE EXTENDED TO struc //.dbf -*USE struc NEW -*LIST field_name, field_type, field_len ,field_dec -aStruct := DBSTRUCT() - -AEVAL( aStruct, {| aField | cData := cData + ; - aField[ DBS_NAME ] + " " + ; - aField[ DBS_TYPE ] + " " +; - LTRIM( STR( aField[ DBS_LEN ] )) + " " +; - LTRIM( STR( aField[ DBS_DEC ] )) + CRLF } ) -? cData - -cDBase := "Tablon" - -* Build field list -nFields := LEN( aStruct ) - -/* -FOR n := 1 TO nFields - cFList := cFList + ; - cSpace + aStruct[ n][DBS_NAME] + cSpace +; - ConvertFldType( aStruct[ n][DBS_TYPE] ) +; - IIF( ConvertFldLen( aStruct[ n][DBS_TYPE] ), ; - "(" + LTRIM( STR( aStruct[ n][DBS_LEN] )) + ")", ; - "") +; - IIF( n < nFields, "," , "") -NEXT -*/ -cField_Def := LOWER( cFList ) - -* Create table -cHeader := "create table" + cSpace + cDBase + "(" + cField_Def + ");" -? cHeader -* aResult := SQLITE_EXECUTE( cHeader ) -* ? SQLITE_ERROR() - -* Repeat for every reccord... -DO WHILE ! EOF() - - * Put all fields in a row list comma separated - cFList := "" - FOR n := 1 TO nFields - cFList := cFList + ; - cQuote + RTRIM( xconvert( FIELDGET( n )) ) + cQuote+ ; - IIF( n < FCOUNT(), ",", "") - NEXT - - cSQL := "insert into " + cDBase + cSpace + "values(" + cFList + ");" -* ? cFList -* ? cSQL - - SQLITE_EXECUTE( cSQL ) // insert reccord - - IF SQLITE_ERROR() != NIL - ALERT( "Error !;;" + SQLITE_ERROR() ) - ENDIF - - SKIP -ENDDO - -inkey(0) -RETURN( "") - - -*--------------------- - FUNCTION AppendFrom() -*--------------------------------------------------------------------------- -*--------------------------------------------------------------------------- - SELECT 1 - USE TEST -* BROWSE() - - CreatefromDBF("") - USE -inkey(0) -RETURN 0 - - - -*-------------------------------- - FUNCTION ConvertFldType( cType ) -*--------------------------------------------------------------------------- -* Get a Clipper type and return closest SQLite type -*--------------------------------------------------------------------------- -LOCAL aTypes := { { "C", "CHAR" }, { "L", "BOOLEAN" },; - { "M", "TEXT" }, { "O", "BINARY" },; - { "N", "DOUBLE"}, { "D", "TIMESTAMP" } } -* { "C", "" },; -LOCAL nPos := ASCAN( aTypes, {|aVal| aVal[1] == cType }) -RETURN( IIF( nPos == 0, "", aTypes[nPos][2] )) - - -*------------------------------- - FUNCTION ConvertFldLen( cType ) -*--------------------------------------------------------------------------- -* Get a Clipper type and return if field Len is required for SQLite type -*--------------------------------------------------------------------------- -LOCAL aTypes := { { "C", "CHAR" , .T. }, { "L", "BOOLEAN", .F. },; - { "M", "TEXT" , .T. }, { "O", "BINARY" , .T. },; - { "N", "DOUBLE", .F. }, { "D", "TIMESTAMP",.F. } } -LOCAL nPos := ASCAN( aTypes, {|aVal| aVal[1] == cType }) -RETURN( IIF( nPos == 0, .F., aTypes[nPos][3] )) - - -*--------------------------- - FUNCTION GetFldLen( cType ) -*--------------------------------------------------------------------------- -* Get a SQLite type and return A TENTATIVE length (till I can find the -* correct one) (:{) -* I have the intention of centralize all non explicit lengths to this -* function. -* It is needed a way of get binary/blob length -*--------------------------------------------------------------------------- -LOCAL aTypes := {{ "BOOLEAN", 1 }, { "BOOL", 1 }, ; - { "INTEGER", 4 }, ; - { "FLOAT", 4 }, { "DOUBLE", 8 }, ; - { "DATE", 10 }, { "TIMESTAMP", 18 }, ; - { "BINARY", 0 }, { "BLOB" , 0 } } -LOCAL nPos := ASCAN( aTypes, {|aVal| aVal[1] == cType } ) -RETURN( IIF( nPos == 0, 0, aTypes[nPos][2] )) - - - -*--------------------------------------------------------------------------- -* Samples functions to show posibilities... -*--------------------------------------------------------------------------- - -*---------------------- - FUNCTION ShowVersion() -*--------------------------------------------------------------------------- -* Shows SQLite version -*--------------------------------------------------------------------------- -LOCAL aInfo - aInfo := SQLITE_INFO() // Get gral info about SQLite -ALERT( "SQLITE INFO ;;" +; - " header = " + aInfo [1] + ";" +; - " version library = " + aInfo [2] + ";" +; - " encoding library = " + aInfo [3],; - NIL, "1/15") -RETURN 0 - - -*------------------------------- - FUNCTION ShowTables( lMsgShow ) -*--------------------------------------------------------------------------- -* Shows all tables inside the database -*--------------------------------------------------------------------------- - LOCAL aResult, nChoices - LOCAL nOldCursor, nOldRow, nOldCol, cOldScreen, cOldColor - - * save status - nOldRow := ROW() - nOldCol := COL() - nOldCursor := SETCURSOR( SC_NONE ) - cOldScreen := SAVESCREEN( 0, 0, MAXROW(), MAXCOL() ) - cOldColor := SETCOLOR() - - * Show all tables inside database - aResult := SQLITE_TABLES() - - SETCOLOR( "W+/BG,W+/B,N,N,N/W*" ) - DISPBOX( 9,9, 21, 33, B_DOUBLE + ' ', "W+/BG,W+/B" ) // draw box - - @ 9,17 SAY " Tables " COLOR "GR+/BG" - - IF VALTYPE(lMsgShow) == "L" .AND. lMsgShow == .T. - @ 21,15 SAY " Pick a Table " COLOR "W+/BG" - ENDIF - nChoices := ACHOICE( 10, 11, 20, 31, aResult ) - - // Restore status - RESTSCREEN( 0, 0, MAXROW(), MAXCOL(), cOldScreen ) - SETCURSOR( nOldCursor ) - SETPOS( nOldRow, nOldCol ) - SETCOLOR( cOldColor ) - -RETURN( IIF( nChoices > 0, aResult[ nChoices ], "") ) - - - -*----------------------------- - FUNCTION ShowFields( cTable ) -*--------------------------------------------------------------------------- -* Shows fields on a box from given table -*--------------------------------------------------------------------------- - LOCAL aResult, nChoices - LOCAL nOldCursor, nOldRow, nOldCol, cOldScreen, cOldColor - - * save status - nOldRow := ROW() - nOldCol := COL() - nOldCursor := SETCURSOR( SC_NONE ) - cOldScreen := SAVESCREEN( 0, 0, MAXROW(), MAXCOL() ) - cOldColor := SETCOLOR() - - * Show all tables inside database - IF !( VALTYPE( cTable ) == "C" ) .OR. EMPTY( cTable ) .OR. cTable == NIL - RETURN "" - ELSE - aResult := SQLITE_FIELDS( cTable ) - ENDIF - - AEVAL( aResult, {| aVal, nIndex | ; - aResult[ nIndex] := STR( nIndex, 3) + ". " + aVal } ) - - SETCOLOR( "W+/BG,W+/B,N,N,N/W*" ) - DISPBOX( 9,9, 21, 33, B_DOUBLE + ' ', "W+/BG,W+/B" ) // draw box - - @ 9,17 SAY " Fields " COLOR "GR+/BG" - nChoices := ACHOICE( 10,11, 20, 31, aResult ) - - // Restore status - RESTSCREEN( 0, 0, MAXROW(), MAXCOL(), cOldScreen ) - SETCURSOR( nOldCursor ) - SETPOS( nOldRow, nOldCol ) - SETCOLOR( cOldColor ) - -RETURN( IIF( nChoices > 0, aResult[ nChoices ], "") ) - - - -*--------------------------- - FUNCTION SQLITE_DROPTABLE() -*--------------------------------------------------------------------------- -* Deletes a table from current database -* WARNING !! It deletes forever... -*--------------------------------------------------------------------------- -LOCAL cTable := ShowTables(), aOpt := {" Yes ", " No "} -LOCAL nOpt -nOpt := ALERT("Warning!;;The table selected will be erased;" +; - "without any choice to recover;Continue ? ", aOpt ) -IF nOpt == 1 // Yes - SQLITE_EXECUTE( "drop table " + cTable ) -ENDIF -RETURN 0 - - -*-------------------------------- - FUNCTION xConvert( xData, nPad ) -*--------------------------------------------------------------------------- -* Conversion scheme of types from Clipper/Harbour to SQLite -* Warning !! -* It's a work in progress and would have some errors -*--------------------------------------------------------------------------- -LOCAL cData, cType, nLen -cType := VALTYPE( xData ) - -DO CASE - CASE cType == "N" - cData := STR( xData ) - CASE cType == "C" - cData := xData - CASE cType == "L" - cData := IIF( xData == .T., "TRUE", "FALSE") - CASE cType == "A" - nLen := LEN(xData) - cData := "ARRAY[" + IIF( nLen > 0, STR( nLen, 2), "0") + "]" - CASE cType == "B" - cData := "BLOCK" - CASE cType == "U" - cData := "UNDEF" - CASE cType == "D" - ? xData - cData := DTOS( xData ) - OTHERWISE - cData := VALTYPE( xData) -ENDCASE - -IF nPad == NIL .OR. !( VALTYPE( nPad ) == "N" ) -ELSE - cData := PADL( LTRIM(cData), nPad, " ") -ENDIF - -RETURN( cData) - - -*--------------------------- - FUNCTION ShowData( cDBase ) -*--------------------------------------------------------------------------- -* Shows data -*--------------------------------------------------------------------------- -LOCAL aResult, nFields, nRecc, i, j -LOCAL cQuery := ".", cQuery1 - - IF cDBase == NIL .OR. EMPTY(cDBase) - RETURN 0 - ENDIF - - cQuery1 := PADR("select * from " + cDBase, 74) - - - DO WHILE ! EMPTY( cQuery ) - - cQuery := GetQuery( cQuery1 ) - - aResult := SQLITE_QUERY( RTRIM( cQuery ) + ";") - - @ 1,1 CLEAR TO 21,78 - @ 23,1 CLEAR TO 23,78 - - nFields := SQLITE_GETCOLS() - nRecc := SQLITE_GETROWS() - - IF nRecc < 1 - - IF SQLITE_ERROR() != NIL - ALERT( "Error!;;" + SQLITE_ERROR() ) - LOOP - ENDIF - - ENDIF - - IF nRecc < 2 - IF Answer("No record match your query. Retry ?") == 2 - RETURN 0 - ENDIF - LOOP - ENDIF - - DataBar( cDBase ) // status bar - - IF nRecc > 15 - nRecc := 15 - ENDIF - - FOR i := 1 TO nRecc // skip title field - - IF nFields > 1 - - // print the headers of fields - - // print data - FOR j := 1 TO nFields - IF i == 1 - SETCOLOR("N/BG") - ELSE - SETCOLOR("W+/BG,W+/N,N,N,N/W*") - ENDIF - @ 1+i,(j*12)-10 SAY aResult[ i][j] - NEXT - - ELSE - FOR j := 1 TO nFields - @ 1+i,(j*12)-10 SAY aResult[ i] - NEXT - - ENDIF - - NEXT - - IF Answer("New Query ?") != 1 - EXIT - ENDIF - - ENDDO - -RETURN 0 - - -*--------------------------- - FUNCTION ShowData2( cDBase ) -*--------------------------------------------------------------------------- -* Shows data I will change to use TBrowse object -*--------------------------------------------------------------------------- -LOCAL aResult, nFields, nRecc, i, j -LOCAL cQuery := ".", cQuery1 -LOCAL cQuery2 := SPACE(74) -LOCAL GetList := {} - - IF cDBase == NIL .OR. EMPTY(cDBase) - RETURN 0 - ENDIF - - cQuery1 := PADR("select * from " + cDBase, 74) - - DO WHILE ! EMPTY( cQuery ) - - @ 1,1 CLEAR TO 21,78 - DISPBOX( 9,1, 14, 78, B_DOUBLE + ' ', "W+/BG,W+/B" ) - - SET CURSOR ON - @ 9,38 SAY " QUERY " - @ 10,03 SAY "Input your SQL query to table" - @ 11,03 GET cQuery1 COLOR "N/W*,N/W*" - @ 12,03 GET cQuery2 COLOR "N/W*,N/W*" - READ - - cQuery := RTRIM( cQuery1 ) + RTRIM( cQuery2 ) - - IF LASTKEY() == 27 // ! EMPTY( cQuery ) - EXIT - ENDIF - - aResult := SQLITE_QUERY( RTRIM( cQuery ) + ";") - - @ 1,1 CLEAR TO 21,78 - @ 23,1 CLEAR TO 23,78 - - nFields := SQLITE_GETCOLS() - nRecc := SQLITE_GETROWS() - - IF nRecc < 1 - ALERT( "Error!;" + SQLITE_ERROR() ) - LOOP - ENDIF - - IF nRecc < 2 - IF Answer("No record match your query. Retry ?") == 2 - RETURN 0 - ENDIF - LOOP - ENDIF - - DataBar( cDBase ) // status bar - - IF nRecc > 15 - nRecc := 15 - ENDIF - - FOR i := 1 TO nRecc // skip title field - - IF nFields > 1 - - // print the headers of fields - // print data - FOR j := 1 TO nFields - IF i == 1 - SETCOLOR("N/BG") - ELSE - SETCOLOR("W+/BG,W+/N,N,N,N/W*") - ENDIF - @ 1+i,(j*12)-10 SAY aResult[ i][j] - NEXT - - ELSE - FOR j := 1 TO nFields - @ 1+i,(j*12)-10 SAY aResult[ i] - NEXT - - ENDIF - - NEXT - - IF Answer("New Query ?") != 1 - EXIT - ENDIF - - ENDDO - -RETURN 0 - - - -*-------------------------- - FUNCTION DataBar( cTable ) -*--------------------------------------------------------------------------- -IF cTable == NIL - cTable := "" -ENDIF - -@ 24,02 SAY REPLIC( "Í", 74) COLOR "W+/BG" - -@ 24,02 SAY "db: " COLOR "W+/BG" -@ 24,20 SAY " Table: " COLOR "W+/BG" -@ 24,42 SAY " Rows: " COLOR "W+/BG" -@ 24,58 SAY " Cols: " COLOR "W+/BG" -@ 24,06 SAY cDatabase -@ 24,28 SAY cTable -@ 24,48 SAY STR( SQLITE_GETROWS(), 5) COLOR "W+/BG" -@ 24,64 SAY STR( SQLITE_GETCOLS(), 3) COLOR "W+/BG" - -Ins_Stat() // shows Insert key status -RETURN 0 - - -*------------------------ - FUNCTION Answer( cMsg ) -*--------------------------------------------------------------------------- -LOCAL nOpt, nLen := LEN( cMsg ) -LOCAL nCol := 40 - INT( (11 + nLen) / 2) -@ 23,1 CLEAR TO 23,78 -@ 23, nCol SAY cMsg -@ 23, nCol+nLen + 2 PROMPT " Yes " -@ 23, nCol+nLen + 9 PROMPT " No " -MENU TO nOpt -@ 23,1 CLEAR TO 23,78 -RETURN( nOpt ) - - - -*------------------- - FUNCTION ChooseDB() -*--------------------------------------------------------------------------- -* Enter a Database to work with it -*--------------------------------------------------------------------------- - LOCAL cDB := PADR("example.db", 25) - LOCAL nOldCursor, nOldRow, nOldCol, cOldScreen, cOldColor - LOCAL GetList := {} - - * save status - nOldRow := ROW() - nOldCol := COL() - nOldCursor := SETCURSOR( .t. ) - cOldScreen := SAVESCREEN( 0, 0, MAXROW(), MAXCOL() ) - cOldColor := SETCOLOR() - - SETCOLOR( "W+/BG,W+/B,N,N,N/W*" ) - DISPBOX( 8,9, 13, 40, B_DOUBLE + ' ', "W+/BG,W+/B" ) // draw box - @ 8,13 SAY " Main Database " COLOR "GR+/BG" - @ 10,11 SAY "Input the working database:" - - Ins_Stat() - - DO WHILE LASTKEY() != 27 - - @ 12,11 GET cDB COLOR "N/W*" - READ - - IF ! EMPTY( cDB ) - - IF ! REALFILE( RTRIM( cDB ) ) - * file not exist! - IF ALERT('FUNCTION ChooseDB;; File "' + RTRIM( cDB ) + ; - '" Not found ! ;;;' +; - 'Input another file ?', { " No ", " Yes "} ) < 2 - cDB := "" // return an empty db - EXIT - ELSE - LOOP - ENDIF - - ELSE - * file exist - EXIT - ENDIF - - ENDIF - - ENDDO - - // Restore status - RESTSCREEN( 0, 0, MAXROW(), MAXCOL(), cOldScreen ) - SETCURSOR( nOldCursor ) - SETPOS( nOldRow, nOldCol ) - SETCOLOR( cOldColor ) - - cDatabase := IIF( ! EMPTY(cDB), LOWER( RTRIM( cDB ) ), "" ) - - RETURN( cDataBase ) - - - -*------------------------------ - FUNCTION REALFILE( cFilename ) -*--------------------------------------------------------------------------- -* It's odd but necessarily. We need to identify if it's a SQLite database -*--------------------------------------------------------------------------- -LOCAL lFound := .F., nHandle, nOfs := 0 -LOCAL cBuffer, cMarker -LOCAL nLength -#include "fileio.ch" - -IF FILE( cFilename ) - - nHandle := FOPEN( cFilename, FO_READ) - - * Don't show any error here -* IF FERROR() != 0 -* ALERT("Can't open file: " + cFilename + ";check the PATH.") -* ENDIF - - nLength := FSEEK( nHandle, nOfs, FS_END ) - - FSEEK( nHandle, nOfs, FS_SET ) // goto begining - - IF nLength > 0 - cBuffer := SPACE( 50 ) - - * The following is needed because for an unknown reason some - * empty files or with a few bytes (not SQLite database) don't - * give any error ???!! - * So we read the SQLite Tag at the beginning of the database - * (used to identify the database version). In that way we are - * sure now if it is really an SQLite database. - * - * This behavior was found - - IF FREAD( nHandle, @cBuffer, XSQLITE_TAG_LEN ) == XSQLITE_TAG_LEN - - cMarker := UPPER( LEFT( cBuffer, XSQLITE_TAG_LEN )) - - IF cMarker == UPPER( XSQLITE_TAG ) - lFound := .T. - ENDIF - ENDIF - - ENDIF - - FCLOSE( nHandle) - -ENDIF - -RETURN( lFound ) - -* sqlite-users-digest-subscribe@sqlite.org - - -PROCEDURE HELP - - ALERT( "HARBOUR INTERFACE for SQLITE;;" +; - "Version: " + HB_HB4SQLITE_VER + ";;" +; - "Copyright 2003 Alejandro de Garate;" +; - "" ,, "N/*W") - -RETURN - - -*----------------------------- - FUNCTION GetQuery( cDfltTxt ) -*--------------------------------------------------------------------------- -* Open a window an let you to type a query, and returns it as string -*--------------------------------------------------------------------------- -LOCAL cQuery, cQuery1, GetList :={} -LOCAL cQuery2 := SPACE(74) -LOCAL cQuery3 := SPACE(74) -LOCAL nOldCursor, nOldRow, nOldCol, cOldScreen, cOldColor -LOCAL nWide := 74 // length of edit line - - cQuery1 := PADR( cDfltTxt, nWide) // initial text as a guide - - * save status - nOldRow := ROW() - nOldCol := COL() - nOldCursor := SETCURSOR( SC_NONE ) - cOldScreen := SAVESCREEN( 0, 0, MAXROW(), MAXCOL() ) - cOldColor := SETCOLOR() - - DISPBOX( 9,1, 15, 78, B_DOUBLE + ' ', "W+/BG,W+/B" ) - - SET CURSOR ON - @ 9,38 SAY " QUERY " COLOR "GR+/BG,N/W*" - @ 10,03 SAY "Input your SQL query to table" COLOR "W+/BG,N/W*" - - cQuery := cDfltTxt - - - DO WHILE ! EMPTY( cQuery ) - - SET COLOR TO "N/W*,N/W*" -* cQuery := MEMOEDIT( cQuery, 11, 3, 13, 77, .T., "", nWide ) - - @ 11,03 GET cQuery1 COLOR "N/W*,N/W*" - @ 12,03 GET cQuery2 COLOR "N/W*,N/W*" - @ 13,03 GET cQuery3 COLOR "N/W*,N/W*" - READ - - cQuery := cQuery1 + cQuery2 + cQuery3 - - cQuery := ALLTRIM( cQuery ) - - DO CASE - CASE LASTKEY() == 27 - EXIT - - CASE LASTKEY() == 13 - IF ! EMPTY( cQuery ) - EXIT - ELSE - LOOP - ENDIF - OTHERWISE - ENDCASE - - ENDDO - - * restore status - RESTSCREEN( 0, 0, MAXROW(), MAXCOL(), cOldScreen ) - SETCURSOR( nOldCursor ) - SETPOS( nOldRow, nOldCol ) - SETCOLOR( cOldColor ) - -RETURN( cQuery ) - - -*----------------- - PROCEDURE INSERT -*--------------------------------------------------------------------------- -* insert -* CAMBIA EL MODO INSERT ON /OFF DESDE UN "READ" -*--------------------------------------------------------------------------- -ins_on := ! ins_on -IIF(ins_on, READINSERT(.T.), READINSERT(.F.)) -Ins_stat() -RETURN - -*------------------ - FUNCTION Ins_stat -*--------------------------------------------------------------------------- -* update the status line in the browse window -*--------------------------------------------------------------------------- -LOCAL c:= 24, r:= 72, nRow, nCol, cOldColor -* Relocate the status line -nRow := ROW() -nCol := COL() - -cOldColor := SETCOLOR() -SET COLOR TO "W+/BG" - -* display record pointer information -@ r, c SAY IIF( ins_on, "Insert ", "Replace") -SETCOLOR( cOldColor ) - -* restore cursor position -@ nRow, nCol SAY "" -RETURN 0 - - -*--------------------------------- - FUNCTION PickSQLiteFile( cAtrib ) -*--------------------------------------------------------------------------- -* Pick a SQLite file *** UNDER DEVELOPMENT *** -*--------------------------------------------------------------------------- - #include "directry.ch" - LOCAL aFiles, aNames := {}, aShow := {}, cPick := "" - LOCAL nOldCursor, nOldRow, nOldCol, cOldScreen, cOldColor - LOCAL n - LOCAL cFile - LOCAL nPick - - IF cAtrib == NIL - cAtrib := "*.*" - ENDIF - - * save status - nOldRow := ROW() - nOldCol := COL() - nOldCursor := SETCURSOR( SC_NONE ) - cOldScreen := SAVESCREEN( 0, 0, MAXROW(), MAXCOL() ) - cOldColor := SETCOLOR() - - DISPBOX( 9, 10, 13, 70, B_DOUBLE + ' ', "W+/BG,W+/B" ) - - @ 11,12 SAY "Searching for SQLite databases...on current directory" - - aFiles := DIRECTORY( cAtrib ) - -/* - AEVAL( aFiles, { | file| ; - IIF( Realfile( file[F_NAME]), AADD( aNames, file[F_NAME]); - AADD( aNames, PADR( file[F_NAME], 25) +; - " " + TRANSF( file[F_SIZE], "@E 999,999,999") ), ) } ) -*/ - - FOR n := 1 TO LEN( aFiles ) - cFile := aFiles[ n ][F_NAME] - - IF Realfile( cFile ) - AADD( aShow, PADR( cFile, 25) + " " + ; - TRANSF( aFiles[n][F_SIZE], "@E 999,999,999") ) - AADD( aNames, cFile ) - ENDIF - - NEXT - - @ 9, 10 clear to 13, 70 - - IF LEN( aNames ) > 0 - - DISPBOX( 6,8, 22, 50, B_DOUBLE + ' ', "W+/BG,W+/B" ) - @ 6,20 SAY " Pick a database " - @ 8,10 SAY " Name"+ SPACE(28) +"Size " COLOR "N/W*" - - nPick := ACHOICE( 10, 10, 20, 48, aShow ) - ELSE - ALERT("Notice;; I can't found a SQLite db on current directory") - ENDIF - - IF nPick > 0 - cPick := ALLTRIM( aNames[ nPick ] ) - ENDIF - - * restore status - RESTSCREEN( 0, 0, MAXROW(), MAXCOL(), cOldScreen ) - SETCURSOR( nOldCursor ) - SETPOS( nOldRow, nOldCol ) - SETCOLOR( cOldColor ) - -RETURN cPick