directory_backing_store.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 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 <string> 9 10#include "base/memory/scoped_ptr.h" 11#include "base/threading/non_thread_safe.h" 12#include "sql/connection.h" 13#include "sql/statement.h" 14#include "sync/internal_api/public/base/model_type.h" 15#include "sync/syncable/dir_open_result.h" 16#include "sync/syncable/directory.h" 17#include "sync/syncable/metahandle_set.h" 18 19namespace sync_pb { 20class EntitySpecifics; 21} 22 23namespace syncer { 24namespace syncable { 25 26struct ColumnSpec; 27typedef Directory::MetahandlesIndex MetahandlesIndex; 28 29// Interface that provides persistence for a syncable::Directory object. You can 30// load all the persisted data to prime a syncable::Directory on startup by 31// invoking Load. The only other thing you (or more correctly, a Directory) can 32// do here is save any changes that have occurred since calling Load, which can 33// be done periodically as often as desired. 34// 35// The DirectoryBackingStore will own an sqlite lock on its database for most of 36// its lifetime. You must not have two DirectoryBackingStore objects accessing 37// the database simultaneously. Because the lock exists at the database level, 38// not even two separate browser instances would be able to acquire it 39// simultaneously. 40// 41// This class is abstract so that we can extend it in interesting ways for use 42// in tests. The concrete class used in non-test scenarios is 43// OnDiskDirectoryBackingStore. 44class DirectoryBackingStore : public base::NonThreadSafe { 45 public: 46 explicit DirectoryBackingStore(const std::string& dir_name); 47 virtual ~DirectoryBackingStore(); 48 49 // Loads and drops all currently persisted meta entries into |entry_bucket| 50 // and loads appropriate persisted kernel info into |info_bucket|. 51 // 52 // This function can perform some cleanup tasks behind the scenes. It will 53 // clean up unused entries from the database and migrate to the latest 54 // database version. The caller can safely ignore these details. 55 // 56 // NOTE: On success (return value of OPENED), the buckets are populated with 57 // newly allocated items, meaning ownership is bestowed upon the caller. 58 virtual DirOpenResult Load(MetahandlesIndex* entry_bucket, 59 Directory::KernelLoadInfo* kernel_load_info) = 0; 60 61 // Updates the on-disk store with the input |snapshot| as a database 62 // transaction. Does NOT open any syncable transactions as this would cause 63 // opening transactions elsewhere to block on synchronous I/O. 64 // DO NOT CALL THIS FROM MORE THAN ONE THREAD EVER. Also, whichever thread 65 // calls SaveChanges *must* be the thread that owns/destroys |this|. 66 virtual bool SaveChanges(const Directory::SaveChangesSnapshot& snapshot); 67 68 protected: 69 // For test classes. 70 DirectoryBackingStore(const std::string& dir_name, 71 sql::Connection* connection); 72 73 // General Directory initialization and load helpers. 74 bool InitializeTables(); 75 bool CreateTables(); 76 77 // Create 'share_info' or 'temp_share_info' depending on value of 78 // is_temporary. Returns an sqlite 79 bool CreateShareInfoTable(bool is_temporary); 80 81 bool CreateShareInfoTableVersion71(bool is_temporary); 82 // Create 'metas' or 'temp_metas' depending on value of is_temporary. 83 bool CreateMetasTable(bool is_temporary); 84 bool CreateModelsTable(); 85 bool CreateV71ModelsTable(); 86 87 // We don't need to load any synced and applied deleted entries, we can 88 // in fact just purge them forever on startup. 89 bool DropDeletedEntries(); 90 // Drops a table if it exists, harmless if the table did not already exist. 91 bool SafeDropTable(const char* table_name); 92 93 // Load helpers for entries and attributes. 94 bool LoadEntries(MetahandlesIndex* entry_bucket); 95 bool LoadInfo(Directory::KernelLoadInfo* info); 96 97 // Save/update helpers for entries. Return false if sqlite commit fails. 98 bool SaveEntryToDB(const EntryKernel& entry); 99 bool SaveNewEntryToDB(const EntryKernel& entry); 100 bool UpdateEntryToDB(const EntryKernel& entry); 101 102 DirOpenResult DoLoad(MetahandlesIndex* entry_bucket, 103 Directory::KernelLoadInfo* kernel_load_info); 104 105 // Close save_dbhandle_. Broken out for testing. 106 void EndSave(); 107 108 // Removes each entry whose metahandle is in |handles| from the database. 109 // Does synchronous I/O. Returns false on error. 110 bool DeleteEntries(const MetahandleSet& handles); 111 112 // Drop all tables in preparation for reinitialization. 113 void DropAllTables(); 114 115 // Serialization helpers for ModelType. These convert between 116 // the ModelType enum and the values we persist in the database to identify 117 // a model. We persist a default instance of the specifics protobuf as the 118 // ID, rather than the enum value. 119 static ModelType ModelIdToModelTypeEnum(const void* data, int length); 120 static std::string ModelTypeEnumToModelId(ModelType model_type); 121 122 static std::string GenerateCacheGUID(); 123 124 // Runs an integrity check on the current database. If the 125 // integrity check fails, false is returned and error is populated 126 // with an error message. 127 bool CheckIntegrity(sqlite3* handle, std::string* error) const; 128 129 // Checks that the references between sync nodes is consistent. 130 static bool VerifyReferenceIntegrity(const MetahandlesIndex& entries); 131 132 // Migration utilities. 133 bool RefreshColumns(); 134 bool SetVersion(int version); 135 int GetVersion(); 136 137 bool MigrateToSpecifics(const char* old_columns, 138 const char* specifics_column, 139 void(*handler_function) ( 140 sql::Statement* old_value_query, 141 int old_value_column, 142 sync_pb::EntitySpecifics* mutable_new_value)); 143 144 // Individual version migrations. 145 bool MigrateVersion67To68(); 146 bool MigrateVersion68To69(); 147 bool MigrateVersion69To70(); 148 bool MigrateVersion70To71(); 149 bool MigrateVersion71To72(); 150 bool MigrateVersion72To73(); 151 bool MigrateVersion73To74(); 152 bool MigrateVersion74To75(); 153 bool MigrateVersion75To76(); 154 bool MigrateVersion76To77(); 155 bool MigrateVersion77To78(); 156 bool MigrateVersion78To79(); 157 bool MigrateVersion79To80(); 158 bool MigrateVersion80To81(); 159 bool MigrateVersion81To82(); 160 bool MigrateVersion82To83(); 161 162 scoped_ptr<sql::Connection> db_; 163 sql::Statement save_entry_statement_; 164 std::string dir_name_; 165 166 // Set to true if migration left some old columns around that need to be 167 // discarded. 168 bool needs_column_refresh_; 169 170 DISALLOW_COPY_AND_ASSIGN(DirectoryBackingStore); 171}; 172 173} // namespace syncable 174} // namespace syncer 175 176#endif // SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ 177