1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/quota/CachingDatabaseConnection.h"
9 #include "GeckoProfiler.h"
10 #include "mozilla/ipc/BackgroundParent.h"
12 namespace mozilla::dom::quota
{
14 CachingDatabaseConnection::CachingDatabaseConnection(
15 MovingNotNull
<nsCOMPtr
<mozIStorageConnection
>> aStorageConnection
)
17 #ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
18 mOwningThread
{nsAutoOwningThread
{}},
20 mStorageConnection(std::move(aStorageConnection
)) {
23 void CachingDatabaseConnection::LazyInit(
24 MovingNotNull
<nsCOMPtr
<mozIStorageConnection
>> aStorageConnection
) {
25 #ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
28 mStorageConnection
.init(std::move(aStorageConnection
));
31 Result
<CachingDatabaseConnection::CachedStatement
, nsresult
>
32 CachingDatabaseConnection::GetCachedStatement(const nsACString
& aQuery
) {
33 AssertIsOnConnectionThread();
34 MOZ_ASSERT(!aQuery
.IsEmpty());
35 MOZ_ASSERT(mStorageConnection
);
37 AUTO_PROFILER_LABEL("CachingDatabaseConnection::GetCachedStatement", DOM
);
39 nsCOMPtr
<mozIStorageStatement
> stmt
;
41 if (!mCachedStatements
.Get(aQuery
, getter_AddRefs(stmt
))) {
42 const auto extraInfo
=
43 ScopedLogExtraInfo
{ScopedLogExtraInfo::kTagQuery
, aQuery
};
47 MOZ_TO_RESULT_INVOKE_TYPED(nsCOMPtr
<mozIStorageStatement
>,
48 **mStorageConnection
, CreateStatement
,
51 ([&aQuery
, &storageConnection
= **mStorageConnection
](const auto&) {
54 MOZ_ALWAYS_SUCCEEDS(storageConnection
.GetLastErrorString(msg
));
57 "The statement '"_ns
+ aQuery
+
58 "' failed to compile with the error message '"_ns
+ msg
+ "'."_ns
;
60 NS_WARNING(error
.get());
66 mCachedStatements
.Put(aQuery
, stmt
);
69 return CachedStatement
{this, std::move(stmt
), aQuery
};
72 Result
<CachingDatabaseConnection::BorrowedStatement
, nsresult
>
73 CachingDatabaseConnection::BorrowCachedStatement(const nsACString
& aQuery
) {
74 QM_TRY_UNWRAP(auto cachedStatement
, GetCachedStatement(aQuery
));
76 return cachedStatement
.Borrow();
79 nsresult
CachingDatabaseConnection::ExecuteCachedStatement(
80 const nsACString
& aQuery
) {
81 return ExecuteCachedStatement(aQuery
, [](auto&) { return NS_OK
; });
84 void CachingDatabaseConnection::Close() {
85 AssertIsOnConnectionThread();
86 MOZ_ASSERT(HasStorageConnection());
88 AUTO_PROFILER_LABEL("CachingDatabaseConnection::Close", DOM
);
90 mCachedStatements
.Clear();
92 MOZ_ALWAYS_SUCCEEDS((*mStorageConnection
)->Close());
93 mStorageConnection
.destroy();
96 #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING)
97 CachingDatabaseConnection::CachedStatement::CachedStatement()
99 : mDEBUGConnection(nullptr)
102 AssertIsOnConnectionThread();
104 MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement
);
107 CachingDatabaseConnection::CachedStatement::~CachedStatement() {
108 AssertIsOnConnectionThread();
110 MOZ_COUNT_DTOR(CachingDatabaseConnection::CachedStatement
);
114 CachingDatabaseConnection::CachedStatement::operator bool() const {
115 AssertIsOnConnectionThread();
120 mozIStorageStatement
& CachingDatabaseConnection::BorrowedStatement::operator*()
122 return *operator->();
125 mozIStorageStatement
* CachingDatabaseConnection::BorrowedStatement::operator->()
127 MOZ_ASSERT(mStatement
);
132 CachingDatabaseConnection::BorrowedStatement
133 CachingDatabaseConnection::CachedStatement::Borrow() const {
134 AssertIsOnConnectionThread();
136 #if defined(EARLY_BETA_OR_EARLIER) || defined(DEBUG)
137 return BorrowedStatement
{WrapNotNull(mStatement
), mQuery
};
139 return BorrowedStatement
{WrapNotNull(mStatement
)};
143 CachingDatabaseConnection::CachedStatement::CachedStatement(
144 CachingDatabaseConnection
* aConnection
,
145 nsCOMPtr
<mozIStorageStatement
> aStatement
, const nsACString
& aQuery
)
146 : mStatement(std::move(aStatement
))
147 #if defined(EARLY_BETA_OR_EARLIER) || defined(DEBUG)
153 mDEBUGConnection(aConnection
)
157 MOZ_ASSERT(aConnection
);
158 aConnection
->AssertIsOnConnectionThread();
160 MOZ_ASSERT(mStatement
);
161 AssertIsOnConnectionThread();
163 MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement
);
166 void CachingDatabaseConnection::CachedStatement::AssertIsOnConnectionThread()
169 if (mDEBUGConnection
) {
170 mDEBUGConnection
->AssertIsOnConnectionThread();
172 MOZ_ASSERT(!NS_IsMainThread());
173 MOZ_ASSERT(!mozilla::ipc::IsOnBackgroundThread());
177 Result
<CachingDatabaseConnection::BorrowedStatement
, nsresult
>
178 CachingDatabaseConnection::LazyStatement::Borrow() {
179 if (!mCachedStatement
) {
180 QM_TRY(Initialize());
183 return mCachedStatement
.Borrow();
186 Result
<Ok
, nsresult
> CachingDatabaseConnection::LazyStatement::Initialize() {
187 QM_TRY_UNWRAP(mCachedStatement
, mConnection
.GetCachedStatement(mQueryString
));
191 } // namespace mozilla::dom::quota