/* * Copy one or more records from one WorkArea to another. */ static HB_ERRCODE hb_delimTrans( DELIMAREAP pArea, LPDBTRANSINFO pTransInfo ) { HB_TRACE(HB_TR_DEBUG, ("hb_delimTrans(%p, %p)", pArea, pTransInfo)); if( pTransInfo->uiFlags & DBTF_MATCH ) { if( !pArea->fTransRec || pArea->cdPage != pTransInfo->lpaDest->cdPage ) pTransInfo->uiFlags &= ~DBTF_PUTREC; else if( pArea->rddID == pTransInfo->lpaDest->rddID ) pTransInfo->uiFlags |= DBTF_PUTREC; else { PHB_ITEM pPutRec = hb_itemPutL( NULL, FALSE ); if( SELF_INFO( ( AREAP ) pTransInfo->lpaDest, DBI_CANPUTREC, pPutRec ) != HB_SUCCESS ) { hb_itemRelease( pPutRec ); return HB_FAILURE; } if( hb_itemGetL( pPutRec ) ) pTransInfo->uiFlags |= DBTF_PUTREC; else pTransInfo->uiFlags &= ~DBTF_PUTREC; hb_itemRelease( pPutRec ); } } return SUPER_TRANS( ( AREAP ) pArea, pTransInfo ); }
static void hb_sxRollBackChild( AREAP pArea, PHB_ITEM pItem ) { LPDBRELINFO lpdbRelation = pArea->lpdbRelations; while( lpdbRelation ) { if( SELF_INFO( lpdbRelation->lpaChild, DBI_ROLLBACK, pItem ) != HB_SUCCESS ) break; hb_sxRollBackChild( lpdbRelation->lpaChild, pItem ); lpdbRelation = lpdbRelation->lpdbriNext; } }
HB_ERRCODE hb_rddCreateTableTemp( const char * szDriver, const char * szAlias, const char * szCpId, HB_ULONG ulConnection, PHB_ITEM pStruct ) { char szDriverBuffer[ HB_RDD_MAX_DRIVERNAME_LEN + 1 ]; DBOPENINFO pInfo; PHB_ITEM pItem; HB_ERRCODE errCode; HB_USHORT uiPrevArea; AREAP pArea; if( szDriver && szDriver[ 0 ] ) { hb_strncpyUpper( szDriverBuffer, szDriver, sizeof( szDriverBuffer ) - 1 ); szDriver = szDriverBuffer; } else szDriver = hb_rddDefaultDrv( NULL ); uiPrevArea = ( HB_AREANO ) hb_rddGetCurrentWorkAreaNumber(); /* 0 means chose first available in hb_rddInsertAreaNode() */ hb_rddSelectWorkAreaNumber( 0 ); /* Create a new WorkArea node */ if( ! hb_rddInsertAreaNode( szDriver ) ) { hb_rddSelectWorkAreaNumber( uiPrevArea ); hb_errRT_DBCMD( EG_ARG, EDBCMD_BADPARAMETER, NULL, HB_ERR_FUNCNAME ); return HB_FAILURE; } pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); /* Fill pInfo structure */ pInfo.uiArea = pArea->uiArea; pInfo.abName = NULL; pInfo.atomAlias = szAlias; pInfo.fShared = HB_FALSE; pInfo.fReadonly = HB_FALSE; pInfo.cdpId = szCpId ? szCpId : hb_setGetDBCODEPAGE(); pInfo.ulConnection = ulConnection; pInfo.lpdbHeader = NULL; pItem = hb_itemPutL( NULL, HB_TRUE ); errCode = SELF_INFO( pArea, DBI_ISTEMPORARY, pItem ); hb_itemRelease( pItem ); if( errCode == HB_SUCCESS ) { errCode = SELF_CREATEFIELDS( pArea, pStruct ); if( errCode == HB_SUCCESS ) errCode = SELF_CREATE( pArea, &pInfo ); } if( errCode != HB_SUCCESS ) { hb_rddReleaseCurrentArea(); hb_rddSelectWorkAreaNumber( uiPrevArea ); } return errCode; }
HB_ERRCODE hb_rddOpenTable( const char * szFileName, const char * szDriver, HB_USHORT uiArea, const char * szAlias, HB_BOOL fShared, HB_BOOL fReadonly, const char * szCpId, HB_ULONG ulConnection, PHB_ITEM pStruct, PHB_ITEM pDelim ) { char szDriverBuffer[ HB_RDD_MAX_DRIVERNAME_LEN + 1 ]; DBOPENINFO pInfo; HB_ERRCODE errCode; AREAP pArea; /* uiArea = 0 in hb_rddInsertAreaNode() means chose first * available free area, otherwise we should close table in * current WA and it should be done before parameter validation * RT errors below. This breaks xHarbour like MT code which * shares WA between threads so dbUseArea() should be covered * by external mutex to make lNewArea MT safe, [druzus] */ if( uiArea ) { hb_rddSelectWorkAreaNumber( uiArea ); hb_rddReleaseCurrentArea(); } else hb_rddSelectFirstAvailable(); /* Clipper clears NETERR flag before parameter validation, [druzus] */ hb_rddSetNetErr( HB_FALSE ); /* Now check parameters, first RDD name. * Clipper seems to make sth like: * if( szDriver && strlen( szDriver ) > 1 ) * but I do not think we should replicate it, [druzus] */ if( szDriver && szDriver[ 0 ] ) { hb_strncpyUpper( szDriverBuffer, szDriver, sizeof( szDriverBuffer ) - 1 ); szDriver = szDriverBuffer; } else szDriver = hb_rddDefaultDrv( NULL ); /* First try to create new are node and validate RDD name */ if( ! hb_rddInsertAreaNode( szDriver ) ) { hb_errRT_DBCMD( EG_ARG, EDBCMD_BADPARAMETER, NULL, HB_ERR_FUNCNAME ); return HB_FAILURE; } /* Then check if valid file name was given - Clipper allows to use empty * ("") file name */ if( ! szFileName ) { hb_rddReleaseCurrentArea(); hb_errRT_DBCMD( EG_ARG, EDBCMD_USE_BADPARAMETER, NULL, HB_ERR_FUNCNAME ); return HB_FAILURE; } pArea = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); /* Fill pInfo structure */ pInfo.uiArea = pArea->uiArea; pInfo.abName = szFileName; pInfo.atomAlias = szAlias; pInfo.fShared = fShared; pInfo.fReadonly = fReadonly; pInfo.cdpId = szCpId ? szCpId : hb_setGetDBCODEPAGE(); pInfo.ulConnection = ulConnection; pInfo.lpdbHeader = NULL; errCode = pStruct ? SELF_CREATEFIELDS( pArea, pStruct ) : HB_SUCCESS; if( errCode == HB_SUCCESS ) { if( pDelim && ! HB_IS_NIL( pDelim ) ) errCode = SELF_INFO( pArea, DBI_SETDELIMITER, pDelim ); if( errCode == HB_SUCCESS ) /* Open file */ errCode = SELF_OPEN( pArea, &pInfo ); } if( errCode != HB_SUCCESS ) hb_rddReleaseCurrentArea(); return errCode; }
HB_ERRCODE hb_rddTransRecords( AREAP pArea, const char * szFileName, const char * szDriver, HB_ULONG ulConnection, PHB_ITEM pFields, HB_BOOL fExport, PHB_ITEM pCobFor, PHB_ITEM pStrFor, PHB_ITEM pCobWhile, PHB_ITEM pStrWhile, PHB_ITEM pNext, PHB_ITEM pRecID, PHB_ITEM pRest, const char * szCpId, PHB_ITEM pDelim ) { AREAP lpaClose = NULL; PHB_ITEM pStruct = NULL; DBTRANSINFO dbTransInfo; HB_USHORT uiPrevArea, uiCount, uiSwap; HB_ERRCODE errCode; memset( &dbTransInfo, 0, sizeof( dbTransInfo ) ); uiPrevArea = ( HB_AREANO ) hb_rddGetCurrentWorkAreaNumber(); if( szDriver == NULL ) /* szDriver = SELF_RDDNODE( pArea )->szName; */ szDriver = hb_rddDefaultDrv( NULL ); if( fExport ) { errCode = hb_dbTransStruct( pArea, NULL, &dbTransInfo, &pStruct, pFields ); if( errCode == HB_SUCCESS ) { errCode = hb_rddCreateTable( szFileName, szDriver, 0, "", HB_TRUE, szCpId, ulConnection, pStruct, pDelim ); if( errCode == HB_SUCCESS ) dbTransInfo.lpaDest = lpaClose = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); } } else { LPRDDNODE pRddNode = hb_rddFindNode( szDriver, NULL ); if( ! pRddNode ) { hb_errRT_DBCMD( EG_ARG, EDBCMD_USE_BADPARAMETER, NULL, HB_ERR_FUNCNAME ); return HB_FAILURE; } if( pRddNode->uiType == RDT_TRANSFER ) { errCode = hb_dbTransStruct( pArea, NULL, &dbTransInfo, &pStruct, pFields ); /* revert area and items */ dbTransInfo.lpaDest = dbTransInfo.lpaSource; for( uiCount = 0; uiCount < dbTransInfo.uiItemCount; ++uiCount ) { uiSwap = dbTransInfo.lpTransItems[ uiCount ].uiSource; dbTransInfo.lpTransItems[ uiCount ].uiSource = dbTransInfo.lpTransItems[ uiCount ].uiDest; dbTransInfo.lpTransItems[ uiCount ].uiDest = uiSwap; } if( errCode == HB_SUCCESS ) { errCode = hb_rddOpenTable( szFileName, szDriver, 0, "", HB_TRUE, HB_TRUE, szCpId, ulConnection, pStruct, pDelim ); if( errCode == HB_SUCCESS ) { lpaClose = dbTransInfo.lpaSource = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); } } } else { errCode = hb_rddOpenTable( szFileName, szDriver, 0, "", HB_TRUE, HB_TRUE, szCpId, ulConnection, NULL, pDelim ); if( errCode == HB_SUCCESS ) { lpaClose = ( AREAP ) hb_rddGetCurrentWorkAreaPointer(); errCode = hb_dbTransStruct( lpaClose, pArea, &dbTransInfo, NULL, pFields ); } } } if( pStruct ) hb_itemRelease( pStruct ); if( errCode == HB_SUCCESS ) { PHB_ITEM pTransItm; hb_rddSelectWorkAreaNumber( dbTransInfo.lpaSource->uiArea ); dbTransInfo.dbsci.itmCobFor = pCobFor; dbTransInfo.dbsci.lpstrFor = pStrFor; dbTransInfo.dbsci.itmCobWhile = pCobWhile; dbTransInfo.dbsci.lpstrWhile = pStrWhile; dbTransInfo.dbsci.lNext = pNext; dbTransInfo.dbsci.itmRecID = pRecID; dbTransInfo.dbsci.fRest = pRest; dbTransInfo.dbsci.fIgnoreFilter = HB_TRUE; dbTransInfo.dbsci.fIncludeDeleted = HB_TRUE; dbTransInfo.dbsci.fLast = HB_FALSE; dbTransInfo.dbsci.fIgnoreDuplicates = HB_FALSE; dbTransInfo.dbsci.fBackward = HB_FALSE; pTransItm = hb_dbTransInfoPut( NULL, &dbTransInfo ); errCode = SELF_INFO( dbTransInfo.lpaDest, DBI_TRANSREC, pTransItm ); if( errCode == HB_SUCCESS ) { errCode = dbTransInfo.uiItemCount == 0 ? HB_FAILURE : SELF_TRANS( dbTransInfo.lpaSource, &dbTransInfo ); /* we always call DBI_TRANSREC second time after TRANS() method * even if TRANS() failed - it's for RDDs which may need to store * pointer to dbTransInfo in first call and then release it and/or * clean some structures allocated for transfer operation [druzus] */ SELF_INFO( dbTransInfo.lpaDest, DBI_TRANSREC, pTransItm ); if( errCode == HB_SUCCESS && ( dbTransInfo.uiFlags & DBTF_CPYCTR ) ) errCode = hb_dbTransCounters( &dbTransInfo ); } hb_itemRelease( pTransItm ); } if( dbTransInfo.lpTransItems ) hb_xfree( dbTransInfo.lpTransItems ); if( lpaClose ) { hb_rddSelectWorkAreaNumber( lpaClose->uiArea ); hb_rddReleaseCurrentArea(); } hb_rddSelectWorkAreaNumber( uiPrevArea ); return errCode; }
/* * Open a data store in the WorkArea. */ static HB_ERRCODE hb_sdfOpen( SDFAREAP pArea, LPDBOPENINFO pOpenInfo ) { PHB_ITEM pError = NULL; PHB_FNAME pFileName; HB_ERRCODE errCode; HB_USHORT uiFlags; HB_BOOL fRetry; char szFileName[ HB_PATH_MAX ]; char szAlias[ HB_RDD_MAX_ALIAS_LEN + 1 ]; HB_TRACE( HB_TR_DEBUG, ( "hb_sdfOpen(%p,%p)", pArea, pOpenInfo ) ); pArea->fShared = HB_TRUE; /* pOpenInfo->fShared; */ pArea->fReadonly = HB_TRUE; /* pOpenInfo->fReadonly; */ if( pOpenInfo->cdpId ) { pArea->area.cdPage = hb_cdpFindExt( pOpenInfo->cdpId ); if( ! pArea->area.cdPage ) pArea->area.cdPage = hb_vmCDP(); } else pArea->area.cdPage = hb_vmCDP(); uiFlags = ( pArea->fReadonly ? FO_READ : FO_READWRITE ) | ( pArea->fShared ? FO_DENYNONE : FO_EXCLUSIVE ); pFileName = hb_fsFNameSplit( pOpenInfo->abName ); /* Add default file name extension if necessary */ if( hb_setGetDefExtension() && ! pFileName->szExtension ) { PHB_ITEM pFileExt = hb_itemPutC( NULL, NULL ); SELF_INFO( &pArea->area, DBI_TABLEEXT, pFileExt ); pFileName->szExtension = hb_itemGetCPtr( pFileExt ); hb_fsFNameMerge( szFileName, pFileName ); hb_itemRelease( pFileExt ); } else { hb_strncpy( szFileName, pOpenInfo->abName, sizeof( szFileName ) - 1 ); } /* Create default alias if necessary */ if( ! pOpenInfo->atomAlias && pFileName->szName ) { const char * szName = strrchr( pFileName->szName, ':' ); if( szName == NULL ) szName = pFileName->szName; else ++szName; hb_strncpyUpperTrim( szAlias, szName, sizeof( szAlias ) - 1 ); pOpenInfo->atomAlias = szAlias; } hb_xfree( pFileName ); /* Try open */ do { pArea->pFile = hb_fileExtOpen( szFileName, NULL, uiFlags | FXO_DEFAULTS | FXO_SHARELOCK | FXO_COPYNAME | FXO_NOSEEKPOS, NULL, pError ); if( ! pArea->pFile ) { if( ! pError ) { pError = hb_errNew(); hb_errPutGenCode( pError, EG_OPEN ); hb_errPutSubCode( pError, EDBF_OPEN_DBF ); hb_errPutOsCode( pError, hb_fsError() ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_OPEN ) ); hb_errPutFileName( pError, szFileName ); hb_errPutFlags( pError, EF_CANRETRY | EF_CANDEFAULT ); } fRetry = ( SELF_ERROR( &pArea->area, pError ) == E_RETRY ); } else fRetry = HB_FALSE; } while( fRetry ); if( pError ) hb_itemRelease( pError ); if( ! pArea->pFile ) return HB_FAILURE; errCode = SUPER_OPEN( &pArea->area, pOpenInfo ); if( errCode != HB_SUCCESS ) { SELF_CLOSE( &pArea->area ); return HB_FAILURE; } hb_sdfInitArea( pArea, szFileName ); /* Position cursor at the first record */ return SELF_GOTOP( &pArea->area ); }
/* * Create a data store in the specified WorkArea. */ static HB_ERRCODE hb_sdfCreate( SDFAREAP pArea, LPDBOPENINFO pCreateInfo ) { HB_ERRCODE errCode; PHB_FNAME pFileName; PHB_ITEM pError = NULL; HB_BOOL fRetry; char szFileName[ HB_PATH_MAX ]; HB_TRACE( HB_TR_DEBUG, ( "hb_sdfCreate(%p,%p)", pArea, pCreateInfo ) ); pArea->fShared = HB_FALSE; /* pCreateInfo->fShared; */ pArea->fReadonly = HB_FALSE; /* pCreateInfo->fReadonly */ if( pCreateInfo->cdpId ) { pArea->area.cdPage = hb_cdpFindExt( pCreateInfo->cdpId ); if( ! pArea->area.cdPage ) pArea->area.cdPage = hb_vmCDP(); } else pArea->area.cdPage = hb_vmCDP(); pFileName = hb_fsFNameSplit( pCreateInfo->abName ); if( hb_setGetDefExtension() && ! pFileName->szExtension ) { PHB_ITEM pItem = hb_itemPutC( NULL, NULL ); SELF_INFO( &pArea->area, DBI_TABLEEXT, pItem ); pFileName->szExtension = hb_itemGetCPtr( pItem ); hb_fsFNameMerge( szFileName, pFileName ); hb_itemRelease( pItem ); } else { hb_strncpy( szFileName, pCreateInfo->abName, sizeof( szFileName ) - 1 ); } hb_xfree( pFileName ); /* Try create */ do { pArea->pFile = hb_fileExtOpen( szFileName, NULL, FO_READWRITE | FO_EXCLUSIVE | FXO_TRUNCATE | FXO_DEFAULTS | FXO_SHARELOCK | FXO_COPYNAME | FXO_NOSEEKPOS, NULL, pError ); if( ! pArea->pFile ) { if( ! pError ) { pError = hb_errNew(); hb_errPutGenCode( pError, EG_CREATE ); hb_errPutSubCode( pError, EDBF_CREATE_DBF ); hb_errPutOsCode( pError, hb_fsError() ); hb_errPutDescription( pError, hb_langDGetErrorDesc( EG_CREATE ) ); hb_errPutFileName( pError, szFileName ); hb_errPutFlags( pError, EF_CANRETRY | EF_CANDEFAULT ); } fRetry = ( SELF_ERROR( &pArea->area, pError ) == E_RETRY ); } else fRetry = HB_FALSE; } while( fRetry ); if( pError ) hb_itemRelease( pError ); if( ! pArea->pFile ) return HB_FAILURE; errCode = SUPER_CREATE( &pArea->area, pCreateInfo ); if( errCode != HB_SUCCESS ) { SELF_CLOSE( &pArea->area ); return errCode; } hb_sdfInitArea( pArea, szFileName ); /* Position cursor at the first record */ return SELF_GOTOP( &pArea->area ); }