1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/Database.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,308 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#ifndef mozilla_places_Database_h_ 1.9 +#define mozilla_places_Database_h_ 1.10 + 1.11 +#include "MainThreadUtils.h" 1.12 +#include "nsWeakReference.h" 1.13 +#include "nsIInterfaceRequestorUtils.h" 1.14 +#include "nsIObserver.h" 1.15 +#include "mozilla/storage.h" 1.16 +#include "mozilla/storage/StatementCache.h" 1.17 +#include "mozilla/Attributes.h" 1.18 +#include "nsIEventTarget.h" 1.19 + 1.20 +// This is the schema version. Update it at any schema change and add a 1.21 +// corresponding migrateVxx method below. 1.22 +#define DATABASE_SCHEMA_VERSION 23 1.23 + 1.24 +// Fired after Places inited. 1.25 +#define TOPIC_PLACES_INIT_COMPLETE "places-init-complete" 1.26 +// Fired when initialization fails due to a locked database. 1.27 +#define TOPIC_DATABASE_LOCKED "places-database-locked" 1.28 +// This topic is received when the profile is about to be lost. Places does 1.29 +// initial shutdown work and notifies TOPIC_PLACES_SHUTDOWN to all listeners. 1.30 +// Any shutdown work that requires the Places APIs should happen here. 1.31 +#define TOPIC_PROFILE_CHANGE_TEARDOWN "profile-change-teardown" 1.32 +// This topic is received just before the profile is lost. Places begins 1.33 +// shutting down the connection and notifies TOPIC_PLACES_WILL_CLOSE_CONNECTION 1.34 +// to all listeners. Only critical database cleanups should happen here, 1.35 +// some APIs may bail out already. 1.36 +#define TOPIC_PROFILE_BEFORE_CHANGE "profile-before-change" 1.37 +// Fired when Places is shutting down. Any code should stop accessing Places 1.38 +// APIs after this notification. If you need to listen for Places shutdown 1.39 +// you should only use this notification, next ones are intended only for 1.40 +// internal Places use. 1.41 +#define TOPIC_PLACES_SHUTDOWN "places-shutdown" 1.42 +// For Internal use only. Fired when connection is about to be closed, only 1.43 +// cleanup tasks should run at this stage, nothing should be added to the 1.44 +// database, nor APIs should be called. 1.45 +#define TOPIC_PLACES_WILL_CLOSE_CONNECTION "places-will-close-connection" 1.46 +// Fired when the connection has gone, nothing will work from now on. 1.47 +#define TOPIC_PLACES_CONNECTION_CLOSED "places-connection-closed" 1.48 + 1.49 +class nsIStringBundle; 1.50 +class nsIRunnable; 1.51 + 1.52 +namespace mozilla { 1.53 +namespace places { 1.54 + 1.55 +enum JournalMode { 1.56 + // Default SQLite journal mode. 1.57 + JOURNAL_DELETE = 0 1.58 + // Can reduce fsyncs on Linux when journal is deleted (See bug 460315). 1.59 + // We fallback to this mode when WAL is unavailable. 1.60 +, JOURNAL_TRUNCATE 1.61 + // Unsafe in case of crashes on database swap or low memory. 1.62 +, JOURNAL_MEMORY 1.63 + // Can reduce number of fsyncs. We try to use this mode by default. 1.64 +, JOURNAL_WAL 1.65 +}; 1.66 + 1.67 +class Database MOZ_FINAL : public nsIObserver 1.68 + , public nsSupportsWeakReference 1.69 +{ 1.70 + typedef mozilla::storage::StatementCache<mozIStorageStatement> StatementCache; 1.71 + typedef mozilla::storage::StatementCache<mozIStorageAsyncStatement> AsyncStatementCache; 1.72 + 1.73 +public: 1.74 + NS_DECL_THREADSAFE_ISUPPORTS 1.75 + NS_DECL_NSIOBSERVER 1.76 + 1.77 + Database(); 1.78 + 1.79 + /** 1.80 + * Initializes the database connection and the schema. 1.81 + * In case of corruption the database is copied to a backup file and replaced. 1.82 + */ 1.83 + nsresult Init(); 1.84 + 1.85 + /** 1.86 + * Finalizes the cached statements and closes the database connection. 1.87 + * A TOPIC_PLACES_CONNECTION_CLOSED notification is fired when done. 1.88 + */ 1.89 + void Shutdown(); 1.90 + 1.91 + /** 1.92 + * Getter to use when instantiating the class. 1.93 + * 1.94 + * @return Singleton instance of this class. 1.95 + */ 1.96 + static already_AddRefed<Database> GetDatabase() 1.97 + { 1.98 + return GetSingleton(); 1.99 + } 1.100 + 1.101 + /** 1.102 + * Returns last known database status. 1.103 + * 1.104 + * @return one of the nsINavHistoryService::DATABASE_STATUS_* constants. 1.105 + */ 1.106 + uint16_t GetDatabaseStatus() const 1.107 + { 1.108 + return mDatabaseStatus; 1.109 + } 1.110 + 1.111 + /** 1.112 + * Returns a pointer to the storage connection. 1.113 + * 1.114 + * @return The connection handle. 1.115 + */ 1.116 + mozIStorageConnection* MainConn() const 1.117 + { 1.118 + return mMainConn; 1.119 + } 1.120 + 1.121 + /** 1.122 + * Dispatches a runnable to the connection async thread, to be serialized 1.123 + * with async statements. 1.124 + * 1.125 + * @param aEvent 1.126 + * The runnable to be dispatched. 1.127 + */ 1.128 + void DispatchToAsyncThread(nsIRunnable* aEvent) const 1.129 + { 1.130 + if (mClosed) { 1.131 + return; 1.132 + } 1.133 + nsCOMPtr<nsIEventTarget> target = do_GetInterface(mMainConn); 1.134 + if (target) { 1.135 + (void)target->Dispatch(aEvent, NS_DISPATCH_NORMAL); 1.136 + } 1.137 + } 1.138 + 1.139 + ////////////////////////////////////////////////////////////////////////////// 1.140 + //// Statements Getters. 1.141 + 1.142 + /** 1.143 + * Gets a cached synchronous statement. 1.144 + * 1.145 + * @param aQuery 1.146 + * SQL query literal. 1.147 + * @return The cached statement. 1.148 + * @note Always null check the result. 1.149 + * @note Always use a scoper to reset the statement. 1.150 + */ 1.151 + template<int N> 1.152 + already_AddRefed<mozIStorageStatement> 1.153 + GetStatement(const char (&aQuery)[N]) const 1.154 + { 1.155 + nsDependentCString query(aQuery, N - 1); 1.156 + return GetStatement(query); 1.157 + } 1.158 + 1.159 + /** 1.160 + * Gets a cached synchronous statement. 1.161 + * 1.162 + * @param aQuery 1.163 + * nsCString of SQL query. 1.164 + * @return The cached statement. 1.165 + * @note Always null check the result. 1.166 + * @note Always use a scoper to reset the statement. 1.167 + */ 1.168 + already_AddRefed<mozIStorageStatement> 1.169 + GetStatement(const nsACString& aQuery) const 1.170 + { 1.171 + if (mShuttingDown) { 1.172 + return nullptr; 1.173 + } 1.174 + if (NS_IsMainThread()) { 1.175 + return mMainThreadStatements.GetCachedStatement(aQuery); 1.176 + } 1.177 + return mAsyncThreadStatements.GetCachedStatement(aQuery); 1.178 + } 1.179 + 1.180 + /** 1.181 + * Gets a cached asynchronous statement. 1.182 + * 1.183 + * @param aQuery 1.184 + * SQL query literal. 1.185 + * @return The cached statement. 1.186 + * @note Always null check the result. 1.187 + * @note AsyncStatements are automatically reset on execution. 1.188 + */ 1.189 + template<int N> 1.190 + already_AddRefed<mozIStorageAsyncStatement> 1.191 + GetAsyncStatement(const char (&aQuery)[N]) const 1.192 + { 1.193 + nsDependentCString query(aQuery, N - 1); 1.194 + return GetAsyncStatement(query); 1.195 + } 1.196 + 1.197 + /** 1.198 + * Gets a cached asynchronous statement. 1.199 + * 1.200 + * @param aQuery 1.201 + * nsCString of SQL query. 1.202 + * @return The cached statement. 1.203 + * @note Always null check the result. 1.204 + * @note AsyncStatements are automatically reset on execution. 1.205 + */ 1.206 + already_AddRefed<mozIStorageAsyncStatement> 1.207 + GetAsyncStatement(const nsACString& aQuery) const 1.208 + { 1.209 + if (mShuttingDown) { 1.210 + return nullptr; 1.211 + } 1.212 + MOZ_ASSERT(NS_IsMainThread()); 1.213 + return mMainThreadAsyncStatements.GetCachedStatement(aQuery); 1.214 + } 1.215 + 1.216 +protected: 1.217 + /** 1.218 + * Initializes the database file. If the database does not exist or is 1.219 + * corrupt, a new one is created. In case of corruption it also creates a 1.220 + * backup copy of the database. 1.221 + * 1.222 + * @param aStorage 1.223 + * mozStorage service instance. 1.224 + * @param aNewDatabaseCreated 1.225 + * whether a new database file has been created. 1.226 + */ 1.227 + nsresult InitDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage, 1.228 + bool* aNewDatabaseCreated); 1.229 + 1.230 + /** 1.231 + * Creates a database backup and replaces the original file with a new 1.232 + * one. 1.233 + * 1.234 + * @param aStorage 1.235 + * mozStorage service instance. 1.236 + */ 1.237 + nsresult BackupAndReplaceDatabaseFile(nsCOMPtr<mozIStorageService>& aStorage); 1.238 + 1.239 + /** 1.240 + * Initializes the database. This performs any necessary migrations for the 1.241 + * database. All migration is done inside a transaction that is rolled back 1.242 + * if any error occurs. 1.243 + * @param aDatabaseMigrated 1.244 + * Whether a schema upgrade happened. 1.245 + */ 1.246 + nsresult InitSchema(bool* aDatabaseMigrated); 1.247 + 1.248 + /** 1.249 + * Creates bookmark roots in a new DB. 1.250 + */ 1.251 + nsresult CreateBookmarkRoots(); 1.252 + 1.253 + /** 1.254 + * Initializes additionale SQLite functions, defined in SQLFunctions.h 1.255 + */ 1.256 + nsresult InitFunctions(); 1.257 + 1.258 + /** 1.259 + * Initializes triggers defined in nsPlacesTriggers.h 1.260 + */ 1.261 + nsresult InitTempTriggers(); 1.262 + 1.263 + /** 1.264 + * Helpers used by schema upgrades. 1.265 + */ 1.266 + nsresult MigrateV7Up(); 1.267 + nsresult MigrateV8Up(); 1.268 + nsresult MigrateV9Up(); 1.269 + nsresult MigrateV10Up(); 1.270 + nsresult MigrateV11Up(); 1.271 + nsresult MigrateV13Up(); 1.272 + nsresult MigrateV14Up(); 1.273 + nsresult MigrateV15Up(); 1.274 + nsresult MigrateV16Up(); 1.275 + nsresult MigrateV17Up(); 1.276 + nsresult MigrateV18Up(); 1.277 + nsresult MigrateV19Up(); 1.278 + nsresult MigrateV20Up(); 1.279 + nsresult MigrateV21Up(); 1.280 + nsresult MigrateV22Up(); 1.281 + nsresult MigrateV23Up(); 1.282 + 1.283 + nsresult UpdateBookmarkRootTitles(); 1.284 + nsresult CheckAndUpdateGUIDs(); 1.285 + 1.286 +private: 1.287 + ~Database(); 1.288 + 1.289 + /** 1.290 + * Singleton getter, invoked by class instantiation. 1.291 + */ 1.292 + static already_AddRefed<Database> GetSingleton(); 1.293 + 1.294 + static Database* gDatabase; 1.295 + 1.296 + nsCOMPtr<mozIStorageConnection> mMainConn; 1.297 + 1.298 + mutable StatementCache mMainThreadStatements; 1.299 + mutable AsyncStatementCache mMainThreadAsyncStatements; 1.300 + mutable StatementCache mAsyncThreadStatements; 1.301 + 1.302 + int32_t mDBPageSize; 1.303 + uint16_t mDatabaseStatus; 1.304 + bool mShuttingDown; 1.305 + bool mClosed; 1.306 +}; 1.307 + 1.308 +} // namespace places 1.309 +} // namespace mozilla 1.310 + 1.311 +#endif // mozilla_places_Database_h_