diff --git a/ChangeLog.txt b/ChangeLog.txt index 39558fd518..3ab5cba1eb 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,48 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2015-03-03 16:26 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + * contrib/rddads/ads1.c + ! use AdsSetLongLong() (if available) instead of AdsSetDouble() to not + strip less significant bits from 64bit integer number during conversion + to double + * allow ADS to decide if writing into rowver and modtime fields is legal + instead of generating our own arbitrary RTE + + * include/dbinfo.ch + * src/rdd/workarea.c + + added new dbInfo() action DBI_TRANSREC + It indicates if area is destination table of currently processed COPY TO + or APPEND FROM operation. + + * include/hbapirdd.h + * src/rdd/wafunc.c + + added new C function: + HB_ERRCODE hb_dbTransCounters( LPDBTRANSINFO lpdbTransInfo ); + It copies field counters from source into destination table used + in transfer operation. + + * src/rdd/dbcmd.c + * src/rdd/wafunc.c + + call DBI_TRANSREC to inform destination area that record transfer + operation starts and stop. It allows destination RDD to change + rules used for assign to automatically updated fields, i.e. unblock + such operation. + + call hb_dbTransCounters() to update counters in destination table + after COPY TO operation + + * src/rdd/sdf1.c + * src/rdd/delim1.c + * clear AutoInc flag + + * src/rdd/dbf1.c + + allow to set get and set counter for RowVer fields using DBS_COUNTER + action + * return HB_FAILURE for DBS_COUNTER and DBS_STEP if it's not supported + by given field. + + added support for DBI_TRANSREC - in case of DBF* RDDs it unblocks + writing to automatically updated fields + 2015-03-03 15:57 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * contrib/gtalleg/gtallegd.c * contrib/gtqtc/gtqtc1.cpp diff --git a/contrib/rddads/ads1.c b/contrib/rddads/ads1.c index 3c22008d82..20fdbba661 100644 --- a/contrib/rddads/ads1.c +++ b/contrib/rddads/ads1.c @@ -2694,10 +2694,20 @@ static HB_ERRCODE adsPutValue( ADSAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem } break; - case HB_FT_LONG: - case HB_FT_INTEGER: - case HB_FT_DOUBLE: + case HB_FT_ROWVER: case HB_FT_AUTOINC: + case HB_FT_INTEGER: +#if ADS_LIB_VERSION >= 700 && ! defined( HB_LONG_LONG_OFF ) + if( HB_IS_NUMERIC( pItem ) ) + { + bTypeError = HB_FALSE; + u32RetVal = AdsSetLongLong( pArea->hTable, ADSFIELD( uiIndex ), hb_itemGetNInt( pItem ) ); + /* write to autoincrement field will gen error 5066 */ + } + break; +#endif + case HB_FT_LONG: + case HB_FT_DOUBLE: case HB_FT_CURDOUBLE: case HB_FT_CURRENCY: if( HB_IS_NUMERIC( pItem ) ) diff --git a/include/dbinfo.ch b/include/dbinfo.ch index b48ca5f385..724402ad21 100644 --- a/include/dbinfo.ch +++ b/include/dbinfo.ch @@ -292,6 +292,7 @@ #define DBI_ISTEMPORARY 145 /* Is the table a temporary one? */ #define DBI_LOCKTEST 146 /* record / file lock test */ #define DBI_CODEPAGE 147 /* Codepage used */ +#define DBI_TRANSREC 148 /* Is it destination table of currently processed COPY TO or APPEND FROM operation? */ /* RECORD MAP (RM) support */ #define DBI_RM_SUPPORTED 150 /* has WA RDD record map support? */ diff --git a/include/hbapirdd.h b/include/hbapirdd.h index 0e3b263462..03c2c639b2 100644 --- a/include/hbapirdd.h +++ b/include/hbapirdd.h @@ -1207,6 +1207,7 @@ extern HB_EXPORT HB_ERRCODE hb_rddCreateTableTemp( const char * szAlias, const char * szCpId, HB_ULONG ulConnection, PHB_ITEM pStruct ); +extern HB_EXPORT HB_ERRCODE hb_dbTransCounters( LPDBTRANSINFO lpdbTransInfo ); extern HB_EXPORT HB_ERRCODE hb_dbTransStruct( AREAP lpaSource, AREAP lpaDest, LPDBTRANSINFO lpdbTransInfo, diff --git a/include/hbrdddbf.h b/include/hbrdddbf.h index 6aa4dd8987..46f43e17b4 100644 --- a/include/hbrdddbf.h +++ b/include/hbrdddbf.h @@ -233,6 +233,7 @@ typedef struct _DBFAREA HB_BOOL fFLocked; /* HB_TRUE if file is locked */ HB_BOOL fHeaderLocked; /* HB_TRUE if DBF header is locked */ HB_BOOL fPackMemo; /* Pack memo file in pack operation */ + HB_BOOL fTransRec; /* HB_TRUE if records are transfered to this area, allow to change autoupdate fields and disable their initialization */ HB_BOOL fTrigger; /* Execute trigger function */ LPDBOPENINFO lpdbOpenInfo; /* Pointer to current dbOpenInfo structure in OPEN/CREATE methods */ LPDBRELINFO lpdbPendingRel; /* Pointer to parent rel struct */ diff --git a/src/rdd/dbcmd.c b/src/rdd/dbcmd.c index 64a5238c26..e606937d4c 100644 --- a/src/rdd/dbcmd.c +++ b/src/rdd/dbcmd.c @@ -1973,6 +1973,8 @@ HB_FUNC( __DBTRANS ) NULL, pFields ); if( errCode == HB_SUCCESS ) { + PHB_ITEM pTransItm; + hb_rddSelectWorkAreaNumber( dbTransInfo.lpaSource->uiArea ); dbTransInfo.dbsci.itmCobFor = hb_param( 3, HB_IT_BLOCK ); @@ -1989,7 +1991,12 @@ HB_FUNC( __DBTRANS ) dbTransInfo.dbsci.fIgnoreDuplicates = HB_FALSE; dbTransInfo.dbsci.fBackward = HB_FALSE; + pTransItm = hb_itemPutL( NULL, HB_TRUE ); + SELF_INFO( dbTransInfo.lpaDest, DBI_TRANSREC, pTransItm ); + errCode = SELF_TRANS( dbTransInfo.lpaSource, &dbTransInfo ); + + SELF_INFO( dbTransInfo.lpaDest, DBI_TRANSREC, pTransItm ); } if( dbTransInfo.lpTransItems ) diff --git a/src/rdd/dbf1.c b/src/rdd/dbf1.c index 718b8e3933..a1f33e8bcb 100644 --- a/src/rdd/dbf1.c +++ b/src/rdd/dbf1.c @@ -173,6 +173,8 @@ static HB_BOOL hb_dbfIsAutoIncField( LPFIELD pField ) if( pField->uiType == HB_FT_AUTOINC ) return pField->uiLen - pField->uiDec > 4 ? HB_AUTOINC_LONG : HB_AUTOINC_STD; + else if( pField->uiType == HB_FT_ROWVER ) + return HB_AUTOINC_LONG; else if( ( pField->uiFlags & HB_FF_AUTOINC ) != 0 ) { switch( pField->uiType ) @@ -2627,13 +2629,14 @@ static HB_ERRCODE hb_dbfPutValue( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pI } } else if( pField->uiType == HB_FT_TIMESTAMP || - pField->uiType == HB_FT_TIME ) + pField->uiType == HB_FT_TIME || + ( pField->uiType == HB_FT_MODTIME && pArea->fTransRec ) ) { long lDate, lTime; hb_itemGetTDT( pItem, &lDate, &lTime ); ptr = pArea->pRecord + pArea->pFieldOffset[ uiIndex ]; - if( pField->uiType == HB_FT_TIMESTAMP ) + if( pField->uiType != HB_FT_TIME ) { HB_PUT_LE_UINT32( ptr, lDate ); ptr += 4; @@ -2664,7 +2667,9 @@ static HB_ERRCODE hb_dbfPutValue( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pI '*', pField->uiLen ); } } - else if( pField->uiType == HB_FT_INTEGER ) + else if( pField->uiType == HB_FT_INTEGER || + ( pArea->fTransRec && ( pField->uiType == HB_FT_AUTOINC || + pField->uiType == HB_FT_ROWVER ) ) ) { HB_MAXINT lVal; double dVal; @@ -3581,14 +3586,21 @@ static HB_ERRCODE hb_dbfInfo( DBFAREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem ( HB_MAXINT ) ( HB_NHANDLE ) hb_fileHandle( pArea->pMemoFile ) ); break; + case DBI_TRANSREC: + { + HB_BOOL fTransRec = pArea->fTransRec; + + if( HB_IS_LOGICAL( pItem ) ) + pArea->fTransRec = hb_itemGetL( pItem ); + hb_itemPutL( pItem, fTransRec ); + break; + } case DBI_SHARED: { HB_BOOL fShared = pArea->fShared; if( HB_IS_LOGICAL( pItem ) ) - { pArea->fShared = hb_itemGetL( pItem ); - } hb_itemPutL( pItem, fShared ); break; } @@ -3772,9 +3784,9 @@ static HB_ERRCODE hb_dbfFieldInfo( DBFAREAP pArea, HB_USHORT uiIndex, HB_USHORT hb_dbfGetNullFlag( pArea, pArea->pFieldBits[ uiIndex ].uiNullBit ) ); return HB_SUCCESS; case DBS_COUNTER: - nValue = 0; if( hb_dbfIsAutoIncField( pArea->area.lpFields + uiIndex - 1 ) != HB_AUTOINC_NONE ) { + nValue = 0; fLck = HB_FALSE; if( pArea->fShared && ! pArea->fFLocked && ! pArea->fHeaderLocked ) { @@ -3790,13 +3802,15 @@ static HB_ERRCODE hb_dbfFieldInfo( DBFAREAP pArea, HB_USHORT uiIndex, HB_USHORT if( fLck ) SELF_RAWLOCK( &pArea->area, HEADER_UNLOCK, 0 ); + hb_itemPutNInt( pItem, nValue ); + return HB_SUCCESS; } - hb_itemPutNInt( pItem, nValue ); - return HB_SUCCESS; + hb_itemClear( pItem ); + return HB_FAILURE; case DBS_STEP: - iValue = 0; if( hb_dbfIsAutoIncField( pArea->area.lpFields + uiIndex - 1 ) != HB_AUTOINC_NONE ) { + iValue = 0; if( HB_IS_NUMERIC( pItem ) ) { fLck = HB_FALSE; @@ -3813,9 +3827,11 @@ static HB_ERRCODE hb_dbfFieldInfo( DBFAREAP pArea, HB_USHORT uiIndex, HB_USHORT } else iValue = hb_dbfNextValueStep( pArea, uiIndex - 1, 0 ); + hb_itemPutNI( pItem, iValue ); + return HB_SUCCESS; } - hb_itemPutNI( pItem, iValue ); - return HB_SUCCESS; + hb_itemClear( pItem ); + return HB_FAILURE; default: return SUPER_FIELDINFO( &pArea->area, uiIndex, uiType, pItem ); } @@ -4935,6 +4951,7 @@ static HB_ERRCODE hb_dbfTrans( DBFAREAP pArea, LPDBTRANSINFO pTransInfo ) hb_itemRelease( pPutRec ); } } + return SUPER_TRANS( &pArea->area, pTransInfo ); } @@ -4980,10 +4997,10 @@ static HB_ERRCODE hb_dbfZap( DBFAREAP pArea ) /* reset autoincrement and row version fields */ for( uiField = 0; uiField < pArea->area.uiFieldCount; uiField++ ) { - if( hb_dbfIsAutoIncField( &pArea->area.lpFields[ uiField ] ) != HB_AUTOINC_NONE ) - hb_dbfNextValueSet( pArea, uiField, 1 ); - else if( pArea->area.lpFields[ uiField ].uiType == HB_FT_ROWVER ) + if( pArea->area.lpFields[ uiField ].uiType == HB_FT_ROWVER ) hb_dbfRowVerSet( pArea, uiField, 0 ); + else if( hb_dbfIsAutoIncField( &pArea->area.lpFields[ uiField ] ) != HB_AUTOINC_NONE ) + hb_dbfNextValueSet( pArea, uiField, 1 ); } /* Zap memo file */ diff --git a/src/rdd/delim1.c b/src/rdd/delim1.c index 7022fc1cf2..4f93211f55 100644 --- a/src/rdd/delim1.c +++ b/src/rdd/delim1.c @@ -1104,6 +1104,9 @@ static HB_ERRCODE hb_delimAddField( DELIMAREAP pArea, LPDBFIELDINFO pFieldInfo ) } break; + case HB_FT_LONG: + break; + case HB_FT_FLOAT: pFieldInfo->uiType = HB_FT_LONG; break; @@ -1140,9 +1143,6 @@ static HB_ERRCODE hb_delimAddField( DELIMAREAP pArea, LPDBFIELDINFO pFieldInfo ) } break; - case HB_FT_LONG: - break; - case HB_FT_TIME: pFieldInfo->uiType = HB_FT_TIMESTAMP; pFieldInfo->uiLen = 12; @@ -1165,6 +1165,8 @@ static HB_ERRCODE hb_delimAddField( DELIMAREAP pArea, LPDBFIELDINFO pFieldInfo ) break; } + pFieldInfo->uiFlags &= ~HB_FF_AUTOINC; + /* Update field offset */ pArea->pFieldOffset[ pArea->area.uiFieldCount ] = pArea->uiRecordLen; pArea->uiRecordLen += pFieldInfo->uiLen; diff --git a/src/rdd/sdf1.c b/src/rdd/sdf1.c index cd8e419d5f..332f96ff6d 100644 --- a/src/rdd/sdf1.c +++ b/src/rdd/sdf1.c @@ -848,6 +848,10 @@ static HB_ERRCODE hb_sdfAddField( SDFAREAP pArea, LPDBFIELDINFO pFieldInfo ) } break; + case HB_FT_STRING: + case HB_FT_LONG: + break; + case HB_FT_FLOAT: pFieldInfo->uiType = HB_FT_LONG; break; @@ -883,10 +887,6 @@ static HB_ERRCODE hb_sdfAddField( SDFAREAP pArea, LPDBFIELDINFO pFieldInfo ) } break; - case HB_FT_LONG: - case HB_FT_STRING: - break; - case HB_FT_TIME: pFieldInfo->uiType = HB_FT_TIMESTAMP; pFieldInfo->uiLen = 12; @@ -907,6 +907,8 @@ static HB_ERRCODE hb_sdfAddField( SDFAREAP pArea, LPDBFIELDINFO pFieldInfo ) break; } + pFieldInfo->uiFlags &= ~HB_FF_AUTOINC; + /* Update field offset */ pArea->pFieldOffset[ pArea->area.uiFieldCount ] = pArea->uiRecordLen; pArea->uiRecordLen += pFieldInfo->uiLen; diff --git a/src/rdd/wafunc.c b/src/rdd/wafunc.c index 64e11125de..befbb9b630 100644 --- a/src/rdd/wafunc.c +++ b/src/rdd/wafunc.c @@ -870,6 +870,34 @@ static const char * hb_dbTransFieldPos( PHB_ITEM pFields, HB_USHORT uiField ) return szField; } +/* update counters for autoinc and rowver fields */ +HB_ERRCODE hb_dbTransCounters( LPDBTRANSINFO lpdbTransInfo ) +{ + PHB_ITEM pItem = hb_itemNew( NULL ); + HB_USHORT uiCount; + + for( uiCount = 1; uiCount <= lpdbTransInfo->uiItemCount; ++uiCount ) + { + LPDBTRANSITEM lpdbTransItem = &lpdbTransInfo->lpTransItems[ uiCount ]; + + if( SELF_FIELDINFO( lpdbTransInfo->lpaSource, lpdbTransItem->uiSource, + DBS_COUNTER, pItem ) == HB_SUCCESS && + SELF_FIELDINFO( lpdbTransInfo->lpaDest, lpdbTransItem->uiDest, + DBS_COUNTER, pItem ) == HB_SUCCESS ) + { + hb_itemClear( pItem ); + if( SELF_FIELDINFO( lpdbTransInfo->lpaSource, lpdbTransItem->uiSource, + DBS_STEP, pItem ) == HB_SUCCESS ) + SELF_FIELDINFO( lpdbTransInfo->lpaDest, lpdbTransItem->uiDest, + DBS_STEP, pItem ); + } + hb_itemClear( pItem ); + } + hb_itemRelease( pItem ); + + return HB_SUCCESS; +} + HB_ERRCODE hb_dbTransStruct( AREAP lpaSource, AREAP lpaDest, LPDBTRANSINFO lpdbTransInfo, PHB_ITEM * pStruct, PHB_ITEM pFields ) @@ -1085,6 +1113,7 @@ HB_ERRCODE hb_rddTransRecords( AREAP pArea, PHB_ITEM pStruct = NULL; DBTRANSINFO dbTransInfo; HB_USHORT uiPrevArea, uiCount, uiSwap; + HB_BOOL fUpdateCtr = HB_FALSE; HB_ERRCODE errCode; memset( &dbTransInfo, 0, sizeof( dbTransInfo ) ); @@ -1105,6 +1134,7 @@ HB_ERRCODE hb_rddTransRecords( AREAP pArea, szCpId, ulConnection, pStruct, pDelim ); if( errCode == HB_SUCCESS ) { + fUpdateCtr = HB_TRUE; dbTransInfo.lpaDest = lpaClose = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); } @@ -1164,6 +1194,8 @@ HB_ERRCODE hb_rddTransRecords( AREAP pArea, if( errCode == HB_SUCCESS ) { + PHB_ITEM pTransItm; + hb_rddSelectWorkAreaNumber( dbTransInfo.lpaSource->uiArea ); dbTransInfo.dbsci.itmCobFor = pCobFor; @@ -1180,7 +1212,15 @@ HB_ERRCODE hb_rddTransRecords( AREAP pArea, dbTransInfo.dbsci.fIgnoreDuplicates = HB_FALSE; dbTransInfo.dbsci.fBackward = HB_FALSE; + pTransItm = hb_itemPutL( NULL, HB_TRUE ); + SELF_INFO( dbTransInfo.lpaDest, DBI_TRANSREC, pTransItm ); + errCode = SELF_TRANS( dbTransInfo.lpaSource, &dbTransInfo ); + + SELF_INFO( dbTransInfo.lpaDest, DBI_TRANSREC, pTransItm ); + + if( errCode == HB_SUCCESS && fUpdateCtr ) + errCode = hb_dbTransCounters( &dbTransInfo ); } if( dbTransInfo.lpTransItems ) diff --git a/src/rdd/workarea.c b/src/rdd/workarea.c index 4c7ecc7599..e1451f8263 100644 --- a/src/rdd/workarea.c +++ b/src/rdd/workarea.c @@ -562,8 +562,8 @@ static HB_ERRCODE hb_waFieldInfo( AREAP pArea, HB_USHORT uiIndex, HB_USHORT uiTy { case HB_FT_STRING: cType = 'C'; - uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_COMPRESSED | - HB_FF_ENCRYPTED | HB_FF_UNICODE; + uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_UNICODE | + HB_FF_ENCRYPTED | HB_FF_COMPRESSED; break; case HB_FT_LOGICAL: @@ -631,20 +631,20 @@ static HB_ERRCODE hb_waFieldInfo( AREAP pArea, HB_USHORT uiIndex, HB_USHORT uiTy case HB_FT_VARLENGTH: cType = 'Q'; - uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_COMPRESSED | - HB_FF_ENCRYPTED | HB_FF_UNICODE; + uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_UNICODE | + HB_FF_ENCRYPTED | HB_FF_COMPRESSED; break; case HB_FT_ANY: cType = 'V'; - uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_COMPRESSED | - HB_FF_ENCRYPTED | HB_FF_UNICODE; + uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_UNICODE | + HB_FF_ENCRYPTED | HB_FF_COMPRESSED; break; case HB_FT_MEMO: cType = 'M'; - uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_COMPRESSED | - HB_FF_ENCRYPTED | HB_FF_UNICODE; + uiFlags = HB_FF_NULLABLE | HB_FF_BINARY | HB_FF_UNICODE | + HB_FF_ENCRYPTED | HB_FF_COMPRESSED; break; case HB_FT_IMAGE: @@ -790,6 +790,7 @@ static HB_ERRCODE hb_waInfo( AREAP pArea, HB_USHORT uiIndex, PHB_ITEM pItem ) case DBI_CANPUTREC: case DBI_ISFLOCK: case DBI_SHARED: + case DBI_TRANSREC: hb_itemPutL( pItem, HB_FALSE ); break;