#include "modules/webdatabase/SQLTransactionClient.h"
#include "modules/webdatabase/SQLTransactionCoordinator.h"
#include "wtf/StdLibExtras.h"
-#include "wtf/text/WTFString.h"
// How does a SQLTransaction work?
// - state CleanupAndTerminate calls doCleanup().
-namespace WebCore {
+namespace blink {
-PassRefPtr<SQLTransactionBackend> SQLTransactionBackend::create(DatabaseBackend* db,
- PassRefPtr<AbstractSQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
+PassRefPtrWillBeRawPtr<SQLTransactionBackend> SQLTransactionBackend::create(DatabaseBackend* db,
+ PassRefPtrWillBeRawPtr<AbstractSQLTransaction> frontend,
+ PassRefPtrWillBeRawPtr<SQLTransactionWrapper> wrapper,
+ bool readOnly)
{
- return adoptRef(new SQLTransactionBackend(db, frontend, wrapper, readOnly));
+ return adoptRefWillBeNoop(new SQLTransactionBackend(db, frontend, wrapper, readOnly));
}
SQLTransactionBackend::SQLTransactionBackend(DatabaseBackend* db,
- PassRefPtr<AbstractSQLTransaction> frontend, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly)
+ PassRefPtrWillBeRawPtr<AbstractSQLTransaction> frontend,
+ PassRefPtrWillBeRawPtr<SQLTransactionWrapper> wrapper,
+ bool readOnly)
: m_frontend(frontend)
, m_database(db)
, m_wrapper(wrapper)
ASSERT(!m_sqliteTransaction);
}
+void SQLTransactionBackend::trace(Visitor* visitor)
+{
+ visitor->trace(m_frontend);
+ visitor->trace(m_currentStatementBackend);
+ visitor->trace(m_database);
+ visitor->trace(m_wrapper);
+ visitor->trace(m_statementQueue);
+ AbstractSQLTransactionBackend::trace(visitor);
+}
+
void SQLTransactionBackend::doCleanup()
{
if (!m_frontend)
return;
- m_frontend = 0; // Break the reference cycle. See comment about the life-cycle above.
+ m_frontend = nullptr; // Break the reference cycle. See comment about the life-cycle above.
- ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
+ ASSERT(database()->databaseContext()->databaseThread()->isDatabaseThread());
MutexLocker locker(m_statementMutex);
m_statementQueue.clear();
// SQLTransactionBackend is guaranteed to not destruct until the frontend
// is also destructing.
- m_wrapper = 0;
+ m_wrapper = nullptr;
}
AbstractSQLStatement* SQLTransactionBackend::currentStatement()
return m_currentStatementBackend->frontend();
}
-PassRefPtr<SQLError> SQLTransactionBackend::transactionError()
+SQLErrorData* SQLTransactionBackend::transactionError()
{
- return m_transactionError;
+ return m_transactionError.get();
}
void SQLTransactionBackend::setShouldRetryCurrentStatement(bool shouldRetry)
return stateFunctions[static_cast<int>(state)];
}
-void SQLTransactionBackend::enqueueStatementBackend(PassRefPtr<SQLStatementBackend> statementBackend)
+void SQLTransactionBackend::enqueueStatementBackend(PassRefPtrWillBeRawPtr<SQLStatementBackend> statementBackend)
{
MutexLocker locker(m_statementMutex);
m_statementQueue.append(statementBackend);
|| m_nextState == SQLTransactionState::CleanupAndTerminate
|| m_nextState == SQLTransactionState::CleanupAfterTransactionErrorCallback);
- LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState));
+ WTF_LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState));
return;
}
m_nextState = SQLTransactionState::End;
// If the database was stopped, don't do anything and cancel queued work
- LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction");
+ WTF_LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction");
// The current SQLite transaction should be stopped, as well
if (m_sqliteTransaction) {
runStateMachine();
}
-void SQLTransactionBackend::executeSQL(PassOwnPtr<AbstractSQLStatement> statement,
+void SQLTransactionBackend::executeSQL(PassOwnPtrWillBeRawPtr<AbstractSQLStatement> statement,
const String& sqlStatement, const Vector<SQLValue>& arguments, int permissions)
{
- RefPtr<SQLStatementBackend> statementBackend;
- statementBackend = SQLStatementBackend::create(statement, sqlStatement, arguments, permissions);
-
- if (Database::from(m_database.get())->deleted())
- statementBackend->setDatabaseDeletedError(m_database.get());
-
- enqueueStatementBackend(statementBackend);
+ enqueueStatementBackend(SQLStatementBackend::create(statement, sqlStatement, arguments, permissions));
}
void SQLTransactionBackend::notifyDatabaseThreadIsShuttingDown()
{
- ASSERT(currentThread() == database()->databaseContext()->databaseThread()->getThreadID());
+ ASSERT(database()->databaseContext()->databaseThread()->isDatabaseThread());
// If the transaction is in progress, we should roll it back here, since this
// is our last opportunity to do something related to this transaction on the
ASSERT(!m_database->sqliteDatabase().transactionInProgress());
ASSERT(m_lockAcquired);
- LOG(StorageAPI, "Opening and preflighting transaction %p", this);
-
- // If the database was deleted, jump to the error callback
- if (Database::from(m_database.get())->deleted()) {
- m_database->reportStartTransactionResult(1, SQLError::UNKNOWN_ERR, 0);
- m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unable to open a transaction, because the user deleted the database");
- return nextStateForTransactionError();
- }
+ WTF_LOG(StorageAPI, "Opening and preflighting transaction %p", this);
// Set the maximum usage for this transaction if this transactions is not read-only
if (!m_readOnly)
if (!m_sqliteTransaction->inProgress()) {
ASSERT(!m_database->sqliteDatabase().transactionInProgress());
m_database->reportStartTransactionResult(2, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError());
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to begin transaction",
+ m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "unable to begin transaction",
m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
m_sqliteTransaction.clear();
return nextStateForTransactionError();
String actualVersion;
if (!m_database->getActualVersionForTransaction(actualVersion)) {
m_database->reportStartTransactionResult(3, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError());
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to read version",
+ m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "unable to read version",
m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
m_database->disableAuthorizer();
m_sqliteTransaction.clear();
m_database->disableAuthorizer();
m_sqliteTransaction.clear();
m_database->enableAuthorizer();
- m_transactionError = m_wrapper->sqlError();
- if (!m_transactionError) {
+ if (m_wrapper->sqlError()) {
+ m_transactionError = SQLErrorData::create(*m_wrapper->sqlError());
+ } else {
m_database->reportStartTransactionResult(4, SQLError::UNKNOWN_ERR, 0);
- m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight");
+ m_transactionError = SQLErrorData::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction preflight");
}
return nextStateForTransactionError();
}
void SQLTransactionBackend::getNextStatement()
{
- m_currentStatementBackend = 0;
+ m_currentStatementBackend = nullptr;
MutexLocker locker(m_statementMutex);
if (!m_statementQueue.isEmpty())
if (m_currentStatementBackend->hasStatementErrorCallback() && !m_sqliteTransaction->wasRolledBackBySqlite())
return SQLTransactionState::DeliverStatementCallback;
- m_transactionError = m_currentStatementBackend->sqlError();
- if (!m_transactionError) {
+ if (m_currentStatementBackend->sqlError()) {
+ m_transactionError = SQLErrorData::create(*m_currentStatementBackend->sqlError());
+ } else {
m_database->reportCommitTransactionResult(1, SQLError::DATABASE_ERR, 0);
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "the statement failed to execute");
+ m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "the statement failed to execute");
}
return nextStateForTransactionError();
}
// Spec 4.3.2.7: Perform postflight steps, jumping to the error callback if they fail.
if (m_wrapper && !m_wrapper->performPostflight(this)) {
- m_transactionError = m_wrapper->sqlError();
- if (!m_transactionError) {
+ if (m_wrapper->sqlError()) {
+ m_transactionError = SQLErrorData::create(*m_wrapper->sqlError());
+ } else {
m_database->reportCommitTransactionResult(3, SQLError::UNKNOWN_ERR, 0);
- m_transactionError = SQLError::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight");
+ m_transactionError = SQLErrorData::create(SQLError::UNKNOWN_ERR, "unknown error occurred during transaction postflight");
}
return nextStateForTransactionError();
}
if (m_wrapper)
m_wrapper->handleCommitFailedAfterPostflight(this);
m_database->reportCommitTransactionResult(4, SQLError::DATABASE_ERR, m_database->sqliteDatabase().lastError());
- m_transactionError = SQLError::create(SQLError::DATABASE_ERR, "unable to commit transaction",
+ m_transactionError = SQLErrorData::create(SQLError::DATABASE_ERR, "unable to commit transaction",
m_database->sqliteDatabase().lastError(), m_database->sqliteDatabase().lastErrorMsg());
return nextStateForTransactionError();
}
ASSERT(m_lockAcquired);
// Spec 4.3.2.9: End transaction steps. There is no next step.
- LOG(StorageAPI, "Transaction %p is complete\n", this);
+ WTF_LOG(StorageAPI, "Transaction %p is complete\n", this);
ASSERT(!m_database->sqliteDatabase().transactionInProgress());
// Phase 5 cleanup. See comment on the SQLTransaction life-cycle above.
{
ASSERT(m_lockAcquired);
- LOG(StorageAPI, "Transaction %p is complete with an error\n", this);
+ WTF_LOG(StorageAPI, "Transaction %p is complete with an error\n", this);
m_database->disableAuthorizer();
if (m_sqliteTransaction) {
// Spec 4.3.2.10: Rollback the transaction.
// modify is m_requestedState which is meant for this purpose.
void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState)
{
- LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this);
+ WTF_LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this);
m_requestedState = nextState;
ASSERT(m_requestedState != SQLTransactionState::End);
m_database->scheduleTransactionStep(this);
return SQLTransactionState::Idle;
}
-} // namespace WebCore
+} // namespace blink