tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StatementCache.h (3901B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_storage_StatementCache_h
      8 #define mozilla_storage_StatementCache_h
      9 
     10 #include "mozIStorageConnection.h"
     11 #include "mozIStorageStatement.h"
     12 #include "mozIStorageAsyncStatement.h"
     13 
     14 #include "nsHashKeys.h"
     15 #include "nsInterfaceHashtable.h"
     16 
     17 namespace mozilla {
     18 namespace storage {
     19 
     20 /**
     21 * Class used to cache statements (mozIStorageStatement or
     22 * mozIStorageAsyncStatement).
     23 */
     24 template <typename StatementType>
     25 class StatementCache {
     26 public:
     27  /**
     28   * Constructor for the cache.
     29   *
     30   * @note a connection can have more than one cache.
     31   *
     32   * @param aConnection
     33   *        A reference to the nsCOMPtr for the connection this cache is to be
     34   *        used for.  This nsCOMPtr must at least live as long as this class,
     35   *        otherwise crashes will happen.
     36   */
     37  explicit StatementCache(nsCOMPtr<mozIStorageConnection>& aConnection)
     38      : mConnection(aConnection) {}
     39 
     40  /**
     41   * Obtains a cached statement.  If this statement is not yet created, it will
     42   * be created and stored for later use.
     43   *
     44   * @param aQuery
     45   *        The SQL string (either a const char [] or nsACString) to get a
     46   *        cached query for.
     47   * @return the cached statement, or null upon error.
     48   */
     49  inline already_AddRefed<StatementType> GetCachedStatement(
     50      const nsACString& aQuery) {
     51    nsCOMPtr<StatementType> stmt;
     52    if (!mCachedStatements.Get(aQuery, getter_AddRefs(stmt))) {
     53      stmt = CreateStatement(aQuery);
     54      NS_ENSURE_TRUE(stmt, nullptr);
     55 
     56      mCachedStatements.InsertOrUpdate(aQuery, stmt);
     57    }
     58    return stmt.forget();
     59  }
     60 
     61  template <int N>
     62  MOZ_ALWAYS_INLINE already_AddRefed<StatementType> GetCachedStatement(
     63      const char (&aQuery)[N]) {
     64    nsDependentCString query(aQuery, N - 1);
     65    return GetCachedStatement(query);
     66  }
     67 
     68  /**
     69   * Finalizes all cached statements so the database can be safely closed.  The
     70   * behavior of this cache is unspecified after this method is called.
     71   */
     72  inline void FinalizeStatements() {
     73    for (const auto& data : mCachedStatements.Values()) {
     74      (void)data->Finalize();
     75    }
     76 
     77    // Clear the cache at this time too!
     78    (void)mCachedStatements.Clear();
     79  }
     80 
     81 private:
     82  inline already_AddRefed<StatementType> CreateStatement(
     83      const nsACString& aQuery);
     84 
     85  nsInterfaceHashtable<nsCStringHashKey, StatementType> mCachedStatements;
     86  nsCOMPtr<mozIStorageConnection>& mConnection;
     87 };
     88 
     89 template <>
     90 inline already_AddRefed<mozIStorageStatement>
     91 StatementCache<mozIStorageStatement>::CreateStatement(
     92    const nsACString& aQuery) {
     93  NS_ENSURE_TRUE(mConnection, nullptr);
     94 
     95  nsCOMPtr<mozIStorageStatement> stmt;
     96  nsresult rv = mConnection->CreateStatement(aQuery, getter_AddRefs(stmt));
     97  if (NS_FAILED(rv)) {
     98    nsCString error;
     99    error.AppendLiteral("The statement '");
    100    error.Append(aQuery);
    101    error.AppendLiteral("' failed to compile with the error message '");
    102    nsCString msg;
    103    (void)mConnection->GetLastErrorString(msg);
    104    error.Append(msg);
    105    error.AppendLiteral("'.");
    106    NS_ERROR(error.get());
    107  }
    108  NS_ENSURE_SUCCESS(rv, nullptr);
    109 
    110  return stmt.forget();
    111 }
    112 
    113 template <>
    114 inline already_AddRefed<mozIStorageAsyncStatement>
    115 StatementCache<mozIStorageAsyncStatement>::CreateStatement(
    116    const nsACString& aQuery) {
    117  NS_ENSURE_TRUE(mConnection, nullptr);
    118 
    119  nsCOMPtr<mozIStorageAsyncStatement> stmt;
    120  nsresult rv = mConnection->CreateAsyncStatement(aQuery, getter_AddRefs(stmt));
    121  NS_ENSURE_SUCCESS(rv, nullptr);
    122 
    123  return stmt.forget();
    124 }
    125 
    126 }  // namespace storage
    127 }  // namespace mozilla
    128 
    129 #endif  // mozilla_storage_StatementCache_h