From a108fb353423cfeb8e1a1c83686cc29d508ccc68 Mon Sep 17 00:00:00 2001 From: Horacio Dario Roldan Kasimatis Date: Wed, 7 Aug 2002 21:07:30 +0000 Subject: [PATCH] 2002-08-07 17:58 UTC-0300 Horacio Roldan * include/hbapirdd.h * source/rdd/dbcmd.c * source/rdd/workarea.c ! fixed gpf in dbCloseArea, now relations are closed if child area is closed, reported by Brian Hays --- harbour/include/hbapirdd.h | 3 ++ harbour/source/rdd/dbcmd.c | 23 ++++++++++++++- harbour/source/rdd/workarea.c | 53 ++++++++++++++++++++++++++++++++++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/harbour/include/hbapirdd.h b/harbour/include/hbapirdd.h index 821ebe63eb..dc3e9a1fe7 100644 --- a/harbour/include/hbapirdd.h +++ b/harbour/include/hbapirdd.h @@ -1166,6 +1166,9 @@ extern ERRCODE hb_rddDisinherit( BYTE * drvName ); extern USHORT hb_rddExtendType( USHORT fieldType ); extern USHORT hb_rddFieldType( USHORT extendType ); +typedef short (* WACALLBACK )( AREA *, int ); +extern ERRCODE hb_rddIterateWorkAreas ( WACALLBACK pCallBack, int data ); + #if defined(HB_EXTERN_C) } #endif diff --git a/harbour/source/rdd/dbcmd.c b/harbour/source/rdd/dbcmd.c index 06d660d5b3..93306e06bc 100644 --- a/harbour/source/rdd/dbcmd.c +++ b/harbour/source/rdd/dbcmd.c @@ -56,6 +56,7 @@ * ordKeyVal() * ordKeyAdd() * ordKeyDel() + * hb_rddIterateWorkAreas() * */ @@ -478,6 +479,7 @@ ERRCODE hb_rddInherit( PRDDFUNCS pTable, PRDDFUNCS pSubTable, PRDDFUNCS pSuperTa void hb_rddReleaseCurrentArea( void ) { HB_TRACE(HB_TR_DEBUG, ("hb_rddReleaseCurrentArea()")); + SELF_FORCEREL( ( AREAP ) s_pCurrArea->pArea ); SELF_CLOSE( ( AREAP ) s_pCurrArea->pArea ); SELF_RELEASE( ( AREAP ) s_pCurrArea->pArea ); @@ -611,6 +613,25 @@ static USHORT hb_rddFieldIndex( AREAP pArea, char * szName ) return 0; } + + +ERRCODE hb_rddIterateWorkAreas ( WACALLBACK pCallBack, int data ) +{ + LPAREANODE pAreaNode; + + HB_TRACE(HB_TR_DEBUG, ("hb_rddIterateWorkAreas(%p)", pCallBack)); + + pAreaNode = s_pWorkAreas; + while( pAreaNode ) + { + if ( ! (*pCallBack)( ( AREAP ) pAreaNode->pArea, data ) ) + break; + pAreaNode = pAreaNode->pNext; + } + return SUCCESS; +} + + /* * -- FUNCTIONS ACCESSED FROM VIRTUAL MACHINE -- */ @@ -3604,7 +3625,7 @@ static void rddMoveFields( AREAP pAreaFrom, AREAP pAreaTo, PHB_ITEM pFields, BOO f = hb_rddFieldIndex( pAreaTo, (( PHB_DYNS )(pAreaFrom->lpFields + i)->sym )->pSymbol->szName ); if ( f ) { - LPAREANODE s_curr = s_pCurrArea; + LPAREANODE s_curr = s_pCurrArea; SELF_GETVALUE( pAreaFrom, i+1, fieldValue ); if( s ) s_pCurrArea = s; diff --git a/harbour/source/rdd/workarea.c b/harbour/source/rdd/workarea.c index 5a97e7a4c6..9b0dcb754d 100644 --- a/harbour/source/rdd/workarea.c +++ b/harbour/source/rdd/workarea.c @@ -48,6 +48,11 @@ * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * + * + * The following functions are added by + * Horacio Roldan + * hb_waCloseAux() + * */ #include @@ -445,6 +450,8 @@ ERRCODE hb_waAlias( AREAP pArea, BYTE * szAlias ) /* * Close the table in the WorkArea. */ +short hb_waCloseAux ( AREAP pArea, int nChildArea ); + ERRCODE hb_waClose( AREAP pArea ) { HB_TRACE(HB_TR_DEBUG, ("hb_waClose(%p)", pArea)); @@ -455,12 +462,56 @@ ERRCODE hb_waClose( AREAP pArea ) SELF_CLEARLOCATE( pArea ); if( pArea->uiParents > 0 ) - printf( "\nTODO: hb_waClose() %d\n",pArea->uiParents ); + { + /* Clear relations that has this area as a child */ + hb_rddIterateWorkAreas ( hb_waCloseAux, pArea->uiArea ); + } ( ( PHB_DYNS ) pArea->atomAlias )->hArea = 0; return SUCCESS; } +short hb_waCloseAux ( AREAP pArea, int nChildArea ) +{ + USHORT uiPrevArea, uiArea; + LPDBRELINFO lpdbRelation, lpdbRelPrev, lpdbRelTmp; + + uiArea = ( USHORT ) nChildArea; + if ( pArea->lpdbRelations ) + { + uiPrevArea = hb_rddGetCurrentWorkAreaNumber(); + lpdbRelation = pArea->lpdbRelations; + lpdbRelPrev = NULL; + while ( lpdbRelation ) { + if ( lpdbRelation->lpaChild->uiArea == uiArea ) { + /* Clear this relation */ + hb_rddSelectWorkAreaNumber( lpdbRelation->lpaChild->uiArea ); + SELF_CHILDEND( lpdbRelation->lpaChild, lpdbRelation ); + hb_rddSelectWorkAreaNumber( uiPrevArea ); + if( lpdbRelation->itmCobExpr ) + { + hb_itemRelease( lpdbRelation->itmCobExpr ); + } + if( lpdbRelation->abKey ) + hb_itemRelease( lpdbRelation->abKey ); + lpdbRelTmp = lpdbRelation; + if ( lpdbRelPrev ) + lpdbRelPrev->lpdbriNext = lpdbRelation->lpdbriNext; + else + pArea->lpdbRelations = lpdbRelation->lpdbriNext; + lpdbRelation = lpdbRelation->lpdbriNext; + hb_xfree( lpdbRelTmp ); + } + else + { + lpdbRelPrev = lpdbRelation; + lpdbRelation = lpdbRelation->lpdbriNext; + } + } + } + return 1; +} + /* * Retrieve information about the current driver. */