OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 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 CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ |
| 6 #define CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ |
| 7 |
| 8 #include <set> |
| 9 |
| 10 #include "chrome/browser/sync/syncable/dir_open_result.h" |
| 11 #include "chrome/browser/sync/syncable/syncable.h" |
| 12 |
| 13 extern "C" { |
| 14 struct sqlite3; |
| 15 struct sqlite3_stmt; |
| 16 } |
| 17 |
| 18 namespace syncable { |
| 19 |
| 20 struct ColumnSpec; |
| 21 typedef Directory::MetahandlesIndex MetahandlesIndex; |
| 22 |
| 23 // Provides sqlite3-based persistence for a syncable::Directory object. You can |
| 24 // load all the persisted data to prime a syncable::Directory on startup by |
| 25 // invoking Load. The only other thing you (or more correctly, a Directory) |
| 26 // can do here is save any changes that have occurred since calling Load, which |
| 27 // can be done periodically as often as desired* |
| 28 // |
| 29 // * If you only ever use a DirectoryBackingStore (DBS) from a single thread |
| 30 // then you can stop reading now. This is implemented using sqlite3, which |
| 31 // requires that each thread accesses a DB via a handle (sqlite3*) opened by |
| 32 // sqlite_open for that thread and only that thread. To avoid complicated TLS |
| 33 // logic to swap handles in-and-out as different threads try to get a hold of a |
| 34 // DBS, the DBS does two things: |
| 35 // 1. Uses a separate handle for Load()ing which is closed as soon as loading |
| 36 // finishes, and |
| 37 // 2. Requires that SaveChanges *only* be called from a single thread, and that |
| 38 // thread *must* be the thread that owns / is responsible for destroying |
| 39 // the DBS. |
| 40 // This way, any thread may open a Directory (which today can be either the |
| 41 // AuthWatcherThread or SyncCoreThread) and Load its DBS. The first time |
| 42 // SaveChanges is called a new sqlite3 handle is created, and it will get closed |
| 43 // when the DBS is destroyed, which is the reason for the requirement that the |
| 44 // thread that "uses" the DBS is the thread that destroys it. |
| 45 class DirectoryBackingStore { |
| 46 public: |
| 47 DirectoryBackingStore(const PathString& dir_name, |
| 48 const PathString& backing_filepath); |
| 49 |
| 50 virtual ~DirectoryBackingStore(); |
| 51 |
| 52 // Loads and drops all currently persisted meta entries into |
| 53 // |entry_bucket|, all currently persisted xattrs in |xattrs_bucket|, |
| 54 // and loads appropriate persisted kernel info in |info_bucket|. |
| 55 // NOTE: On success (return value of OPENED), the buckets are populated with |
| 56 // newly allocated items, meaning ownership is bestowed upon the caller. |
| 57 DirOpenResult Load(MetahandlesIndex* entry_bucket, |
| 58 ExtendedAttributes* xattrs_bucket, |
| 59 Directory::KernelLoadInfo* kernel_load_info); |
| 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 private: |
| 69 // General Directory initialization and load helpers. |
| 70 DirOpenResult InitializeTables(); |
| 71 // Returns an sqlite return code, usually SQLITE_DONE. |
| 72 int CreateTables(); |
| 73 int CreateExtendedAttributeTable(); |
| 74 // We don't need to load any synced and applied deleted entries, we can |
| 75 // in fact just purge them forever on startup. |
| 76 void DropDeletedEntries(); |
| 77 // Drops a table if it exists, harmless if the table did not already exist. |
| 78 void SafeDropTable(const char* table_name); |
| 79 |
| 80 // Load helpers for entries and attributes. |
| 81 void LoadEntries(MetahandlesIndex* entry_bucket); |
| 82 void LoadExtendedAttributes(ExtendedAttributes* xattrs_bucket); |
| 83 void LoadInfo(Directory::KernelLoadInfo* info); |
| 84 |
| 85 // Save/update helpers for entries. Return false if sqlite commit fails. |
| 86 bool SaveEntryToDB(const EntryKernel& entry); |
| 87 bool SaveNewEntryToDB(const EntryKernel& entry); |
| 88 bool UpdateEntryToDB(const EntryKernel& entry); |
| 89 |
| 90 // Save/update helpers for attributes. Return false if sqlite commit fails. |
| 91 bool SaveExtendedAttributeToDB(ExtendedAttributes::const_iterator i); |
| 92 bool DeleteExtendedAttributeFromDB(ExtendedAttributes::const_iterator i); |
| 93 |
| 94 // Creates a new sqlite3 handle to the backing database. Sets sqlite operation |
| 95 // timeout preferences and registers our overridden sqlite3 operators for |
| 96 // said handle. Returns true on success, false if the sqlite open operation |
| 97 // did not succeed. |
| 98 bool OpenAndConfigureHandleHelper(sqlite3** handle) const; |
| 99 |
| 100 // Lazy creation of save_dbhandle_ for use by SaveChanges code path. |
| 101 sqlite3* LazyGetSaveHandle(); |
| 102 |
| 103 // Drop all tables in preparation for reinitialization. |
| 104 void DropAllTables(); |
| 105 |
| 106 // The handle to our sqlite on-disk store for initialization and loading, and |
| 107 // for saving changes periodically via SaveChanges, respectively. |
| 108 // TODO(timsteele): We should only have one handle here. The reason we need |
| 109 // two at the moment is because the DB can be opened by either the AuthWatcher |
| 110 // or SyncCore threads, but SaveChanges is always called by the latter. We |
| 111 // need to change initialization so the DB is only accessed from one thread. |
| 112 sqlite3* load_dbhandle_; |
| 113 sqlite3* save_dbhandle_; |
| 114 |
| 115 PathString dir_name_; |
| 116 PathString backing_filepath_; |
| 117 |
| 118 DISALLOW_COPY_AND_ASSIGN(DirectoryBackingStore); |
| 119 }; |
| 120 |
| 121 } // namespace syncable |
| 122 |
| 123 #endif // CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_BACKING_STORE_H_ |
OLD | NEW |