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 deaac12f4f..0000000000 Binary files a/harbour/examples/hbsqlit2/tests/example.db and /dev/null differ 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