Backed out changeset ee5e8cc2e91d (bug 1874789) as requested, for causing audio issue...
[gecko.git] / storage / mozStorageAsyncStatementExecution.h
bloba7f35dcfbe8967f04db911a84c6899d19f634215
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 "nsThreadUtils.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 namespace mozilla::storage {
34 class AsyncExecuteStatements final : public Runnable,
35 public mozIStoragePendingStatement {
36 public:
37 NS_DECL_ISUPPORTS_INHERITED
38 NS_DECL_NSIRUNNABLE
39 NS_DECL_MOZISTORAGEPENDINGSTATEMENT
41 /**
42 * Describes the state of execution.
44 enum ExecutionState {
45 PENDING = -1,
46 COMPLETED = mozIStorageStatementCallback::REASON_FINISHED,
47 CANCELED = mozIStorageStatementCallback::REASON_CANCELED,
48 ERROR = mozIStorageStatementCallback::REASON_ERROR
51 typedef nsTArray<StatementData> StatementDataArray;
53 /**
54 * Executes a statement in the background, and passes results back to the
55 * caller.
57 * @param aStatements
58 * The statements to execute and possibly bind in the background.
59 * Ownership is transfered from the caller.
60 * @param aConnection
61 * The connection that created the statements to execute.
62 * @param aNativeConnection
63 * The native Sqlite connection that created the statements to execute.
64 * @param aCallback
65 * The callback that is notified of results, completion, and errors.
66 * @param _stmt
67 * The handle to control the execution of the statements.
69 static nsresult execute(StatementDataArray&& aStatements,
70 Connection* aConnection, sqlite3* aNativeConnection,
71 mozIStorageStatementCallback* aCallback,
72 mozIStoragePendingStatement** _stmt);
74 /**
75 * Indicates when events on the calling thread should run or not. Certain
76 * events posted back to the calling thread should call this see if they
77 * should run or not.
79 * @pre mMutex is not held
81 * @returns true if the event should notify still, false otherwise.
83 bool shouldNotify();
85 /**
86 * Used by notifyComplete(), notifyError() and notifyResults() to notify on
87 * the calling thread.
89 nsresult notifyCompleteOnCallingThread();
90 nsresult notifyErrorOnCallingThread(mozIStorageError* aError);
91 nsresult notifyResultsOnCallingThread(ResultSet* aResultSet);
93 private:
94 AsyncExecuteStatements(StatementDataArray&& aStatements,
95 Connection* aConnection, sqlite3* aNativeConnection,
96 mozIStorageStatementCallback* aCallback);
97 ~AsyncExecuteStatements();
99 /**
100 * Binds and then executes a given statement until completion, an error
101 * occurs, or we are canceled. If aLastStatement is true, we should set
102 * mState accordingly.
104 * @pre mMutex is not held
106 * @param aData
107 * The StatementData to bind, execute, and then process.
108 * @param aLastStatement
109 * Indicates if this is the last statement or not. If it is, we have
110 * to set the proper state.
111 * @returns true if we should continue to process statements, false otherwise.
113 bool bindExecuteAndProcessStatement(StatementData& aData,
114 bool aLastStatement);
117 * Executes a given statement until completion, an error occurs, or we are
118 * canceled. If aLastStatement is true, we should set mState accordingly.
120 * @pre mMutex is not held
122 * @param aData
123 * The StatementData to execute, and then process.
124 * @param aLastStatement
125 * Indicates if this is the last statement or not. If it is, we have
126 * to set the proper state.
127 * @returns true if we should continue to process statements, false otherwise.
129 bool executeAndProcessStatement(StatementData& aData, bool aLastStatement);
132 * Executes a statement to completion, properly handling any error conditions.
134 * @pre mMutex is not held
136 * @param aData
137 * The StatementData to execute to completion.
138 * @returns true if results were obtained, false otherwise.
140 bool executeStatement(StatementData& aData);
143 * Builds a result set up with a row from a given statement. If we meet the
144 * right criteria, go ahead and notify about this results too.
146 * @pre mMutex is not held
148 * @param aStatement
149 * The statement to get the row data from.
151 nsresult buildAndNotifyResults(sqlite3_stmt* aStatement);
154 * Notifies callback about completion, and does any necessary cleanup.
156 * @pre mMutex is not held
158 nsresult notifyComplete();
161 * Notifies callback about an error.
163 * @pre mMutex is not held
164 * @pre mDBMutex is not held
166 * @param aErrorCode
167 * The error code defined in mozIStorageError for the error.
168 * @param aMessage
169 * The error string, if any.
170 * @param aError
171 * The error object to notify the caller with.
173 nsresult notifyError(int32_t aErrorCode, const char* aMessage);
174 nsresult notifyError(mozIStorageError* aError);
177 * Notifies the callback about a result set.
179 * @pre mMutex is not held
181 nsresult notifyResults();
184 * Tests whether the current statements should be wrapped in an explicit
185 * transaction.
187 * @return true if an explicit transaction is needed, false otherwise.
189 bool statementsNeedTransaction();
191 StatementDataArray mStatements;
192 RefPtr<Connection> mConnection;
193 sqlite3* mNativeConnection;
194 bool mHasTransaction;
195 // Note, this may not be a threadsafe object - never addref/release off
196 // the calling thread. We take a reference when this is created, and
197 // release it in the CompletionNotifier::Run() call back to this thread.
198 nsCOMPtr<mozIStorageStatementCallback> mCallback;
199 nsCOMPtr<nsIThread> mCallingThread;
200 RefPtr<ResultSet> mResultSet;
203 * The maximum amount of time we want to wait between results. Defined by
204 * MAX_MILLISECONDS_BETWEEN_RESULTS and set at construction.
206 const TimeDuration mMaxWait;
209 * The start time since our last set of results.
211 TimeStamp mIntervalStart;
214 * Indicates our state of execution.
216 ExecutionState mState;
219 * Indicates if we should try to cancel at a cancelation point.
221 bool mCancelRequested;
224 * This is the mutex that protects our state from changing between threads.
225 * This includes the following variables:
226 * - mCancelRequested is only set on the calling thread while the lock is
227 * held. It is always read from within the lock on the background thread,
228 * but not on the calling thread (see shouldNotify for why).
230 Mutex& mMutex;
233 * The wrapped SQLite recursive connection mutex. We use it whenever we call
234 * sqlite3_step and care about having reliable error messages. By taking it
235 * prior to the call and holding it until the point where we no longer care
236 * about the error message, the user gets reliable error messages.
238 SQLiteMutex& mDBMutex;
241 } // namespace mozilla::storage
243 #endif // mozStorageAsyncStatementExecution_h