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 */