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
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"
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
{
39 NS_DECL_THREADSAFE_ISUPPORTS
41 NS_DECL_MOZISTORAGEPENDINGSTATEMENT
44 * Describes the state of execution.
48 COMPLETED
= mozIStorageStatementCallback::REASON_FINISHED
,
49 CANCELED
= mozIStorageStatementCallback::REASON_CANCELED
,
50 ERROR
= mozIStorageStatementCallback::REASON_ERROR
53 typedef nsTArray
<StatementData
> StatementDataArray
;
56 * Executes a statement in the background, and passes results back to the
60 * The statements to execute and possibly bind in the background.
61 * Ownership is transfered from the caller.
63 * The connection that created the statements to execute.
64 * @param aNativeConnection
65 * The native Sqlite connection that created the statements to execute.
67 * The callback that is notified of results, completion, and errors.
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
);
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
81 * @pre mMutex is not held
83 * @returns true if the event should notify still, false otherwise.
88 * Used by notifyComplete(), notifyError() and notifyResults() to notify on
91 nsresult
notifyCompleteOnCallingThread();
92 nsresult
notifyErrorOnCallingThread(mozIStorageError
* aError
);
93 nsresult
notifyResultsOnCallingThread(ResultSet
* aResultSet
);
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
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
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
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
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
170 * The error code defined in mozIStorageError for the error.
172 * The error string, if any.
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
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).
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.
248 TimeStamp mRequestStartDate
;
251 } // namespace mozilla::storage
253 #endif // mozStorageAsyncStatementExecution_h