Bug 1632310 [wpt PR 23186] - Add test for computed versus resolved style., a=testonly
[gecko.git] / storage / mozStorageAsyncStatementExecution.h
blob60f0d0f7ad527768c4ec832fa838cfb2a33b4920
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 mozStorageAsyncStatementExecution_h
8 #define mozStorageAsyncStatementExecution_h
10 #include "nscore.h"
11 #include "nsTArray.h"
12 #include "mozilla/Mutex.h"
13 #include "mozilla/TimeStamp.h"
14 #include "mozilla/Attributes.h"
15 #include "nsIRunnable.h"
17 #include "SQLiteMutex.h"
18 #include "mozIStoragePendingStatement.h"
19 #include "mozIStorageStatementCallback.h"
20 #include "mozStorageHelper.h"
22 struct sqlite3_stmt;
24 namespace mozilla {
25 namespace storage {
27 class Connection;
28 class ResultSet;
29 class StatementData;
30 } // namespace storage
31 } // namespace mozilla
33 MOZ_DECLARE_COPY_CONSTRUCTIBLE(mozilla::storage::StatementData)
35 namespace mozilla::storage {
36 class AsyncExecuteStatements final : public nsIRunnable,
37 public mozIStoragePendingStatement {
38 public:
39 NS_DECL_THREADSAFE_ISUPPORTS
40 NS_DECL_NSIRUNNABLE
41 NS_DECL_MOZISTORAGEPENDINGSTATEMENT
43 /**
44 * Describes the state of execution.
46 enum ExecutionState {
47 PENDING = -1,
48 COMPLETED = mozIStorageStatementCallback::REASON_FINISHED,
49 CANCELED = mozIStorageStatementCallback::REASON_CANCELED,
50 ERROR = mozIStorageStatementCallback::REASON_ERROR
53 typedef nsTArray<StatementData> StatementDataArray;
55 /**
56 * Executes a statement in the background, and passes results back to the
57 * caller.
59 * @param aStatements
60 * The statements to execute and possibly bind in the background.
61 * Ownership is transfered from the caller.
62 * @param aConnection
63 * The connection that created the statements to execute.
64 * @param aNativeConnection
65 * The native Sqlite connection that created the statements to execute.
66 * @param aCallback
67 * The callback that is notified of results, completion, and errors.
68 * @param _stmt
69 * The handle to control the execution of the statements.
71 static nsresult execute(StatementDataArray& aStatements,
72 Connection* aConnection, sqlite3* aNativeConnection,
73 mozIStorageStatementCallback* aCallback,
74 mozIStoragePendingStatement** _stmt);
76 /**
77 * Indicates when events on the calling thread should run or not. Certain
78 * events posted back to the calling thread should call this see if they
79 * should run or not.
81 * @pre mMutex is not held
83 * @returns true if the event should notify still, false otherwise.
85 bool shouldNotify();
87 /**
88 * Used by notifyComplete(), notifyError() and notifyResults() to notify on
89 * the calling thread.
91 nsresult notifyCompleteOnCallingThread();
92 nsresult notifyErrorOnCallingThread(mozIStorageError* aError);
93 nsresult notifyResultsOnCallingThread(ResultSet* aResultSet);
95 private:
96 AsyncExecuteStatements(StatementDataArray& aStatements,
97 Connection* aConnection, sqlite3* aNativeConnection,
98 mozIStorageStatementCallback* aCallback);
99 ~AsyncExecuteStatements();
102 * Binds and then executes a given statement until completion, an error
103 * occurs, or we are canceled. If aLastStatement is true, we should set
104 * mState accordingly.
106 * @pre mMutex is not held
108 * @param aData
109 * The StatementData to bind, execute, and then process.
110 * @param aLastStatement
111 * Indicates if this is the last statement or not. If it is, we have
112 * to set the proper state.
113 * @returns true if we should continue to process statements, false otherwise.
115 bool bindExecuteAndProcessStatement(StatementData& aData,
116 bool aLastStatement);
119 * Executes a given statement until completion, an error occurs, or we are
120 * canceled. If aLastStatement is true, we should set mState accordingly.
122 * @pre mMutex is not held
124 * @param aStatement
125 * The statement to execute and then process.
126 * @param aLastStatement
127 * Indicates if this is the last statement or not. If it is, we have
128 * to set the proper state.
129 * @returns true if we should continue to process statements, false otherwise.
131 bool executeAndProcessStatement(sqlite3_stmt* aStatement,
132 bool aLastStatement);
135 * Executes a statement to completion, properly handling any error conditions.
137 * @pre mMutex is not held
139 * @param aStatement
140 * The statement to execute to completion.
141 * @returns true if results were obtained, false otherwise.
143 bool executeStatement(sqlite3_stmt* aStatement);
146 * Builds a result set up with a row from a given statement. If we meet the
147 * right criteria, go ahead and notify about this results too.
149 * @pre mMutex is not held
151 * @param aStatement
152 * The statement to get the row data from.
154 nsresult buildAndNotifyResults(sqlite3_stmt* aStatement);
157 * Notifies callback about completion, and does any necessary cleanup.
159 * @pre mMutex is not held
161 nsresult notifyComplete();
164 * Notifies callback about an error.
166 * @pre mMutex is not held
167 * @pre mDBMutex is not held
169 * @param aErrorCode
170 * The error code defined in mozIStorageError for the error.
171 * @param aMessage
172 * The error string, if any.
173 * @param aError
174 * The error object to notify the caller with.
176 nsresult notifyError(int32_t aErrorCode, const char* aMessage);
177 nsresult notifyError(mozIStorageError* aError);
180 * Notifies the callback about a result set.
182 * @pre mMutex is not held
184 nsresult notifyResults();
187 * Tests whether the current statements should be wrapped in an explicit
188 * transaction.
190 * @return true if an explicit transaction is needed, false otherwise.
192 bool statementsNeedTransaction();
194 StatementDataArray mStatements;
195 RefPtr<Connection> mConnection;
196 sqlite3* mNativeConnection;
197 bool mHasTransaction;
198 // Note, this may not be a threadsafe object - never addref/release off
199 // the calling thread. We take a reference when this is created, and
200 // release it in the CompletionNotifier::Run() call back to this thread.
201 nsCOMPtr<mozIStorageStatementCallback> mCallback;
202 nsCOMPtr<nsIThread> mCallingThread;
203 RefPtr<ResultSet> mResultSet;
206 * The maximum amount of time we want to wait between results. Defined by
207 * MAX_MILLISECONDS_BETWEEN_RESULTS and set at construction.
209 const TimeDuration mMaxWait;
212 * The start time since our last set of results.
214 TimeStamp mIntervalStart;
217 * Indicates our state of execution.
219 ExecutionState mState;
222 * Indicates if we should try to cancel at a cancelation point.
224 bool mCancelRequested;
227 * This is the mutex that protects our state from changing between threads.
228 * This includes the following variables:
229 * - mCancelRequested is only set on the calling thread while the lock is
230 * held. It is always read from within the lock on the background thread,
231 * but not on the calling thread (see shouldNotify for why).
233 Mutex& mMutex;
236 * The wrapped SQLite recursive connection mutex. We use it whenever we call
237 * sqlite3_step and care about having reliable error messages. By taking it
238 * prior to the call and holding it until the point where we no longer care
239 * about the error message, the user gets reliable error messages.
241 SQLiteMutex& mDBMutex;
244 * The instant at which the request was started.
246 * Used by telemetry.
248 TimeStamp mRequestStartDate;
251 } // namespace mozilla::storage
253 #endif // mozStorageAsyncStatementExecution_h