Changeset 142921 in webkit
- Timestamp:
- Feb 14, 2013 2:31:20 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 added
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r142809 r142921 964 964 Modules/webdatabase/SQLTransactionClient.cpp 965 965 Modules/webdatabase/SQLTransactionCoordinator.cpp 966 Modules/webdatabase/SQLTransactionStateMachine.cpp 966 967 Modules/webdatabase/SQLTransactionSync.cpp 967 968 -
trunk/Source/WebCore/ChangeLog
r142918 r142921 1 2013-02-14 Mark Lam <mark.lam@apple.com> 2 3 Split SQLTransaction work between the frontend and backend. 4 https://bugs.webkit.org/show_bug.cgi?id=104750. 5 6 Reviewed by Sam Weinig. 7 8 This is part of the webdatabase refactoring for webkit2. 9 10 1. Changed how transactions are created. 11 12 - Database::runTransaction() first creates a SQLTransaction frontend 13 which encapsulates the 3 script callbacks. It then passes the 14 SQLTransaction to the backend database to create the 15 SQLTransactionBackend. 16 - The SQLTransactionBackend manages all SQLiteTransaction work. 17 18 2. Introduced SQLTransactionState and SQLTransactionStateMachine. 19 20 - Instead of tracking the transaction phases as "steps" in m_nextStep, 21 we now use m_nextState which is of enum class SQLTransactionState. 22 Unlike m_nextStep which is a pointer to a "step" function, 23 m_nextState is a state variable which is used to index into a 24 state dispatch table. 25 26 - Both SQLTransaction and SQLTransactionBackend now extends 27 SQLTransactionStateMachine, and uses its dispatch mechanism based on 28 the SQLTransactionState. 29 30 - Instead of having 1 state machine instances, there are 2: 1 in the 31 frontend, and 1 in the backend. The 2 have mirrored states, and 32 transfers work to the other state machine when needed. 33 34 - Previously, state functions can be called inline from other states. 35 They are now only called from the state machines runStateMachine() 36 method. This makes it possible to isolate the state transition 37 mechanism going between the sides (frontend and backend) to 2 38 functions only: SQLTransaction::sendToBackendState() and 39 SQLTransactionBackend::sendToFrontendState(). 40 41 3. Consolidated cleanup work (mostly) to a unified cleanup function. 42 43 4. Changed the frontend Database::runTransaction() to use a 44 ChangeVersionData* (instead of a ChangeVersionWrapper ref ptr). 45 46 - This is necessary because ChangeVersionWrapper contains functionality 47 used in processing a transaction (to be invoked in the backend). 48 Instead, what we want is to simply pass the 2 old and new version 49 strings to the backend. The new ChangeVersionData simply packages up 50 these 2 strings. 51 - This makes ChangeVersionData easy to serialize for IPC messaging later. 52 53 5. Moved some transaction functions back to the frontend SQLTransaction 54 because they belong there. 55 56 6. Moved some Database functions to its DatabaseBackendAsync backend 57 now that the transaction has been split up. 58 59 - This is driven naturally by those functions being used exclusively 60 in the backend for transaction work. 61 - SQLTransactionClient, SQLTransactionCoordinator, and 62 SQLTransactionWrapper are now exclusively backend data structures. 63 SQLTransactionClient still has some frontend "pollution" that I'll 64 fix later. 65 66 7. Made the few database report functions used only by Chromium conditional 67 on PLATFORM(chromium). 68 69 - The report functions gets re-routed to Chromium's DatabaseObserver 70 which further routes them elsewhere. It is unclear how Chromium uses 71 these routed messages, and I am therefore not able to determine how 72 they should work in a frontend/backend world. So, I'm #ifdef'ing 73 them out. They still work like in the old way for Chromium. 74 75 8. Added new files to the build / project files. 76 77 9. Updated / added comments about how the transaction and its states work. 78 79 No new tests. 80 81 * CMakeLists.txt: 82 * GNUmakefile.list.am: 83 * Modules/webdatabase/AbstractDatabaseServer.h: 84 * Modules/webdatabase/ChangeVersionData.h: Added. 85 (ChangeVersionData): 86 (WebCore::ChangeVersionData::ChangeVersionData): 87 (WebCore::ChangeVersionData::oldVersion): 88 (WebCore::ChangeVersionData::newVersion): 89 * Modules/webdatabase/ChangeVersionWrapper.cpp: 90 (WebCore::ChangeVersionWrapper::performPreflight): 91 (WebCore::ChangeVersionWrapper::performPostflight): 92 (WebCore::ChangeVersionWrapper::handleCommitFailedAfterPostflight): 93 * Modules/webdatabase/ChangeVersionWrapper.h: 94 (ChangeVersionWrapper): 95 * Modules/webdatabase/Database.cpp: 96 (WebCore::Database::Database): 97 (WebCore::Database::close): 98 (WebCore::Database::changeVersion): 99 (WebCore::Database::transaction): 100 (WebCore::Database::readTransaction): 101 (WebCore::Database::runTransaction): 102 (WebCore::Database::reportStartTransactionResult): 103 (WebCore::Database::reportCommitTransactionResult): 104 (WebCore::Database::reportExecuteStatementResult): 105 * Modules/webdatabase/Database.h: 106 (WebCore::Database::databaseContext): 107 (Database): 108 (WebCore::Database::reportStartTransactionResult): 109 (WebCore::Database::reportCommitTransactionResult): 110 (WebCore::Database::reportExecuteStatementResult): 111 * Modules/webdatabase/DatabaseBackend.cpp: 112 * Modules/webdatabase/DatabaseBackend.h: 113 (DatabaseBackend): 114 (WebCore::DatabaseBackend::reportOpenDatabaseResult): 115 (WebCore::DatabaseBackend::reportChangeVersionResult): 116 (WebCore::DatabaseBackend::reportStartTransactionResult): 117 (WebCore::DatabaseBackend::reportCommitTransactionResult): 118 (WebCore::DatabaseBackend::reportExecuteStatementResult): 119 (WebCore::DatabaseBackend::reportVacuumDatabaseResult): 120 * Modules/webdatabase/DatabaseBackendAsync.cpp: 121 (WebCore::DatabaseBackendAsync::DatabaseBackendAsync): 122 (WebCore::DatabaseBackendAsync::runTransaction): 123 (WebCore::DatabaseBackendAsync::inProgressTransactionCompleted): Moved from frontend. 124 (WebCore::DatabaseBackendAsync::scheduleTransaction): Moved from frontend. 125 (WebCore::DatabaseBackendAsync::scheduleTransactionStep): Moved from frontend. 126 (WebCore::DatabaseBackendAsync::transactionClient): Moved from frontend. 127 (WebCore::DatabaseBackendAsync::transactionCoordinator): Moved from frontend. 128 * Modules/webdatabase/DatabaseBackendAsync.h: 129 (DatabaseBackendAsync): 130 * Modules/webdatabase/DatabaseBackendContext.cpp: 131 (WebCore::DatabaseBackendContext::frontend): 132 * Modules/webdatabase/DatabaseBackendContext.h: 133 (DatabaseBackendContext): 134 * Modules/webdatabase/DatabaseManager.cpp: 135 * Modules/webdatabase/DatabaseManager.h: 136 (DatabaseManager): 137 * Modules/webdatabase/DatabaseServer.cpp: 138 * Modules/webdatabase/DatabaseServer.h: 139 * Modules/webdatabase/DatabaseTask.cpp: 140 (WebCore::DatabaseBackendAsync::DatabaseTransactionTask::doPerformTask): 141 * Modules/webdatabase/SQLTransaction.cpp: 142 (WebCore::SQLTransaction::create): 143 (WebCore::SQLTransaction::SQLTransaction): 144 (WebCore::SQLTransaction::setBackend): 145 (WebCore::SQLTransaction::stateFunctionFor): 146 (WebCore::SQLTransaction::requestTransitToState): 147 (WebCore::SQLTransaction::nextStateForTransactionError): 148 - was handleTransactionError(). There's also a backend version. 149 (WebCore::SQLTransaction::deliverTransactionCallback): Moved from backend. 150 (WebCore::SQLTransaction::deliverTransactionErrorCallback): Moved from backend. 151 (WebCore::SQLTransaction::deliverStatementCallback): Moved from backend. 152 (WebCore::SQLTransaction::deliverQuotaIncreaseCallback): Moved from backend. 153 (WebCore::SQLTransaction::deliverSuccessCallback): Moved from backend. 154 (WebCore::SQLTransaction::unreachableState): 155 (WebCore::SQLTransaction::sendToBackendState): 156 (WebCore::SQLTransaction::performPendingCallback): Moved from backend. 157 (WebCore::SQLTransaction::executeSQL): Moved from backend. 158 (WebCore::SQLTransaction::checkAndHandleClosedOrInterruptedDatabase): 159 (WebCore::SQLTransaction::clearCallbackWrappers): 160 * Modules/webdatabase/SQLTransaction.h: 161 (SQLTransaction): 162 (WebCore::SQLTransaction::database): 163 (WebCore::SQLTransaction::hasCallback): 164 (WebCore::SQLTransaction::hasSuccessCallback): 165 (WebCore::SQLTransaction::hasErrorCallback): 166 * Modules/webdatabase/SQLTransactionBackend.cpp: 167 (WebCore::SQLTransactionBackend::create): 168 (WebCore::SQLTransactionBackend::SQLTransactionBackend): 169 (WebCore::SQLTransactionBackend::doCleanup): 170 (WebCore::SQLTransactionBackend::transactionError): 171 (WebCore::SQLTransactionBackend::setShouldRetryCurrentStatement): 172 (WebCore::SQLTransactionBackend::stateFunctionFor): 173 (WebCore::SQLTransactionBackend::enqueueStatement): 174 (WebCore::SQLTransactionBackend::checkAndHandleClosedOrInterruptedDatabase): 175 (WebCore::SQLTransactionBackend::performNextStep): 176 (WebCore::SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown): 177 (WebCore::SQLTransactionBackend::acquireLock): 178 (WebCore::SQLTransactionBackend::lockAcquired): 179 (WebCore::SQLTransactionBackend::openTransactionAndPreflight): 180 (WebCore::SQLTransactionBackend::runStatements): 181 (WebCore::SQLTransactionBackend::runCurrentStatementAndGetNextState): 182 - was runCurrentStatement(). 183 (WebCore::SQLTransactionBackend::nextStateForCurrentStatementError): 184 - was handleCurrentStatementError(). 185 (WebCore::SQLTransactionBackend::postflightAndCommit): 186 (WebCore::SQLTransactionBackend::cleanupAndTerminate): 187 (WebCore::SQLTransactionBackend::nextStateForTransactionError): 188 - was handleTransactionError(). There's also a frontend version. 189 (WebCore::SQLTransactionBackend::cleanupAfterTransactionErrorCallback): 190 (WebCore::SQLTransactionBackend::requestTransitToState): 191 (WebCore::SQLTransactionBackend::unreachableState): 192 (WebCore::SQLTransactionBackend::sendToFrontendState): 193 * Modules/webdatabase/SQLTransactionBackend.h: 194 (SQLTransactionWrapper): 195 (SQLTransactionBackend): 196 (WebCore::SQLTransactionBackend::database): 197 * Modules/webdatabase/SQLTransactionClient.cpp: 198 (WebCore::SQLTransactionClient::didCommitWriteTransaction): 199 (WebCore::SQLTransactionClient::didExecuteStatement): 200 * Modules/webdatabase/SQLTransactionCoordinator.cpp: 201 (WebCore::getDatabaseIdentifier): 202 * Modules/webdatabase/SQLTransactionState.h: Added. 203 * Modules/webdatabase/SQLTransactionStateMachine.cpp: Added. 204 (WebCore::nameForSQLTransactionState): 205 - was debugStepName(). 206 * Modules/webdatabase/SQLTransactionStateMachine.h: Added. 207 (SQLTransactionStateMachine): 208 (WebCore::SQLTransactionStateMachine::~SQLTransactionStateMachine): 209 (WebCore::::SQLTransactionStateMachine): 210 (WebCore::::setStateToRequestedState): 211 (WebCore::::runStateMachine): 212 * Target.pri: 213 * WebCore.gypi: 214 * WebCore.vcproj/WebCore.vcproj: 215 * WebCore.vcxproj/WebCore.vcxproj: 216 * WebCore.vcxproj/WebCore.vcxproj.filters: 217 * WebCore.xcodeproj/project.pbxproj: 218 * inspector/InspectorDatabaseAgent.cpp: 219 1 220 2013-02-14 Jer Noble <jer.noble@apple.com> 2 221 -
trunk/Source/WebCore/GNUmakefile.list.am
r142823 r142921 2101 2101 Source/WebCore/Modules/webaudio/WaveTable.h \ 2102 2102 Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h \ 2103 Source/WebCore/Modules/webdatabase/ChangeVersionData.h \ 2103 2104 Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.cpp \ 2104 2105 Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.h \ … … 2169 2170 Source/WebCore/Modules/webdatabase/SQLTransactionErrorCallback.h \ 2170 2171 Source/WebCore/Modules/webdatabase/SQLTransactionSyncCallback.h \ 2172 Source/WebCore/Modules/webdatabase/SQLTransactionState.h \ 2173 Source/WebCore/Modules/webdatabase/SQLTransactionStateMachine.cpp \ 2174 Source/WebCore/Modules/webdatabase/SQLTransactionStateMachine.h \ 2171 2175 Source/WebCore/Modules/webdatabase/SQLTransactionSync.cpp \ 2172 2176 Source/WebCore/Modules/webdatabase/SQLTransactionSync.h \ -
trunk/Source/WebCore/Modules/webdatabase/AbstractDatabaseServer.h
r142030 r142921 75 75 virtual bool deleteDatabase(SecurityOrigin*, const String& name) = 0; 76 76 77 // From a secondary thread, must be thread safe with its data78 virtual void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name) = 0;79 virtual void databaseChanged(DatabaseBackend*) = 0;80 81 77 #else // PLATFORM(CHROMIUM) 82 78 virtual void closeDatabasesImmediately(const String& originIdentifier, const String& name) = 0; -
trunk/Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.cpp
r109877 r142921 1 1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 44 44 } 45 45 46 bool ChangeVersionWrapper::performPreflight(SQLTransaction * transaction)46 bool ChangeVersionWrapper::performPreflight(SQLTransactionBackend* transaction) 47 47 { 48 48 ASSERT(transaction && transaction->database()); 49 49 50 Database * database = transaction->database();50 DatabaseBackendAsync* database = transaction->database(); 51 51 52 52 String actualVersion; … … 68 68 } 69 69 70 bool ChangeVersionWrapper::performPostflight(SQLTransaction * transaction)70 bool ChangeVersionWrapper::performPostflight(SQLTransactionBackend* transaction) 71 71 { 72 72 ASSERT(transaction && transaction->database()); 73 73 74 Database * database = transaction->database();74 DatabaseBackendAsync* database = transaction->database(); 75 75 76 76 if (!database->setVersionInDatabase(m_newVersion)) { … … 88 88 } 89 89 90 void ChangeVersionWrapper::handleCommitFailedAfterPostflight(SQLTransaction * transaction)90 void ChangeVersionWrapper::handleCommitFailedAfterPostflight(SQLTransactionBackend* transaction) 91 91 { 92 92 transaction->database()->setCachedVersion(m_oldVersion); -
trunk/Source/WebCore/Modules/webdatabase/ChangeVersionWrapper.h
r127757 r142921 1 1 /* 2 * Copyright (C) 2007 Apple Inc. All rights reserved.2 * Copyright (C) 2007, 2013 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 31 31 #if ENABLE(SQL_DATABASE) 32 32 33 #include "SQLTransaction .h"33 #include "SQLTransactionBackend.h" 34 34 #include <wtf/Forward.h> 35 35 … … 42 42 static PassRefPtr<ChangeVersionWrapper> create(const String& oldVersion, const String& newVersion) { return adoptRef(new ChangeVersionWrapper(oldVersion, newVersion)); } 43 43 44 virtual bool performPreflight(SQLTransaction *);45 virtual bool performPostflight(SQLTransaction *);44 virtual bool performPreflight(SQLTransactionBackend*); 45 virtual bool performPostflight(SQLTransactionBackend*); 46 46 virtual SQLError* sqlError() const { return m_sqlError.get(); } 47 virtual void handleCommitFailedAfterPostflight(SQLTransaction *);47 virtual void handleCommitFailedAfterPostflight(SQLTransactionBackend*); 48 48 49 49 private: -
trunk/Source/WebCore/Modules/webdatabase/Database.cpp
r142193 r142921 32 32 #if ENABLE(SQL_DATABASE) 33 33 34 #include "ChangeVersion Wrapper.h"34 #include "ChangeVersionData.h" 35 35 #include "CrossThreadTask.h" 36 36 #include "DatabaseBackendContext.h" … … 46 46 #include "Page.h" 47 47 #include "SQLError.h" 48 #include "SQLTransaction.h" 48 49 #include "SQLTransactionCallback.h" 49 #include "SQLTransactionClient.h"50 #include "SQLTransactionCoordinator.h"51 50 #include "SQLTransactionErrorCallback.h" 52 51 #include "SQLiteStatement.h" … … 69 68 PassRefPtr<Database> Database::create(ScriptExecutionContext*, PassRefPtr<DatabaseBackend> backend) 70 69 { 70 // FIXME: Currently, we're only simulating the backend by return the 71 // frontend database as its own the backend. When we split the 2 apart, 72 // this create() function should be changed to be a factory method for 73 // instantiating the backend. 71 74 return static_cast<Database*>(backend.get()); 72 75 } … … 76 79 : DatabaseBase(databaseContext->scriptExecutionContext()) 77 80 , DatabaseBackendAsync(databaseContext, name, expectedVersion, displayName, estimatedSize) 78 , m_transactionInProgress(false) 79 , m_isTransactionQueueEnabled(true) 81 , m_databaseContext(DatabaseBackendAsync::databaseContext()->frontend()) 80 82 , m_deleted(false) 81 83 { … … 163 165 ASSERT(currentThread() == databaseContext()->databaseThread()->getThreadID()); 164 166 165 {166 MutexLocker locker(m_transactionInProgressMutex);167 m_isTransactionQueueEnabled = false;168 m_transactionInProgress = false;169 m_transactionQueue.clear();170 }171 172 167 closeDatabase(); 173 168 … … 197 192 PassRefPtr<VoidCallback> successCallback) 198 193 { 199 runTransaction(callback, errorCallback, successCallback, ChangeVersionWrapper::create(oldVersion, newVersion), false); 194 ChangeVersionData data(oldVersion, newVersion); 195 runTransaction(callback, errorCallback, successCallback, false, &data); 200 196 } 201 197 202 198 void Database::transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback) 203 199 { 204 runTransaction(callback, errorCallback, successCallback, 0,false);200 runTransaction(callback, errorCallback, successCallback, false); 205 201 } 206 202 207 203 void Database::readTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback) 208 204 { 209 runTransaction(callback, errorCallback, successCallback, 0,true);205 runTransaction(callback, errorCallback, successCallback, true); 210 206 } 211 207 … … 216 212 217 213 void Database::runTransaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, 218 PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) 219 { 220 MutexLocker locker(m_transactionInProgressMutex); 221 if (!m_isTransactionQueueEnabled) { 222 if (errorCallback) { 223 RefPtr<SQLError> error = SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed"); 224 scriptExecutionContext()->postTask(createCallbackTask(&callTransactionErrorCallback, errorCallback, error.release())); 225 } 226 return; 227 } 228 RefPtr<SQLTransaction> transaction = SQLTransaction::create(this, callback, errorCallback, successCallback, wrapper, readOnly); 229 m_transactionQueue.append(transaction.release()); 230 if (!m_transactionInProgress) 231 scheduleTransaction(); 232 } 233 234 void Database::inProgressTransactionCompleted() 235 { 236 MutexLocker locker(m_transactionInProgressMutex); 237 m_transactionInProgress = false; 238 scheduleTransaction(); 239 } 240 241 void Database::scheduleTransaction() 242 { 243 ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller. 244 RefPtr<SQLTransaction> transaction; 245 246 if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty()) 247 transaction = m_transactionQueue.takeFirst(); 248 249 if (transaction && databaseContext()->databaseThread()) { 250 OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); 251 LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction()); 252 m_transactionInProgress = true; 253 databaseContext()->databaseThread()->scheduleTask(task.release()); 254 } else 255 m_transactionInProgress = false; 256 } 257 258 void Database::scheduleTransactionStep(SQLTransactionBackend* transaction, bool immediately) 259 { 260 if (!databaseContext()->databaseThread()) 261 return; 262 263 OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); 264 LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get()); 265 if (immediately) 266 databaseContext()->databaseThread()->scheduleImmediateTask(task.release()); 267 else 268 databaseContext()->databaseThread()->scheduleTask(task.release()); 214 PassRefPtr<VoidCallback> successCallback, bool readOnly, const ChangeVersionData* changeVersionData) 215 { 216 RefPtr<SQLTransactionErrorCallback> anotherRefToErrorCallback = errorCallback; 217 RefPtr<SQLTransaction> transaction = SQLTransaction::create(this, callback, successCallback, anotherRefToErrorCallback, readOnly); 218 219 RefPtr<SQLTransactionBackend> transactionBackend; 220 transactionBackend = backend()->runTransaction(transaction.release(), readOnly, changeVersionData); 221 if (!transactionBackend && anotherRefToErrorCallback) { 222 RefPtr<SQLError> error = SQLError::create(SQLError::UNKNOWN_ERR, "database has been closed"); 223 scriptExecutionContext()->postTask(createCallbackTask(&callTransactionErrorCallback, anotherRefToErrorCallback, error.release())); 224 } 269 225 } 270 226 … … 324 280 } 325 281 326 SQLTransactionClient* Database::transactionClient() const327 {328 return databaseContext()->databaseThread()->transactionClient();329 }330 331 SQLTransactionCoordinator* Database::transactionCoordinator() const332 {333 return databaseContext()->databaseThread()->transactionCoordinator();334 }335 336 282 Vector<String> Database::tableNames() 337 283 { … … 359 305 } 360 306 307 #if PLATFORM(CHROMIUM) 308 void Database::reportStartTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 309 { 310 backend()->reportStartTransactionResult(errorSite, webSqlErrorCode, sqliteErrorCode); 311 } 312 313 void Database::reportCommitTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 314 { 315 backend()->reportCommitTransactionResult(errorSite, webSqlErrorCode, sqliteErrorCode); 316 } 317 318 void Database::reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode) 319 { 320 backend()->reportExecuteStatementResult(errorSite, webSqlErrorCode, sqliteErrorCode); 321 } 322 #endif 323 361 324 } // namespace WebCore 362 325 -
trunk/Source/WebCore/Modules/webdatabase/Database.h
r142193 r142921 36 36 #include "DatabaseBasicTypes.h" 37 37 #include "DatabaseError.h" 38 #include <wtf/Deque.h>39 #include <wtf/Forward.h>40 38 #include <wtf/text/WTFString.h> 41 39 42 40 namespace WebCore { 43 41 42 class ChangeVersionData; 44 43 class DatabaseCallback; 44 class DatabaseContext; 45 45 class SecurityOrigin; 46 46 class SQLTransaction; 47 47 class SQLTransactionBackend; 48 48 class SQLTransactionCallback; 49 class SQLTransactionClient;50 class SQLTransactionCoordinator;51 49 class SQLTransactionErrorCallback; 52 class SQLTransactionWrapper;53 50 class VoidCallback; 54 51 … … 66 63 // Internal engine support 67 64 static Database* from(DatabaseBackendAsync*); 65 DatabaseContext* databaseContext() const { return m_databaseContext.get(); } 68 66 69 67 Vector<String> tableNames(); … … 81 79 82 80 void scheduleTransactionCallback(SQLTransaction*); 83 void scheduleTransactionStep(SQLTransactionBackend*, bool immediately = false);84 85 SQLTransactionClient* transactionClient() const;86 SQLTransactionCoordinator* transactionCoordinator() const;87 81 88 82 private: … … 93 87 94 88 void runTransaction(PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, 95 PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper>, bool readOnly); 96 97 void inProgressTransactionCompleted(); 98 void scheduleTransaction(); 89 PassRefPtr<VoidCallback> successCallback, bool readOnly, const ChangeVersionData* = 0); 99 90 100 91 Vector<String> performGetTableNames(); 101 92 102 Deque<RefPtr<SQLTransaction> > m_transactionQueue; 103 Mutex m_transactionInProgressMutex; 104 bool m_transactionInProgress; 105 bool m_isTransactionQueueEnabled; 93 #if PLATFORM(CHROMIUM) 94 void reportStartTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode); 95 void reportCommitTransactionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode); 96 void reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode); 97 #else 98 void reportStartTransactionResult(int, int, int) { } 99 void reportCommitTransactionResult(int, int, int) { } 100 void reportExecuteStatementResult(int, int, int) { } 101 #endif 106 102 107 103 RefPtr<SecurityOrigin> m_databaseThreadSecurityOrigin; 104 RefPtr<DatabaseContext> m_databaseContext; 108 105 109 106 bool m_deleted; … … 112 109 friend class DatabaseServer; // FIXME: remove this when the backend has been split out. 113 110 friend class DatabaseBackendAsync; // FIXME: remove this when the backend has been split out. 111 friend class SQLStatement; 112 friend class SQLTransaction; 114 113 }; 115 114 -
trunk/Source/WebCore/Modules/webdatabase/DatabaseBackend.cpp
r142030 r142921 653 653 } 654 654 655 #else656 void DatabaseBackend::reportOpenDatabaseResult(int, int, int) { }657 void DatabaseBackend::reportChangeVersionResult(int, int, int) { }658 void DatabaseBackend::reportStartTransactionResult(int, int, int) { }659 void DatabaseBackend::reportCommitTransactionResult(int, int, int) { }660 void DatabaseBackend::reportExecuteStatementResult(int, int, int) { }661 void DatabaseBackend::reportVacuumDatabaseResult(int) { }662 655 #endif // PLATFORM(CHROMIUM) 663 656 -
trunk/Source/WebCore/Modules/webdatabase/DatabaseBackend.h
r142193 r142921 115 115 bool getActualVersionForTransaction(String& version); 116 116 117 #if PLATFORM(CHROMIUM) 117 118 void reportOpenDatabaseResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode); 118 119 void reportChangeVersionResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode); … … 121 122 void reportExecuteStatementResult(int errorSite, int webSqlErrorCode, int sqliteErrorCode); 122 123 void reportVacuumDatabaseResult(int sqliteErrorCode); 124 #else 125 void reportOpenDatabaseResult(int, int, int) { } 126 void reportChangeVersionResult(int, int, int) { } 127 void reportStartTransactionResult(int, int, int) { } 128 void reportCommitTransactionResult(int, int, int) { } 129 void reportExecuteStatementResult(int, int, int) { } 130 void reportVacuumDatabaseResult(int) { } 131 #endif 123 132 124 133 static const char* databaseInfoTableName(); -
trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendAsync.cpp
r142030 r142921 29 29 #if ENABLE(SQL_DATABASE) 30 30 31 #include "ChangeVersionData.h" 32 #include "ChangeVersionWrapper.h" 31 33 #include "DatabaseBackendContext.h" 32 34 #include "DatabaseTask.h" 33 35 #include "DatabaseThread.h" 34 36 #include "DatabaseTracker.h" 37 #include "Logging.h" 38 #include "SQLTransaction.h" 39 #include "SQLTransactionBackend.h" 40 #include "SQLTransactionClient.h" 41 #include "SQLTransactionCoordinator.h" 35 42 36 43 namespace WebCore { … … 38 45 DatabaseBackendAsync::DatabaseBackendAsync(PassRefPtr<DatabaseBackendContext> databaseContext, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize) 39 46 : DatabaseBackend(databaseContext, name, expectedVersion, displayName, estimatedSize, DatabaseType::Async) 47 , m_transactionInProgress(false) 48 , m_isTransactionQueueEnabled(true) 40 49 { 41 50 } … … 70 79 } 71 80 81 PassRefPtr<SQLTransactionBackend> DatabaseBackendAsync::runTransaction(PassRefPtr<SQLTransaction> transaction, 82 bool readOnly, const ChangeVersionData* data) 83 { 84 MutexLocker locker(m_transactionInProgressMutex); 85 if (!m_isTransactionQueueEnabled) 86 return 0; 87 88 RefPtr<SQLTransactionWrapper> wrapper; 89 if (data) 90 wrapper = ChangeVersionWrapper::create(data->oldVersion(), data->newVersion()); 91 92 RefPtr<SQLTransactionBackend> transactionBackend = SQLTransactionBackend::create(this, transaction, wrapper, readOnly); 93 m_transactionQueue.append(transactionBackend); 94 if (!m_transactionInProgress) 95 scheduleTransaction(); 96 97 return transactionBackend; 98 } 99 100 void DatabaseBackendAsync::inProgressTransactionCompleted() 101 { 102 MutexLocker locker(m_transactionInProgressMutex); 103 m_transactionInProgress = false; 104 scheduleTransaction(); 105 } 106 107 void DatabaseBackendAsync::scheduleTransaction() 108 { 109 ASSERT(!m_transactionInProgressMutex.tryLock()); // Locked by caller. 110 RefPtr<SQLTransactionBackend> transaction; 111 112 if (m_isTransactionQueueEnabled && !m_transactionQueue.isEmpty()) 113 transaction = m_transactionQueue.takeFirst(); 114 115 if (transaction && databaseContext()->databaseThread()) { 116 OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); 117 LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction()); 118 m_transactionInProgress = true; 119 databaseContext()->databaseThread()->scheduleTask(task.release()); 120 } else 121 m_transactionInProgress = false; 122 } 123 124 void DatabaseBackendAsync::scheduleTransactionStep(SQLTransactionBackend* transaction) 125 { 126 if (!databaseContext()->databaseThread()) 127 return; 128 129 OwnPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); 130 LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get()); 131 databaseContext()->databaseThread()->scheduleTask(task.release()); 132 } 133 134 SQLTransactionClient* DatabaseBackendAsync::transactionClient() const 135 { 136 return databaseContext()->databaseThread()->transactionClient(); 137 } 138 139 SQLTransactionCoordinator* DatabaseBackendAsync::transactionCoordinator() const 140 { 141 return databaseContext()->databaseThread()->transactionCoordinator(); 142 } 143 72 144 } // namespace WebCore 73 145 -
trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendAsync.h
r142030 r142921 30 30 31 31 #include "DatabaseBackend.h" 32 #include <wtf/Deque.h> 32 33 #include <wtf/text/WTFString.h> 33 34 34 35 namespace WebCore { 35 36 37 class ChangeVersionData; 36 38 class Database; 37 39 class DatabaseServer; 40 class SQLTransaction; 41 class SQLTransactionBackend; 42 class SQLTransactionClient; 43 class SQLTransactionCoordinator; 38 44 39 45 // FIXME: This implementation of DatabaseBackendAsync is only a place holder … … 48 54 49 55 virtual bool openAndVerifyVersion(bool setVersionInNewDatabase, DatabaseError&, String& errorMessage); 50 virtual bool performOpenAndVerify(bool setVersionInNewDatabase, DatabaseError&, String& errorMessage); 56 57 PassRefPtr<SQLTransactionBackend> runTransaction(PassRefPtr<SQLTransaction>, bool readOnly, const ChangeVersionData*); 58 void scheduleTransactionStep(SQLTransactionBackend*); 59 void inProgressTransactionCompleted(); 60 61 SQLTransactionClient* transactionClient() const; 62 SQLTransactionCoordinator* transactionCoordinator() const; 51 63 52 64 private: … … 55 67 class DatabaseTransactionTask; 56 68 class DatabaseTableNamesTask; 69 70 virtual bool performOpenAndVerify(bool setVersionInNewDatabase, DatabaseError&, String& errorMessage); 71 72 void scheduleTransaction(); 73 74 Deque<RefPtr<SQLTransactionBackend> > m_transactionQueue; 75 Mutex m_transactionInProgressMutex; 76 bool m_transactionInProgress; 77 bool m_isTransactionQueueEnabled; 57 78 58 79 friend class Database; -
trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendContext.cpp
r141928 r142921 33 33 namespace WebCore { 34 34 35 DatabaseContext* DatabaseBackendContext::frontend() 36 { 37 // FIXME: Currently, we're only simulating the frontend by return the 38 // backend context as its own the frontend. When we split the 2 apart, this 39 // create() function should be changed to return a cached m_frontend. 40 return static_cast<DatabaseContext*>(this); 41 } 42 35 43 SecurityOrigin* DatabaseBackendContext::securityOrigin() const 36 44 { -
trunk/Source/WebCore/Modules/webdatabase/DatabaseBackendContext.h
r141928 r142921 44 44 class DatabaseBackendContext : public DatabaseContext { 45 45 public: 46 DatabaseContext* frontend(); 47 46 48 ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; } 47 49 SecurityOrigin* securityOrigin() const; -
trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp
r142698 r142921 415 415 } 416 416 417 // From a secondary thread, must be thread safe with its data418 void DatabaseManager::scheduleNotifyDatabaseChanged(SecurityOrigin* origin, const String& name)419 {420 m_server->scheduleNotifyDatabaseChanged(origin, name);421 }422 423 void DatabaseManager::databaseChanged(DatabaseBackend* database)424 {425 m_server->databaseChanged(database);426 }427 428 417 #else // PLATFORM(CHROMIUM) 429 418 void DatabaseManager::closeDatabasesImmediately(const String& originIdentifier, const String& name) -
trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h
r142030 r142921 105 105 bool deleteDatabase(SecurityOrigin*, const String& name); 106 106 107 // From a secondary thread, must be thread safe with its data108 void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name);109 110 void databaseChanged(DatabaseBackend*);111 112 107 #else // PLATFORM(CHROMIUM) 113 108 void closeDatabasesImmediately(const String& originIdentifier, const String& name); -
trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.cpp
r142030 r142921 129 129 } 130 130 131 // From a secondary thread, must be thread safe with its data132 void DatabaseServer::scheduleNotifyDatabaseChanged(SecurityOrigin* origin, const String& name)133 {134 DatabaseTracker::tracker().scheduleNotifyDatabaseChanged(origin, name);135 }136 137 void DatabaseServer::databaseChanged(DatabaseBackend* database)138 {139 DatabaseTracker::tracker().databaseChanged(database);140 }141 142 131 #else // PLATFORM(CHROMIUM) 143 132 void DatabaseServer::closeDatabasesImmediately(const String& originIdentifier, const String& name) -
trunk/Source/WebCore/Modules/webdatabase/DatabaseServer.h
r142030 r142921 63 63 virtual bool deleteDatabase(SecurityOrigin*, const String& name); 64 64 65 // From a secondary thread, must be thread safe with its data66 virtual void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name);67 virtual void databaseChanged(DatabaseBackend*);68 69 65 #else // PLATFORM(CHROMIUM) 70 66 virtual void closeDatabasesImmediately(const String& originIdentifier, const String& name); -
trunk/Source/WebCore/Modules/webdatabase/DatabaseTask.cpp
r142193 r142921 156 156 void DatabaseBackendAsync::DatabaseTransactionTask::doPerformTask() 157 157 { 158 if (m_transaction->performNextStep()) 159 Database::from(m_transaction->database())->inProgressTransactionCompleted(); 158 m_transaction->performNextStep(); 160 159 } 161 160 -
trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.cpp
r142194 r142921 32 32 #if ENABLE(SQL_DATABASE) 33 33 34 #include "Database.h" 35 #include "DatabaseAuthorizer.h" 36 #include "DatabaseContext.h" 37 #include "ExceptionCode.h" 38 #include "Logging.h" 39 #include "SQLError.h" 40 #include "SQLStatementCallback.h" 41 #include "SQLStatementErrorCallback.h" 42 #include "SQLTransactionBackend.h" 34 43 #include "SQLTransactionCallback.h" 44 #include "SQLTransactionClient.h" 35 45 #include "SQLTransactionErrorCallback.h" 36 46 #include "VoidCallback.h" 47 #include <wtf/StdLibExtras.h> 48 #include <wtf/Vector.h> 37 49 38 50 namespace WebCore { 39 51 40 52 PassRefPtr<SQLTransaction> SQLTransaction::create(Database* db, PassRefPtr<SQLTransactionCallback> callback, 41 PassRefPtr< SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback,42 PassRefPtr<SQLTransactionWrapper> wrapper,bool readOnly)43 { 44 return adoptRef(new SQLTransaction(db, callback, errorCallback, successCallback, wrapper, readOnly));53 PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, 54 bool readOnly) 55 { 56 return adoptRef(new SQLTransaction(db, callback, successCallback, errorCallback, readOnly)); 45 57 } 46 58 47 59 SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> callback, 48 PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback, 49 PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) 50 : SQLTransactionBackend(db, callback, errorCallback, successCallback, wrapper, readOnly) 51 { 52 } 53 54 SQLTransaction* SQLTransaction::from(SQLTransactionBackend* backend) 55 { 56 return static_cast<SQLTransaction*>(backend); 60 PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, 61 bool readOnly) 62 : m_database(db) 63 , m_callbackWrapper(callback, db->scriptExecutionContext()) 64 , m_successCallbackWrapper(successCallback, db->scriptExecutionContext()) 65 , m_errorCallbackWrapper(errorCallback, db->scriptExecutionContext()) 66 , m_executeSqlAllowed(false) 67 , m_readOnly(readOnly) 68 { 69 ASSERT(m_database); 70 } 71 72 void SQLTransaction::setBackend(SQLTransactionBackend* backend) 73 { 74 ASSERT(!m_backend); 75 m_backend = backend; 76 } 77 78 SQLTransaction::StateFunction SQLTransaction::stateFunctionFor(SQLTransactionState state) 79 { 80 static const StateFunction stateFunctions[] = { 81 &SQLTransaction::unreachableState, // 0. illegal 82 &SQLTransaction::unreachableState, // 1. idle 83 &SQLTransaction::unreachableState, // 2. acquireLock 84 &SQLTransaction::unreachableState, // 3. openTransactionAndPreflight 85 &SQLTransaction::sendToBackendState, // 4. runStatements 86 &SQLTransaction::unreachableState, // 5. postflightAndCommit 87 &SQLTransaction::sendToBackendState, // 6. cleanupAndTerminate 88 &SQLTransaction::sendToBackendState, // 7. cleanupAfterTransactionErrorCallback 89 &SQLTransaction::deliverTransactionCallback, // 8. 90 &SQLTransaction::deliverTransactionErrorCallback, // 9. 91 &SQLTransaction::deliverStatementCallback, // 10. 92 &SQLTransaction::deliverQuotaIncreaseCallback, // 11. 93 &SQLTransaction::deliverSuccessCallback // 12. 94 }; 95 96 ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates)); 97 ASSERT(state < SQLTransactionState::NumberOfStates); 98 99 return stateFunctions[static_cast<int>(state)]; 100 } 101 102 // requestTransitToState() can be called from the backend. Hence, it should 103 // NOT be modifying SQLTransactionBackend in general. The only safe field to 104 // modify is m_requestedState which is meant for this purpose. 105 void SQLTransaction::requestTransitToState(SQLTransactionState nextState) 106 { 107 LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this); 108 m_requestedState = nextState; 109 m_database->scheduleTransactionCallback(this); 110 } 111 112 SQLTransactionState SQLTransaction::nextStateForTransactionError() 113 { 114 ASSERT(m_transactionError); 115 if (m_errorCallbackWrapper.hasCallback()) 116 return SQLTransactionState::DeliverTransactionErrorCallback; 117 118 // No error callback, so fast-forward to: 119 // Transaction Step 11 - Rollback the transaction. 120 return SQLTransactionState::CleanupAfterTransactionErrorCallback; 121 } 122 123 SQLTransactionState SQLTransaction::deliverTransactionCallback() 124 { 125 bool shouldDeliverErrorCallback = false; 126 127 // Spec 4.3.2 4: Invoke the transaction callback with the new SQLTransaction object 128 RefPtr<SQLTransactionCallback> callback = m_callbackWrapper.unwrap(); 129 if (callback) { 130 m_executeSqlAllowed = true; 131 shouldDeliverErrorCallback = !callback->handleEvent(this); 132 m_executeSqlAllowed = false; 133 } 134 135 // Spec 4.3.2 5: If the transaction callback was null or raised an exception, jump to the error callback 136 SQLTransactionState nextState = SQLTransactionState::RunStatements; 137 if (shouldDeliverErrorCallback) { 138 m_database->reportStartTransactionResult(5, SQLError::UNKNOWN_ERR, 0); 139 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the SQLTransactionCallback was null or threw an exception"); 140 nextState = SQLTransactionState::DeliverTransactionErrorCallback; 141 } 142 m_database->reportStartTransactionResult(0, -1, 0); // OK 143 return nextState; 144 } 145 146 SQLTransactionState SQLTransaction::deliverTransactionErrorCallback() 147 { 148 // Spec 4.3.2.10: If exists, invoke error callback with the last 149 // error to have occurred in this transaction. 150 RefPtr<SQLTransactionErrorCallback> errorCallback = m_errorCallbackWrapper.unwrap(); 151 if (errorCallback) { 152 // If we get here with an empty m_transactionError, then the backend 153 // must be waiting in the idle state waiting for this state to finish. 154 // Hence, it's thread safe to fetch the backend transactionError without 155 // a lock. 156 if (!m_transactionError) 157 m_transactionError = m_backend->transactionError(); 158 159 ASSERT(m_transactionError); 160 errorCallback->handleEvent(m_transactionError.get()); 161 162 m_transactionError = 0; 163 } 164 165 clearCallbackWrappers(); 166 167 // Spec 4.3.2.10: Rollback the transaction. 168 return SQLTransactionState::CleanupAfterTransactionErrorCallback; 169 } 170 171 SQLTransactionState SQLTransaction::deliverStatementCallback() 172 { 173 ASSERT(m_backend->m_currentStatement); 174 175 // Spec 4.3.2.6.6 and 4.3.2.6.3: If the statement callback went wrong, jump to the transaction error callback 176 // Otherwise, continue to loop through the statement queue 177 m_executeSqlAllowed = true; 178 bool result = m_backend->m_currentStatement->performCallback(this); 179 m_executeSqlAllowed = false; 180 181 if (result) { 182 m_database->reportCommitTransactionResult(2, SQLError::UNKNOWN_ERR, 0); 183 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the statement callback raised an exception or statement error callback did not return false"); 184 return nextStateForTransactionError(); 185 } 186 return SQLTransactionState::RunStatements; 187 } 188 189 SQLTransactionState SQLTransaction::deliverQuotaIncreaseCallback() 190 { 191 ASSERT(m_backend->m_currentStatement); 192 193 bool shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(database()); 194 m_backend->setShouldRetryCurrentStatement(shouldRetryCurrentStatement); 195 196 return SQLTransactionState::RunStatements; 197 } 198 199 SQLTransactionState SQLTransaction::deliverSuccessCallback() 200 { 201 // Spec 4.3.2.8: Deliver success callback. 202 RefPtr<VoidCallback> successCallback = m_successCallbackWrapper.unwrap(); 203 if (successCallback) 204 successCallback->handleEvent(); 205 206 clearCallbackWrappers(); 207 208 // Schedule a "post-success callback" step to return control to the database thread in case there 209 // are further transactions queued up for this Database 210 return SQLTransactionState::CleanupAndTerminate; 211 } 212 213 // This state function is used as a stub function to plug unimplemented states 214 // in the state dispatch table. They are unimplemented because they should 215 // never be reached in the course of correct execution. 216 SQLTransactionState SQLTransaction::unreachableState() 217 { 218 ASSERT_NOT_REACHED(); 219 return SQLTransactionState::End; 220 } 221 222 SQLTransactionState SQLTransaction::sendToBackendState() 223 { 224 ASSERT(m_nextState != SQLTransactionState::Idle); 225 m_backend->requestTransitToState(m_nextState); 226 return SQLTransactionState::Idle; 227 } 228 229 void SQLTransaction::performPendingCallback() 230 { 231 LOG(StorageAPI, "Callback %s\n", nameForSQLTransactionState(m_nextState)); 232 233 setStateToRequestedState(); 234 ASSERT(m_nextState == SQLTransactionState::End 235 || m_nextState == SQLTransactionState::DeliverTransactionCallback 236 || m_nextState == SQLTransactionState::DeliverTransactionErrorCallback 237 || m_nextState == SQLTransactionState::DeliverStatementCallback 238 || m_nextState == SQLTransactionState::DeliverQuotaIncreaseCallback 239 || m_nextState == SQLTransactionState::DeliverSuccessCallback); 240 241 checkAndHandleClosedOrInterruptedDatabase(); 242 runStateMachine(); 243 } 244 245 void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> callbackError, ExceptionCode& e) 246 { 247 if (!m_executeSqlAllowed || !m_database->opened()) { 248 e = INVALID_STATE_ERR; 249 return; 250 } 251 252 int permissions = DatabaseAuthorizer::ReadWriteMask; 253 if (!m_database->databaseContext()->allowDatabaseAccess()) 254 permissions |= DatabaseAuthorizer::NoAccessMask; 255 else if (m_readOnly) 256 permissions |= DatabaseAuthorizer::ReadOnlyMask; 257 258 RefPtr<SQLStatement> statement = SQLStatement::create(m_database.get(), sqlStatement, arguments, callback, callbackError, permissions); 259 260 if (m_database->deleted()) 261 statement->setDatabaseDeletedError(m_database.get()); 262 263 m_backend->enqueueStatement(statement); 264 } 265 266 bool SQLTransaction::checkAndHandleClosedOrInterruptedDatabase() 267 { 268 if (m_database->opened() && !m_database->isInterrupted()) 269 return false; 270 271 clearCallbackWrappers(); 272 m_nextState = SQLTransactionState::CleanupAndTerminate; 273 274 return true; 275 } 276 277 void SQLTransaction::clearCallbackWrappers() 278 { 279 // Release the unneeded callbacks, to break reference cycles. 280 m_callbackWrapper.clear(); 281 m_successCallbackWrapper.clear(); 282 m_errorCallbackWrapper.clear(); 57 283 } 58 284 -
trunk/Source/WebCore/Modules/webdatabase/SQLTransaction.h
r142194 r142921 32 32 #if ENABLE(SQL_DATABASE) 33 33 34 #include "SQLTransactionBackend.h" 34 #include "SQLCallbackWrapper.h" 35 #include "SQLStatement.h" 36 #include "SQLTransactionStateMachine.h" 37 #include <wtf/PassRefPtr.h> 38 #include <wtf/RefPtr.h> 35 39 36 40 namespace WebCore { 37 41 38 class SQLTransaction : public SQLTransactionBackend { 42 class Database; 43 class SQLError; 44 class SQLStatementCallback; 45 class SQLStatementErrorCallback; 46 class SQLTransactionBackend; 47 class SQLTransactionCallback; 48 class SQLTransactionErrorCallback; 49 class SQLValue; 50 class VoidCallback; 51 52 class SQLTransaction : public SQLTransactionStateMachine<SQLTransaction> { 39 53 public: 40 static PassRefPtr<SQLTransaction> create(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, 41 PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly = false); 54 static PassRefPtr<SQLTransaction> create(Database*, PassRefPtr<SQLTransactionCallback>, 55 PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback>, 56 bool readOnly); 42 57 43 static SQLTransaction* from(SQLTransactionBackend*); 58 void setBackend(SQLTransactionBackend*); 59 60 void performPendingCallback(); 61 62 void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, 63 PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, ExceptionCode&); 64 65 Database* database() { return m_database.get(); } 66 67 bool hasCallback() const { return m_callbackWrapper.hasCallback(); } 68 bool hasSuccessCallback() const { return m_successCallbackWrapper.hasCallback(); } 69 bool hasErrorCallback() const { return m_errorCallbackWrapper.hasCallback(); } 44 70 45 71 private: 46 SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, 47 PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly); 72 SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>, 73 PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionErrorCallback>, 74 bool readOnly); 75 76 bool checkAndHandleClosedOrInterruptedDatabase(); 77 void clearCallbackWrappers(); 78 79 // State Machine functions: 80 virtual StateFunction stateFunctionFor(SQLTransactionState); 81 void requestTransitToState(SQLTransactionState); 82 83 // State functions: 84 SQLTransactionState deliverTransactionCallback(); 85 SQLTransactionState deliverTransactionErrorCallback(); 86 SQLTransactionState deliverStatementCallback(); 87 SQLTransactionState deliverQuotaIncreaseCallback(); 88 SQLTransactionState deliverSuccessCallback(); 89 90 SQLTransactionState unreachableState(); 91 SQLTransactionState sendToBackendState(); 92 93 SQLTransactionState nextStateForTransactionError(); 94 95 RefPtr<Database> m_database; 96 RefPtr<SQLTransactionBackend> m_backend; 97 SQLCallbackWrapper<SQLTransactionCallback> m_callbackWrapper; 98 SQLCallbackWrapper<VoidCallback> m_successCallbackWrapper; 99 SQLCallbackWrapper<SQLTransactionErrorCallback> m_errorCallbackWrapper; 100 101 bool m_executeSqlAllowed; 102 RefPtr<SQLError> m_transactionError; 103 104 bool m_readOnly; 105 106 friend class SQLTransactionBackend; 48 107 }; 49 108 -
trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.cpp
r142213 r142921 40 40 #include "SQLError.h" 41 41 #include "SQLStatement.h" 42 #include "SQLStatementCallback.h" 43 #include "SQLStatementErrorCallback.h" 42 #include "SQLStatementCallback.h" // FIXME: remove when SQLStatement has been refactored. 43 #include "SQLStatementErrorCallback.h" // FIXME: remove when SQLStatement has been refactored. 44 44 #include "SQLTransaction.h" 45 #include "SQLTransactionCallback.h"46 45 #include "SQLTransactionClient.h" 47 46 #include "SQLTransactionCoordinator.h" 48 #include "SQLTransactionErrorCallback.h"49 47 #include "SQLValue.h" 50 48 #include "SQLiteTransaction.h" 51 #include "ScriptExecutionContext.h" 52 #include "VoidCallback.h" 53 #include <wtf/OwnPtr.h> 54 #include <wtf/PassRefPtr.h> 55 #include <wtf/RefPtr.h> 49 #include <wtf/StdLibExtras.h> 56 50 #include <wtf/text/WTFString.h> 57 51 … … 61 55 // The SQLTransaction is a state machine that executes a series of states / steps. 62 56 // 63 // ths State Transition Graph at a glance: 57 // The work of the transaction states are defined in section of 4.3.2 of the 58 // webdatabase spec: http://dev.w3.org/html5/webdatabase/#processing-model 59 // 60 // the State Transition Graph at a glance: 64 61 // ====================================== 65 62 // 66 // Backend (works with SQLiteDatabase) . Frontend (works with Script) 67 // =================================== . ============================ 68 // ,--> State 0: [initial state] . 69 // | ^ v . 70 // | | State 1: [acquireLock] . 71 // | | v . 72 // | | State 2: [openTransactionAndPreflight] ----------------------------------------------------. 73 // | | | . | 74 // | | `---------------------------------------> State 3: [deliverTransactionCallback] -----. | 75 // | | . | v v 76 // | | ,--------------------------------------------' State 10: [deliverTransactionErrorCallback] + 77 // | | | . ^ ^ ^ | 78 // | | v . | | | | 79 // | | State 4: [runStatements] ---------------------------------------------------------------' | | | 80 // | | | ^ ^ | ^ | . | | | 81 // | | |--------' | | | `--------------------> State 8: [deliverStatementCallback] +---------' | | 82 // | | | | | `------------------------------------------------------------' | | 83 // | | | | `-------------------------> State 9: [deliverQuotaIncreaseCallback] + | | 84 // | | | `--------------------------------------------------------------------' | | 85 // | | v . | | 86 // | | State 5: [postflightAndCommit] --+------------------------------------------------------------' | 87 // | | |---------> State 6: [deliverSuccessCallback] + | 88 // | | ,-----------------------------' . | | 89 // | | v . | | 90 // | | State 7: [cleanupAfterSuccessCallback] <---------------------------------------' | 91 // | `-----' . | 92 // `------------------------------------------------------------------------------------------------------' 93 // . 63 // Backend . Frontend 64 // (works with SQLiteDatabase) . (works with Script) 65 // =========================== . =================== 66 // . 67 // 1. Idle . 68 // v . 69 // 2. AcquireLock . 70 // v . 71 // 3. OpenTransactionAndPreflight ------------------------------------------. 72 // | . | 73 // `-------------------------------> 8. DeliverTransactionCallback --. | 74 // . | v v 75 // ,-------------------------------------' 9. DeliverTransactionErrorCallback + 76 // | . ^ ^ ^ | 77 // v . | | | | 78 // 4. RunStatements -----------------------------------------------------' | | | 79 // | ^ ^ | ^ | . | | | 80 // |--------' | | | `------------> 10. DeliverStatementCallback +-----' | | 81 // | | | `---------------------------------------------' | | 82 // | | `-----------------> 11. DeliverQuotaIncreaseCallback + | | 83 // | `-----------------------------------------------------' | | 84 // v . | | 85 // 5. PostflightAndCommit --+--------------------------------------------------' | 86 // |----------> 12. DeliverSuccessCallback + | 87 // ,--------------------' . | | 88 // v . | | 89 // 6. CleanupAndTerminate <-----------------------------------------' | 90 // v ^ . | 91 // 0. End | . | 92 // | . | 93 // 7: CleanupAfterTransactionErrorCallback <----------------------------' 94 // . 94 95 // 95 96 // the States and State Transitions: 96 97 // ================================ 97 // Executed in the back-end: 98 // State 0: [initial state] 99 // - On scheduled transaction, goto [acquireLock]. 100 // 101 // State 1: [acquireLock] 102 // - acquire lock. 103 // - on "lock" acquisition, goto [openTransactionAndPreflight]. 104 // 105 // State 2: [openTransactionAndPreflight] 106 // - Sets up an SQLiteTransaction. 107 // - begin the SQLiteTransaction. 108 // - call the SQLTransactionWrapper preflight if available. 109 // - schedule script callback. 110 // - on error (see handleTransactionError), goto [deliverTransactionErrorCallback]. 111 // - goto [deliverTransactionCallback]. 112 // 113 // Executed in the front-end: 114 // State 3: [deliverTransactionCallback] 115 // - invoke the script function callback() if available. 116 // - on error, goto [deliverTransactionErrorCallback]. 117 // - goto [runStatements]. 118 // 119 // Executed in the back-end: 120 // State 4: [runStatements] 121 // - while there are statements { 122 // - run a statement. 123 // - if statementCallback is available, goto [deliverStatementCallback]. 124 // - on error, 125 // goto [deliverQuotaIncreaseCallback], or 126 // goto [deliverStatementCallback] (see handleCurrentStatementError), or 127 // goto [deliverTransactionErrorCallback]. 128 // } 129 // - goto [postflightAndCommit]. 130 // 131 // State 5: [postflightAndCommit] 132 // - call the SQLTransactionWrapper postflight if available. 133 // - commit the SQLiteTansaction. 134 // - on error, goto [deliverTransactionErrorCallback] (see handleTransactionError). 135 // - if successCallback is available, goto [deliverSuccessCallback]. 136 // else goto [cleanupAfterSuccessCallback]. 137 // 138 // Executed in the front-end: 139 // State 6: [deliverSuccessCallback] 140 // - invoke the script function successCallback() if available. 141 // - goto [cleanupAfterSuccessCallback]. 142 // 143 // Executed in the back-end: 144 // State 7: [cleanupAfterSuccessCallback] 145 // - clean the SQLiteTransaction. 146 // - release lock. 147 // - goto [initial state]. 148 // 149 // Other states: 150 // Executed in the front-end: 151 // State 8: [deliverStatementCallback] 152 // - invoke script statement callback (assume available). 153 // - on error (see handleTransactionError), 154 // goto [deliverTransactionErrorCallback]. 155 // - goto [runStatements]. 156 // 157 // State 9: [deliverQuotaIncreaseCallback] 158 // - give client a chance to increase the quota. 159 // - goto [runStatements]. 160 // 161 // State 10: [deliverTransactionErrorCallback] 162 // - invoke the script function errorCallback if available. 163 // - goto [cleanupAfterTransactionErrorCallback]. 164 // 165 // Executed in the back-end: 166 // State 11: [cleanupAfterTransactionErrorCallback] 167 // - rollback and clear SQLiteTransaction. 168 // - clear statements. 169 // - release lock. 170 // - goto [initial state]. 98 // 0. SQLTransactionState::End 99 // - the end state. 100 // 101 // 1. SQLTransactionState::Idle 102 // - placeholder state while waiting on frontend/backend, etc. See comment on 103 // "State transitions between SQLTransaction and SQLTransactionBackend" 104 // below. 105 // 106 // 2. SQLTransactionState::AcquireLock (runs in backend) 107 // - this is the start state. 108 // - acquire the "lock". 109 // - on "lock" acquisition, goto SQLTransactionState::OpenTransactionAndPreflight. 110 // 111 // 3. SQLTransactionState::openTransactionAndPreflight (runs in backend) 112 // - Sets up an SQLiteTransaction. 113 // - begin the SQLiteTransaction. 114 // - call the SQLTransactionWrapper preflight if available. 115 // - schedule script callback. 116 // - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 117 // - goto SQLTransactionState::DeliverTransactionCallback. 118 // 119 // 4. SQLTransactionState::DeliverTransactionCallback (runs in frontend) 120 // - invoke the script function callback() if available. 121 // - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 122 // - goto SQLTransactionState::RunStatements. 123 // 124 // 5. SQLTransactionState::DeliverTransactionErrorCallback (runs in frontend) 125 // - invoke the script function errorCallback if available. 126 // - goto SQLTransactionState::CleanupAfterTransactionErrorCallback. 127 // 128 // 6. SQLTransactionState::RunStatements (runs in backend) 129 // - while there are statements { 130 // - run a statement. 131 // - if statementCallback is available, goto SQLTransactionState::DeliverStatementCallback. 132 // - on error, 133 // goto SQLTransactionState::DeliverQuotaIncreaseCallback, or 134 // goto SQLTransactionState::DeliverStatementCallback, or 135 // goto SQLTransactionState::deliverTransactionErrorCallback. 136 // } 137 // - goto SQLTransactionState::PostflightAndCommit. 138 // 139 // 7. SQLTransactionState::DeliverStatementCallback (runs in frontend) 140 // - invoke script statement callback (assume available). 141 // - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 142 // - goto SQLTransactionState::RunStatements. 143 // 144 // 8. SQLTransactionState::DeliverQuotaIncreaseCallback (runs in frontend) 145 // - give client a chance to increase the quota. 146 // - goto SQLTransactionState::RunStatements. 147 // 148 // 9. SQLTransactionState::PostflightAndCommit (runs in backend) 149 // - call the SQLTransactionWrapper postflight if available. 150 // - commit the SQLiteTansaction. 151 // - on error, goto SQLTransactionState::DeliverTransactionErrorCallback. 152 // - if successCallback is available, goto SQLTransactionState::DeliverSuccessCallback. 153 // else goto SQLTransactionState::CleanupAndTerminate. 154 // 155 // 10. SQLTransactionState::DeliverSuccessCallback (runs in frontend) 156 // - invoke the script function successCallback() if available. 157 // - goto SQLTransactionState::CleanupAndTerminate. 158 // 159 // 11. SQLTransactionState::CleanupAndTerminate (runs in backend) 160 // - stop and clear the SQLiteTransaction. 161 // - release the "lock". 162 // - goto SQLTransactionState::End. 163 // 164 // 12. SQLTransactionState::CleanupAfterTransactionErrorCallback (runs in backend) 165 // - rollback the SQLiteTransaction. 166 // - goto SQLTransactionState::CleanupAndTerminate. 167 // 168 // State transitions between SQLTransaction and SQLTransactionBackend 169 // ================================================================== 170 // As shown above, there are state transitions that crosses the boundary between 171 // the frontend and backend. For example, 172 // 173 // OpenTransactionAndPreflight (state 3 in the backend) 174 // transitions to DeliverTransactionCallback (state 8 in the frontend), 175 // which in turn transitions to RunStatements (state 4 in the backend). 176 // 177 // This cross boundary transition is done by posting transition requests to the 178 // other side and letting the other side's state machine execute the state 179 // transition in the appropriate thread (i.e. the script thread for the frontend, 180 // and the database thread for the backend). 181 // 182 // Logically, the state transitions work as shown in the graph above. But 183 // physically, the transition mechanism uses the Idle state (both in the frontend 184 // and backend) as a waiting state for further activity. For example, taking a 185 // closer look at the 3 state transition example above, what actually happens 186 // is as follows: 187 // 188 // Step 1: 189 // ====== 190 // In the frontend thread: 191 // - waiting quietly is Idle. Not doing any work. 192 // 193 // In the backend: 194 // - is in OpenTransactionAndPreflight, and doing its work. 195 // - when done, it transits to the backend DeliverTransactionCallback. 196 // - the backend DeliverTransactionCallback sends a request to the frontend 197 // to transit to DeliverTransactionCallback, and then itself transits to 198 // Idle. 199 // 200 // Step 2: 201 // ====== 202 // In the frontend thread: 203 // - transits to DeliverTransactionCallback and does its work. 204 // - when done, it transits to the frontend RunStatements. 205 // - the frontend RunStatements sends a request to the backend to transit 206 // to RunStatements, and then itself transits to Idle. 207 // 208 // In the backend: 209 // - waiting quietly in Idle. 210 // 211 // Step 3: 212 // ====== 213 // In the frontend thread: 214 // - waiting quietly is Idle. Not doing any work. 215 // 216 // In the backend: 217 // - transits to RunStatements, and does its work. 218 // ... 219 // 220 // So, when the frontend or backend are not active, they will park themselves in 221 // their Idle states. This means their m_nextState is set to Idle, but they never 222 // actually run the corresponding state function. Note: for both the frontend and 223 // backend, the state function for Idle is unreachableState(). 224 // 225 // The states that send a request to their peer across the front/back boundary 226 // are implemented with just 2 functions: SQLTransaction::sendToBackendState() 227 // and SQLTransactionBackend::sendToFrontendState(). These state functions do 228 // nothing but sends a request to the other side to transit to the current 229 // state (indicated by m_nextState), and then transits itself to the Idle state 230 // to wait for further action. 231 232 233 // The Life-Cycle of a SQLTransaction i.e. Who's keeping the SQLTransactionAlive? 234 // ============================================================================= 235 // The RefPtr chain goes something like this: 236 // 237 // At birth (in DatabaseBackendAsync::runTransaction()): 238 // ==================================================== 239 // DatabaseBackendAsync // in Deque<RefPtr<SQLTransactionBackend> > m_transactionQueue points to ... 240 // --> SQLTransactionBackend // in RefPtr<SQLTransaction> m_frontend points to ... 241 // --> SQLTransaction // in RefPtr<SQLTransactionBackend> m_backend points to ... 242 // --> SQLTransactionBackend // which is a circular reference. 243 // 244 // Note: there's a circular reference between the SQLTransaction front-end and 245 // back-end. This circular reference is established in the constructor of the 246 // SQLTransactionBackend. The circular reference will only be broken at the end 247 // of the transaction's clean up state i.e. when the transaction should no 248 // longer be in use thereafter. 249 // 250 // After scheduling the transaction with the DatabaseThread (DatabaseBackendAsync::scheduleTransaction()): 251 // ====================================================================================================== 252 // DatabaseThread // in MessageQueue<DatabaseTask> m_queue points to ... 253 // --> DatabaseTransactionTask // in RefPtr<SQLTransactionBackend> m_transaction points to ... 254 // --> SQLTransactionBackend // in RefPtr<SQLTransaction> m_frontend points to ... 255 // --> SQLTransaction // in RefPtr<SQLTransactionBackend> m_backend points to ... 256 // --> SQLTransactionBackend // which is a circular reference. 257 // 258 // When executing the transaction (in DatabaseThread::databaseThread()): 259 // ==================================================================== 260 // OwnPtr<DatabaseTask> task; // points to ... 261 // --> DatabaseTransactionTask // in RefPtr<SQLTransactionBackend> m_transaction points to ... 262 // --> SQLTransactionBackend // in: RefPtr<SQLTransaction> m_frontend; 263 // --> SQLTransaction // in RefPtr<SQLTransactionBackend> m_backend points to ... 264 // --> SQLTransactionBackend // which is a circular reference. 265 // 266 // At the end of cleanupAndTerminate(): 267 // =================================== 268 // At the end of the cleanup state, the SQLTransactionBackend::m_frontend is nullified. 269 // If by then, a JSObject wrapper is referring to the SQLTransaction, then the reference 270 // chain looks like this: 271 // 272 // JSObjectWrapper 273 // --> SQLTransaction // in RefPtr<SQLTransactionBackend> m_backend points to ... 274 // --> SQLTransactionBackend // which no longer points back to its SQLTransaction. 275 // 276 // When the GC collects the corresponding JSObject, the above chain will be cleaned up 277 // and deleted. 278 // 279 // If there is no JSObject wrapper referring to the SQLTransaction when the cleanup 280 // states nullify SQLTransactionBackend::m_frontend, the SQLTransaction will deleted then. 281 // However, there will still be a DatabaseTask pointing to the SQLTransactionBackend (see 282 // the "When executing the transaction" chain above). This will keep the 283 // SQLTransactionBackend alive until DatabaseThread::databaseThread() releases its 284 // task OwnPtr. 285 // 286 // What happens if a transaction is interrupted? 287 // ============================================ 288 // If the transaction is interrupted half way, it won't get to run to state 289 // CleanupAndTerminate, and hence, would not have called doCleanup(). doCleanup() is 290 // where we nullify SQLTransactionBackend::m_frontend to break the reference cycle 291 // between the frontend and backend. Hence, that transaction will never get cleaned 292 // up, unless ... 293 // 294 // ... unless we have a cleanup mechanism for interruptions. That is, during the 295 // shutdown of the DatabaseThread, the SQLTransactionCoordinator will discover this 296 // interrupted transaction and invoke its notifyDatabaseThreadIsShuttingDown(), 297 // which in turn will call doCleanup(). With that, all is well again. 171 298 172 299 … … 178 305 namespace WebCore { 179 306 180 SQLTransactionBackend::SQLTransactionBackend(Database* db, PassRefPtr<SQLTransactionCallback> callback, 181 PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback, 182 PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) 183 : m_nextStep(&SQLTransactionBackend::acquireLock) 184 , m_executeSqlAllowed(false) 307 PassRefPtr<SQLTransactionBackend> SQLTransactionBackend::create(DatabaseBackendAsync* db, 308 PassRefPtr<SQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) 309 { 310 return adoptRef(new SQLTransactionBackend(db, frontend, wrapper, readOnly)); 311 } 312 313 SQLTransactionBackend::SQLTransactionBackend(DatabaseBackendAsync* db, 314 PassRefPtr<SQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) 315 : m_frontend(frontend) 185 316 , m_database(db) 186 317 , m_wrapper(wrapper) 187 , m_ callbackWrapper(callback, db->scriptExecutionContext())188 , m_ successCallbackWrapper(successCallback, db->scriptExecutionContext())189 , m_ errorCallbackWrapper(errorCallback, db->scriptExecutionContext())318 , m_hasCallback(m_frontend->hasCallback()) 319 , m_hasSuccessCallback(m_frontend->hasSuccessCallback()) 320 , m_hasErrorCallback(m_frontend->hasErrorCallback()) 190 321 , m_shouldRetryCurrentStatement(false) 191 322 , m_modifiedDatabase(false) … … 195 326 { 196 327 ASSERT(m_database); 328 m_frontend->setBackend(this); 329 m_requestedState = SQLTransactionState::AcquireLock; 197 330 } 198 331 … … 202 335 } 203 336 204 void SQLTransactionBackend::executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> callbackError, ExceptionCode& e) 205 { 206 if (!m_executeSqlAllowed || !m_database->opened()) { 207 e = INVALID_STATE_ERR; 208 return; 209 } 210 211 int permissions = DatabaseAuthorizer::ReadWriteMask; 212 if (!m_database->databaseContext()->allowDatabaseAccess()) 213 permissions |= DatabaseAuthorizer::NoAccessMask; 214 else if (m_readOnly) 215 permissions |= DatabaseAuthorizer::ReadOnlyMask; 216 217 RefPtr<SQLStatement> statement = SQLStatement::create(m_database.get(), sqlStatement, arguments, callback, callbackError, permissions); 218 219 if (m_database->deleted()) 220 statement->setDatabaseDeletedError(m_database.get()); 221 222 enqueueStatement(statement); 337 void SQLTransactionBackend::doCleanup() 338 { 339 ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID()); 340 341 MutexLocker locker(m_statementMutex); 342 m_statementQueue.clear(); 343 344 if (m_sqliteTransaction) { 345 // In the event we got here because of an interruption or error (i.e. if 346 // the transaction is in progress), we should roll it back here. Clearing 347 // m_sqliteTransaction invokes SQLiteTransaction's destructor which does 348 // just that. We might as well do this unconditionally and free up its 349 // resources because we're already terminating. 350 m_sqliteTransaction.clear(); 351 } 352 353 // Release the lock on this database 354 if (m_lockAcquired) 355 m_database->transactionCoordinator()->releaseLock(this); 356 357 // Now that we're done, break the reference cycle that keeps us alive. 358 // See comment about the life-cycle above. 359 m_frontend = 0; 360 361 // Do some aggresive clean up here except for m_database. 362 // 363 // We can't clear m_database here because the frontend may asynchronously 364 // invoke SQLTransactionBackend::requestTransitToState(), and that function 365 // uses m_database to schedule a state transition. This may occur because 366 // the frontend (being in another thread) may already be on the way to 367 // requesting our next state before it detects an interruption. 368 // 369 // There is no harm in letting it finish making the request. It'll set 370 // m_requestedState, but we won't execute a transition to that state because 371 // we've already shut down the transaction. 372 373 m_currentStatement = 0; 374 m_wrapper = 0; 375 m_transactionError = 0; 376 } 377 378 PassRefPtr<SQLError> SQLTransactionBackend::transactionError() 379 { 380 return m_transactionError; 381 } 382 383 void SQLTransactionBackend::setShouldRetryCurrentStatement(bool shouldRetry) 384 { 385 ASSERT(!m_shouldRetryCurrentStatement); 386 m_shouldRetryCurrentStatement = shouldRetry; 387 } 388 389 SQLTransactionBackend::StateFunction SQLTransactionBackend::stateFunctionFor(SQLTransactionState state) 390 { 391 static const StateFunction stateFunctions[] = { 392 &SQLTransactionBackend::unreachableState, // 0. end 393 &SQLTransactionBackend::unreachableState, // 1. idle 394 &SQLTransactionBackend::acquireLock, // 2. 395 &SQLTransactionBackend::openTransactionAndPreflight, // 3. 396 &SQLTransactionBackend::runStatements, // 4. 397 &SQLTransactionBackend::postflightAndCommit, // 5. 398 &SQLTransactionBackend::cleanupAndTerminate, // 6. 399 &SQLTransactionBackend::cleanupAfterTransactionErrorCallback, // 7. 400 &SQLTransactionBackend::sendToFrontendState, // 8. deliverTransactionCallback 401 &SQLTransactionBackend::sendToFrontendState, // 9. deliverTransactionErrorCallback 402 &SQLTransactionBackend::sendToFrontendState, // 10. deliverStatementCallback 403 &SQLTransactionBackend::sendToFrontendState, // 11. deliverQuotaIncreaseCallback 404 &SQLTransactionBackend::sendToFrontendState // 12. deliverSuccessCallback 405 }; 406 407 ASSERT(WTF_ARRAY_LENGTH(stateFunctions) == static_cast<int>(SQLTransactionState::NumberOfStates)); 408 ASSERT(state < SQLTransactionState::NumberOfStates); 409 410 return stateFunctions[static_cast<int>(state)]; 223 411 } 224 412 … … 229 417 } 230 418 231 #if !LOG_DISABLED232 const char* SQLTransactionBackend::debugStepName(SQLTransactionBackend::TransactionStepMethod step)233 {234 if (step == &SQLTransactionBackend::acquireLock)235 return "acquireLock";236 if (step == &SQLTransactionBackend::openTransactionAndPreflight)237 return "openTransactionAndPreflight";238 if (step == &SQLTransactionBackend::runStatements)239 return "runStatements";240 if (step == &SQLTransactionBackend::postflightAndCommit)241 return "postflightAndCommit";242 if (step == &SQLTransactionBackend::cleanupAfterTransactionErrorCallback)243 return "cleanupAfterTransactionErrorCallback";244 if (step == &SQLTransactionBackend::deliverTransactionCallback)245 return "deliverTransactionCallback";246 if (step == &SQLTransactionBackend::deliverTransactionErrorCallback)247 return "deliverTransactionErrorCallback";248 if (step == &SQLTransactionBackend::deliverStatementCallback)249 return "deliverStatementCallback";250 if (step == &SQLTransactionBackend::deliverQuotaIncreaseCallback)251 return "deliverQuotaIncreaseCallback";252 if (step == &SQLTransactionBackend::deliverSuccessCallback)253 return "deliverSuccessCallback";254 if (step == &SQLTransactionBackend::cleanupAfterSuccessCallback)255 return "cleanupAfterSuccessCallback";256 return "UNKNOWN";257 }258 #endif259 260 419 void SQLTransactionBackend::checkAndHandleClosedOrInterruptedDatabase() 261 420 { … … 265 424 // If the database was stopped, don't do anything and cancel queued work 266 425 LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction"); 267 MutexLocker locker(m_statementMutex);268 m_statementQueue.clear();269 m_nextStep = 0;270 271 // Release the unneeded callbacks, to break reference cycles.272 m_callbackWrapper.clear();273 m_successCallbackWrapper.clear();274 m_errorCallbackWrapper.clear();275 276 // The next steps should be executed only if we're on the DB thread.277 if (currentThread() != database()->databaseContext()->databaseThread()->getThreadID())278 return;279 426 280 427 // The current SQLite transaction should be stopped, as well … … 284 431 } 285 432 286 if (m_lockAcquired) 287 m_database->transactionCoordinator()->releaseLock(this); 288 } 289 290 291 bool SQLTransactionBackend::performNextStep() 292 { 293 LOG(StorageAPI, "Step %s\n", debugStepName(m_nextStep)); 294 295 ASSERT(m_nextStep == &SQLTransactionBackend::acquireLock 296 || m_nextStep == &SQLTransactionBackend::openTransactionAndPreflight 297 || m_nextStep == &SQLTransactionBackend::runStatements 298 || m_nextStep == &SQLTransactionBackend::postflightAndCommit 299 || m_nextStep == &SQLTransactionBackend::cleanupAfterSuccessCallback 300 || m_nextStep == &SQLTransactionBackend::cleanupAfterTransactionErrorCallback); 433 // Terminate the frontend state machine. This also gets the frontend to 434 // call checkAndHandleClosedOrInterruptedDatabase() and clear its wrappers 435 // if needed. 436 m_frontend->requestTransitToState(SQLTransactionState::End); 437 438 // Redirect to the end state to abort, clean up, and end the transaction. 439 doCleanup(); 440 m_nextState = SQLTransactionState::End; 441 } 442 443 void SQLTransactionBackend::performNextStep() 444 { 445 LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState)); 446 447 setStateToRequestedState(); 448 ASSERT(m_nextState == SQLTransactionState::AcquireLock 449 || m_nextState == SQLTransactionState::OpenTransactionAndPreflight 450 || m_nextState == SQLTransactionState::RunStatements 451 || m_nextState == SQLTransactionState::PostflightAndCommit 452 || m_nextState == SQLTransactionState::CleanupAndTerminate 453 || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorCallback); 301 454 302 455 checkAndHandleClosedOrInterruptedDatabase(); 303 304 if (m_nextStep) 305 (this->*m_nextStep)(); 306 307 // If there is no nextStep after performing the above step, the transaction is complete 308 return !m_nextStep; 309 } 310 311 void SQLTransactionBackend::performPendingCallback() 312 { 313 LOG(StorageAPI, "Callback %s\n", debugStepName(m_nextStep)); 314 315 ASSERT(m_nextStep == &SQLTransactionBackend::deliverTransactionCallback 316 || m_nextStep == &SQLTransactionBackend::deliverTransactionErrorCallback 317 || m_nextStep == &SQLTransactionBackend::deliverStatementCallback 318 || m_nextStep == &SQLTransactionBackend::deliverQuotaIncreaseCallback 319 || m_nextStep == &SQLTransactionBackend::deliverSuccessCallback); 320 321 checkAndHandleClosedOrInterruptedDatabase(); 322 323 if (m_nextStep) 324 (this->*m_nextStep)(); 456 runStateMachine(); 325 457 } 326 458 … … 329 461 ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID()); 330 462 331 // If the transaction is in progress, we should roll it back here, since this is our last 332 // oportunity to do something related to this transaction on the DB thread. 333 // Clearing m_sqliteTransaction invokes SQLiteTransaction's destructor which does just that. 334 m_sqliteTransaction.clear(); 335 } 336 337 void SQLTransactionBackend::acquireLock() 463 // If the transaction is in progress, we should roll it back here, since this 464 // is our last opportunity to do something related to this transaction on the 465 // DB thread. Amongst other work, doCleanup() will clear m_sqliteTransaction 466 // which invokes SQLiteTransaction's destructor, which will do the roll back 467 // if necessary. 468 469 // Note: if doCleanup() has already been invoked, then m_frontend would have 470 // been nullified. 471 if (m_frontend) 472 doCleanup(); 473 } 474 475 SQLTransactionState SQLTransactionBackend::acquireLock() 338 476 { 339 477 m_database->transactionCoordinator()->acquireLock(this); 478 return SQLTransactionState::Idle; 340 479 } 341 480 … … 343 482 { 344 483 m_lockAcquired = true; 345 m_nextStep = &SQLTransactionBackend::openTransactionAndPreflight; 346 LOG(StorageAPI, "Scheduling openTransactionAndPreflight immediately for transaction %p\n", this); 347 m_database->scheduleTransactionStep(this, true); 348 } 349 350 void SQLTransactionBackend::openTransactionAndPreflight() 484 requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight); 485 } 486 487 SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() 351 488 { 352 489 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); … … 356 493 357 494 // If the database was deleted, jump to the error callback 358 if ( m_database->deleted()) {495 if (Database::from(m_database.get())->deleted()) { 359 496 m_database->reportStartTransactionResult(1, SQLError::UNKNOWN_ERR, 0); 360 497 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to open a transaction, because the user deleted the database"); 361 handleTransactionError(false); 362 return; 498 return nextStateForTransactionError(); 363 499 } 364 500 … … 375 511 m_database->enableAuthorizer(); 376 512 377 // Transaction Steps 1+2 -Open a transaction to the database, jumping to the error callback if that fails513 // Spec 4.3.2.1+2: Open a transaction to the database, jumping to the error callback if that fails 378 514 if (!m_sqliteTransaction->inProgress()) { 379 515 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); … … 382 518 m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg()); 383 519 m_sqliteTransaction.clear(); 384 handleTransactionError(false); 385 return; 520 return nextStateForTransactionError(); 386 521 } 387 522 … … 397 532 m_sqliteTransaction.clear(); 398 533 m_database->enableAuthorizer(); 399 handleTransactionError(false); 400 return; 534 return nextStateForTransactionError(); 401 535 } 402 536 m_hasVersionMismatch = !m_database->expectedVersion().isEmpty() && (m_database->expectedVersion() != actualVersion); 403 537 404 // Transaction Steps 3 - Peform preflight steps, jumping to the error callback if they fail405 if (m_wrapper && !m_wrapper->performPreflight( SQLTransaction::from(this))) {538 // Spec 4.3.2.3: Perform preflight steps, jumping to the error callback if they fail 539 if (m_wrapper && !m_wrapper->performPreflight(this)) { 406 540 m_database->disableAuthorizer(); 407 541 m_sqliteTransaction.clear(); … … 412 546 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight"); 413 547 } 414 handleTransactionError(false); 415 return; 416 } 417 418 // Transaction Step 4 - Invoke the transaction callback with the new SQLTransaction object 419 m_nextStep = &SQLTransactionBackend::deliverTransactionCallback; 420 LOG(StorageAPI, "Scheduling deliverTransactionCallback for transaction %p\n", this); 421 m_database->scheduleTransactionCallback(SQLTransaction::from(this)); 422 } 423 424 void SQLTransactionBackend::deliverTransactionCallback() 425 { 426 bool shouldDeliverErrorCallback = false; 427 428 RefPtr<SQLTransactionCallback> callback = m_callbackWrapper.unwrap(); 429 if (callback) { 430 m_executeSqlAllowed = true; 431 shouldDeliverErrorCallback = !callback->handleEvent(SQLTransaction::from(this)); 432 m_executeSqlAllowed = false; 433 } 434 435 // Transaction Step 5 - If the transaction callback was null or raised an exception, jump to the error callback 436 if (shouldDeliverErrorCallback) { 437 m_database->reportStartTransactionResult(5, SQLError::UNKNOWN_ERR, 0); 438 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the SQLTransactionCallback was null or threw an exception"); 439 deliverTransactionErrorCallback(); 440 } else 441 scheduleToRunStatements(); 442 443 m_database->reportStartTransactionResult(0, -1, 0); // OK 444 } 445 446 void SQLTransactionBackend::scheduleToRunStatements() 447 { 448 m_nextStep = &SQLTransactionBackend::runStatements; 449 LOG(StorageAPI, "Scheduling runStatements for transaction %p\n", this); 450 m_database->scheduleTransactionStep(this); 451 } 452 453 void SQLTransactionBackend::runStatements() 548 return nextStateForTransactionError(); 549 } 550 551 // Spec 4.3.2.4: Invoke the transaction callback with the new SQLTransaction object 552 if (m_hasCallback) 553 return SQLTransactionState::DeliverTransactionCallback; 554 555 // If we have no callback to make, skip pass to the state after: 556 return SQLTransactionState::RunStatements; 557 } 558 559 SQLTransactionState SQLTransactionBackend::runStatements() 454 560 { 455 561 ASSERT(m_lockAcquired); 562 SQLTransactionState nextState; 456 563 457 564 // If there is a series of statements queued up that are all successful and have no associated … … 472 579 // that means it ended in an error. Handle it now 473 580 if (m_currentStatement && m_currentStatement->lastExecutionFailedDueToQuota()) { 474 handleCurrentStatementError(); 475 break; 581 return nextStateForCurrentStatementError(); 476 582 } 477 583 … … 479 585 getNextStatement(); 480 586 } 481 } while (runCurrentStatement()); 482 483 // If runCurrentStatement() returned false, that means either there was no current statement to run, 484 // or the current statement requires a callback to complete. In the later case, it also scheduled 485 // the callback or performed any other additional work so we can return 486 if (!m_currentStatement) 487 postflightAndCommit(); 587 nextState = runCurrentStatementAndGetNextState(); 588 } while (nextState == SQLTransactionState::RunStatements); 589 590 return nextState; 488 591 } 489 592 … … 497 600 } 498 601 499 bool SQLTransactionBackend::runCurrentStatement() 500 { 501 if (!m_currentStatement) 502 return false; 602 SQLTransactionState SQLTransactionBackend::runCurrentStatementAndGetNextState() 603 { 604 if (!m_currentStatement) { 605 // No more statements to run. So move on to the next state. 606 return SQLTransactionState::PostflightAndCommit; 607 } 503 608 504 609 m_database->resetAuthorizer(); 505 610 506 611 if (m_hasVersionMismatch) 507 m_currentStatement->setVersionMismatchedError( m_database.get());508 509 if (m_currentStatement->execute( m_database.get())) {612 m_currentStatement->setVersionMismatchedError(Database::from(m_database.get())); 613 614 if (m_currentStatement->execute(Database::from(m_database.get()))) { 510 615 if (m_database->lastActionChangedDatabase()) { 511 616 // Flag this transaction as having changed the database for later delegate notification 512 617 m_modifiedDatabase = true; 513 618 // Also dirty the size of this database file for calculating quota usage 514 m_database->transactionClient()->didExecuteStatement( database());619 m_database->transactionClient()->didExecuteStatement(Database::from(database())); 515 620 } 516 621 517 622 if (m_currentStatement->hasStatementCallback()) { 518 m_nextStep = &SQLTransactionBackend::deliverStatementCallback; 519 LOG(StorageAPI, "Scheduling deliverStatementCallback for transaction %p\n", this); 520 m_database->scheduleTransactionCallback(SQLTransaction::from(this)); 521 return false; 623 return SQLTransactionState::DeliverStatementCallback; 522 624 } 523 return true; 625 626 // If we get here, then the statement doesn't have a callback to invoke. 627 // We can move on to the next statement. Hence, stay in this state. 628 return SQLTransactionState::RunStatements; 524 629 } 525 630 526 631 if (m_currentStatement->lastExecutionFailedDueToQuota()) { 527 m_nextStep = &SQLTransactionBackend::deliverQuotaIncreaseCallback; 528 LOG(StorageAPI, "Scheduling deliverQuotaIncreaseCallback for transaction %p\n", this); 529 m_database->scheduleTransactionCallback(SQLTransaction::from(this)); 530 return false; 531 } 532 533 handleCurrentStatementError(); 534 535 return false; 536 } 537 538 void SQLTransactionBackend::handleCurrentStatementError() 539 { 540 // Transaction Steps 6.error - Call the statement's error callback, but if there was no error callback, 632 return SQLTransactionState::DeliverQuotaIncreaseCallback; 633 } 634 635 return nextStateForCurrentStatementError(); 636 } 637 638 SQLTransactionState SQLTransactionBackend::nextStateForCurrentStatementError() 639 { 640 // Spec 4.3.2.6.6: error - Call the statement's error callback, but if there was no error callback, 541 641 // or the transaction was rolled back, jump to the transaction error callback 542 if (m_currentStatement->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite()) { 543 m_nextStep = &SQLTransactionBackend::deliverStatementCallback; 544 LOG(StorageAPI, "Scheduling deliverStatementCallback for transaction %p\n", this); 545 m_database->scheduleTransactionCallback(SQLTransaction::from(this)); 546 } else { 547 m_transactionError = m_currentStatement->sqlError(); 548 if (!m_transactionError) { 549 m_database->reportCommitTransactionResult(1, SQLError::DATABASE_ERR, 0); 550 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute"); 551 } 552 handleTransactionError(false); 553 } 554 } 555 556 void SQLTransactionBackend::deliverStatementCallback() 557 { 558 ASSERT(m_currentStatement); 559 560 // Transaction Step 6.6 and 6.3(error) - If the statement callback went wrong, jump to the transaction error callback 561 // Otherwise, continue to loop through the statement queue 562 m_executeSqlAllowed = true; 563 bool result = m_currentStatement->performCallback(SQLTransaction::from(this)); 564 m_executeSqlAllowed = false; 565 566 if (result) { 567 m_database->reportCommitTransactionResult(2, SQLError::UNKNOWN_ERR, 0); 568 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "the statement callback raised an exception or statement error callback did not return false"); 569 handleTransactionError(true); 570 } else 571 scheduleToRunStatements(); 572 } 573 574 void SQLTransactionBackend::deliverQuotaIncreaseCallback() 575 { 576 ASSERT(m_currentStatement); 577 ASSERT(!m_shouldRetryCurrentStatement); 578 579 m_shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(database()); 580 581 m_nextStep = &SQLTransactionBackend::runStatements; 582 LOG(StorageAPI, "Scheduling runStatements for transaction %p\n", this); 583 m_database->scheduleTransactionStep(this); 584 } 585 586 void SQLTransactionBackend::postflightAndCommit() 642 if (m_currentStatement->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite()) 643 return SQLTransactionState::DeliverStatementCallback; 644 645 m_transactionError = m_currentStatement->sqlError(); 646 if (!m_transactionError) { 647 m_database->reportCommitTransactionResult(1, SQLError::DATABASE_ERR, 0); 648 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute"); 649 } 650 return nextStateForTransactionError(); 651 } 652 653 SQLTransactionState SQLTransactionBackend::postflightAndCommit() 587 654 { 588 655 ASSERT(m_lockAcquired); 589 656 590 // Transaction Step 7 - Peform postflight steps, jumping to the error callback if they fail591 if (m_wrapper && !m_wrapper->performPostflight( SQLTransaction::from(this))) {657 // Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if they fail. 658 if (m_wrapper && !m_wrapper->performPostflight(this)) { 592 659 m_transactionError = m_wrapper->sqlError(); 593 660 if (!m_transactionError) { … … 595 662 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight"); 596 663 } 597 handleTransactionError(false); 598 return; 599 } 600 601 // Transacton Step 8+9 - Commit the transaction, jumping to the error callback if that fails 664 return nextStateForTransactionError(); 665 } 666 667 // Spec 4.3.2.7: Commit the transaction, jumping to the error callback if that fails. 602 668 ASSERT(m_sqliteTransaction); 603 669 … … 609 675 if (m_sqliteTransaction->inProgress()) { 610 676 if (m_wrapper) 611 m_wrapper->handleCommitFailedAfterPostflight(SQLTransaction::from(this)); 612 m_successCallbackWrapper.clear(); 677 m_wrapper->handleCommitFailedAfterPostflight(this); 613 678 m_database->reportCommitTransactionResult(4, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError()); 614 679 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to commit transaction", 615 680 m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg()); 616 handleTransactionError(false); 617 return; 681 return nextStateForTransactionError(); 618 682 } 619 683 … … 628 692 m_database->transactionClient()->didCommitWriteTransaction(database()); 629 693 630 // Now release our unneeded callbacks, to break reference cycles. 631 m_errorCallbackWrapper.clear(); 632 633 // Transaction Step 10 - Deliver success callback, if there is one 634 if (m_successCallbackWrapper.hasCallback()) { 635 m_nextStep = &SQLTransactionBackend::deliverSuccessCallback; 636 LOG(StorageAPI, "Scheduling deliverSuccessCallback for transaction %p\n", this); 637 m_database->scheduleTransactionCallback(SQLTransaction::from(this)); 638 } else 639 cleanupAfterSuccessCallback(); 640 } 641 642 void SQLTransactionBackend::deliverSuccessCallback() 643 { 644 // Transaction Step 10 - Deliver success callback 645 RefPtr<VoidCallback> successCallback = m_successCallbackWrapper.unwrap(); 646 if (successCallback) 647 successCallback->handleEvent(); 648 649 // Schedule a "post-success callback" step to return control to the database thread in case there 650 // are further transactions queued up for this Database 651 m_nextStep = &SQLTransactionBackend::cleanupAfterSuccessCallback; 652 LOG(StorageAPI, "Scheduling cleanupAfterSuccessCallback for transaction %p\n", this); 653 m_database->scheduleTransactionStep(this); 654 } 655 656 void SQLTransactionBackend::cleanupAfterSuccessCallback() 694 // Spec 4.3.2.8: Deliver success callback, if there is one. 695 return SQLTransactionState::DeliverSuccessCallback; 696 } 697 698 SQLTransactionState SQLTransactionBackend::cleanupAndTerminate() 657 699 { 658 700 ASSERT(m_lockAcquired); 659 701 660 // Transaction Step 11 - End transaction steps 661 // There is no next step 702 // Spec 4.3.2.9: End transaction steps. There is no next step. 662 703 LOG(StorageAPI, "Transaction %p is complete\n", this); 663 704 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 664 m_sqliteTransaction.clear(); 665 m_nextStep = 0; 666 667 // Release the lock on this database 668 m_database->transactionCoordinator()->releaseLock(this); 669 } 670 671 void SQLTransactionBackend::handleTransactionError(bool inCallback) 672 { 673 if (m_errorCallbackWrapper.hasCallback()) { 674 if (inCallback) 675 deliverTransactionErrorCallback(); 676 else { 677 m_nextStep = &SQLTransactionBackend::deliverTransactionErrorCallback; 678 LOG(StorageAPI, "Scheduling deliverTransactionErrorCallback for transaction %p\n", this); 679 m_database->scheduleTransactionCallback(SQLTransaction::from(this)); 680 } 681 return; 682 } 683 684 // No error callback, so fast-forward to: 685 // Transaction Step 12 - Rollback the transaction. 686 if (inCallback) { 687 m_nextStep = &SQLTransactionBackend::cleanupAfterTransactionErrorCallback; 688 LOG(StorageAPI, "Scheduling cleanupAfterTransactionErrorCallback for transaction %p\n", this); 689 m_database->scheduleTransactionStep(this); 690 } else 691 cleanupAfterTransactionErrorCallback(); 692 } 693 694 void SQLTransactionBackend::deliverTransactionErrorCallback() 705 706 doCleanup(); 707 m_database->inProgressTransactionCompleted(); 708 return SQLTransactionState::End; 709 } 710 711 SQLTransactionState SQLTransactionBackend::nextStateForTransactionError() 695 712 { 696 713 ASSERT(m_transactionError); 697 698 // Transaction Step 12 - If exists, invoke error callback with the last 699 // error to have occurred in this transaction. 700 RefPtr<SQLTransactionErrorCallback> errorCallback = m_errorCallbackWrapper.unwrap(); 701 if (errorCallback) 702 errorCallback->handleEvent(m_transactionError.get()); 703 704 m_nextStep = &SQLTransactionBackend::cleanupAfterTransactionErrorCallback; 705 LOG(StorageAPI, "Scheduling cleanupAfterTransactionErrorCallback for transaction %p\n", this); 706 m_database->scheduleTransactionStep(this); 707 } 708 709 void SQLTransactionBackend::cleanupAfterTransactionErrorCallback() 714 if (m_hasErrorCallback) 715 return SQLTransactionState::DeliverTransactionErrorCallback; 716 717 // No error callback, so fast-forward to the next state and rollback the 718 // transaction. 719 return SQLTransactionState::CleanupAfterTransactionErrorCallback; 720 } 721 722 SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback() 710 723 { 711 724 ASSERT(m_lockAcquired); 712 725 726 LOG(StorageAPI, "Transaction %p is complete with an error\n", this); 713 727 m_database->disableAuthorizer(); 714 728 if (m_sqliteTransaction) { 715 // Transaction Step 12 -Rollback the transaction.729 // Spec 4.3.2.10: Rollback the transaction. 716 730 m_sqliteTransaction->rollback(); 717 731 … … 721 735 m_database->enableAuthorizer(); 722 736 723 // Transaction Step 12 - Any still-pending statements in the transaction are discarded.724 {725 MutexLocker locker(m_statementMutex);726 m_statementQueue.clear();727 }728 729 // Transaction is complete! There is no next step730 LOG(StorageAPI, "Transaction %p is complete with an error\n", this);731 737 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); 732 m_nextStep = 0; 733 734 // Now release the lock on this database 735 m_database->transactionCoordinator()->releaseLock(this); 738 739 return SQLTransactionState::CleanupAndTerminate; 740 } 741 742 // requestTransitToState() can be called from the frontend. Hence, it should 743 // NOT be modifying SQLTransactionBackend in general. The only safe field to 744 // modify is m_requestedState which is meant for this purpose. 745 void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState) 746 { 747 LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this); 748 m_requestedState = nextState; 749 ASSERT(m_requestedState != SQLTransactionState::End); 750 m_database->scheduleTransactionStep(this); 751 } 752 753 // This state function is used as a stub function to plug unimplemented states 754 // in the state dispatch table. They are unimplemented because they should 755 // never be reached in the course of correct execution. 756 SQLTransactionState SQLTransactionBackend::unreachableState() 757 { 758 ASSERT_NOT_REACHED(); 759 return SQLTransactionState::End; 760 } 761 762 SQLTransactionState SQLTransactionBackend::sendToFrontendState() 763 { 764 ASSERT(m_nextState != SQLTransactionState::Idle); 765 m_frontend->requestTransitToState(m_nextState); 766 return SQLTransactionState::Idle; 736 767 } 737 768 -
trunk/Source/WebCore/Modules/webdatabase/SQLTransactionBackend.h
r142193 r142921 33 33 #include "DatabaseBasicTypes.h" 34 34 #include "SQLStatement.h" 35 #include "SQLTransactionStateMachine.h" 35 36 #include <wtf/Deque.h> 36 37 #include <wtf/Forward.h> 37 #include <wtf/ThreadSafeRefCounted.h>38 #include <wtf/Vector.h>39 38 40 39 namespace WebCore { 41 40 42 class Database ;41 class DatabaseBackendAsync; 43 42 class SQLError; 44 43 class SQLiteTransaction; 45 class SQLStatementCallback;46 class SQLStatementErrorCallback;47 44 class SQLTransaction; 48 class SQLTransactionCallback; 49 class SQLTransactionErrorCallback; 45 class SQLTransactionBackend; 50 46 class SQLValue; 51 class VoidCallback;52 47 53 48 class SQLTransactionWrapper : public ThreadSafeRefCounted<SQLTransactionWrapper> { 54 49 public: 55 50 virtual ~SQLTransactionWrapper() { } 56 virtual bool performPreflight(SQLTransaction *) = 0;57 virtual bool performPostflight(SQLTransaction *) = 0;51 virtual bool performPreflight(SQLTransactionBackend*) = 0; 52 virtual bool performPostflight(SQLTransactionBackend*) = 0; 58 53 virtual SQLError* sqlError() const = 0; 59 virtual void handleCommitFailedAfterPostflight(SQLTransaction *) = 0;54 virtual void handleCommitFailedAfterPostflight(SQLTransactionBackend*) = 0; 60 55 }; 61 56 62 class SQLTransactionBackend : public ThreadSafeRefCounted<SQLTransactionBackend> {57 class SQLTransactionBackend : public SQLTransactionStateMachine<SQLTransactionBackend> { 63 58 public: 64 ~SQLTransactionBackend(); 59 static PassRefPtr<SQLTransactionBackend> create(DatabaseBackendAsync*, 60 PassRefPtr<SQLTransaction>, PassRefPtr<SQLTransactionWrapper>, bool readOnly); 65 61 66 void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, 67 PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, ExceptionCode&); 62 virtual ~SQLTransactionBackend(); 68 63 69 64 void lockAcquired(); 70 bool performNextStep(); 71 void performPendingCallback(); 65 void performNextStep(); 72 66 73 Database * database() { return m_database.get(); }67 DatabaseBackendAsync* database() { return m_database.get(); } 74 68 bool isReadOnly() { return m_readOnly; } 75 69 void notifyDatabaseThreadIsShuttingDown(); 76 70 71 PassRefPtr<SQLError> transactionError(); 72 void setShouldRetryCurrentStatement(bool); 73 77 74 private: 78 SQLTransactionBackend(Database *, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>,79 PassRefPtr< VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly);75 SQLTransactionBackend(DatabaseBackendAsync*, PassRefPtr<SQLTransaction>, 76 PassRefPtr<SQLTransactionWrapper>, bool readOnly); 80 77 81 typedef void (SQLTransactionBackend::*TransactionStepMethod)(); 82 TransactionStepMethod m_nextStep; 78 void doCleanup(); 83 79 84 80 void enqueueStatement(PassRefPtr<SQLStatement>); … … 86 82 void checkAndHandleClosedOrInterruptedDatabase(); 87 83 88 void acquireLock(); 89 void openTransactionAndPreflight(); 90 void deliverTransactionCallback(); 91 void scheduleToRunStatements(); 92 void runStatements(); 84 // State Machine functions: 85 virtual StateFunction stateFunctionFor(SQLTransactionState); 86 void requestTransitToState(SQLTransactionState); 87 88 // State functions: 89 SQLTransactionState acquireLock(); 90 SQLTransactionState openTransactionAndPreflight(); 91 SQLTransactionState runStatements(); 92 SQLTransactionState postflightAndCommit(); 93 SQLTransactionState cleanupAndTerminate(); 94 SQLTransactionState cleanupAfterTransactionErrorCallback(); 95 96 SQLTransactionState unreachableState(); 97 SQLTransactionState sendToFrontendState(); 98 99 SQLTransactionState nextStateForCurrentStatementError(); 100 SQLTransactionState nextStateForTransactionError(); 101 SQLTransactionState runCurrentStatementAndGetNextState(); 102 93 103 void getNextStatement(); 94 bool runCurrentStatement();95 void handleCurrentStatementError();96 void deliverStatementCallback();97 void deliverQuotaIncreaseCallback();98 void postflightAndCommit();99 void deliverSuccessCallback();100 void cleanupAfterSuccessCallback();101 void handleTransactionError(bool inCallback);102 void deliverTransactionErrorCallback();103 void cleanupAfterTransactionErrorCallback();104 104 105 #if !LOG_DISABLED 106 static const char* debugStepName(TransactionStepMethod); 107 #endif 108 105 RefPtr<SQLTransaction> m_frontend; 109 106 RefPtr<SQLStatement> m_currentStatement; 110 107 111 bool m_executeSqlAllowed; 108 RefPtr<DatabaseBackendAsync> m_database; 109 RefPtr<SQLTransactionWrapper> m_wrapper; 110 RefPtr<SQLError> m_transactionError; 112 111 113 RefPtr<Database> m_database; 114 RefPtr<SQLTransactionWrapper> m_wrapper; 115 SQLCallbackWrapper<SQLTransactionCallback> m_callbackWrapper; 116 SQLCallbackWrapper<VoidCallback> m_successCallbackWrapper; 117 SQLCallbackWrapper<SQLTransactionErrorCallback> m_errorCallbackWrapper; 118 RefPtr<SQLError> m_transactionError; 112 bool m_hasCallback; 113 bool m_hasSuccessCallback; 114 bool m_hasErrorCallback; 119 115 bool m_shouldRetryCurrentStatement; 120 116 bool m_modifiedDatabase; … … 128 124 OwnPtr<SQLiteTransaction> m_sqliteTransaction; 129 125 130 friend class SQLTransaction; // FIXME: Remove this once the front-end has been properly isolated.126 friend class SQLTransaction; 131 127 }; 132 128 -
trunk/Source/WebCore/Modules/webdatabase/SQLTransactionClient.cpp
r141928 r142921 37 37 #include "DatabaseBackendContext.h" 38 38 #include "DatabaseManager.h" 39 #include "DatabaseTracker.h" 39 40 #include "ScriptExecutionContext.h" 40 41 #include "SecurityOrigin.h" … … 44 45 void SQLTransactionClient::didCommitWriteTransaction(DatabaseBackend* database) 45 46 { 46 Database Manager::manager().scheduleNotifyDatabaseChanged(47 DatabaseTracker::tracker().scheduleNotifyDatabaseChanged( 47 48 database->securityOrigin(), database->stringIdentifier()); 48 49 } … … 50 51 void SQLTransactionClient::didExecuteStatement(DatabaseBackend* database) 51 52 { 52 Database Manager::manager().databaseChanged(database);53 DatabaseTracker::tracker().databaseChanged(database); 53 54 } 54 55 -
trunk/Source/WebCore/Modules/webdatabase/SQLTransactionCoordinator.cpp
r142193 r142921 35 35 #if ENABLE(SQL_DATABASE) 36 36 37 #include "Database .h"37 #include "DatabaseBackendAsync.h" 38 38 #include "SQLTransactionBackend.h" 39 39 #include <wtf/Deque.h> … … 46 46 static String getDatabaseIdentifier(SQLTransactionBackend* transaction) 47 47 { 48 Database * database = transaction->database();48 DatabaseBackendAsync* database = transaction->database(); 49 49 ASSERT(database); 50 50 return database->stringIdentifier(); -
trunk/Source/WebCore/Target.pri
r142823 r142921 1456 1456 \ 1457 1457 Modules/webdatabase/AbstractDatabaseServer.h \ 1458 Modules/webdatabase/ChangeVersionData.h \ 1458 1459 Modules/webdatabase/ChangeVersionWrapper.h \ 1459 1460 Modules/webdatabase/DOMWindowWebDatabase.h \ … … 1486 1487 Modules/webdatabase/SQLTransactionClient.h \ 1487 1488 Modules/webdatabase/SQLTransactionCoordinator.h \ 1489 Modules/webdatabase/SQLTransactionState.h \ 1490 Modules/webdatabase/SQLTransactionStateMachine.h \ 1488 1491 Modules/webdatabase/SQLTransactionSync.h \ 1489 1492 Modules/webdatabase/SQLTransactionSyncCallback.h \ … … 3075 3078 Modules/webdatabase/SQLTransactionClient.cpp \ 3076 3079 Modules/webdatabase/SQLTransactionCoordinator.cpp \ 3080 Modules/webdatabase/SQLTransactionStateMachine.cpp \ 3077 3081 Modules/webdatabase/SQLTransactionSync.cpp \ 3078 3082 -
trunk/Source/WebCore/WebCore.gypi
r142896 r142921 985 985 'Modules/webaudio/WaveTable.h', 986 986 'Modules/webdatabase/AbstractDatabaseServer.h', 987 'Modules/webdatabase/ChangeVersionData.h', 987 988 'Modules/webdatabase/ChangeVersionWrapper.cpp', 988 989 'Modules/webdatabase/ChangeVersionWrapper.h', … … 1040 1041 'Modules/webdatabase/SQLTransactionCoordinator.cpp', 1041 1042 'Modules/webdatabase/SQLTransactionCoordinator.h', 1043 'Modules/webdatabase/SQLTransactionState.h', 1044 'Modules/webdatabase/SQLTransactionStateMachine.cpp', 1045 'Modules/webdatabase/SQLTransactionStateMachine.h', 1042 1046 'Modules/webdatabase/SQLTransactionSync.cpp', 1043 1047 'Modules/webdatabase/SQLTransactionSync.h', -
trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj
r142862 r142921 25379 25379 </File> 25380 25380 <File 25381 RelativePath="..\Modules\webdatabase\ChangeVersionData.h" 25382 > 25383 </File> 25384 <File 25381 25385 RelativePath="..\Modules\webdatabase\ChangeVersionWrapper.cpp" 25382 25386 > … … 25636 25640 <File 25637 25641 RelativePath="..\Modules\webdatabase\SQLTransactionErrorCallback.h" 25642 > 25643 </File> 25644 <File 25645 RelativePath="..\Modules\webdatabase\SQLTransactionState.h" 25646 > 25647 </File> 25648 <File 25649 RelativePath="..\Modules\webdatabase\SQLTransactionStateMachine.cpp" 25650 > 25651 </File> 25652 <File 25653 RelativePath="..\Modules\webdatabase\SQLTransactionStateMachine.h" 25638 25654 > 25639 25655 </File> -
trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
r142809 r142921 1881 1881 <ClCompile Include="..\Modules\webdatabase\SQLTransactionClient.cpp" /> 1882 1882 <ClCompile Include="..\Modules\webdatabase\SQLTransactionCoordinator.cpp" /> 1883 <ClCompile Include="..\Modules\webdatabase\SQLTransactionStateMachine.cpp" /> 1883 1884 <ClCompile Include="..\Modules\webdatabase\SQLTransactionSync.cpp" /> 1884 1885 <ClCompile Include="..\Modules\webdatabase\WorkerContextWebDatabase.cpp" /> … … 6416 6417 <ClInclude Include="..\Modules\notifications\WorkerContextNotifications.h" /> 6417 6418 <ClInclude Include="..\Modules\webdatabase\AbstractDatabaseServer.h" /> 6419 <ClInclude Include="..\Modules\webdatabase\ChangeVersionData.h" /> 6418 6420 <ClInclude Include="..\Modules\webdatabase\ChangeVersionWrapper.h" /> 6419 6421 <ClInclude Include="..\Modules\webdatabase\Database.h" /> … … 6453 6455 <ClInclude Include="..\Modules\webdatabase\SQLTransactionCoordinator.h" /> 6454 6456 <ClInclude Include="..\Modules\webdatabase\SQLTransactionErrorCallback.h" /> 6457 <ClInclude Include="..\Modules\webdatabase\SQLTransactionState.h" /> 6458 <ClInclude Include="..\Modules\webdatabase\SQLTransactionStateMachine.h" /> 6455 6459 <ClInclude Include="..\Modules\webdatabase\SQLTransactionSync.h" /> 6456 6460 <ClInclude Include="..\Modules\webdatabase\SQLTransactionSyncCallback.h" /> -
trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
r142641 r142921 1900 1900 <Filter>Modules\webdatabase</Filter> 1901 1901 </ClCompile> 1902 <ClCompile Include="..\Modules\webdatabase\SQLTransaction.cpp">1903 <Filter>Modules\webdatabase</Filter>1904 </ClCompile>1905 1902 <ClCompile Include="..\Modules\webdatabase\SQLTransactionBackend.cpp"> 1906 1903 <Filter>Modules\webdatabase</Filter> … … 1913 1910 </ClCompile> 1914 1911 <ClCompile Include="..\Modules\webdatabase\SQLTransactionCoordinator.cpp"> 1912 <Filter>Modules\webdatabase</Filter> 1913 </ClCompile> 1914 <ClCompile Include="..\Modules\webdatabase\SQLTransactionStateMachine.cpp"> 1915 1915 <Filter>Modules\webdatabase</Filter> 1916 1916 </ClCompile> … … 8473 8473 <Filter>Modules\webdatabase</Filter> 8474 8474 </ClInclude> 8475 <ClInclude Include="..\Modules\webdatabase\ChangeVersionData.h"> 8476 <Filter>Modules\webdatabase</Filter> 8477 </ClInclude> 8475 8478 <ClInclude Include="..\Modules\webdatabase\ChangeVersionWrapper.h"> 8476 8479 <Filter>Modules\webdatabase</Filter> … … 8582 8585 </ClInclude> 8583 8586 <ClInclude Include="..\Modules\webdatabase\SQLTransactionErrorCallback.h"> 8587 <Filter>Modules\webdatabase</Filter> 8588 </ClInclude> 8589 <ClInclude Include="..\Modules\webdatabase\SQLTransactionState.h"> 8590 <Filter>Modules\webdatabase</Filter> 8591 </ClInclude> 8592 <ClInclude Include="..\Modules\webdatabase\SQLTransactionStateMachine.h"> 8584 8593 <Filter>Modules\webdatabase</Filter> 8585 8594 </ClInclude> -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r142823 r142921 3707 3707 97BC69DA1505F076001B74AC /* DatabaseBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC69D61505F076001B74AC /* DatabaseBackend.cpp */; }; 3708 3708 97BC69DB1505F076001B74AC /* DatabaseBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC69D71505F076001B74AC /* DatabaseBackend.h */; settings = {ATTRIBUTES = (Private, ); }; }; 3709 FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */ = {isa = PBXBuildFile; fileRef = FE36FD1116C7826400F887C1 /* ChangeVersionData.h */; }; 3709 3710 97BC69DC1505F076001B74AC /* ChangeVersionWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC69D81505F076001B74AC /* ChangeVersionWrapper.cpp */; }; 3710 3711 97BC69DD1505F076001B74AC /* ChangeVersionWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC69D91505F076001B74AC /* ChangeVersionWrapper.h */; }; … … 3746 3747 97BC6A4F1505F081001B74AC /* SQLTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC6A0D1505F081001B74AC /* SQLTransaction.cpp */; }; 3747 3748 97BC6A501505F081001B74AC /* SQLTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A0E1505F081001B74AC /* SQLTransaction.h */; }; 3749 FEE1811316C319E800084849 /* SQLTransactionBackend.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEE1811116C319E800084849 /* SQLTransactionBackend.cpp */; }; 3750 FEE1811416C319E800084849 /* SQLTransactionBackend.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE1811216C319E800084849 /* SQLTransactionBackend.h */; }; 3751 FEAD7D8716C339EE00D4670B /* SQLTransactionBackendSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEAD7D8516C339EE00D4670B /* SQLTransactionBackendSync.cpp */; }; 3752 FEAD7D8816C339EE00D4670B /* SQLTransactionBackendSync.h in Headers */ = {isa = PBXBuildFile; fileRef = FEAD7D8616C339EE00D4670B /* SQLTransactionBackendSync.h */; }; 3748 3753 97BC6A521505F081001B74AC /* SQLTransactionCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A101505F081001B74AC /* SQLTransactionCallback.h */; }; 3749 3754 97BC6A541505F081001B74AC /* SQLTransactionClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC6A121505F081001B74AC /* SQLTransactionClient.cpp */; }; … … 3752 3757 97BC6A571505F081001B74AC /* SQLTransactionCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A151505F081001B74AC /* SQLTransactionCoordinator.h */; }; 3753 3758 97BC6A581505F081001B74AC /* SQLTransactionErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A161505F081001B74AC /* SQLTransactionErrorCallback.h */; }; 3759 FE36FD1816C7826500F887C1 /* SQLTransactionState.h in Headers */ = {isa = PBXBuildFile; fileRef = FE36FD1416C7826400F887C1 /* SQLTransactionState.h */; }; 3760 FE36FD1616C7826500F887C1 /* SQLTransactionStateMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE36FD1216C7826400F887C1 /* SQLTransactionStateMachine.cpp */; }; 3761 FE36FD1716C7826500F887C1 /* SQLTransactionStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = FE36FD1316C7826400F887C1 /* SQLTransactionStateMachine.h */; }; 3754 3762 97BC6A5A1505F081001B74AC /* SQLTransactionSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 97BC6A181505F081001B74AC /* SQLTransactionSync.cpp */; }; 3755 3763 97BC6A5B1505F081001B74AC /* SQLTransactionSync.h in Headers */ = {isa = PBXBuildFile; fileRef = 97BC6A191505F081001B74AC /* SQLTransactionSync.h */; }; … … 11158 11166 97BC69D61505F076001B74AC /* DatabaseBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DatabaseBackend.cpp; path = Modules/webdatabase/DatabaseBackend.cpp; sourceTree = "<group>"; }; 11159 11167 97BC69D71505F076001B74AC /* DatabaseBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DatabaseBackend.h; path = Modules/webdatabase/DatabaseBackend.h; sourceTree = "<group>"; }; 11168 FE36FD1116C7826400F887C1 /* ChangeVersionData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChangeVersionData.h; path = Modules/webdatabase/ChangeVersionData.h; sourceTree = "<group>"; }; 11160 11169 97BC69D81505F076001B74AC /* ChangeVersionWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ChangeVersionWrapper.cpp; path = Modules/webdatabase/ChangeVersionWrapper.cpp; sourceTree = "<group>"; }; 11161 11170 97BC69D91505F076001B74AC /* ChangeVersionWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ChangeVersionWrapper.h; path = Modules/webdatabase/ChangeVersionWrapper.h; sourceTree = "<group>"; }; … … 11207 11216 97BC6A0E1505F081001B74AC /* SQLTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransaction.h; path = Modules/webdatabase/SQLTransaction.h; sourceTree = "<group>"; }; 11208 11217 97BC6A0F1505F081001B74AC /* SQLTransaction.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SQLTransaction.idl; path = Modules/webdatabase/SQLTransaction.idl; sourceTree = "<group>"; }; 11218 FEE1811116C319E800084849 /* SQLTransactionBackend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionBackend.cpp; path = Modules/webdatabase/SQLTransactionBackend.cpp; sourceTree = "<group>"; }; 11219 FEE1811216C319E800084849 /* SQLTransactionBackend.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionBackend.h; path = Modules/webdatabase/SQLTransactionBackend.h; sourceTree = "<group>"; }; 11220 FEAD7D8516C339EE00D4670B /* SQLTransactionBackendSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionBackendSync.cpp; path = Modules/webdatabase/SQLTransactionBackendSync.cpp; sourceTree = "<group>"; }; 11221 FEAD7D8616C339EE00D4670B /* SQLTransactionBackendSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionBackendSync.h; path = Modules/webdatabase/SQLTransactionBackendSync.h; sourceTree = "<group>"; }; 11209 11222 97BC6A101505F081001B74AC /* SQLTransactionCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionCallback.h; path = Modules/webdatabase/SQLTransactionCallback.h; sourceTree = "<group>"; }; 11210 11223 97BC6A111505F081001B74AC /* SQLTransactionCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SQLTransactionCallback.idl; path = Modules/webdatabase/SQLTransactionCallback.idl; sourceTree = "<group>"; }; … … 11215 11228 97BC6A161505F081001B74AC /* SQLTransactionErrorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionErrorCallback.h; path = Modules/webdatabase/SQLTransactionErrorCallback.h; sourceTree = "<group>"; }; 11216 11229 97BC6A171505F081001B74AC /* SQLTransactionErrorCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = SQLTransactionErrorCallback.idl; path = Modules/webdatabase/SQLTransactionErrorCallback.idl; sourceTree = "<group>"; }; 11230 FE36FD1416C7826400F887C1 /* SQLTransactionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionState.h; path = Modules/webdatabase/SQLTransactionState.h; sourceTree = "<group>"; }; 11231 FE36FD1216C7826400F887C1 /* SQLTransactionStateMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionStateMachine.cpp; path = Modules/webdatabase/SQLTransactionStateMachine.cpp; sourceTree = "<group>"; }; 11232 FE36FD1316C7826400F887C1 /* SQLTransactionStateMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionStateMachine.h; path = Modules/webdatabase/SQLTransactionStateMachine.h; sourceTree = "<group>"; }; 11217 11233 97BC6A181505F081001B74AC /* SQLTransactionSync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SQLTransactionSync.cpp; path = Modules/webdatabase/SQLTransactionSync.cpp; sourceTree = "<group>"; }; 11218 11234 97BC6A191505F081001B74AC /* SQLTransactionSync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SQLTransactionSync.h; path = Modules/webdatabase/SQLTransactionSync.h; sourceTree = "<group>"; }; … … 18616 18632 children = ( 18617 18633 FE115FA9167988CD00249134 /* AbstractDatabaseServer.h */, 18634 FE36FD1116C7826400F887C1 /* ChangeVersionData.h */, 18618 18635 97BC69D81505F076001B74AC /* ChangeVersionWrapper.cpp */, 18619 18636 97BC69D91505F076001B74AC /* ChangeVersionWrapper.h */, … … 18696 18713 97BC6A161505F081001B74AC /* SQLTransactionErrorCallback.h */, 18697 18714 97BC6A171505F081001B74AC /* SQLTransactionErrorCallback.idl */, 18715 FE36FD1416C7826400F887C1 /* SQLTransactionState.h */, 18716 FE36FD1216C7826400F887C1 /* SQLTransactionStateMachine.cpp */, 18717 FE36FD1316C7826400F887C1 /* SQLTransactionStateMachine.h */, 18698 18718 97BC6A181505F081001B74AC /* SQLTransactionSync.cpp */, 18699 18719 97BC6A191505F081001B74AC /* SQLTransactionSync.h */, … … 23314 23334 079D086B162F21F900DB8658 /* CaptionUserPreferencesMac.h in Headers */, 23315 23335 6550B69E099DF0270090D781 /* CDATASection.h in Headers */, 23336 FE36FD1516C7826500F887C1 /* ChangeVersionData.h in Headers */, 23316 23337 97BC69DD1505F076001B74AC /* ChangeVersionWrapper.h in Headers */, 23317 23338 FD315FFF12B0267600C1A359 /* ChannelMergerNode.h in Headers */, … … 25928 25949 97BC6A571505F081001B74AC /* SQLTransactionCoordinator.h in Headers */, 25929 25950 97BC6A581505F081001B74AC /* SQLTransactionErrorCallback.h in Headers */, 25951 FE36FD1816C7826500F887C1 /* SQLTransactionState.h in Headers */, 25952 FE36FD1716C7826500F887C1 /* SQLTransactionStateMachine.h in Headers */, 25930 25953 97BC6A5B1505F081001B74AC /* SQLTransactionSync.h in Headers */, 25931 25954 97BC6A5D1505F081001B74AC /* SQLTransactionSyncCallback.h in Headers */, … … 29226 29249 97BC6A541505F081001B74AC /* SQLTransactionClient.cpp in Sources */, 29227 29250 97BC6A561505F081001B74AC /* SQLTransactionCoordinator.cpp in Sources */, 29251 FE36FD1616C7826500F887C1 /* SQLTransactionStateMachine.cpp in Sources */, 29228 29252 97BC6A5A1505F081001B74AC /* SQLTransactionSync.cpp in Sources */, 29229 29253 1A2E6E590CC55213004A2062 /* SQLValue.cpp in Sources */, -
trunk/Source/WebCore/inspector/InspectorDatabaseAgent.cpp
r142375 r142921 42 42 #include "InstrumentingAgents.h" 43 43 #include "SQLError.h" 44 #include "SQLResultSet.h" 45 #include "SQLResultSetRowList.h" 44 46 #include "SQLStatementCallback.h" 45 47 #include "SQLStatementErrorCallback.h" 46 #include "SQLResultSetRowList.h"47 48 #include "SQLTransaction.h" 48 49 #include "SQLTransactionCallback.h"
Note: See TracChangeset
for help on using the changeset viewer.