📄 bj_datarecovery.cpp
字号:
// BJ_DataRecovery.cpp// 北京数据恢复服务的本地代理的实现// #include "BJ_DataRecovery.h"#include "table_struct.h"#include <string.h>#define NOT_FINISH_GETING_RESULT 101 //代表还需要继续取结果#define FINISH_GETING_RESULT 102 //代表已经取完数据了#define NOT_ENOUGH_ROOM_FOR_RECOVERYFILE -103 //用户提供的供恢复的文件大小using namespace std;BJ_DataRecovery::BJ_DataRecovery(){ ifstream ifile("aflsAddr_for_bjDataRecoveryServer.conf"); char str[255]; ifile.getline(str,255); ifile.close(); CORBA::ORB_var orb; int n =1; char* ll = "-ORBid StarBusORB"; try { orb = CORBA::ORB_init(n,&ll); CORBA::Object_var obj = orb->string_to_object(str); Afls_var afls = Afls::_narrow(obj); assert(!CORBA::is_nil(afls)); obj= afls->alloc_obj("DRServer.RAO"); assert(!CORBA::is_nil(obj)); bjDRServer = IDRecoveryServer::_narrow(obj); } catch(const CORBA::Exception& ce) { cerr<<ce<<endl; } if(CORBA::is_nil(orb)) { try { orb->destroy(); } catch(const CORBA::Exception& ex) { cerr<<ex<<endl; } } bjDR = bjDRServer -> ResGet("testRao", 0); }BJ_DataRecovery::~BJ_DataRecovery(){ if (m_outfile != NULL) m_outfile.close(); bjDR -> destroy(); CORBA::release(bjDR);}// 异地中间件的数据恢复管理服务调用该方法通知其数据丢失。// 返回值:int 0:成功,<0:失败,>0:警告int BJ_DataRecovery::loseData(const char DXX_BLOCK_ID[DXX_BLOCK_ID_LENGTH], const TimeInterval timeInter, const char* strProvinceCode, const char* TableName) throw(Exception602){ int rc; try { rc = bjDR->loseData(DXX_BLOCK_ID,timeInter.BeginTime, \ timeInter.EndTime,strProvinceCode,TableName); } catch(CORBA::Exception& ex) { //最常用的截获异常再抛一个异常的方式 Exception602 exx("",-1); throw exx; } return rc;}// 开始一个恢复数据的会话,根据输入参数,将数据保存在调用方指定的路径下// 的文件中,该方法由数据提供方实现,由丢失数据的本地中间件调用// 返回值:int 0:成功,<0:失败,>0:警告// 短信息文件格式为文本文件,文本文件的格式是一行一条记录,如附件eg.txt// 所示,统计和配置数据为Oracle的Export导出的不带元信息和约束索引等的// 数据文件,需要用Oracle的Import导入int BJ_DataRecovery::nBeginGetData(const char DXX_BLOCK_ID[DXX_BLOCK_ID_LENGTH], const TimeInterval timeInter, const char* strProvinceCode, const char* strTableName, const char* strFileName, const char* strPathName, const int nFileSize, const int timeout) throw(Exception602){ //BJ_DataRecovery是在GZ或SH本地调用的,所以可以在本地打开文件strPathName,然后把数据写到strPathName //中去 int rc; int i; int nSDataLen; strcpy(m_strPathName, strPathName); //CORBA::Short_out nRealFileSize = (CORBA::Short_out)(-1); strcpy(m_TableName, strTableName); m_nTableType = -1; try { assert(!CORBA::is_nil(bjDR)); m_nTableType = bjDR -> nTableType(strTableName); } catch(CORBA::Exception& ex) { Exception602 exx("",-1); throw exx; } switch (m_nTableType) { case 1: //日志表(短信息表) //如果是日志表(短信息表),则直接填入字段信息 //通过表名,找到对应的表字段信息 if (strcmp("DZFX_DXX", strTableName) == 0 || strcmp("dzfx_dxx", strTableName) == 0 || strcmp("DZFD_DXX", strTableName) == 0 || strcmp("dzfd_dxx", strTableName) == 0 || strcmp("NRFD_DXX", strTableName) == 0 || strcmp("nrfd_dxx", strTableName) == 0 || strcmp("DZCT_DXX", strTableName) == 0 || strcmp("dzct_dxx", strTableName) == 0 || strcmp("NRCT_DXX", strTableName) == 0 || strcmp("nrct_dxx", strTableName) == 0 || strcmp("NRJC_DXX", strTableName) == 0 || strcmp("nrjc_dxx", strTableName) == 0 || strcmp("DZJS_DXX", strTableName) == 0 || strcmp("dzjs_dxx", strTableName) == 0 || strcmp("NRJS_DXX", strTableName) == 0 || strcmp("nrjs_dxx", strTableName) == 0 ) { m_nDXX_TABLE_FIELD = 25; for (i=0; i<m_nDXX_TABLE_FIELD; i++) m_DXX_TABLE[i] = nCOMMON_DXX[i]; } else if( strcmp("JM_DXX", strTableName) == 0 || strcmp("jm_dxx", strTableName) == 0 ) { m_nDXX_TABLE_FIELD = 23; for (i=0; i<m_nDXX_TABLE_FIELD; i++) m_DXX_TABLE[i] = nJM_DXX[i]; } else if( strcmp("BF_DXX", strTableName) == 0 || strcmp("bf_dxx", strTableName) == 0 ) { m_nDXX_TABLE_FIELD = 17; for (i=0; i<m_nDXX_TABLE_FIELD; i++) m_DXX_TABLE[i] = nBF_DXX[i]; } nSDataLen=0; //这里得到的是基本记录本身的长度值 for (i=0;i<m_nDXX_TABLE_FIELD;i++) nSDataLen += (m_DXX_TABLE[i]-1); //由于在table_struct中,都算了一位字符串结束符,所以要减1 nSDataLen ++; //得到用户一次允许接收的记录的最大数目 nFileSize以M来计算,而nSDataLen是以B来计算的! m_RecordsNum = nFileSize * 1024 * 1024 / nSDataLen; try { assert(!CORBA::is_nil(bjDR)); rc = bjDR->nBeginGetData(DXX_BLOCK_ID,timeInter.BeginTime, timeInter.EndTime, \ strProvinceCode,strTableName,strFileName,strPathName, \ nFileSize,timeout,m_nTableType,m_nRealFileSize, m_nExpdTimes); } catch(CORBA::Exception& ex) { Exception602 exx("",-1); throw exx; } //由于可能会出错,一定要小心线程的控制! // m_pTransformThread -> stop(); //如果函数调用成功,将文件打开,准备往里面写! if (rc == SUCCESS) { //这里要求将 sprintf(m_strPathName, "/%s", strFileName); m_outfile.open(m_strPathName, std::ios::out); } //注意,当用户调用nBeginGetData的时候,要求返回第一批数据,由于我们整个数据返回机制包在nGetNextData中, //所以在用户第一次调用nBeginGetData的时候,调一次nGetNextData。将其返回值当作nBeginGetData的返回值,如果 //返回值为IS_EOF或FINISH_GETING_RESULT,则不用再继续取数据了,否则,用户还要再调用nGetNextData来继续取数据。 rc = nGetNextData(); break; case 2: //配置表 //对于配置表而言,如果nFileSize的大小比要恢复的数据文件大小要小的话,则返回给用户错误信息, //告知其不能恢复,需要将nFileSize设大到至少为“需要恢复的数据文件大小” try { assert(!CORBA::is_nil(bjDR)); rc = bjDR->nBeginGetData(DXX_BLOCK_ID,timeInter.BeginTime, timeInter.EndTime, \ strProvinceCode,strTableName,strFileName,strPathName, \ nFileSize,timeout,m_nTableType, m_nRealFileSize, m_nExpdTimes); } catch(CORBA::Exception& ex) { Exception602 exx("",-1); throw exx; } if (rc == NOT_ENOUGH_ROOM_FOR_RECOVERYFILE) { //使用strErrorMessage,通知用户出错原因,并且告知其文件大小应该为多大。 } else if (rc == SUCCESS) { DataRecovery::RECOVERED_DATA R_Data; //R_Data.length(1); fstream tmpR_Data; //tmpR_Data.open(m_strPathName); CORBA::Long i,length; try { assert(!CORBA::is_nil(bjDR)); sprintf(m_strPathName, "/%s", strFileName); tmpR_Data.open("/home/oracle/pdb_rx/DataRecovery/BJ_DataRecovery/tab.dmp", std::ios::out); rc = bjDR->transfer(R_Data); for (i=0; i<R_Data.length(); i++) tmpR_Data << R_Data[i]; } catch(CORBA::Exception& ex) { //最常用的截获异常再抛一个异常的方式 Exception602 exx("",-1); tmpR_Data.close(); throw exx; } tmpR_Data.close(); //rc = SUCCESS; } break; case 3: //统计表 try { assert(!CORBA::is_nil(bjDR)); rc = bjDR->nBeginGetData(DXX_BLOCK_ID,timeInter.BeginTime, timeInter.EndTime, \ strProvinceCode,strTableName,strFileName,strPathName, \ nFileSize,timeout,m_nTableType, m_nRealFileSize, m_nExpdTimes); //可能分割之后,nFileSize还是不能装下一次恢复的数据 if (rc == NOT_ENOUGH_ROOM_FOR_RECOVERYFILE) { //使用strErrorMessage,通知用户出错原因,并且告知其文件大小应该为多大。 } } catch(CORBA::Exception& ex) { Exception602 exx("",-1); throw exx; } //注意,当用户调用nBeginGetData的时候,要求返回第一批数据,由于我们整个数据返回机制包在nGetNextData中, //所以在用户第一次调用nBeginGetData的时候,调一次nGetNextData。将其返回值当作nBeginGetData的返回值,如果 //返回值为IS_EOF或FINISH_GETING_RESULT,则不用再继续取数据了,否则,用户还要再调用nGetNextData来继续取数据。 //这个东西并不准 //m_nExpdTimes = 1 + m_nRealFileSize / nFileSize; m_nCurrentExpdTimes = 1; rc = nGetNextData(); break; default: cerr << "Table dis type error"<< endl; return -1; } return rc;}// 得到下一个文件// 返回值:int 0:成功,<0:失败,>0:警告// 文件为空,即表示数据处理结束int BJ_DataRecovery::nGetNextData() throw(Exception602){ int rc; int i,j,k; int exeCount; int nFieldCount; int nRecordCount = 0 ; int exeTimes; switch (m_nTableType) { case 1: //为了性能稳定,我们规定每次传数据不超过100条记录 //m_RecordsdNum是由nFileSize得来的,相当于用户可用于数据恢复的缓冲区能装多少数据 exeTimes = m_RecordsNum/100 + 1; if ( exeTimes < 0 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -