| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ | |
| 6 #define SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ | |
| 7 | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <memory> | |
| 11 #include <string> | |
| 12 | |
| 13 #include "base/gtest_prod_util.h" | |
| 14 #include "base/macros.h" | |
| 15 #include "base/threading/non_thread_safe.h" | |
| 16 #include "sql/connection.h" | |
| 17 #include "sql/statement.h" | |
| 18 #include "sync/base/sync_export.h" | |
| 19 #include "sync/internal_api/public/base/model_type.h" | |
| 20 #include "sync/syncable/dir_open_result.h" | |
| 21 #include "sync/syncable/directory.h" | |
| 22 #include "sync/syncable/metahandle_set.h" | |
| 23 | |
| 24 namespace sync_pb { | |
| 25 class EntitySpecifics; | |
| 26 } | |
| 27 | |
| 28 namespace syncer { | |
| 29 namespace syncable { | |
| 30 | |
| 31 SYNC_EXPORT extern const int32_t kCurrentDBVersion; | |
| 32 SYNC_EXPORT extern const int32_t kCurrentPageSizeKB; | |
| 33 | |
| 34 struct ColumnSpec; | |
| 35 | |
| 36 // Interface that provides persistence for a syncable::Directory object. You can | |
| 37 // load all the persisted data to prime a syncable::Directory on startup by | |
| 38 // invoking Load. The only other thing you (or more correctly, a Directory) can | |
| 39 // do here is save any changes that have occurred since calling Load, which can | |
| 40 // be done periodically as often as desired. | |
| 41 // | |
| 42 // The DirectoryBackingStore will own an sqlite lock on its database for most of | |
| 43 // its lifetime. You must not have two DirectoryBackingStore objects accessing | |
| 44 // the database simultaneously. Because the lock exists at the database level, | |
| 45 // not even two separate browser instances would be able to acquire it | |
| 46 // simultaneously. | |
| 47 // | |
| 48 // This class is abstract so that we can extend it in interesting ways for use | |
| 49 // in tests. The concrete class used in non-test scenarios is | |
| 50 // OnDiskDirectoryBackingStore. | |
| 51 class SYNC_EXPORT DirectoryBackingStore : public base::NonThreadSafe { | |
| 52 public: | |
| 53 explicit DirectoryBackingStore(const std::string& dir_name); | |
| 54 virtual ~DirectoryBackingStore(); | |
| 55 | |
| 56 // Loads and drops all currently persisted meta entries into |handles_map| | |
| 57 // and loads appropriate persisted kernel info into |kernel_load_info|. | |
| 58 // The function determines which entries can be safely dropped and inserts | |
| 59 // their keys into |metahandles_to_purge|. It is up to the caller to | |
| 60 // perform the actual cleanup. | |
| 61 // | |
| 62 // This function will migrate to the latest database version. | |
| 63 // | |
| 64 // NOTE: On success (return value of OPENED), the buckets are populated with | |
| 65 // newly allocated items, meaning ownership is bestowed upon the caller. | |
| 66 virtual DirOpenResult Load(Directory::MetahandlesMap* handles_map, | |
| 67 JournalIndex* delete_journals, | |
| 68 MetahandleSet* metahandles_to_purge, | |
| 69 Directory::KernelLoadInfo* kernel_load_info) = 0; | |
| 70 | |
| 71 // Updates the on-disk store with the input |snapshot| as a database | |
| 72 // transaction. Does NOT open any syncable transactions as this would cause | |
| 73 // opening transactions elsewhere to block on synchronous I/O. | |
| 74 // DO NOT CALL THIS FROM MORE THAN ONE THREAD EVER. Also, whichever thread | |
| 75 // calls SaveChanges *must* be the thread that owns/destroys |this|. | |
| 76 // | |
| 77 // Returns true if the changes were saved successfully. Returns false if an | |
| 78 // error (of any kind) occurred. See also |SetCatastrophicErrorHandler| for a | |
| 79 // systematic way of handling underlying DB errors. | |
| 80 virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot); | |
| 81 | |
| 82 // Set the catastrophic error handler. | |
| 83 // | |
| 84 // When a catastrophic error is encountered while accessing the underlying DB, | |
| 85 // |catastrophic_error_handler| will be invoked (via PostTask) on the thread | |
| 86 // on which this DirectoryBackingStore object lives. | |
| 87 // | |
| 88 // For a definition of what's catastrophic, see sql::IsErrorCatastrophic. | |
| 89 // | |
| 90 // |catastrophic_error_handler| must be initialized (i.e. !is_null()). | |
| 91 // | |
| 92 // A single operation (like Load or SaveChanges) may result in the | |
| 93 // |catastrophic_error_handler| being invoked several times. | |
| 94 // | |
| 95 // There can be at most one handler. If this method is invoked when there is | |
| 96 // already a handler, the existing handler is overwritten with | |
| 97 // |catastrophic_error_handler|. | |
| 98 virtual void SetCatastrophicErrorHandler( | |
| 99 const base::Closure& catastrophic_error_handler); | |
| 100 | |
| 101 // Returns true on success, false on error. | |
| 102 bool GetDatabasePageSize(int* page_size); | |
| 103 | |
| 104 protected: | |
| 105 // For test classes. | |
| 106 DirectoryBackingStore(const std::string& dir_name, | |
| 107 sql::Connection* connection); | |
| 108 | |
| 109 // An accessor for the underlying sql::Connection. Avoid using outside of | |
| 110 // tests. | |
| 111 sql::Connection* db(); | |
| 112 | |
| 113 // Return true if the DB is open. | |
| 114 bool IsOpen() const; | |
| 115 | |
| 116 // Open the DB at |path|. | |
| 117 // Return true on success, false on failure. | |
| 118 bool Open(const base::FilePath& path); | |
| 119 | |
| 120 // Open an in memory DB. | |
| 121 // Return true on success, false on failure. | |
| 122 bool OpenInMemory(); | |
| 123 | |
| 124 // Initialize database tables. Return true on success, false on error. | |
| 125 bool InitializeTables(); | |
| 126 | |
| 127 // Load helpers for entries and attributes. Return true on success, false on | |
| 128 // error. | |
| 129 bool LoadEntries(Directory::MetahandlesMap* handles_map, | |
| 130 MetahandleSet* metahandles_to_purge); | |
| 131 bool LoadDeleteJournals(JournalIndex* delete_journals); | |
| 132 bool LoadInfo(Directory::KernelLoadInfo* info); | |
| 133 | |
| 134 enum EntryTable { | |
| 135 METAS_TABLE, | |
| 136 DELETE_JOURNAL_TABLE, | |
| 137 }; | |
| 138 // Removes each entry whose metahandle is in |handles| from the table | |
| 139 // specified by |from| table. Does synchronous I/O. Returns false on error. | |
| 140 bool DeleteEntries(EntryTable from, const MetahandleSet& handles); | |
| 141 | |
| 142 // Serialization helpers for ModelType. These convert between | |
| 143 // the ModelType enum and the values we persist in the database to identify | |
| 144 // a model. We persist a default instance of the specifics protobuf as the | |
| 145 // ID, rather than the enum value. | |
| 146 static ModelType ModelIdToModelTypeEnum(const void* data, int length); | |
| 147 static std::string ModelTypeEnumToModelId(ModelType model_type); | |
| 148 | |
| 149 static std::string GenerateCacheGUID(); | |
| 150 | |
| 151 // Checks that the references between sync nodes is consistent. | |
| 152 static bool VerifyReferenceIntegrity( | |
| 153 const Directory::MetahandlesMap* handles_map); | |
| 154 | |
| 155 // Migration utilities. | |
| 156 bool RefreshColumns(); | |
| 157 bool SetVersion(int version); | |
| 158 int GetVersion(); | |
| 159 | |
| 160 // Individual version migrations. | |
| 161 bool MigrateVersion67To68(); | |
| 162 bool MigrateVersion68To69(); | |
| 163 bool MigrateVersion69To70(); | |
| 164 bool MigrateVersion70To71(); | |
| 165 bool MigrateVersion71To72(); | |
| 166 bool MigrateVersion72To73(); | |
| 167 bool MigrateVersion73To74(); | |
| 168 bool MigrateVersion74To75(); | |
| 169 bool MigrateVersion75To76(); | |
| 170 bool MigrateVersion76To77(); | |
| 171 bool MigrateVersion77To78(); | |
| 172 bool MigrateVersion78To79(); | |
| 173 bool MigrateVersion79To80(); | |
| 174 bool MigrateVersion80To81(); | |
| 175 bool MigrateVersion81To82(); | |
| 176 bool MigrateVersion82To83(); | |
| 177 bool MigrateVersion83To84(); | |
| 178 bool MigrateVersion84To85(); | |
| 179 bool MigrateVersion85To86(); | |
| 180 bool MigrateVersion86To87(); | |
| 181 bool MigrateVersion87To88(); | |
| 182 bool MigrateVersion88To89(); | |
| 183 bool MigrateVersion89To90(); | |
| 184 | |
| 185 // Accessor for needs_column_refresh_. Used in tests. | |
| 186 bool needs_column_refresh() const; | |
| 187 | |
| 188 // Destroys the existing Connection and creates a new one. | |
| 189 void ResetAndCreateConnection(); | |
| 190 | |
| 191 private: | |
| 192 friend class DirectoryBackingStoreTest; | |
| 193 friend class TestDirectoryBackingStore; | |
| 194 FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, | |
| 195 IncreaseDatabasePageSizeFrom4KTo32K); | |
| 196 FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, | |
| 197 CatastrophicErrorHandler_KeptAcrossReset); | |
| 198 FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, | |
| 199 CatastrophicErrorHandler_InvocationDuringLoad); | |
| 200 FRIEND_TEST_ALL_PREFIXES( | |
| 201 DirectoryBackingStoreTest, | |
| 202 CatastrophicErrorHandler_InvocationDuringSaveChanges); | |
| 203 FRIEND_TEST_ALL_PREFIXES(MigrationTest, ToCurrentVersion); | |
| 204 | |
| 205 // Drop all tables in preparation for reinitialization. | |
| 206 void DropAllTables(); | |
| 207 | |
| 208 bool SafeToPurgeOnLoading(const EntryKernel& entry) const; | |
| 209 | |
| 210 // Drops a table if it exists, harmless if the table did not already exist. | |
| 211 bool SafeDropTable(const char* table_name); | |
| 212 | |
| 213 bool CreateTables(); | |
| 214 | |
| 215 // Create 'share_info' or 'temp_share_info' depending on value of | |
| 216 // is_temporary. Returns true on success, false on error. | |
| 217 bool CreateShareInfoTable(bool is_temporary); | |
| 218 bool CreateShareInfoTableVersion71(bool is_temporary); | |
| 219 | |
| 220 // Create 'metas' or 'temp_metas' depending on value of is_temporary. Also | |
| 221 // create a 'deleted_metas' table using same schema. Returns true on success, | |
| 222 // false on error. | |
| 223 bool CreateMetasTable(bool is_temporary); | |
| 224 | |
| 225 // Returns true on success, false on error. | |
| 226 bool CreateModelsTable(); | |
| 227 bool CreateV71ModelsTable(); | |
| 228 bool CreateV75ModelsTable(); | |
| 229 bool CreateV81ModelsTable(); | |
| 230 | |
| 231 // Returns true on success, false on error. | |
| 232 bool MigrateToSpecifics(const char* old_columns, | |
| 233 const char* specifics_column, | |
| 234 void(*handler_function) ( | |
| 235 sql::Statement* old_value_query, | |
| 236 int old_value_column, | |
| 237 sync_pb::EntitySpecifics* mutable_new_value)); | |
| 238 | |
| 239 // Returns true on success, false on error. | |
| 240 bool Vacuum(); | |
| 241 | |
| 242 // Returns true on success, false on error. | |
| 243 bool UpdatePageSizeIfNecessary(); | |
| 244 | |
| 245 // Prepares |save_statement| for saving entries in |table|. | |
| 246 void PrepareSaveEntryStatement(EntryTable table, | |
| 247 sql::Statement* save_statement); | |
| 248 | |
| 249 const std::string dir_name_; | |
| 250 const int database_page_size_; | |
| 251 | |
| 252 std::unique_ptr<sql::Connection> db_; | |
| 253 sql::Statement save_meta_statement_; | |
| 254 sql::Statement save_delete_journal_statement_; | |
| 255 | |
| 256 // Set to true if migration left some old columns around that need to be | |
| 257 // discarded. | |
| 258 bool needs_metas_column_refresh_; | |
| 259 bool needs_share_info_column_refresh_; | |
| 260 | |
| 261 // We keep a copy of the Closure so we reinstall it when the underlying | |
| 262 // sql::Connection is destroyed/recreated. | |
| 263 base::Closure catastrophic_error_handler_; | |
| 264 | |
| 265 DISALLOW_COPY_AND_ASSIGN(DirectoryBackingStore); | |
| 266 }; | |
| 267 | |
| 268 } // namespace syncable | |
| 269 } // namespace syncer | |
| 270 | |
| 271 #endif // SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ | |
| OLD | NEW |