toolkit/components/places/Database.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial