Backed out changeset 36e95068e103 (bug 1848160) for bc failures on browser_preference...
[gecko.git] / storage / StatementCache.h
blob3d07c4ef573ad71504f7d7e9886a2a2b6f507951
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/. */
7 #ifndef mozilla_storage_StatementCache_h
8 #define mozilla_storage_StatementCache_h
10 #include "mozIStorageConnection.h"
11 #include "mozIStorageStatement.h"
12 #include "mozIStorageAsyncStatement.h"
14 #include "nsHashKeys.h"
15 #include "nsInterfaceHashtable.h"
17 namespace mozilla {
18 namespace storage {
20 /**
21 * Class used to cache statements (mozIStorageStatement or
22 * mozIStorageAsyncStatement).
24 template <typename StatementType>
25 class StatementCache {
26 public:
27 /**
28 * Constructor for the cache.
30 * @note a connection can have more than one cache.
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.
37 explicit StatementCache(nsCOMPtr<mozIStorageConnection>& aConnection)
38 : mConnection(aConnection) {}
40 /**
41 * Obtains a cached statement. If this statement is not yet created, it will
42 * be created and stored for later use.
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.
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);
56 mCachedStatements.InsertOrUpdate(aQuery, stmt);
58 return stmt.forget();
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);
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.
72 inline void FinalizeStatements() {
73 for (const auto& data : mCachedStatements.Values()) {
74 (void)data->Finalize();
77 // Clear the cache at this time too!
78 (void)mCachedStatements.Clear();
81 private:
82 inline already_AddRefed<StatementType> CreateStatement(
83 const nsACString& aQuery);
85 nsInterfaceHashtable<nsCStringHashKey, StatementType> mCachedStatements;
86 nsCOMPtr<mozIStorageConnection>& mConnection;
89 template <>
90 inline already_AddRefed<mozIStorageStatement>
91 StatementCache<mozIStorageStatement>::CreateStatement(
92 const nsACString& aQuery) {
93 NS_ENSURE_TRUE(mConnection, nullptr);
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());
108 NS_ENSURE_SUCCESS(rv, nullptr);
110 return stmt.forget();
113 template <>
114 inline already_AddRefed<mozIStorageAsyncStatement>
115 StatementCache<mozIStorageAsyncStatement>::CreateStatement(
116 const nsACString& aQuery) {
117 NS_ENSURE_TRUE(mConnection, nullptr);
119 nsCOMPtr<mozIStorageAsyncStatement> stmt;
120 nsresult rv = mConnection->CreateAsyncStatement(aQuery, getter_AddRefs(stmt));
121 NS_ENSURE_SUCCESS(rv, nullptr);
123 return stmt.forget();
126 } // namespace storage
127 } // namespace mozilla
129 #endif // mozilla_storage_StatementCache_h