Bug 1874684 - Part 6: Limit day length calculations to safe integers. r=mgaudet
[gecko.git] / dom / quota / CachingDatabaseConnection.cpp
blobdfdf0f71da761155b938c48b32c261538ce4aaae
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{}},
19 #endif
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();
27 #endif
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 QM_TRY_UNWRAP(
40 auto stmt,
41 mCachedStatements.TryLookupOrInsertWith(
42 aQuery, [&]() -> Result<nsCOMPtr<mozIStorageStatement>, nsresult> {
43 const auto extraInfo = ScopedLogExtraInfo{
44 ScopedLogExtraInfo::kTagQueryTainted, aQuery};
46 QM_TRY_RETURN(
47 MOZ_TO_RESULT_INVOKE_MEMBER_TYPED(
48 nsCOMPtr<mozIStorageStatement>, **mStorageConnection,
49 CreateStatement, aQuery),
50 QM_PROPAGATE,
51 ([&aQuery,
52 &storageConnection = **mStorageConnection](const auto&) {
53 #ifdef DEBUG
54 nsCString msg;
55 MOZ_ALWAYS_SUCCEEDS(
56 storageConnection.GetLastErrorString(msg));
58 nsAutoCString error =
59 "The statement '"_ns + aQuery +
60 "' failed to compile with the error message '"_ns + msg +
61 "'."_ns;
63 NS_WARNING(error.get());
64 #else
65 (void)aQuery;
66 #endif
67 }));
68 }));
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()
100 # ifdef DEBUG
101 : mDEBUGConnection(nullptr)
102 # endif
104 AssertIsOnConnectionThread();
106 MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement);
109 CachingDatabaseConnection::CachedStatement::~CachedStatement() {
110 AssertIsOnConnectionThread();
112 MOZ_COUNT_DTOR(CachingDatabaseConnection::CachedStatement);
114 #endif
116 CachingDatabaseConnection::CachedStatement::operator bool() const {
117 AssertIsOnConnectionThread();
119 return mStatement;
122 mozIStorageStatement& CachingDatabaseConnection::BorrowedStatement::operator*()
123 const {
124 return *operator->();
127 mozIStorageStatement* CachingDatabaseConnection::BorrowedStatement::operator->()
128 const {
129 MOZ_ASSERT(mStatement);
131 return 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};
140 #else
141 return BorrowedStatement{WrapNotNull(mStatement)};
142 #endif
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
151 mQuery(aQuery)
152 #endif
153 #if defined(DEBUG)
155 mDEBUGConnection(aConnection)
156 #endif
158 #ifdef DEBUG
159 MOZ_ASSERT(aConnection);
160 aConnection->AssertIsOnConnectionThread();
161 #endif
162 MOZ_ASSERT(mStatement);
163 AssertIsOnConnectionThread();
165 MOZ_COUNT_CTOR(CachingDatabaseConnection::CachedStatement);
168 void CachingDatabaseConnection::CachedStatement::AssertIsOnConnectionThread()
169 const {
170 #ifdef DEBUG
171 if (mDEBUGConnection) {
172 mDEBUGConnection->AssertIsOnConnectionThread();
174 MOZ_ASSERT(!NS_IsMainThread());
175 MOZ_ASSERT(!mozilla::ipc::IsOnBackgroundThread());
176 #endif
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));
190 return Ok{};
193 } // namespace mozilla::dom::quota