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 "mozilla/ProfilerLabels.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 mOwningEventTarget
{nsAutoOwningEventTarget
{}},
20 mStorageConnection(std::move(aStorageConnection
)) {
23 void CachingDatabaseConnection::LazyInit(
24 MovingNotNull
<nsCOMPtr
<mozIStorageConnection
>> aStorageConnection
) {
25 #ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
26 mOwningEventTarget
.init();
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
);
41 mCachedStatements
.TryLookupOrInsertWith(
42 aQuery
, [&]() -> Result
<nsCOMPtr
<mozIStorageStatement
>, nsresult
> {
43 const auto extraInfo
= ScopedLogExtraInfo
{
44 ScopedLogExtraInfo::kTagQueryTainted
, aQuery
};
47 MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
48 nsCOMPtr
<mozIStorageStatement
>, **mStorageConnection
,
49 CreateStatement
, aQuery
),
52 &storageConnection
= **mStorageConnection
](const auto&) {
56 storageConnection
.GetLastErrorString(msg
));
59 "The statement '"_ns
+ aQuery
+
60 "' failed to compile with the error message '"_ns
+ msg
+
63 NS_WARNING(error
.get());
70 return CachedStatement
{this, std::move(stmt
), aQuery
};
73 Result
<CachingDatabaseConnection::BorrowedStatement
, nsresult
>
74 CachingDatabaseConnection::BorrowCachedStatement(const nsACString
& aQuery
) {
75 QM_TRY_UNWRAP(auto cachedStatement
, GetCachedStatement(aQuery
));
77 return cachedStatement
.Borrow();
80 nsresult
CachingDatabaseConnection::ExecuteCachedStatement(
81 const nsACString
& aQuery
) {
82 return ExecuteCachedStatement(
83 aQuery
, [](auto&) -> Result
<Ok
, nsresult
> { return Ok
{}; });
86 void CachingDatabaseConnection::Close() {
87 AssertIsOnConnectionThread();
88 MOZ_ASSERT(HasStorageConnection());
90 AUTO_PROFILER_LABEL("CachingDatabaseConnection::Close", DOM
);
92 mCachedStatements
.Clear();
94 MOZ_ALWAYS_SUCCEEDS((*mStorageConnection
)->Close());
95 mStorageConnection
.destroy();
98 #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING)
99 CachingDatabaseConnection::CachedStatement::CachedStatement()
101 : mDEBUGConnection(nullptr)
104 AssertIsOnConnectionThread();
106 MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement
);
109 CachingDatabaseConnection::CachedStatement::~CachedStatement() {
110 AssertIsOnConnectionThread();
112 MOZ_COUNT_DTOR(CachingDatabaseConnection::CachedStatement
);
116 CachingDatabaseConnection::CachedStatement::operator bool() const {
117 AssertIsOnConnectionThread();
122 mozIStorageStatement
& CachingDatabaseConnection::BorrowedStatement::operator*()
124 return *operator->();
127 mozIStorageStatement
* CachingDatabaseConnection::BorrowedStatement::operator->()
129 MOZ_ASSERT(mStatement
);
134 CachingDatabaseConnection::BorrowedStatement
135 CachingDatabaseConnection::CachedStatement::Borrow() const {
136 AssertIsOnConnectionThread();
138 #ifdef QM_SCOPED_LOG_EXTRA_INFO_ENABLED
139 return BorrowedStatement
{WrapNotNull(mStatement
), mQuery
};
141 return BorrowedStatement
{WrapNotNull(mStatement
)};
145 CachingDatabaseConnection::CachedStatement::CachedStatement(
146 CachingDatabaseConnection
* aConnection
,
147 nsCOMPtr
<mozIStorageStatement
> aStatement
, const nsACString
& aQuery
)
148 : mStatement(std::move(aStatement
))
149 #ifdef QM_SCOPED_LOG_EXTRA_INFO_ENABLED
155 mDEBUGConnection(aConnection
)
159 MOZ_ASSERT(aConnection
);
160 aConnection
->AssertIsOnConnectionThread();
162 MOZ_ASSERT(mStatement
);
163 AssertIsOnConnectionThread();
165 MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement
);
168 void CachingDatabaseConnection::CachedStatement::AssertIsOnConnectionThread()
171 if (mDEBUGConnection
) {
172 mDEBUGConnection
->AssertIsOnConnectionThread();
174 MOZ_ASSERT(!NS_IsMainThread());
175 MOZ_ASSERT(!mozilla::ipc::IsOnBackgroundThread());
179 Result
<CachingDatabaseConnection::BorrowedStatement
, nsresult
>
180 CachingDatabaseConnection::LazyStatement::Borrow() {
181 if (!mCachedStatement
) {
182 QM_TRY(Initialize());
185 return mCachedStatement
.Borrow();
188 Result
<Ok
, nsresult
> CachingDatabaseConnection::LazyStatement::Initialize() {
189 QM_TRY_UNWRAP(mCachedStatement
, mConnection
.GetCachedStatement(mQueryString
));
193 } // namespace mozilla::dom::quota