1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/storage/src/mozStorageAsyncStatementExecution.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,242 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozStorageAsyncStatementExecution_h 1.11 +#define mozStorageAsyncStatementExecution_h 1.12 + 1.13 +#include "nscore.h" 1.14 +#include "nsTArray.h" 1.15 +#include "nsAutoPtr.h" 1.16 +#include "mozilla/Mutex.h" 1.17 +#include "mozilla/TimeStamp.h" 1.18 +#include "mozilla/Attributes.h" 1.19 +#include "nsIRunnable.h" 1.20 + 1.21 +#include "SQLiteMutex.h" 1.22 +#include "mozIStoragePendingStatement.h" 1.23 +#include "mozIStorageStatementCallback.h" 1.24 +#include "mozStorageHelper.h" 1.25 + 1.26 +struct sqlite3_stmt; 1.27 + 1.28 +namespace mozilla { 1.29 +namespace storage { 1.30 + 1.31 +class Connection; 1.32 +class ResultSet; 1.33 +class StatementData; 1.34 + 1.35 +class AsyncExecuteStatements MOZ_FINAL : public nsIRunnable 1.36 + , public mozIStoragePendingStatement 1.37 +{ 1.38 +public: 1.39 + NS_DECL_THREADSAFE_ISUPPORTS 1.40 + NS_DECL_NSIRUNNABLE 1.41 + NS_DECL_MOZISTORAGEPENDINGSTATEMENT 1.42 + 1.43 + /** 1.44 + * Describes the state of execution. 1.45 + */ 1.46 + enum ExecutionState { 1.47 + PENDING = -1, 1.48 + COMPLETED = mozIStorageStatementCallback::REASON_FINISHED, 1.49 + CANCELED = mozIStorageStatementCallback::REASON_CANCELED, 1.50 + ERROR = mozIStorageStatementCallback::REASON_ERROR 1.51 + }; 1.52 + 1.53 + typedef nsTArray<StatementData> StatementDataArray; 1.54 + 1.55 + /** 1.56 + * Executes a statement in the background, and passes results back to the 1.57 + * caller. 1.58 + * 1.59 + * @param aStatements 1.60 + * The statements to execute and possibly bind in the background. 1.61 + * Ownership is transfered from the caller. 1.62 + * @param aConnection 1.63 + * The connection that created the statements to execute. 1.64 + * @param aNativeConnection 1.65 + * The native Sqlite connection that created the statements to execute. 1.66 + * @param aCallback 1.67 + * The callback that is notified of results, completion, and errors. 1.68 + * @param _stmt 1.69 + * The handle to control the execution of the statements. 1.70 + */ 1.71 + static nsresult execute(StatementDataArray &aStatements, 1.72 + Connection *aConnection, 1.73 + sqlite3 *aNativeConnection, 1.74 + mozIStorageStatementCallback *aCallback, 1.75 + mozIStoragePendingStatement **_stmt); 1.76 + 1.77 + /** 1.78 + * Indicates when events on the calling thread should run or not. Certain 1.79 + * events posted back to the calling thread should call this see if they 1.80 + * should run or not. 1.81 + * 1.82 + * @pre mMutex is not held 1.83 + * 1.84 + * @returns true if the event should notify still, false otherwise. 1.85 + */ 1.86 + bool shouldNotify(); 1.87 + 1.88 +private: 1.89 + AsyncExecuteStatements(StatementDataArray &aStatements, 1.90 + Connection *aConnection, 1.91 + sqlite3 *aNativeConnection, 1.92 + mozIStorageStatementCallback *aCallback); 1.93 + ~AsyncExecuteStatements(); 1.94 + 1.95 + /** 1.96 + * Binds and then executes a given statement until completion, an error 1.97 + * occurs, or we are canceled. If aLastStatement is true, we should set 1.98 + * mState accordingly. 1.99 + * 1.100 + * @pre mMutex is not held 1.101 + * 1.102 + * @param aData 1.103 + * The StatementData to bind, execute, and then process. 1.104 + * @param aLastStatement 1.105 + * Indicates if this is the last statement or not. If it is, we have 1.106 + * to set the proper state. 1.107 + * @returns true if we should continue to process statements, false otherwise. 1.108 + */ 1.109 + bool bindExecuteAndProcessStatement(StatementData &aData, 1.110 + bool aLastStatement); 1.111 + 1.112 + /** 1.113 + * Executes a given statement until completion, an error occurs, or we are 1.114 + * canceled. If aLastStatement is true, we should set mState accordingly. 1.115 + * 1.116 + * @pre mMutex is not held 1.117 + * 1.118 + * @param aStatement 1.119 + * The statement to execute and then process. 1.120 + * @param aLastStatement 1.121 + * Indicates if this is the last statement or not. If it is, we have 1.122 + * to set the proper state. 1.123 + * @returns true if we should continue to process statements, false otherwise. 1.124 + */ 1.125 + bool executeAndProcessStatement(sqlite3_stmt *aStatement, 1.126 + bool aLastStatement); 1.127 + 1.128 + /** 1.129 + * Executes a statement to completion, properly handling any error conditions. 1.130 + * 1.131 + * @pre mMutex is not held 1.132 + * 1.133 + * @param aStatement 1.134 + * The statement to execute to completion. 1.135 + * @returns true if results were obtained, false otherwise. 1.136 + */ 1.137 + bool executeStatement(sqlite3_stmt *aStatement); 1.138 + 1.139 + /** 1.140 + * Builds a result set up with a row from a given statement. If we meet the 1.141 + * right criteria, go ahead and notify about this results too. 1.142 + * 1.143 + * @pre mMutex is not held 1.144 + * 1.145 + * @param aStatement 1.146 + * The statement to get the row data from. 1.147 + */ 1.148 + nsresult buildAndNotifyResults(sqlite3_stmt *aStatement); 1.149 + 1.150 + /** 1.151 + * Notifies callback about completion, and does any necessary cleanup. 1.152 + * 1.153 + * @pre mMutex is not held 1.154 + */ 1.155 + nsresult notifyComplete(); 1.156 + 1.157 + /** 1.158 + * Notifies callback about an error. 1.159 + * 1.160 + * @pre mMutex is not held 1.161 + * @pre mDBMutex is not held 1.162 + * 1.163 + * @param aErrorCode 1.164 + * The error code defined in mozIStorageError for the error. 1.165 + * @param aMessage 1.166 + * The error string, if any. 1.167 + * @param aError 1.168 + * The error object to notify the caller with. 1.169 + */ 1.170 + nsresult notifyError(int32_t aErrorCode, const char *aMessage); 1.171 + nsresult notifyError(mozIStorageError *aError); 1.172 + 1.173 + /** 1.174 + * Notifies the callback about a result set. 1.175 + * 1.176 + * @pre mMutex is not held 1.177 + */ 1.178 + nsresult notifyResults(); 1.179 + 1.180 + /** 1.181 + * Tests whether the current statements should be wrapped in an explicit 1.182 + * transaction. 1.183 + * 1.184 + * @return true if an explicit transaction is needed, false otherwise. 1.185 + */ 1.186 + bool statementsNeedTransaction(); 1.187 + 1.188 + StatementDataArray mStatements; 1.189 + nsRefPtr<Connection> mConnection; 1.190 + sqlite3 *mNativeConnection; 1.191 + bool mHasTransaction; 1.192 + mozIStorageStatementCallback *mCallback; 1.193 + nsCOMPtr<nsIThread> mCallingThread; 1.194 + nsRefPtr<ResultSet> mResultSet; 1.195 + 1.196 + /** 1.197 + * The maximum amount of time we want to wait between results. Defined by 1.198 + * MAX_MILLISECONDS_BETWEEN_RESULTS and set at construction. 1.199 + */ 1.200 + const TimeDuration mMaxWait; 1.201 + 1.202 + /** 1.203 + * The start time since our last set of results. 1.204 + */ 1.205 + TimeStamp mIntervalStart; 1.206 + 1.207 + /** 1.208 + * Indicates our state of execution. 1.209 + */ 1.210 + ExecutionState mState; 1.211 + 1.212 + /** 1.213 + * Indicates if we should try to cancel at a cancelation point. 1.214 + */ 1.215 + bool mCancelRequested; 1.216 + 1.217 + /** 1.218 + * This is the mutex that protects our state from changing between threads. 1.219 + * This includes the following variables: 1.220 + * - mCancelRequested is only set on the calling thread while the lock is 1.221 + * held. It is always read from within the lock on the background thread, 1.222 + * but not on the calling thread (see shouldNotify for why). 1.223 + */ 1.224 + Mutex &mMutex; 1.225 + 1.226 + /** 1.227 + * The wrapped SQLite recursive connection mutex. We use it whenever we call 1.228 + * sqlite3_step and care about having reliable error messages. By taking it 1.229 + * prior to the call and holding it until the point where we no longer care 1.230 + * about the error message, the user gets reliable error messages. 1.231 + */ 1.232 + SQLiteMutex &mDBMutex; 1.233 + 1.234 + /** 1.235 + * The instant at which the request was started. 1.236 + * 1.237 + * Used by telemetry. 1.238 + */ 1.239 + TimeStamp mRequestStartDate; 1.240 +}; 1.241 + 1.242 +} // namespace storage 1.243 +} // namespace mozilla 1.244 + 1.245 +#endif // mozStorageAsyncStatementExecution_h