OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 , m_executeSqlAllowed(false) | 71 , m_executeSqlAllowed(false) |
72 , m_database(db) | 72 , m_database(db) |
73 , m_wrapper(wrapper) | 73 , m_wrapper(wrapper) |
74 , m_callbackWrapper(callback, db->scriptExecutionContext()) | 74 , m_callbackWrapper(callback, db->scriptExecutionContext()) |
75 , m_successCallbackWrapper(successCallback, db->scriptExecutionContext()) | 75 , m_successCallbackWrapper(successCallback, db->scriptExecutionContext()) |
76 , m_errorCallbackWrapper(errorCallback, db->scriptExecutionContext()) | 76 , m_errorCallbackWrapper(errorCallback, db->scriptExecutionContext()) |
77 , m_shouldRetryCurrentStatement(false) | 77 , m_shouldRetryCurrentStatement(false) |
78 , m_modifiedDatabase(false) | 78 , m_modifiedDatabase(false) |
79 , m_lockAcquired(false) | 79 , m_lockAcquired(false) |
80 , m_readOnly(readOnly) | 80 , m_readOnly(readOnly) |
| 81 , m_hasVersionMismatch(false) |
81 { | 82 { |
82 ASSERT(m_database); | 83 ASSERT(m_database); |
83 } | 84 } |
84 | 85 |
85 SQLTransaction::~SQLTransaction() | 86 SQLTransaction::~SQLTransaction() |
86 { | 87 { |
87 ASSERT(!m_sqliteTransaction); | 88 ASSERT(!m_sqliteTransaction); |
88 } | 89 } |
89 | 90 |
90 void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValu
e>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatemen
tErrorCallback> callbackError, ExceptionCode& e) | 91 void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValu
e>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatemen
tErrorCallback> callbackError, ExceptionCode& e) |
91 { | 92 { |
92 if (!m_executeSqlAllowed || !m_database->opened()) { | 93 if (!m_executeSqlAllowed || !m_database->opened()) { |
93 e = INVALID_STATE_ERR; | 94 e = INVALID_STATE_ERR; |
94 return; | 95 return; |
95 } | 96 } |
96 | 97 |
97 int permissions = DatabaseAuthorizer::ReadWriteMask; | 98 int permissions = DatabaseAuthorizer::ReadWriteMask; |
98 if (!m_database->scriptExecutionContext()->allowDatabaseAccess()) | 99 if (!m_database->scriptExecutionContext()->allowDatabaseAccess()) |
99 permissions |= DatabaseAuthorizer::NoAccessMask; | 100 permissions |= DatabaseAuthorizer::NoAccessMask; |
100 else if (m_readOnly) | 101 else if (m_readOnly) |
101 permissions |= DatabaseAuthorizer::ReadOnlyMask; | 102 permissions |= DatabaseAuthorizer::ReadOnlyMask; |
102 | 103 |
103 RefPtr<SQLStatement> statement = SQLStatement::create(m_database.get(), sqlS
tatement, arguments, callback, callbackError, permissions); | 104 RefPtr<SQLStatement> statement = SQLStatement::create(m_database.get(), sqlS
tatement, arguments, callback, callbackError, permissions); |
104 | 105 |
105 if (m_database->deleted()) | 106 if (m_database->deleted()) |
106 statement->setDatabaseDeletedError(); | 107 statement->setDatabaseDeletedError(); |
107 | 108 |
108 if (!m_database->versionMatchesExpected()) | |
109 statement->setVersionMismatchedError(); | |
110 | |
111 enqueueStatement(statement); | 109 enqueueStatement(statement); |
112 } | 110 } |
113 | 111 |
114 void SQLTransaction::enqueueStatement(PassRefPtr<SQLStatement> statement) | 112 void SQLTransaction::enqueueStatement(PassRefPtr<SQLStatement> statement) |
115 { | 113 { |
116 MutexLocker locker(m_statementMutex); | 114 MutexLocker locker(m_statementMutex); |
117 m_statementQueue.append(statement); | 115 m_statementQueue.append(statement); |
118 } | 116 } |
119 | 117 |
120 #if !LOG_DISABLED | 118 #if !LOG_DISABLED |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 | 263 |
266 // Transaction Steps 1+2 - Open a transaction to the database, jumping to th
e error callback if that fails | 264 // Transaction Steps 1+2 - Open a transaction to the database, jumping to th
e error callback if that fails |
267 if (!m_sqliteTransaction->inProgress()) { | 265 if (!m_sqliteTransaction->inProgress()) { |
268 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 266 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
269 m_sqliteTransaction.clear(); | 267 m_sqliteTransaction.clear(); |
270 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to
open a transaction to the database"); | 268 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to
open a transaction to the database"); |
271 handleTransactionError(false); | 269 handleTransactionError(false); |
272 return; | 270 return; |
273 } | 271 } |
274 | 272 |
| 273 // Note: We intentionally retrieve the actual version even with an empty exp
ected version. |
| 274 // In multi-process browsers, we take this opportinutiy to update the cached
value for |
| 275 // the actual version. In single-process browsers, this is just a map lookup
. |
| 276 String actualVersion; |
| 277 if (!m_database->getActualVersionForTransaction(actualVersion)) { |
| 278 m_database->disableAuthorizer(); |
| 279 m_sqliteTransaction.clear(); |
| 280 m_database->enableAuthorizer(); |
| 281 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to
read version"); |
| 282 handleTransactionError(false); |
| 283 return; |
| 284 } |
| 285 m_hasVersionMismatch = !m_database->expectedVersion().isEmpty() |
| 286 && (m_database->expectedVersion() != actualVersion); |
| 287 |
275 // Transaction Steps 3 - Peform preflight steps, jumping to the error callba
ck if they fail | 288 // Transaction Steps 3 - Peform preflight steps, jumping to the error callba
ck if they fail |
276 if (m_wrapper && !m_wrapper->performPreflight(this)) { | 289 if (m_wrapper && !m_wrapper->performPreflight(this)) { |
| 290 m_database->disableAuthorizer(); |
277 m_sqliteTransaction.clear(); | 291 m_sqliteTransaction.clear(); |
| 292 m_database->enableAuthorizer(); |
278 m_transactionError = m_wrapper->sqlError(); | 293 m_transactionError = m_wrapper->sqlError(); |
279 if (!m_transactionError) | 294 if (!m_transactionError) |
280 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknow
n error occured setting up transaction"); | 295 m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknow
n error occured setting up transaction"); |
281 | 296 |
282 handleTransactionError(false); | 297 handleTransactionError(false); |
283 return; | 298 return; |
284 } | 299 } |
285 | 300 |
286 // Transaction Step 4 - Invoke the transaction callback with the new SQLTran
saction object | 301 // Transaction Step 4 - Invoke the transaction callback with the new SQLTran
saction object |
287 m_nextStep = &SQLTransaction::deliverTransactionCallback; | 302 m_nextStep = &SQLTransaction::deliverTransactionCallback; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 } | 377 } |
363 } | 378 } |
364 | 379 |
365 bool SQLTransaction::runCurrentStatement() | 380 bool SQLTransaction::runCurrentStatement() |
366 { | 381 { |
367 if (!m_currentStatement) | 382 if (!m_currentStatement) |
368 return false; | 383 return false; |
369 | 384 |
370 m_database->resetAuthorizer(); | 385 m_database->resetAuthorizer(); |
371 | 386 |
| 387 if (m_hasVersionMismatch) |
| 388 m_currentStatement->setVersionMismatchedError(); |
| 389 |
372 if (m_currentStatement->execute(m_database.get())) { | 390 if (m_currentStatement->execute(m_database.get())) { |
373 if (m_database->lastActionChangedDatabase()) { | 391 if (m_database->lastActionChangedDatabase()) { |
374 // Flag this transaction as having changed the database for later de
legate notification | 392 // Flag this transaction as having changed the database for later de
legate notification |
375 m_modifiedDatabase = true; | 393 m_modifiedDatabase = true; |
376 // Also dirty the size of this database file for calculating quota u
sage | 394 // Also dirty the size of this database file for calculating quota u
sage |
377 m_database->transactionClient()->didExecuteStatement(database()); | 395 m_database->transactionClient()->didExecuteStatement(database()); |
378 } | 396 } |
379 | 397 |
380 if (m_currentStatement->hasStatementCallback()) { | 398 if (m_currentStatement->hasStatementCallback()) { |
381 m_nextStep = &SQLTransaction::deliverStatementCallback; | 399 m_nextStep = &SQLTransaction::deliverStatementCallback; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 476 |
459 // Transacton Step 8+9 - Commit the transaction, jumping to the error callba
ck if that fails | 477 // Transacton Step 8+9 - Commit the transaction, jumping to the error callba
ck if that fails |
460 ASSERT(m_sqliteTransaction); | 478 ASSERT(m_sqliteTransaction); |
461 | 479 |
462 m_database->disableAuthorizer(); | 480 m_database->disableAuthorizer(); |
463 m_sqliteTransaction->commit(); | 481 m_sqliteTransaction->commit(); |
464 m_database->enableAuthorizer(); | 482 m_database->enableAuthorizer(); |
465 | 483 |
466 // If the commit failed, the transaction will still be marked as "in progres
s" | 484 // If the commit failed, the transaction will still be marked as "in progres
s" |
467 if (m_sqliteTransaction->inProgress()) { | 485 if (m_sqliteTransaction->inProgress()) { |
| 486 if (m_wrapper) |
| 487 m_wrapper->handleCommitFailedAfterPostflight(this); |
468 m_successCallbackWrapper.clear(); | 488 m_successCallbackWrapper.clear(); |
469 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "failed to
commit the transaction"); | 489 m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "failed to
commit the transaction"); |
470 handleTransactionError(false); | 490 handleTransactionError(false); |
471 return; | 491 return; |
472 } | 492 } |
473 | 493 |
474 // Vacuum the database if anything was deleted. | 494 // Vacuum the database if anything was deleted. |
475 if (m_database->hadDeletes()) | 495 if (m_database->hadDeletes()) |
476 m_database->incrementalVacuumIfNeeded(); | 496 m_database->incrementalVacuumIfNeeded(); |
477 | 497 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 604 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
585 m_nextStep = 0; | 605 m_nextStep = 0; |
586 | 606 |
587 // Now release the lock on this database | 607 // Now release the lock on this database |
588 m_database->transactionCoordinator()->releaseLock(this); | 608 m_database->transactionCoordinator()->releaseLock(this); |
589 } | 609 } |
590 | 610 |
591 } // namespace WebCore | 611 } // namespace WebCore |
592 | 612 |
593 #endif // ENABLE(DATABASE) | 613 #endif // ENABLE(DATABASE) |
OLD | NEW |