00001 /// 00002 /// \file restore.h 00003 /// Builder class for restoring from Barry Backup files 00004 /// 00005 00006 /* 00007 Copyright (C) 2010-2011, Net Direct Inc. (http://www.netdirect.ca/) 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 2 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00017 00018 See the GNU General Public License in the COPYING file at the 00019 root directory of this project for more details. 00020 */ 00021 00022 #ifndef __BARRYBACKUP_RESTORE_H__ 00023 #define __BARRYBACKUP_RESTORE_H__ 00024 00025 #include "dll.h" 00026 #include "builder.h" 00027 #include "configfile.h" 00028 #include <string> 00029 #include <vector> 00030 #include <memory> 00031 00032 // forward declarations 00033 namespace reuse { 00034 class TarFile; 00035 } 00036 00037 namespace Barry { 00038 00039 // 00040 // Restore 00041 // 00042 /// Barry Backup Restore builder class. This class is suitable 00043 /// to be used as a builder object anywhere a builder object is 00044 /// accepted. It reads from a Barry Backup tar.gz backup file, 00045 /// and builds records in a staged manner. 00046 /// 00047 /// If a backup file contains more than one database (for example 00048 /// both Address Book and Calendar), then it will build one database 00049 /// first, return false on Retrieve(), and then build the next. 00050 /// If Retrieve() returns false, but EndOfFile() also returns false, 00051 /// then more databases are available. 00052 /// 00053 /// The idea is that you can call Desktop::SaveDatabase() multiple 00054 /// times with this same Restore object, for all the databases in 00055 /// the backup file. 00056 /// 00057 /// It is safe to call Retrieve() multiple times, so when first 00058 /// starting a restore: 00059 /// - call the constructor 00060 /// - call AddDB() with any filters 00061 /// - then call Retrieve(), which will grab the first record, 00062 /// and make GetDBName() valid. 00063 /// 00064 class BXEXPORT Restore : public Barry::Builder 00065 { 00066 public: 00067 typedef Barry::ConfigFile::DBListType DBListType; 00068 00069 private: 00070 enum RetrievalState 00071 { 00072 RS_EMPTY, // no record loaded 00073 RS_UNKNOWN, // record data loaded, but not yet checked 00074 // whether this is part of current database 00075 RS_NEXT, // record loaded, part of current database 00076 RS_DBEND, // next record loaded, but end-of-database 00077 // not yet processed by Builder API 00078 RS_EOF // no recrd loaded, end of tar file 00079 }; 00080 00081 DBListType m_dbList; 00082 00083 std::string m_tarpath; 00084 std::auto_ptr<reuse::TarFile> m_tar; 00085 00086 bool m_default_all_db; 00087 RetrievalState m_tar_record_state; 00088 uint8_t m_rec_type; 00089 uint32_t m_unique_id; 00090 std::string m_current_dbname; 00091 Barry::Data m_record_data; 00092 std::string m_tar_id_text; 00093 00094 protected: 00095 static bool SplitTarPath(const std::string &tarpath, 00096 std::string &dbname, std::string &dbid_text, 00097 uint8_t &dbrectype, uint32_t &dbid); 00098 00099 bool IsSelected(const std::string &dbName) const; 00100 RetrievalState Retrieve(Data &record_data); 00101 00102 00103 public: 00104 /// If default_all_db is true, and none of the Add*() functions 00105 /// are called (meaning that Restore has an empty database list), 00106 /// then all records are restored. If false in this situation, 00107 /// nothing is restored. 00108 /// 00109 /// If any of the Add*() functions are called, then the database 00110 /// list takes precedence, and default_all_db has no effect. 00111 /// 00112 explicit Restore(const std::string &tarpath, 00113 bool default_all_db = true); 00114 ~Restore(); 00115 00116 /// Add database name to the read filter. 00117 void AddDB(const std::string &dbName); 00118 00119 /// Add all database names in dblist to the read filter 00120 /// This function is additive. 00121 void Add(const DBListType &dbList); 00122 00123 // Skip the current DB, in case of error, or preference 00124 void SkipCurrentDB(); 00125 00126 /// Loads the given file, and counts all records according 00127 /// to the current read filter. Does not use the main 00128 /// Restore file, but opens the file separately. 00129 /// It is safe to call this function as often as needed. 00130 unsigned int GetRecordTotal() const; 00131 00132 /// Static version of above call 00133 static unsigned int GetRecordTotal(const std::string &tarpath, 00134 const DBListType &dbList, bool default_all_db); 00135 00136 /// If this function returns true, it fills data with the 00137 /// meta data that the next call to BuildRecord() will retrieve. 00138 /// This is useful for applications that need to setup a manual 00139 /// call to Desktop::SaveDatabase(). 00140 bool GetNextMeta(DBData &data); 00141 00142 // Barry::Builder overrides 00143 bool BuildRecord(Barry::DBData &data, size_t &offset, 00144 const Barry::IConverter *ic); 00145 bool FetchRecord(Barry::DBData &data, const Barry::IConverter *ic); 00146 bool EndOfFile() const; 00147 }; 00148 00149 } // namespace Barry 00150 00151 #endif 00152