toolkit/components/places/Database.h

changeset 0
6474c204b198
     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_

mercurial