Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #ifndef mozilla_places_Database_h_
6 #define mozilla_places_Database_h_
8 #include "MainThreadUtils.h"
9 #include "nsWeakReference.h"
10 #include "nsIInterfaceRequestorUtils.h"
11 #include "nsIObserver.h"
12 #include "mozilla/storage.h"
13 #include "mozilla/storage/StatementCache.h"
14 #include "mozilla/Attributes.h"
15 #include "nsIEventTarget.h"
17 // This is the schema version. Update it at any schema change and add a
18 // corresponding migrateVxx method below.
19 #define DATABASE_SCHEMA_VERSION 23
21 // Fired after Places inited.
22 #define TOPIC_PLACES_INIT_COMPLETE "places-init-complete"
23 // Fired when initialization fails due to a locked database.
24 #define TOPIC_DATABASE_LOCKED "places-database-locked"
25 // This topic is received when the profile is about to be lost. Places does
26 // initial shutdown work and notifies TOPIC_PLACES_SHUTDOWN to all listeners.
27 // Any shutdown work that requires the Places APIs should happen here.
28 #define TOPIC_PROFILE_CHANGE_TEARDOWN "profile-change-teardown"
29 // This topic is received just before the profile is lost. Places begins
30 // shutting down the connection and notifies TOPIC_PLACES_WILL_CLOSE_CONNECTION
31 // to all listeners. Only critical database cleanups should happen here,
32 // some APIs may bail out already.
33 #define TOPIC_PROFILE_BEFORE_CHANGE "profile-before-change"
34 // Fired when Places is shutting down. Any code should stop accessing Places
35 // APIs after this notification. If you need to listen for Places shutdown
36 // you should only use this notification, next ones are intended only for
37 // internal Places use.
38 #define TOPIC_PLACES_SHUTDOWN "places-shutdown"
39 // For Internal use only. Fired when connection is about to be closed, only
40 // cleanup tasks should run at this stage, nothing should be added to the
41 // database, nor APIs should be called.
42 #define TOPIC_PLACES_WILL_CLOSE_CONNECTION "places-will-close-connection"
43 // Fired when the connection has gone, nothing will work from now on.
44 #define TOPIC_PLACES_CONNECTION_CLOSED "places-connection-closed"
46 class nsIStringBundle;
47 class nsIRunnable;
49 namespace mozilla {
50 namespace places {
52 enum JournalMode {
53 // Default SQLite journal mode.
54 JOURNAL_DELETE = 0
55 // Can reduce fsyncs on Linux when journal is deleted (See bug 460315).
56 // We fallback to this mode when WAL is unavailable.
57 , JOURNAL_TRUNCATE
58 // Unsafe in case of crashes on database swap or low memory.
59 , JOURNAL_MEMORY
60 // Can reduce number of fsyncs. We try to use this mode by default.
61 , JOURNAL_WAL
62 };
64 class Database MOZ_FINAL : public nsIObserver
65 , public nsSupportsWeakReference
66 {
67 typedef mozilla::storage::StatementCache<mozIStorageStatement> StatementCache;
68 typedef mozilla::storage::StatementCache<mozIStorageAsyncStatement> AsyncStatementCache;
70 public:
71 NS_DECL_THREADSAFE_ISUPPORTS
72 NS_DECL_NSIOBSERVER
74 Database();
76 /**
77 * Initializes the database connection and the schema.
78 * In case of corruption the database is copied to a backup file and replaced.
79 */
80 nsresult Init();
82 /**
83 * Finalizes the cached statements and closes the database connection.
84 * A TOPIC_PLACES_CONNECTION_CLOSED notification is fired when done.
85 */
86 void Shutdown();
88 /**
89 * Getter to use when instantiating the class.
90 *
91 * @return Singleton instance of this class.
92 */
93 static already_AddRefed<Database> GetDatabase()
94 {
95 return GetSingleton();
96 }
98 /**
99 * Returns last known database status.
100 *
101 * @return one of the nsINavHistoryService::DATABASE_STATUS_* constants.
102 */
103 uint16_t GetDatabaseStatus() const
104 {
105 return mDatabaseStatus;
106 }
108 /**
109 * Returns a pointer to the storage connection.
110 *
111 * @return The connection handle.
112 */
113 mozIStorageConnection* MainConn() const
114 {
115 return mMainConn;
116 }
118 /**
119 * Dispatches a runnable to the connection async thread, to be serialized
120 * with async statements.
121 *
122 * @param aEvent
123 * The runnable to be dispatched.
124 */
125 void DispatchToAsyncThread(nsIRunnable* aEvent) const
126 {
127 if (mClosed) {
128 return;
129 }
130 nsCOMPtr<nsIEventTarget> target = do_GetInterface(mMainConn);
131 if (target) {
132 (void)target->Dispatch(aEvent, NS_DISPATCH_NORMAL);
133 }
134 }
136 //////////////////////////////////////////////////////////////////////////////
137 //// Statements Getters.
139 /**
140 * Gets a cached synchronous statement.
141 *
142 * @param aQuery
143 * SQL query literal.
144 * @return The cached statement.
145 * @note Always null check the result.
146 * @note Always use a scoper to reset the statement.
147 */
148 template<int N>
149 already_AddRefed<mozIStorageStatement>
150 GetStatement(const char (&aQuery)[N]) const
151 {
152 nsDependentCString query(aQuery, N - 1);
153 return GetStatement(query);
154 }
156 /**
157 * Gets a cached synchronous statement.
158 *
159 * @param aQuery
160 * nsCString of SQL query.
161 * @return The cached statement.
162 * @note Always null check the result.
163 * @note Always use a scoper to reset the statement.
164 */
165 already_AddRefed<mozIStorageStatement>
166 GetStatement(const nsACString& aQuery) const
167 {
168 if (mShuttingDown) {
169 return nullptr;
170 }
171 if (NS_IsMainThread()) {
172 return mMainThreadStatements.GetCachedStatement(aQuery);
173 }
174 return mAsyncThreadStatements.GetCachedStatement(aQuery);
175 }
177 /**
178 * Gets a cached asynchronous statement.
179 *
180 * @param aQuery
181 * SQL query literal.
182 * @return The cached statement.
183 * @note Always null check the result.
184 * @note AsyncStatements are automatically reset on execution.
185 */
186 template<int N>
187 already_AddRefed<mozIStorageAsyncStatement>
188 GetAsyncStatement(const char (&aQuery)[N]) const
189 {
190 nsDependentCString query(aQuery, N - 1);
191 return GetAsyncStatement(query);
192 }
194 /**
195 * Gets a cached asynchronous statement.
196 *
197 * @param aQuery
198 * nsCString of SQL query.
199 * @return The cached statement.
200 * @note Always null check the result.
201 * @note AsyncStatements are automatically reset on execution.
202 */
203 already_AddRefed<mozIStorageAsyncStatement>
204 GetAsyncStatement(const nsACString& aQuery) const
205 {
206 if (mShuttingDown) {
207 return nullptr;
208 }
209 MOZ_ASSERT(NS_IsMainThread());
210 return mMainThreadAsyncStatements.GetCachedStatement(aQuery);
211 }
213 protected:
214 /**
215 * Initializes the database file. If the database does not exist or is
216 * corrupt, a new one is created. In case of corruption it also creates a
217 * backup copy of the database.
218 *
219 * @param aStorage
220 * mozStorage service instance.
221 * @param aNewDatabaseCreated
222 * whether a new database file has been created.
223 */
224 nsresult InitDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage,
225 bool* aNewDatabaseCreated);
227 /**
228 * Creates a database backup and replaces the original file with a new
229 * one.
230 *
231 * @param aStorage
232 * mozStorage service instance.
233 */
234 nsresult BackupAndReplaceDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage);
236 /**
237 * Initializes the database. This performs any necessary migrations for the
238 * database. All migration is done inside a transaction that is rolled back
239 * if any error occurs.
240 * @param aDatabaseMigrated
241 * Whether a schema upgrade happened.
242 */
243 nsresult InitSchema(bool* aDatabaseMigrated);
245 /**
246 * Creates bookmark roots in a new DB.
247 */
248 nsresult CreateBookmarkRoots();
250 /**
251 * Initializes additionale SQLite functions, defined in SQLFunctions.h
252 */
253 nsresult InitFunctions();
255 /**
256 * Initializes triggers defined in nsPlacesTriggers.h
257 */
258 nsresult InitTempTriggers();
260 /**
261 * Helpers used by schema upgrades.
262 */
263 nsresult MigrateV7Up();
264 nsresult MigrateV8Up();
265 nsresult MigrateV9Up();
266 nsresult MigrateV10Up();
267 nsresult MigrateV11Up();
268 nsresult MigrateV13Up();
269 nsresult MigrateV14Up();
270 nsresult MigrateV15Up();
271 nsresult MigrateV16Up();
272 nsresult MigrateV17Up();
273 nsresult MigrateV18Up();
274 nsresult MigrateV19Up();
275 nsresult MigrateV20Up();
276 nsresult MigrateV21Up();
277 nsresult MigrateV22Up();
278 nsresult MigrateV23Up();
280 nsresult UpdateBookmarkRootTitles();
281 nsresult CheckAndUpdateGUIDs();
283 private:
284 ~Database();
286 /**
287 * Singleton getter, invoked by class instantiation.
288 */
289 static already_AddRefed<Database> GetSingleton();
291 static Database* gDatabase;
293 nsCOMPtr<mozIStorageConnection> mMainConn;
295 mutable StatementCache mMainThreadStatements;
296 mutable AsyncStatementCache mMainThreadAsyncStatements;
297 mutable StatementCache mAsyncThreadStatements;
299 int32_t mDBPageSize;
300 uint16_t mDatabaseStatus;
301 bool mShuttingDown;
302 bool mClosed;
303 };
305 } // namespace places
306 } // namespace mozilla
308 #endif // mozilla_places_Database_h_