summaryrefslogtreecommitdiffstats
path: root/WebCore/storage/IDBTransactionBackendImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/storage/IDBTransactionBackendImpl.cpp')
-rw-r--r--WebCore/storage/IDBTransactionBackendImpl.cpp91
1 files changed, 85 insertions, 6 deletions
diff --git a/WebCore/storage/IDBTransactionBackendImpl.cpp b/WebCore/storage/IDBTransactionBackendImpl.cpp
index 51b33b2..4f18437 100644
--- a/WebCore/storage/IDBTransactionBackendImpl.cpp
+++ b/WebCore/storage/IDBTransactionBackendImpl.cpp
@@ -29,11 +29,12 @@
#if ENABLE(INDEXED_DATABASE)
#include "IDBDatabaseBackendImpl.h"
+#include "IDBTransactionCoordinator.h"
#include "SQLiteDatabase.h"
namespace WebCore {
-PassRefPtr<IDBTransactionBackendInterface> IDBTransactionBackendImpl::create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl* database)
+PassRefPtr<IDBTransactionBackendImpl> IDBTransactionBackendImpl::create(DOMStringList* objectStores, unsigned short mode, unsigned long timeout, int id, IDBDatabaseBackendImpl* database)
{
return adoptRef(new IDBTransactionBackendImpl(objectStores, mode, timeout, id, database));
}
@@ -43,26 +44,104 @@ IDBTransactionBackendImpl::IDBTransactionBackendImpl(DOMStringList* objectStores
, m_mode(mode)
, m_timeout(timeout)
, m_id(id)
- , m_aborted(false)
+ , m_state(NotStarted)
, m_database(database)
+ , m_transaction(new SQLiteTransaction(database->sqliteDatabase()))
+ , m_timer(this, &IDBTransactionBackendImpl::timerFired)
+ , m_pendingEvents(0)
{
}
PassRefPtr<IDBObjectStoreBackendInterface> IDBTransactionBackendImpl::objectStore(const String& name)
{
+ if (isFinished())
+ return 0;
return m_database->objectStore(name, 0); // FIXME: remove mode param.
}
-void IDBTransactionBackendImpl::scheduleTask(PassOwnPtr<ScriptExecutionContext::Task>)
+bool IDBTransactionBackendImpl::scheduleTask(PassOwnPtr<ScriptExecutionContext::Task> task)
{
- // FIXME: implement.
- ASSERT_NOT_REACHED();
+ if (isFinished())
+ return false;
+
+ m_taskQueue.append(task);
+ if (m_state == NotStarted)
+ start();
+
+ return true;
}
void IDBTransactionBackendImpl::abort()
{
- m_aborted = true;
+ if (isFinished())
+ return;
+
+ m_state = Finished;
+ m_transaction->rollback();
m_callbacks->onAbort();
+ m_database->transactionCoordinator()->didFinishTransaction(this);
+}
+
+void IDBTransactionBackendImpl::didCompleteTaskEvents()
+{
+ ASSERT(m_state == Started);
+ ASSERT(m_pendingEvents);
+
+ m_pendingEvents--;
+
+ if (!m_pendingEvents && m_taskQueue.isEmpty()) {
+ // The last task event has completed and the task
+ // queue is empty. Commit the transaction.
+ commit();
+ return;
+ }
+
+ // We are still waiting for other events to complete. However,
+ // the task queue is non-empty and the timer is inactive.
+ // We can therfore schedule the timer again.
+ if (!m_taskQueue.isEmpty() && !m_timer.isActive())
+ m_timer.startOneShot(0);
+}
+
+void IDBTransactionBackendImpl::run()
+{
+ ASSERT(m_state == Started);
+ ASSERT(!m_timer.isActive());
+
+ m_timer.startOneShot(0);
+}
+
+void IDBTransactionBackendImpl::start()
+{
+ ASSERT(m_state == NotStarted);
+
+ m_state = Started;
+ m_transaction->begin();
+ m_database->transactionCoordinator()->didStartTransaction(this);
+}
+
+void IDBTransactionBackendImpl::commit()
+{
+ ASSERT(m_state == Started);
+
+ m_state = Finished;
+ m_transaction->commit();
+ m_database->transactionCoordinator()->didFinishTransaction(this);
+}
+
+void IDBTransactionBackendImpl::timerFired(Timer<IDBTransactionBackendImpl>*)
+{
+ ASSERT(!m_taskQueue.isEmpty());
+ ASSERT(m_state == Started);
+
+ TaskQueue queue;
+ queue.swap(m_taskQueue);
+ while (!queue.isEmpty()) {
+ OwnPtr<ScriptExecutionContext::Task> task(queue.first().release());
+ queue.removeFirst();
+ m_pendingEvents++;
+ task->performTask(0);
+ }
}
};