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