WEB开发网
开发学院软件开发VC 介绍一种数据库远程备份方案 阅读

介绍一种数据库远程备份方案

 2007-03-17 22:00:29 来源:WEB开发网   
核心提示: // 接收指定的XML文件#define PRE_AGREED_PORT8686// 指定端口号#define RECV_BUFFER_SIZE4096// 缓冲区大小BOOL CDBClientDlg::GetFileFromRemoteSender(CString strIP, CSt
// 接收指定的XML文件
#define PRE_AGREED_PORT  8686    // 指定端口号
#define RECV_BUFFER_SIZE  4096    // 缓冲区大小
BOOL CDBClientDlg::GetFileFromRemoteSender(CString strIP, CString fName)
{
  // 创建客户端socket
  AfxSocketInit( NULL );  // 初始化socket
  CSocket sockClient;
  sockClient.Create();
  
  // 连接到指定IP和端口号
  sockClient.Connect( strIP, PRE_AGREED_PORT );  // PRE_AGREED_PORT 端口号被指定为 8686
  
  
  // 传送是否成功
  BOOL bRet = TRUE;                
  
  int dataLength, cbBytesRet, cbLeftToReceive;  // 接收数据长度及进度
  
  BYTE* recdData = NULL;              // 接收数据缓冲
  
  CFile destFile;
  CFileException fe;
  BOOL bFileIsOpen = FALSE;
  
  // 打开或创建指定文件,用来接收数据
  if( !( bFileIsOpen = destFile.Open( fName, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary, &fe ) ) )
  {
    TCHAR strCause[256];
    fe.GetErrorMessage( strCause, 255 );
    TRACE( "GetFileFromRemoteSender encountered an error while opening the local file
"
      "  File name = %s
  Cause = %s
  m_cause = %d
  m_IOsError = %d
",
      fe.m_strFileName, strCause, fe.m_cause, fe.m_lOsError );
    
    
    bRet = FALSE;
    goto PreReturnCleanup;
  }
  
  // 首先,获取文件长度
  cbLeftToReceive = sizeof( dataLength );
  do
  {
    BYTE* bp = (BYTE*)(&dataLength) + sizeof(dataLength) - cbLeftToReceive;
    cbBytesRet = sockClient.Receive( bp, cbLeftToReceive );
    
    // 是否出错
    if( cbBytesRet == SOCKET_ERROR || cbBytesRet == 0 )
    {
      int iErr = ::GetLastError();
      TRACE( "GetFileFromRemoteSite returned a socket error while getting file length
"
        "  Number of Bytes received (zero means connection was closed) = %d
"
        "  GetLastError = %d
", cbBytesRet, iErr );
      
      bRet = FALSE;
      goto PreReturnCleanup;
    }
    
    // 接收成功,剩余长度
    cbLeftToReceive -= cbBytesRet;
    
  }
  while( cbLeftToReceive > 0 );
  
  dataLength = ntohl( dataLength );
  
  // 然后,每次接收指定缓冲的数据
  recdData    = new byte[RECV_BUFFER_SIZE];
  cbLeftToReceive = dataLength;
  
  do
  {  
    int iiGet, iiRecd;
    
    iiGet = (cbLeftToReceive<RECV_BUFFER_SIZE) ? cbLeftToReceive : RECV_BUFFER_SIZE ;
    iiRecd = sockClient.Receive( recdData, iiGet );
    
    // 是否错误
    if ( iiRecd == SOCKET_ERROR || iiRecd == 0 )
    {
      int iErr = ::GetLastError();
      TRACE( "GetFileFromRemoteSite returned a socket error while getting chunked file data
"
        "  Number of Bytes received (zero means connection was closed) = %d
"
        "  GetLastError = %d
", iiRecd, iErr );
      
      bRet = FALSE;
      goto PreReturnCleanup;
    }
    
    // 接收成功, 剩余字节数
    destFile.Write( recdData, iiRecd ); // 写入文件
    cbLeftToReceive -= iiRecd;
    
  }
  while( cbLeftToReceive > 0 );
  
PreReturnCleanup:    // 结束及清理
  
  // 释放内存及关闭打开句柄
  delete[] recdData;    
  
  if ( bFileIsOpen )
    destFile.Close();
  
  sockClient.Close();
  
  return bRet;
}
// 解析XML库并生成数据库
bool CBulidDB::Parse_XML_Document()
{
  if( !m_bDone )
  {
    if( Is_Tag( "<Database>" ) )
    {
      // 获取生成数据库名称
      if( Is_Having_Attribute( "name" ) )
        m_strDBName = Get_Attribute_Value();
    }
    
    if( Is_Tag( "<Table>" ) )
    { 
      // 获取库内表名
      if( Is_Having_Attribute( "name" ) )
        m_strTableName = Get_Attribute_Value();
    }
    
    // 库名或表名为空退出
    if( "" == m_strDBName || "" == m_strTableName )
      return false;
    
    // 获取主程序所在路径,存在sPath中
    CString sPath;
    GetModuleFileName( NULL, sPath.GetBufferSetLength( MAX_PATH + 1 ), MAX_PATH );
    sPath.ReleaseBuffer();
    int nPos;
    nPos  = sPath.ReverseFind( ''\'' );
    sPath  = sPath.Left( nPos );
    
    CString lpszFile = sPath + "\" + m_strDBName;
    CFileFind fFind;
    BOOL bSuccess;
    bSuccess = fFind.FindFile( lpszFile );
    fFind.Close ();
    
    CDaoDatabase db;          // 数据库
    CDaoRecordset RecSet( &db );    // 记录集
    // 是否已有创建好的库文件,没有则创建它
    if( !bSuccess )
    {
      // 创建Mdb库
      db.Create( lpszFile );
      
      // 移动节点到指定位置
      Go_to_Parent("Table");
      Go_to_Child("Struct");
      Go_to_Child( "Field" );
      // 获取库结构
      CString sqlCmd = "CREATE TABLE " + m_strTableName + "(";
      while( Is_Tag( "<Field>" ) && Is_Child_of( "<Database><Table><Struct>" ) )
      { 
        CString strField = "";
        // 列名
        if( Is_Having_Attribute( "fieldName" ) )
          strField = Get_Attribute_Value();
        sqlCmd += strField + " ";
        
        // 列类型
        if( Is_Having_Attribute( "fieldType" ) )
          strField = Get_Attribute_Value();
        sqlCmd += strField + "(";
        
        // 列长度
        if( Is_Having_Attribute( "fieldLength" ) )
          strField = Get_Attribute_Value();
        sqlCmd += strField + "),";
        
        // 同一级下一节点
        if( !Go_Forward() )
          break;
      }
      
      // 删除尾部多余逗号
      if( -1 != sqlCmd.ReverseFind( '','' ) )
        sqlCmd.Delete( sqlCmd.GetLength() - 1, 1 );
      
      sqlCmd += ");";
      // 创建库结构
      db.Execute( sqlCmd );
      
      CString strQuery = "SELECT * FROM " + m_strTableName;
      // 打开已创建的数据表
      RecSet.Open( AFX_DAO_USE_DEFAULT_TYPE,
        strQuery, 0 );
      
      // 移动节点到指定位置
      Go_to_Parent("Table");
      Go_to_Child("Content");
      Go_to_Child( "Record" );
      // 创建库内容记录
      while( Is_Tag( "<Record>" ) && Is_Child_of( "<Database><Table><Content>" ) )
      { 
        CString sqlRecordCmd = "INSERT INTO " + m_strTableName + "(Name,Age) VALUES(";
        
        CString strRecord = "";
        // 名字
        if( Is_Having_Attribute( "name" ) )
          strRecord = Get_Attribute_Value();
        sqlRecordCmd += "''" + strRecord + "'', ";
        
        // 年龄
        if( Is_Having_Attribute( "age" ) )
          strRecord = Get_Attribute_Value();
        sqlRecordCmd += strRecord + ")";
        
        // 插入记录
        db.Execute( sqlRecordCmd );
        
        // 同一级下一节点
        if( !Go_Forward() )
          break;
      }
      
      // 关闭记录集及库
      RecSet.Close();
      db.Close();
      
      // 完成
      m_bDone = true;
      AfxMessageBox( lpszFile + "Access库成功创建!" );
      
      return true;
    }
    else
    {
      AfxMessageBox( lpszFile + "Access库已经存在!" );
    }
  }
  return false;
}
小结

数据库远程备份基本功能已实现,还有很多待完善的地方,如服务端没有实现直接读取数据库生成指定XML库文件的功能。服务端和客户端没有实现多线程发送/接收等。

上一页  1 2 3 

Tags:介绍 数据库 远程

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接