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.
This commit is contained in:
Przemysław Czerpak
2015-03-17 12:55:32 +01:00
parent 11e823dba2
commit 66bf4f5867
2 changed files with 57 additions and 69 deletions

View File

@@ -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

View File

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