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
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "mozilla/dom/cache/Connection.h"
8 
9 #include "mozilla/dom/cache/DBSchema.h"
10 #include "mozStorageHelper.h"
11 
12 namespace mozilla::dom::cache {
13 
14 using mozilla::dom::quota::QuotaObject;
15 
16 NS_IMPL_ISUPPORTS(cache::Connection, mozIStorageAsyncConnection,
17                   mozIStorageConnection);
18 
Connection(mozIStorageConnection * aBase)19 Connection::Connection(mozIStorageConnection* aBase)
20     : mBase(aBase), mClosed(false) {
21   MOZ_DIAGNOSTIC_ASSERT(mBase);
22 }
23 
~Connection()24 Connection::~Connection() {
25   NS_ASSERT_OWNINGTHREAD(Connection);
26   MOZ_ALWAYS_SUCCEEDS(Close());
27 }
28 
29 NS_IMETHODIMP
Close()30 Connection::Close() {
31   NS_ASSERT_OWNINGTHREAD(Connection);
32 
33   if (mClosed) {
34     return NS_OK;
35   }
36   mClosed = true;
37 
38   // If we are closing here, then Cache must not have a transaction
39   // open anywhere else.  This may fail if storage is corrupted.
40   Unused << NS_WARN_IF(NS_FAILED(db::IncrementalVacuum(*this)));
41 
42   return mBase->Close();
43 }
44 
45 // The following methods are all boilerplate that either forward to the
46 // base connection or block the method.  All the async execution methods
47 // are blocked because Cache does not use them and they would require more
48 // work to wrap properly.
49 
50 // mozIStorageAsyncConnection methods
51 
52 NS_IMETHODIMP
AsyncClose(mozIStorageCompletionCallback *)53 Connection::AsyncClose(mozIStorageCompletionCallback*) {
54   // async methods are not supported
55   return NS_ERROR_NOT_IMPLEMENTED;
56 }
57 
58 NS_IMETHODIMP
SpinningSynchronousClose()59 Connection::SpinningSynchronousClose() {
60   // not supported
61   return NS_ERROR_NOT_IMPLEMENTED;
62 }
63 
64 NS_IMETHODIMP
AsyncClone(bool,mozIStorageCompletionCallback *)65 Connection::AsyncClone(bool, mozIStorageCompletionCallback*) {
66   // async methods are not supported
67   return NS_ERROR_NOT_IMPLEMENTED;
68 }
69 
70 NS_IMETHODIMP
GetDatabaseFile(nsIFile ** aFileOut)71 Connection::GetDatabaseFile(nsIFile** aFileOut) {
72   return mBase->GetDatabaseFile(aFileOut);
73 }
74 
75 NS_IMETHODIMP
CreateAsyncStatement(const nsACString &,mozIStorageAsyncStatement **)76 Connection::CreateAsyncStatement(const nsACString&,
77                                  mozIStorageAsyncStatement**) {
78   // async methods are not supported
79   return NS_ERROR_NOT_IMPLEMENTED;
80 }
81 
82 NS_IMETHODIMP
ExecuteAsync(const nsTArray<RefPtr<mozIStorageBaseStatement>> &,mozIStorageStatementCallback *,mozIStoragePendingStatement **)83 Connection::ExecuteAsync(const nsTArray<RefPtr<mozIStorageBaseStatement>>&,
84                          mozIStorageStatementCallback*,
85                          mozIStoragePendingStatement**) {
86   // async methods are not supported
87   return NS_ERROR_NOT_IMPLEMENTED;
88 }
89 
90 NS_IMETHODIMP
ExecuteSimpleSQLAsync(const nsACString &,mozIStorageStatementCallback *,mozIStoragePendingStatement **)91 Connection::ExecuteSimpleSQLAsync(const nsACString&,
92                                   mozIStorageStatementCallback*,
93                                   mozIStoragePendingStatement**) {
94   // async methods are not supported
95   return NS_ERROR_NOT_IMPLEMENTED;
96 }
97 
98 NS_IMETHODIMP
CreateFunction(const nsACString & aFunctionName,int32_t aNumArguments,mozIStorageFunction * aFunction)99 Connection::CreateFunction(const nsACString& aFunctionName,
100                            int32_t aNumArguments,
101                            mozIStorageFunction* aFunction) {
102   // async methods are not supported
103   return NS_ERROR_NOT_IMPLEMENTED;
104 }
105 
106 NS_IMETHODIMP
RemoveFunction(const nsACString & aFunctionName)107 Connection::RemoveFunction(const nsACString& aFunctionName) {
108   return mBase->RemoveFunction(aFunctionName);
109 }
110 
111 NS_IMETHODIMP
SetProgressHandler(int32_t aGranularity,mozIStorageProgressHandler * aHandler,mozIStorageProgressHandler ** aHandlerOut)112 Connection::SetProgressHandler(int32_t aGranularity,
113                                mozIStorageProgressHandler* aHandler,
114                                mozIStorageProgressHandler** aHandlerOut) {
115   return mBase->SetProgressHandler(aGranularity, aHandler, aHandlerOut);
116 }
117 
118 NS_IMETHODIMP
RemoveProgressHandler(mozIStorageProgressHandler ** aHandlerOut)119 Connection::RemoveProgressHandler(mozIStorageProgressHandler** aHandlerOut) {
120   return mBase->RemoveProgressHandler(aHandlerOut);
121 }
122 
123 // mozIStorageConnection methods
124 
125 NS_IMETHODIMP
Clone(bool aReadOnly,mozIStorageConnection ** aConnectionOut)126 Connection::Clone(bool aReadOnly, mozIStorageConnection** aConnectionOut) {
127   nsCOMPtr<mozIStorageConnection> conn;
128   nsresult rv = mBase->Clone(aReadOnly, getter_AddRefs(conn));
129   if (NS_WARN_IF(NS_FAILED(rv))) {
130     return rv;
131   }
132 
133   nsCOMPtr<mozIStorageConnection> wrapped = new Connection(conn);
134   wrapped.forget(aConnectionOut);
135 
136   return rv;
137 }
138 
139 NS_IMETHODIMP
Interrupt()140 Connection::Interrupt() { return mBase->Interrupt(); }
141 
142 NS_IMETHODIMP
GetDefaultPageSize(int32_t * aSizeOut)143 Connection::GetDefaultPageSize(int32_t* aSizeOut) {
144   return mBase->GetDefaultPageSize(aSizeOut);
145 }
146 
147 NS_IMETHODIMP
GetConnectionReady(bool * aReadyOut)148 Connection::GetConnectionReady(bool* aReadyOut) {
149   return mBase->GetConnectionReady(aReadyOut);
150 }
151 
152 NS_IMETHODIMP
GetLastInsertRowID(int64_t * aRowIdOut)153 Connection::GetLastInsertRowID(int64_t* aRowIdOut) {
154   return mBase->GetLastInsertRowID(aRowIdOut);
155 }
156 
157 NS_IMETHODIMP
GetAffectedRows(int32_t * aCountOut)158 Connection::GetAffectedRows(int32_t* aCountOut) {
159   return mBase->GetAffectedRows(aCountOut);
160 }
161 
162 NS_IMETHODIMP
GetLastError(int32_t * aErrorOut)163 Connection::GetLastError(int32_t* aErrorOut) {
164   return mBase->GetLastError(aErrorOut);
165 }
166 
167 NS_IMETHODIMP
GetLastErrorString(nsACString & aErrorOut)168 Connection::GetLastErrorString(nsACString& aErrorOut) {
169   return mBase->GetLastErrorString(aErrorOut);
170 }
171 
172 NS_IMETHODIMP
GetSchemaVersion(int32_t * aVersionOut)173 Connection::GetSchemaVersion(int32_t* aVersionOut) {
174   return mBase->GetSchemaVersion(aVersionOut);
175 }
176 
177 NS_IMETHODIMP
SetSchemaVersion(int32_t aVersion)178 Connection::SetSchemaVersion(int32_t aVersion) {
179   return mBase->SetSchemaVersion(aVersion);
180 }
181 
182 NS_IMETHODIMP
CreateStatement(const nsACString & aQuery,mozIStorageStatement ** aStatementOut)183 Connection::CreateStatement(const nsACString& aQuery,
184                             mozIStorageStatement** aStatementOut) {
185   return mBase->CreateStatement(aQuery, aStatementOut);
186 }
187 
188 NS_IMETHODIMP
ExecuteSimpleSQL(const nsACString & aQuery)189 Connection::ExecuteSimpleSQL(const nsACString& aQuery) {
190   return mBase->ExecuteSimpleSQL(aQuery);
191 }
192 
193 NS_IMETHODIMP
TableExists(const nsACString & aTableName,bool * aExistsOut)194 Connection::TableExists(const nsACString& aTableName, bool* aExistsOut) {
195   return mBase->TableExists(aTableName, aExistsOut);
196 }
197 
198 NS_IMETHODIMP
IndexExists(const nsACString & aIndexName,bool * aExistsOut)199 Connection::IndexExists(const nsACString& aIndexName, bool* aExistsOut) {
200   return mBase->IndexExists(aIndexName, aExistsOut);
201 }
202 
203 NS_IMETHODIMP
GetTransactionInProgress(bool * aResultOut)204 Connection::GetTransactionInProgress(bool* aResultOut) {
205   return mBase->GetTransactionInProgress(aResultOut);
206 }
207 
208 NS_IMETHODIMP
GetDefaultTransactionType(int32_t * aResultOut)209 Connection::GetDefaultTransactionType(int32_t* aResultOut) {
210   return mBase->GetDefaultTransactionType(aResultOut);
211 }
212 
213 NS_IMETHODIMP
SetDefaultTransactionType(int32_t aType)214 Connection::SetDefaultTransactionType(int32_t aType) {
215   return mBase->SetDefaultTransactionType(aType);
216 }
217 
218 NS_IMETHODIMP
GetVariableLimit(int32_t * aResultOut)219 Connection::GetVariableLimit(int32_t* aResultOut) {
220   return mBase->GetVariableLimit(aResultOut);
221 }
222 
223 NS_IMETHODIMP
BeginTransaction()224 Connection::BeginTransaction() { return mBase->BeginTransaction(); }
225 
226 NS_IMETHODIMP
CommitTransaction()227 Connection::CommitTransaction() { return mBase->CommitTransaction(); }
228 
229 NS_IMETHODIMP
RollbackTransaction()230 Connection::RollbackTransaction() { return mBase->RollbackTransaction(); }
231 
232 NS_IMETHODIMP
CreateTable(const char * aTable,const char * aSchema)233 Connection::CreateTable(const char* aTable, const char* aSchema) {
234   return mBase->CreateTable(aTable, aSchema);
235 }
236 
237 NS_IMETHODIMP
SetGrowthIncrement(int32_t aIncrement,const nsACString & aDatabase)238 Connection::SetGrowthIncrement(int32_t aIncrement,
239                                const nsACString& aDatabase) {
240   return mBase->SetGrowthIncrement(aIncrement, aDatabase);
241 }
242 
243 NS_IMETHODIMP
EnableModule(const nsACString & aModule)244 Connection::EnableModule(const nsACString& aModule) {
245   return mBase->EnableModule(aModule);
246 }
247 
248 NS_IMETHODIMP
GetQuotaObjects(QuotaObject ** aDatabaseQuotaObject,QuotaObject ** aJournalQuotaObject)249 Connection::GetQuotaObjects(QuotaObject** aDatabaseQuotaObject,
250                             QuotaObject** aJournalQuotaObject) {
251   return mBase->GetQuotaObjects(aDatabaseQuotaObject, aJournalQuotaObject);
252 }
253 
GetSharedDBMutex()254 mozilla::storage::SQLiteMutex& Connection::GetSharedDBMutex() {
255   return mBase->GetSharedDBMutex();
256 }
257 
GetTransactionNestingLevel(const mozilla::storage::SQLiteMutexAutoLock & aProofOfLock)258 uint32_t Connection::GetTransactionNestingLevel(
259     const mozilla::storage::SQLiteMutexAutoLock& aProofOfLock) {
260   return mBase->GetTransactionNestingLevel(aProofOfLock);
261 }
262 
IncreaseTransactionNestingLevel(const mozilla::storage::SQLiteMutexAutoLock & aProofOfLock)263 uint32_t Connection::IncreaseTransactionNestingLevel(
264     const mozilla::storage::SQLiteMutexAutoLock& aProofOfLock) {
265   return mBase->IncreaseTransactionNestingLevel(aProofOfLock);
266 }
267 
DecreaseTransactionNestingLevel(const mozilla::storage::SQLiteMutexAutoLock & aProofOfLock)268 uint32_t Connection::DecreaseTransactionNestingLevel(
269     const mozilla::storage::SQLiteMutexAutoLock& aProofOfLock) {
270   return mBase->DecreaseTransactionNestingLevel(aProofOfLock);
271 }
272 
273 }  // namespace mozilla::dom::cache
274