From 66bf4f58673ff87e25623489090fa3ee805c0e27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Czerpak?= Date: Tue, 17 Mar 2015 12:55:32 +0100 Subject: [PATCH] 2015-03-17 12:55 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * src/rdd/dbcmd.c ! fixed __dbArrange() to allow record transfer with the same conditions as __dbTrans() just like Cl*pper does. Low level RDD code should respect it, i.e. it should be possible to sort using fields which exist only in source workarea, the order and number of fields in source and destination workareas can be completely different, etc. Low level DBF* SORT() method is completely broken in such cases and has to be rewritten. --- ChangeLog.txt | 11 +++++ src/rdd/dbcmd.c | 115 +++++++++++++++++++----------------------------- 2 files changed, 57 insertions(+), 69 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 8cc26c86ac..b39ab33114 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,17 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2015-03-17 12:55 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * src/rdd/dbcmd.c + ! fixed __dbArrange() to allow record transfer with the same conditions + as __dbTrans() just like Cl*pper does. + Low level RDD code should respect it, i.e. it should be possible to + sort using fields which exist only in source workarea, the order + and number of fields in source and destination workareas can be + completely different, etc. + Low level DBF* SORT() method is completely broken in such cases and + has to be rewritten. + 2015-03-16 23:00 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/hbtip/smtpcli.prg ! do not execute STARTTLS command if server does not report it's supported diff --git a/src/rdd/dbcmd.c b/src/rdd/dbcmd.c index 54a37e4417..c6ec8bbc04 100644 --- a/src/rdd/dbcmd.c +++ b/src/rdd/dbcmd.c @@ -1822,66 +1822,42 @@ HB_FUNC( DBSETRELATION ) HB_FUNC( __DBARRANGE ) { HB_ERRCODE errCode = HB_FAILURE; - AREAP pArea, pDestArea; - PHB_ITEM pStruct; + AREAP pSrcArea, pDstArea; - pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); - pDestArea = ( AREAP ) hb_rddGetWorkAreaPointer( ( HB_AREANO ) hb_parni( 1 ) ); + pSrcArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); + pDstArea = ( AREAP ) hb_rddGetWorkAreaPointer( ( HB_AREANO ) hb_parni( 1 ) ); - /* Fields structure of source WorkArea */ - pStruct = hb_param( 2, HB_IT_ARRAY ); - - /* TODO: check what Clipper does when pDestArea == NULL or pArea == pDestArea */ - if( pArea && pDestArea && pArea != pDestArea && pStruct ) + /* TODO: check what Clipper does when pDstArea == NULL or pSrcArea == pDstArea */ + if( pSrcArea && pDstArea && pSrcArea != pDstArea ) { - DBSORTINFO dbSortInfo; HB_USHORT uiCount, uiDest; + DBSORTINFO dbSortInfo; + /* structure with fields copied copied from source WorkArea */ + PHB_ITEM pStruct = hb_param( 2, HB_IT_ARRAY ); + /* array with sorted fields in source WorkArea */ + PHB_ITEM pFields = hb_param( 8, HB_IT_ARRAY ); memset( &dbSortInfo, 0, sizeof( dbSortInfo ) ); - - dbSortInfo.dbtri.uiFlags = DBTF_PUTREC; - dbSortInfo.dbtri.lpaSource = pArea; - dbSortInfo.dbtri.lpaDest = pDestArea; - - dbSortInfo.dbtri.dbsci.itmCobFor = hb_param( 3, HB_IT_BLOCK ); - dbSortInfo.dbtri.dbsci.lpstrFor = NULL; - dbSortInfo.dbtri.dbsci.itmCobWhile = hb_param( 4, HB_IT_BLOCK ); - dbSortInfo.dbtri.dbsci.lpstrWhile = NULL; - dbSortInfo.dbtri.dbsci.lNext = hb_param( 5, HB_IT_NUMERIC ); - dbSortInfo.dbtri.dbsci.itmRecID = HB_ISNIL( 6 ) ? NULL : hb_param( 6, HB_IT_ANY ); - dbSortInfo.dbtri.dbsci.fRest = hb_param( 7, HB_IT_LOGICAL ); - - dbSortInfo.dbtri.dbsci.fIgnoreFilter = - dbSortInfo.dbtri.dbsci.fLast = - dbSortInfo.dbtri.dbsci.fIgnoreDuplicates = - dbSortInfo.dbtri.dbsci.fBackward = - dbSortInfo.dbtri.dbsci.fOptimized = HB_FALSE; - dbSortInfo.dbtri.dbsci.fIncludeDeleted = HB_TRUE; - - dbSortInfo.dbtri.uiItemCount = ( HB_USHORT ) hb_arrayLen( pStruct ); - if( dbSortInfo.dbtri.uiItemCount > 0 ) + errCode = hb_dbTransStruct( pSrcArea, pDstArea, &dbSortInfo.dbtri, + NULL, pStruct ); + if( errCode == HB_SUCCESS ) { - dbSortInfo.dbtri.lpTransItems = ( LPDBTRANSITEM ) - hb_xgrab( dbSortInfo.dbtri.uiItemCount * sizeof( DBTRANSITEM ) ); - for( uiCount = 0; uiCount < dbSortInfo.dbtri.uiItemCount; ++uiCount ) - { - const char * szName = hb_arrayGetCPtr( hb_arrayGetItemPtr( pStruct, - uiCount + 1 ), 1 ); - dbSortInfo.dbtri.lpTransItems[ uiCount ].uiSource = - hb_rddFieldIndex( pArea, szName ); - dbSortInfo.dbtri.lpTransItems[ uiCount ].uiDest = - hb_rddFieldIndex( pDestArea, szName ); - if( dbSortInfo.dbtri.lpTransItems[ uiCount ].uiSource == 0 || - dbSortInfo.dbtri.lpTransItems[ uiCount ].uiDest == 0 ) - { - dbSortInfo.dbtri.uiItemCount = 0; - break; - } - } - } - if( dbSortInfo.dbtri.uiItemCount > 0 ) - { - PHB_ITEM pFields = hb_param( 8, HB_IT_ARRAY ); + PHB_ITEM pTransItm; + + dbSortInfo.dbtri.dbsci.itmCobFor = hb_param( 3, HB_IT_BLOCK ); + dbSortInfo.dbtri.dbsci.lpstrFor = NULL; + dbSortInfo.dbtri.dbsci.itmCobWhile = hb_param( 4, HB_IT_BLOCK ); + dbSortInfo.dbtri.dbsci.lpstrWhile = NULL; + dbSortInfo.dbtri.dbsci.lNext = hb_param( 5, HB_IT_NUMERIC ); + dbSortInfo.dbtri.dbsci.itmRecID = HB_ISNIL( 6 ) ? NULL : hb_param( 6, HB_IT_ANY ); + dbSortInfo.dbtri.dbsci.fRest = hb_param( 7, HB_IT_LOGICAL ); + + dbSortInfo.dbtri.dbsci.fIgnoreFilter = + dbSortInfo.dbtri.dbsci.fLast = + dbSortInfo.dbtri.dbsci.fIgnoreDuplicates = + dbSortInfo.dbtri.dbsci.fBackward = + dbSortInfo.dbtri.dbsci.fOptimized = HB_FALSE; + dbSortInfo.dbtri.dbsci.fIncludeDeleted = HB_TRUE; dbSortInfo.uiItemCount = pFields ? ( HB_USHORT ) hb_arrayLen( pFields ) : 0; if( dbSortInfo.uiItemCount > 0 ) @@ -1906,6 +1882,8 @@ HB_FUNC( __DBARRANGE ) if( szPos ) { *szPos++ = 0; + /* It's not Cl*pper compatible, Cl*pper checks only + for /D flag and ignores any /A flags [druzus] */ if( strchr( szPos, 'D' ) > strchr( szPos, 'A' ) ) dbSortInfo.lpdbsItem[ uiDest ].uiFlags |= SF_DESCEND; else @@ -1916,7 +1894,10 @@ HB_FUNC( __DBARRANGE ) else dbSortInfo.lpdbsItem[ uiDest ].uiFlags |= SF_ASCEND; - dbSortInfo.lpdbsItem[ uiDest ].uiField = hb_rddFieldExpIndex( pArea, szFieldLine ); + /* Cl*pper sorts records using field values from source + area only, destination area may not contain sorted + fields at all [druzus] */ + dbSortInfo.lpdbsItem[ uiDest ].uiField = hb_rddFieldExpIndex( pSrcArea, szFieldLine ); /* Field found */ if( dbSortInfo.lpdbsItem[ uiDest ].uiField != 0 ) ++uiDest; @@ -1925,23 +1906,19 @@ HB_FUNC( __DBARRANGE ) hb_xfree( szFieldLine ); } - if( dbSortInfo.uiItemCount == 0 ) + pTransItm = hb_dbTransInfoPut( NULL, &dbSortInfo.dbtri ); + errCode = SELF_INFO( dbSortInfo.dbtri.lpaDest, DBI_TRANSREC, pTransItm ); + if( errCode == HB_SUCCESS ) { - PHB_ITEM pTransItm = hb_itemPutL( NULL, HB_TRUE ); - - errCode = SELF_INFO( dbSortInfo.dbtri.lpaDest, DBI_TRANSREC, pTransItm ); - if( errCode == HB_SUCCESS ) - { - errCode = dbSortInfo.dbtri.uiItemCount == 0 ? HB_FAILURE : - SELF_TRANS( pArea, &dbSortInfo.dbtri ); - SELF_INFO( dbSortInfo.dbtri.lpaDest, DBI_TRANSREC, pTransItm ); - if( errCode == HB_SUCCESS && ( dbSortInfo.dbtri.uiFlags & DBTF_CPYCTR ) ) - errCode = hb_dbTransCounters( &dbSortInfo.dbtri ); - } - hb_itemRelease( pTransItm ); + errCode = dbSortInfo.dbtri.uiItemCount == 0 ? HB_FAILURE : + ( dbSortInfo.uiItemCount == 0 ? + SELF_TRANS( pSrcArea, &dbSortInfo.dbtri ) : + SELF_SORT( pSrcArea, &dbSortInfo ) ); + SELF_INFO( dbSortInfo.dbtri.lpaDest, DBI_TRANSREC, pTransItm ); + if( errCode == HB_SUCCESS && ( dbSortInfo.dbtri.uiFlags & DBTF_CPYCTR ) ) + errCode = hb_dbTransCounters( &dbSortInfo.dbtri ); } - else - errCode = SELF_SORT( pArea, &dbSortInfo ); + hb_itemRelease( pTransItm ); } /* Free items */