| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007, 2008, 2013 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 20 matching lines...) Expand all Loading... |
| 31 #include "modules/webdatabase/Database.h" | 31 #include "modules/webdatabase/Database.h" |
| 32 #include "modules/webdatabase/DatabaseAuthorizer.h" | 32 #include "modules/webdatabase/DatabaseAuthorizer.h" |
| 33 #include "modules/webdatabase/DatabaseContext.h" | 33 #include "modules/webdatabase/DatabaseContext.h" |
| 34 #include "modules/webdatabase/DatabaseThread.h" | 34 #include "modules/webdatabase/DatabaseThread.h" |
| 35 #include "modules/webdatabase/DatabaseTracker.h" | 35 #include "modules/webdatabase/DatabaseTracker.h" |
| 36 #include "modules/webdatabase/SQLError.h" | 36 #include "modules/webdatabase/SQLError.h" |
| 37 #include "modules/webdatabase/SQLStatementBackend.h" | 37 #include "modules/webdatabase/SQLStatementBackend.h" |
| 38 #include "modules/webdatabase/SQLTransaction.h" | 38 #include "modules/webdatabase/SQLTransaction.h" |
| 39 #include "modules/webdatabase/SQLTransactionClient.h" | 39 #include "modules/webdatabase/SQLTransactionClient.h" |
| 40 #include "modules/webdatabase/SQLTransactionCoordinator.h" | 40 #include "modules/webdatabase/SQLTransactionCoordinator.h" |
| 41 #include "modules/webdatabase/StorageLog.h" |
| 41 #include "modules/webdatabase/sqlite/SQLValue.h" | 42 #include "modules/webdatabase/sqlite/SQLValue.h" |
| 42 #include "modules/webdatabase/sqlite/SQLiteTransaction.h" | 43 #include "modules/webdatabase/sqlite/SQLiteTransaction.h" |
| 43 #include "platform/Logging.h" | |
| 44 #include "wtf/PtrUtil.h" | 44 #include "wtf/PtrUtil.h" |
| 45 #include "wtf/StdLibExtras.h" | 45 #include "wtf/StdLibExtras.h" |
| 46 #include <memory> | 46 #include <memory> |
| 47 | 47 |
| 48 | 48 |
| 49 // How does a SQLTransaction work? | 49 // How does a SQLTransaction work? |
| 50 // ============================== | 50 // ============================== |
| 51 // The SQLTransaction is a state machine that executes a series of states / step
s. | 51 // The SQLTransaction is a state machine that executes a series of states / step
s. |
| 52 // | 52 // |
| 53 // The work of the transaction states are defined in section of 4.3.2 of the | 53 // The work of the transaction states are defined in section of 4.3.2 of the |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 // Only honor the requested state transition if we're not supposed to be | 478 // Only honor the requested state transition if we're not supposed to be |
| 479 // cleaning up and shutting down: | 479 // cleaning up and shutting down: |
| 480 if (m_database->opened()) { | 480 if (m_database->opened()) { |
| 481 setStateToRequestedState(); | 481 setStateToRequestedState(); |
| 482 ASSERT(m_nextState == SQLTransactionState::AcquireLock | 482 ASSERT(m_nextState == SQLTransactionState::AcquireLock |
| 483 || m_nextState == SQLTransactionState::OpenTransactionAndPreflight | 483 || m_nextState == SQLTransactionState::OpenTransactionAndPreflight |
| 484 || m_nextState == SQLTransactionState::RunStatements | 484 || m_nextState == SQLTransactionState::RunStatements |
| 485 || m_nextState == SQLTransactionState::PostflightAndCommit | 485 || m_nextState == SQLTransactionState::PostflightAndCommit |
| 486 || m_nextState == SQLTransactionState::CleanupAndTerminate | 486 || m_nextState == SQLTransactionState::CleanupAndTerminate |
| 487 || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorC
allback); | 487 || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorC
allback); |
| 488 | 488 #if DCHECK_IS_ON() |
| 489 WTF_LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState
)); | 489 STORAGE_DVLOG(1) << "State " << nameForSQLTransactionState(m_nextState); |
| 490 #endif |
| 490 return; | 491 return; |
| 491 } | 492 } |
| 492 | 493 |
| 493 // If we get here, then we should be shutting down. Do clean up if needed: | 494 // If we get here, then we should be shutting down. Do clean up if needed: |
| 494 if (m_nextState == SQLTransactionState::End) | 495 if (m_nextState == SQLTransactionState::End) |
| 495 return; | 496 return; |
| 496 m_nextState = SQLTransactionState::End; | 497 m_nextState = SQLTransactionState::End; |
| 497 | 498 |
| 498 // If the database was stopped, don't do anything and cancel queued work | 499 // If the database was stopped, don't do anything and cancel queued work |
| 499 WTF_LOG(StorageAPI, "Database was stopped or interrupted - cancelling work f
or this transaction"); | 500 STORAGE_DVLOG(1) << "Database was stopped or interrupted - cancelling work f
or this transaction"; |
| 500 | 501 |
| 501 // The current SQLite transaction should be stopped, as well | 502 // The current SQLite transaction should be stopped, as well |
| 502 if (m_sqliteTransaction) { | 503 if (m_sqliteTransaction) { |
| 503 m_sqliteTransaction->stop(); | 504 m_sqliteTransaction->stop(); |
| 504 m_sqliteTransaction.reset(); | 505 m_sqliteTransaction.reset(); |
| 505 } | 506 } |
| 506 | 507 |
| 507 // Terminate the frontend state machine. This also gets the frontend to | 508 // Terminate the frontend state machine. This also gets the frontend to |
| 508 // call computeNextStateAndCleanupIfNeeded() and clear its wrappers | 509 // call computeNextStateAndCleanupIfNeeded() and clear its wrappers |
| 509 // if needed. | 510 // if needed. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 m_lockAcquired = true; | 550 m_lockAcquired = true; |
| 550 requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight); | 551 requestTransitToState(SQLTransactionState::OpenTransactionAndPreflight); |
| 551 } | 552 } |
| 552 | 553 |
| 553 SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() | 554 SQLTransactionState SQLTransactionBackend::openTransactionAndPreflight() |
| 554 { | 555 { |
| 555 DCHECK(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); | 556 DCHECK(database()->getDatabaseContext()->databaseThread()->isDatabaseThread(
)); |
| 556 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 557 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
| 557 ASSERT(m_lockAcquired); | 558 ASSERT(m_lockAcquired); |
| 558 | 559 |
| 559 WTF_LOG(StorageAPI, "Opening and preflighting transaction %p", this); | 560 STORAGE_DVLOG(1) << "Opening and preflighting transaction " << this; |
| 560 | 561 |
| 561 // Set the maximum usage for this transaction if this transactions is not re
ad-only | 562 // Set the maximum usage for this transaction if this transactions is not re
ad-only |
| 562 if (!m_readOnly) | 563 if (!m_readOnly) |
| 563 m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize()); | 564 m_database->sqliteDatabase().setMaximumSize(m_database->maximumSize()); |
| 564 | 565 |
| 565 ASSERT(!m_sqliteTransaction); | 566 ASSERT(!m_sqliteTransaction); |
| 566 m_sqliteTransaction = wrapUnique(new SQLiteTransaction(m_database->sqliteDat
abase(), m_readOnly)); | 567 m_sqliteTransaction = wrapUnique(new SQLiteTransaction(m_database->sqliteDat
abase(), m_readOnly)); |
| 567 | 568 |
| 568 m_database->resetDeletes(); | 569 m_database->resetDeletes(); |
| 569 m_database->disableAuthorizer(); | 570 m_database->disableAuthorizer(); |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 | 757 |
| 757 // Spec 4.3.2.8: Deliver success callback, if there is one. | 758 // Spec 4.3.2.8: Deliver success callback, if there is one. |
| 758 return SQLTransactionState::DeliverSuccessCallback; | 759 return SQLTransactionState::DeliverSuccessCallback; |
| 759 } | 760 } |
| 760 | 761 |
| 761 SQLTransactionState SQLTransactionBackend::cleanupAndTerminate() | 762 SQLTransactionState SQLTransactionBackend::cleanupAndTerminate() |
| 762 { | 763 { |
| 763 ASSERT(m_lockAcquired); | 764 ASSERT(m_lockAcquired); |
| 764 | 765 |
| 765 // Spec 4.3.2.9: End transaction steps. There is no next step. | 766 // Spec 4.3.2.9: End transaction steps. There is no next step. |
| 766 WTF_LOG(StorageAPI, "Transaction %p is complete\n", this); | 767 STORAGE_DVLOG(1) << "Transaction " << this << " is complete"; |
| 767 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 768 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
| 768 | 769 |
| 769 // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above. | 770 // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above. |
| 770 doCleanup(); | 771 doCleanup(); |
| 771 m_database->inProgressTransactionCompleted(); | 772 m_database->inProgressTransactionCompleted(); |
| 772 return SQLTransactionState::End; | 773 return SQLTransactionState::End; |
| 773 } | 774 } |
| 774 | 775 |
| 775 SQLTransactionState SQLTransactionBackend::nextStateForTransactionError() | 776 SQLTransactionState SQLTransactionBackend::nextStateForTransactionError() |
| 776 { | 777 { |
| 777 ASSERT(m_transactionError); | 778 ASSERT(m_transactionError); |
| 778 if (m_hasErrorCallback) | 779 if (m_hasErrorCallback) |
| 779 return SQLTransactionState::DeliverTransactionErrorCallback; | 780 return SQLTransactionState::DeliverTransactionErrorCallback; |
| 780 | 781 |
| 781 // No error callback, so fast-forward to the next state and rollback the | 782 // No error callback, so fast-forward to the next state and rollback the |
| 782 // transaction. | 783 // transaction. |
| 783 return SQLTransactionState::CleanupAfterTransactionErrorCallback; | 784 return SQLTransactionState::CleanupAfterTransactionErrorCallback; |
| 784 } | 785 } |
| 785 | 786 |
| 786 SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback(
) | 787 SQLTransactionState SQLTransactionBackend::cleanupAfterTransactionErrorCallback(
) |
| 787 { | 788 { |
| 788 ASSERT(m_lockAcquired); | 789 ASSERT(m_lockAcquired); |
| 789 | 790 |
| 790 WTF_LOG(StorageAPI, "Transaction %p is complete with an error\n", this); | 791 STORAGE_DVLOG(1) << "Transaction " << this << " is complete with an error"; |
| 791 m_database->disableAuthorizer(); | 792 m_database->disableAuthorizer(); |
| 792 if (m_sqliteTransaction) { | 793 if (m_sqliteTransaction) { |
| 793 // Spec 4.3.2.10: Rollback the transaction. | 794 // Spec 4.3.2.10: Rollback the transaction. |
| 794 m_sqliteTransaction->rollback(); | 795 m_sqliteTransaction->rollback(); |
| 795 | 796 |
| 796 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 797 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
| 797 m_sqliteTransaction.reset(); | 798 m_sqliteTransaction.reset(); |
| 798 } | 799 } |
| 799 m_database->enableAuthorizer(); | 800 m_database->enableAuthorizer(); |
| 800 | 801 |
| 801 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); | 802 ASSERT(!m_database->sqliteDatabase().transactionInProgress()); |
| 802 | 803 |
| 803 return SQLTransactionState::CleanupAndTerminate; | 804 return SQLTransactionState::CleanupAndTerminate; |
| 804 } | 805 } |
| 805 | 806 |
| 806 // requestTransitToState() can be called from the frontend. Hence, it should | 807 // requestTransitToState() can be called from the frontend. Hence, it should |
| 807 // NOT be modifying SQLTransactionBackend in general. The only safe field to | 808 // NOT be modifying SQLTransactionBackend in general. The only safe field to |
| 808 // modify is m_requestedState which is meant for this purpose. | 809 // modify is m_requestedState which is meant for this purpose. |
| 809 void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState) | 810 void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState) |
| 810 { | 811 { |
| 811 WTF_LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransact
ionState(nextState), this); | 812 #if DCHECK_IS_ON() |
| 813 STORAGE_DVLOG(1) << "Scheduling " << nameForSQLTransactionState(nextState) <
< " for transaction " << this; |
| 814 #endif |
| 812 m_requestedState = nextState; | 815 m_requestedState = nextState; |
| 813 ASSERT(m_requestedState != SQLTransactionState::End); | 816 ASSERT(m_requestedState != SQLTransactionState::End); |
| 814 m_database->scheduleTransactionStep(this); | 817 m_database->scheduleTransactionStep(this); |
| 815 } | 818 } |
| 816 | 819 |
| 817 // This state function is used as a stub function to plug unimplemented states | 820 // This state function is used as a stub function to plug unimplemented states |
| 818 // in the state dispatch table. They are unimplemented because they should | 821 // in the state dispatch table. They are unimplemented because they should |
| 819 // never be reached in the course of correct execution. | 822 // never be reached in the course of correct execution. |
| 820 SQLTransactionState SQLTransactionBackend::unreachableState() | 823 SQLTransactionState SQLTransactionBackend::unreachableState() |
| 821 { | 824 { |
| 822 ASSERT_NOT_REACHED(); | 825 ASSERT_NOT_REACHED(); |
| 823 return SQLTransactionState::End; | 826 return SQLTransactionState::End; |
| 824 } | 827 } |
| 825 | 828 |
| 826 SQLTransactionState SQLTransactionBackend::sendToFrontendState() | 829 SQLTransactionState SQLTransactionBackend::sendToFrontendState() |
| 827 { | 830 { |
| 828 ASSERT(m_nextState != SQLTransactionState::Idle); | 831 ASSERT(m_nextState != SQLTransactionState::Idle); |
| 829 m_frontend->requestTransitToState(m_nextState); | 832 m_frontend->requestTransitToState(m_nextState); |
| 830 return SQLTransactionState::Idle; | 833 return SQLTransactionState::Idle; |
| 831 } | 834 } |
| 832 | 835 |
| 833 } // namespace blink | 836 } // namespace blink |
| OLD | NEW |