Move execution of IDBTransactionBackendOperations to the IDBServerConnection
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Nov 2013 20:57:35 +0000 (20:57 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Nov 2013 20:57:35 +0000 (20:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=124385

Reviewed by Tim Horton.

Source/WebCore:

Each IDBOperation has it’s ::perform() moved to a method on IDBServerConnection.
This almost removes all knowledge of the backing stores from the front end.

* Modules/indexeddb/IDBDatabaseBackend.cpp:
(WebCore::IDBDatabaseBackend::clearObjectStore):
(WebCore::IDBDatabaseBackend::runIntVersionChangeTransaction):
* Modules/indexeddb/IDBDatabaseBackend.h:

* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::clear):

Add methods to reflect each transaction backend operation:
* Modules/indexeddb/IDBServerConnection.h:

Schedule certain operations with callbacks:
* Modules/indexeddb/IDBTransactionBackend.cpp:
(WebCore::IDBTransactionBackend::scheduleVersionChangeOperation):
(WebCore::IDBTransactionBackend::schedulePutOperation):
(WebCore::IDBTransactionBackend::scheduleOpenCursorOperation):
(WebCore::IDBTransactionBackend::scheduleCountOperation):
(WebCore::IDBTransactionBackend::scheduleDeleteRangeOperation):
(WebCore::IDBTransactionBackend::scheduleClearObjectStoreOperation):
* Modules/indexeddb/IDBTransactionBackend.h:

Make each operation’s perform() method defer to the IDBServerConnection (with a callback):
* Modules/indexeddb/IDBTransactionBackendOperations.cpp:
(WebCore::CreateObjectStoreOperation::perform):
(WebCore::CreateIndexOperation::perform):
(WebCore::CreateIndexAbortOperation::perform):
(WebCore::DeleteIndexOperation::perform):
(WebCore::DeleteIndexAbortOperation::perform):
(WebCore::GetOperation::perform):
(WebCore::PutOperation::perform):
(WebCore::SetIndexesReadyOperation::perform):
(WebCore::OpenCursorOperation::perform):
(WebCore::CountOperation::perform):
(WebCore::DeleteRangeOperation::perform):
(WebCore::ClearObjectStoreOperation::perform):
(WebCore::DeleteObjectStoreOperation::perform):
(WebCore::IDBDatabaseBackend::VersionChangeOperation::perform):
(WebCore::CreateObjectStoreAbortOperation::perform):

Add accessors to each operation’s data members so the IDBServerConnection has everything it needs:
* Modules/indexeddb/IDBTransactionBackendOperations.h:
(WebCore::CreateObjectStoreOperation::objectStoreMetadata):
(WebCore::DeleteObjectStoreOperation::objectStoreMetadata):
(WebCore::IDBDatabaseBackend::VersionChangeOperation::create):
(WebCore::IDBDatabaseBackend::VersionChangeOperation::version):
(WebCore::IDBDatabaseBackend::VersionChangeOperation::callbacks):
(WebCore::IDBDatabaseBackend::VersionChangeOperation::databaseCallbacks):
(WebCore::IDBDatabaseBackend::VersionChangeOperation::VersionChangeOperation):
(WebCore::CreateObjectStoreAbortOperation::CreateObjectStoreAbortOperation):
(WebCore::CreateIndexOperation::objectStoreID):
(WebCore::CreateIndexOperation::idbIndexMetadata):
(WebCore::CreateIndexOperation::CreateIndexOperation):
(WebCore::CreateIndexAbortOperation::CreateIndexAbortOperation):
(WebCore::DeleteIndexOperation::objectStoreID):
(WebCore::DeleteIndexOperation::idbIndexMetadata):
(WebCore::DeleteIndexOperation::DeleteIndexOperation):
(WebCore::DeleteIndexAbortOperation::DeleteIndexAbortOperation):
(WebCore::GetOperation::objectStoreID):
(WebCore::GetOperation::indexID):
(WebCore::GetOperation::cursorType):
(WebCore::GetOperation::keyRange):
(WebCore::GetOperation::callbacks):
(WebCore::GetOperation::autoIncrement):
(WebCore::GetOperation::keyPath):
(WebCore::GetOperation::GetOperation):
(WebCore::PutOperation::create):
(WebCore::PutOperation::putMode):
(WebCore::PutOperation::objectStore):
(WebCore::PutOperation::key):
(WebCore::PutOperation::indexIDs):
(WebCore::PutOperation::indexKeys):
(WebCore::PutOperation::callbacks):
(WebCore::PutOperation::value):
(WebCore::PutOperation::PutOperation):
(WebCore::OpenCursorOperation::create):
(WebCore::OpenCursorOperation::objectStoreID):
(WebCore::OpenCursorOperation::indexID):
(WebCore::OpenCursorOperation::direction):
(WebCore::OpenCursorOperation::cursorType):
(WebCore::OpenCursorOperation::taskType):
(WebCore::OpenCursorOperation::keyRange):
(WebCore::OpenCursorOperation::cursorDirection):
(WebCore::OpenCursorOperation::callbacks):
(WebCore::OpenCursorOperation::OpenCursorOperation):
(WebCore::CountOperation::create):
(WebCore::CountOperation::objectStoreID):
(WebCore::CountOperation::indexID):
(WebCore::CountOperation::keyRange):
(WebCore::CountOperation::callbacks):
(WebCore::CountOperation::CountOperation):
(WebCore::DeleteRangeOperation::create):
(WebCore::DeleteRangeOperation::objectStoreID):
(WebCore::DeleteRangeOperation::callbacks):
(WebCore::DeleteRangeOperation::keyRange):
(WebCore::DeleteRangeOperation::DeleteRangeOperation):
(WebCore::ClearObjectStoreOperation::create):
(WebCore::ClearObjectStoreOperation::objectStoreID):
(WebCore::ClearObjectStoreOperation::callbacks):
(WebCore::ClearObjectStoreOperation::ClearObjectStoreOperation):

Implement each operation in terms of the appropriate backing store, then perform the callback:
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
(WebCore::IDBServerConnectionLevelDB::createObjectStore):
(WebCore::IDBServerConnectionLevelDB::createIndex):
(WebCore::IDBServerConnectionLevelDB::deleteIndex):
(WebCore::IDBServerConnectionLevelDB::get):
(WebCore::IDBServerConnectionLevelDB::put):
(WebCore::IDBServerConnectionLevelDB::openCursor):
(WebCore::IDBServerConnectionLevelDB::count):
(WebCore::IDBServerConnectionLevelDB::deleteRange):
(WebCore::IDBServerConnectionLevelDB::clearObjectStore):
(WebCore::IDBServerConnectionLevelDB::deleteObjectStore):
(WebCore::IDBServerConnectionLevelDB::changeDatabaseVersion):
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:

* WebCore.xcodeproj/project.pbxproj:

Source/WebKit2:

* WebProcess/Databases/IndexedDB/WebProcessIDBDatabaseBackend.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@159353 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp
Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.h
Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
Source/WebCore/Modules/indexeddb/IDBServerConnection.h
Source/WebCore/Modules/indexeddb/IDBTransactionBackend.cpp
Source/WebCore/Modules/indexeddb/IDBTransactionBackend.h
Source/WebCore/Modules/indexeddb/IDBTransactionBackendOperations.cpp
Source/WebCore/Modules/indexeddb/IDBTransactionBackendOperations.h
Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.cpp
Source/WebCore/Modules/indexeddb/leveldb/IDBBackingStoreLevelDB.h
Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp
Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Databases/IndexedDB/WebProcessIDBDatabaseBackend.h

index 33c34fa..04d602e 100644 (file)
@@ -1,3 +1,130 @@
+2013-11-15  Brady Eidson  <beidson@apple.com>
+
+        Move execution of IDBTransactionBackendOperations to the IDBServerConnection
+        https://bugs.webkit.org/show_bug.cgi?id=124385
+
+        Reviewed by Tim Horton.
+
+        Each IDBOperation has it’s ::perform() moved to a method on IDBServerConnection.
+        This almost removes all knowledge of the backing stores from the front end.
+
+        * Modules/indexeddb/IDBDatabaseBackend.cpp:
+        (WebCore::IDBDatabaseBackend::clearObjectStore):
+        (WebCore::IDBDatabaseBackend::runIntVersionChangeTransaction):
+        * Modules/indexeddb/IDBDatabaseBackend.h:
+
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::clear):
+
+        Add methods to reflect each transaction backend operation:
+        * Modules/indexeddb/IDBServerConnection.h:
+
+        Schedule certain operations with callbacks:
+        * Modules/indexeddb/IDBTransactionBackend.cpp:
+        (WebCore::IDBTransactionBackend::scheduleVersionChangeOperation):
+        (WebCore::IDBTransactionBackend::schedulePutOperation):
+        (WebCore::IDBTransactionBackend::scheduleOpenCursorOperation):
+        (WebCore::IDBTransactionBackend::scheduleCountOperation):
+        (WebCore::IDBTransactionBackend::scheduleDeleteRangeOperation):
+        (WebCore::IDBTransactionBackend::scheduleClearObjectStoreOperation):
+        * Modules/indexeddb/IDBTransactionBackend.h:
+
+        Make each operation’s perform() method defer to the IDBServerConnection (with a callback):
+        * Modules/indexeddb/IDBTransactionBackendOperations.cpp:
+        (WebCore::CreateObjectStoreOperation::perform):
+        (WebCore::CreateIndexOperation::perform):
+        (WebCore::CreateIndexAbortOperation::perform):
+        (WebCore::DeleteIndexOperation::perform):
+        (WebCore::DeleteIndexAbortOperation::perform):
+        (WebCore::GetOperation::perform):
+        (WebCore::PutOperation::perform):
+        (WebCore::SetIndexesReadyOperation::perform):
+        (WebCore::OpenCursorOperation::perform):
+        (WebCore::CountOperation::perform):
+        (WebCore::DeleteRangeOperation::perform):
+        (WebCore::ClearObjectStoreOperation::perform):
+        (WebCore::DeleteObjectStoreOperation::perform):
+        (WebCore::IDBDatabaseBackend::VersionChangeOperation::perform):
+        (WebCore::CreateObjectStoreAbortOperation::perform):
+
+        Add accessors to each operation’s data members so the IDBServerConnection has everything it needs:
+        * Modules/indexeddb/IDBTransactionBackendOperations.h:
+        (WebCore::CreateObjectStoreOperation::objectStoreMetadata):
+        (WebCore::DeleteObjectStoreOperation::objectStoreMetadata):
+        (WebCore::IDBDatabaseBackend::VersionChangeOperation::create):
+        (WebCore::IDBDatabaseBackend::VersionChangeOperation::version):
+        (WebCore::IDBDatabaseBackend::VersionChangeOperation::callbacks):
+        (WebCore::IDBDatabaseBackend::VersionChangeOperation::databaseCallbacks):
+        (WebCore::IDBDatabaseBackend::VersionChangeOperation::VersionChangeOperation):
+        (WebCore::CreateObjectStoreAbortOperation::CreateObjectStoreAbortOperation):
+        (WebCore::CreateIndexOperation::objectStoreID):
+        (WebCore::CreateIndexOperation::idbIndexMetadata):
+        (WebCore::CreateIndexOperation::CreateIndexOperation):
+        (WebCore::CreateIndexAbortOperation::CreateIndexAbortOperation):
+        (WebCore::DeleteIndexOperation::objectStoreID):
+        (WebCore::DeleteIndexOperation::idbIndexMetadata):
+        (WebCore::DeleteIndexOperation::DeleteIndexOperation):
+        (WebCore::DeleteIndexAbortOperation::DeleteIndexAbortOperation):
+        (WebCore::GetOperation::objectStoreID):
+        (WebCore::GetOperation::indexID):
+        (WebCore::GetOperation::cursorType):
+        (WebCore::GetOperation::keyRange):
+        (WebCore::GetOperation::callbacks):
+        (WebCore::GetOperation::autoIncrement):
+        (WebCore::GetOperation::keyPath):
+        (WebCore::GetOperation::GetOperation):
+        (WebCore::PutOperation::create):
+        (WebCore::PutOperation::putMode):
+        (WebCore::PutOperation::objectStore):
+        (WebCore::PutOperation::key):
+        (WebCore::PutOperation::indexIDs):
+        (WebCore::PutOperation::indexKeys):
+        (WebCore::PutOperation::callbacks):
+        (WebCore::PutOperation::value):
+        (WebCore::PutOperation::PutOperation):
+        (WebCore::OpenCursorOperation::create):
+        (WebCore::OpenCursorOperation::objectStoreID):
+        (WebCore::OpenCursorOperation::indexID):
+        (WebCore::OpenCursorOperation::direction):
+        (WebCore::OpenCursorOperation::cursorType):
+        (WebCore::OpenCursorOperation::taskType):
+        (WebCore::OpenCursorOperation::keyRange):
+        (WebCore::OpenCursorOperation::cursorDirection):
+        (WebCore::OpenCursorOperation::callbacks):
+        (WebCore::OpenCursorOperation::OpenCursorOperation):
+        (WebCore::CountOperation::create):
+        (WebCore::CountOperation::objectStoreID):
+        (WebCore::CountOperation::indexID):
+        (WebCore::CountOperation::keyRange):
+        (WebCore::CountOperation::callbacks):
+        (WebCore::CountOperation::CountOperation):
+        (WebCore::DeleteRangeOperation::create):
+        (WebCore::DeleteRangeOperation::objectStoreID):
+        (WebCore::DeleteRangeOperation::callbacks):
+        (WebCore::DeleteRangeOperation::keyRange):
+        (WebCore::DeleteRangeOperation::DeleteRangeOperation):
+        (WebCore::ClearObjectStoreOperation::create):
+        (WebCore::ClearObjectStoreOperation::objectStoreID):
+        (WebCore::ClearObjectStoreOperation::callbacks):
+        (WebCore::ClearObjectStoreOperation::ClearObjectStoreOperation):
+
+        Implement each operation in terms of the appropriate backing store, then perform the callback:
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.cpp:
+        (WebCore::IDBServerConnectionLevelDB::createObjectStore):
+        (WebCore::IDBServerConnectionLevelDB::createIndex):
+        (WebCore::IDBServerConnectionLevelDB::deleteIndex):
+        (WebCore::IDBServerConnectionLevelDB::get):
+        (WebCore::IDBServerConnectionLevelDB::put):
+        (WebCore::IDBServerConnectionLevelDB::openCursor):
+        (WebCore::IDBServerConnectionLevelDB::count):
+        (WebCore::IDBServerConnectionLevelDB::deleteRange):
+        (WebCore::IDBServerConnectionLevelDB::clearObjectStore):
+        (WebCore::IDBServerConnectionLevelDB::deleteObjectStore):
+        (WebCore::IDBServerConnectionLevelDB::changeDatabaseVersion):
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:
+
+        * WebCore.xcodeproj/project.pbxproj:
+
 2013-11-15  Thiago de Barros Lacerda  <thiago.lacerda@openbossa.org>
 
         Modifying RTCIceCandidate object construction to match the spec
index 314c08b..028c238 100644 (file)
@@ -34,6 +34,7 @@
 #include "IDBFactoryBackendInterface.h"
 #include "IDBKeyRange.h"
 #include "IDBRecordIdentifier.h"
+#include "IDBServerConnection.h"
 #include "IDBTransactionBackend.h"
 #include "IDBTransactionCoordinator.h"
 #include "Logging.h"
@@ -301,7 +302,7 @@ void IDBDatabaseBackend::deleteRange(int64_t transactionId, int64_t objectStoreI
     transaction->scheduleDeleteRangeOperation(objectStoreId, keyRange, callbacks);
 }
 
-void IDBDatabaseBackend::clear(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
+void IDBDatabaseBackend::clearObjectStore(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
 {
     LOG(StorageAPI, "IDBDatabaseBackend::clear");
     IDBTransactionBackend* transaction = m_transactions.get(transactionId);
@@ -309,7 +310,7 @@ void IDBDatabaseBackend::clear(int64_t transactionId, int64_t objectStoreId, Pas
         return;
     ASSERT(transaction->mode() != IndexedDB::TransactionReadOnly);
 
-    transaction->scheduleClearOperation(objectStoreId, callbacks);
+    transaction->scheduleClearObjectStoreOperation(objectStoreId, callbacks);
 }
 
 void IDBDatabaseBackend::transactionStarted(IDBTransactionBackend* transaction)
@@ -524,7 +525,7 @@ void IDBDatabaseBackend::runIntVersionChangeTransaction(PassRefPtr<IDBCallbacks>
     createTransaction(transactionId, databaseCallbacks, objectStoreIds, IndexedDB::TransactionVersionChange);
     RefPtr<IDBTransactionBackend> transaction = m_transactions.get(transactionId);
 
-    transaction->scheduleVersionChangeOperation(transactionId, requestedVersion, callbacks, databaseCallbacks, m_metadata);
+    transaction->scheduleVersionChangeOperation(requestedVersion, callbacks, databaseCallbacks, m_metadata);
 
     ASSERT(!m_pendingSecondHalfOpen);
     m_databaseCallbacksSet.add(databaseCallbacks);
index be707e7..d27d717 100644 (file)
 #ifndef IDBDatabaseBackend_h
 #define IDBDatabaseBackend_h
 
-#include "IDBDatabaseBackend.h"
 #include "IDBDatabaseCallbacks.h"
+#include "IDBKeyRange.h"
 #include "IDBMetadata.h"
 #include "IDBPendingDeleteCall.h"
 #include "IDBPendingOpenCall.h"
-#include "IDBServerConnection.h"
 
 #include <stdint.h>
 #include <wtf/Deque.h>
@@ -46,7 +45,7 @@ class IDBDatabase;
 class IDBFactoryBackendInterface;
 class IDBKey;
 class IDBKeyPath;
-class IDBKeyRange;
+class IDBServerConnection;
 class IDBTransactionBackend;
 class IDBTransactionCoordinator;
 class SharedBuffer;
@@ -114,7 +113,7 @@ public:
     void openCursor(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, IndexedDB::CursorDirection, bool keyOnly, TaskType, PassRefPtr<IDBCallbacks>);
     void count(int64_t transactionId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>);
     void deleteRange(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>);
-    void clear(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks>);
+    void clearObjectStore(int64_t transactionId, int64_t objectStoreId, PassRefPtr<IDBCallbacks>);
 
     const IDBDatabaseMetadata& metadata() const { return m_metadata; }
     void setCurrentVersion(uint64_t version) { m_metadata.version = version; }
index 520c942..69babf1 100644 (file)
@@ -287,7 +287,7 @@ PassRefPtr<IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, Ex
     }
 
     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
-    backendDB()->clear(m_transaction->id(), id(), request);
+    backendDB()->clearObjectStore(m_transaction->id(), id(), request);
     return request.release();
 }
 
index 77be982..346ea1e 100644 (file)
@@ -27,6 +27,7 @@
 #define IDBServerConnection_h
 
 #include "IDBMetadata.h"
+#include "IDBTransactionBackendOperations.h"
 #include "IndexedDB.h"
 #include <functional>
 #include <wtf/HashSet.h>
@@ -41,7 +42,9 @@ class IDBBackingStoreInterface;
 class IDBBackingStoreTransactionInterface;
 class IDBDatabaseError;
 class IDBKey;
+class IDBTransactionBackend;
 
+struct IDBIndexMetadata;
 struct IDBObjectStoreMetadata;
 
 // This interface provides a single asynchronous layer between the web-facing frontend
@@ -54,7 +57,6 @@ public:
     // FIXME: For now, server connection provides a synchronous accessor to the in-process backing store objects.
     // This is temporary and will be removed soon.
     virtual IDBBackingStoreInterface* deprecatedBackingStore() = 0;
-    virtual IDBBackingStoreTransactionInterface* deprecatedBackingStoreTransaction(int64_t transactionID) = 0;
 
     virtual bool isClosed() = 0;
 
@@ -72,8 +74,20 @@ public:
     virtual void commitTransaction(int64_t transactionID, BoolCallbackFunction successCallback) = 0;
     virtual void resetTransaction(int64_t transactionID, std::function<void()> completionCallback) = 0;
     virtual void rollbackTransaction(int64_t transactionID, std::function<void()> completionCallback) = 0;
+
     virtual void setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata&, IDBKey& primaryKey, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
 
+    virtual void createObjectStore(IDBTransactionBackend&, const CreateObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
+    virtual void changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) = 0;
 };
 
 } // namespace WebCore
index b95aacf..7c31286 100644 (file)
@@ -85,15 +85,6 @@ IDBTransactionBackend::~IDBTransactionBackend()
 {
     // It shouldn't be possible for this object to get deleted until it's either complete or aborted.
     ASSERT(m_state == Finished);
-    // The backing store transaction should also be gone by now.
-    ASSERT(!m_database->serverConnection().deprecatedBackingStoreTransaction(m_id));
-}
-
-IDBBackingStoreTransactionInterface& IDBTransactionBackend::deprecatedBackingStoreTransaction()
-{
-    IDBBackingStoreTransactionInterface* backingStoreTransaction = m_database->serverConnection().deprecatedBackingStoreTransaction(m_id);
-    ASSERT(backingStoreTransaction);
-    return *backingStoreTransaction;
 }
 
 void IDBTransactionBackend::scheduleTask(IDBDatabaseBackend::TaskType type, PassRefPtr<IDBOperation> task, PassRefPtr<IDBSynchronousOperation> abortTask)
@@ -311,9 +302,9 @@ void IDBTransactionBackend::scheduleDeleteObjectStoreOperation(const IDBObjectSt
     scheduleTask(DeleteObjectStoreOperation::create(this, objectStoreMetadata), DeleteObjectStoreAbortOperation::create(this, objectStoreMetadata));
 }
 
-void IDBTransactionBackend::scheduleVersionChangeOperation(int64_t transactionId, int64_t requestedVersion, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, const IDBDatabaseMetadata& metadata)
+void IDBTransactionBackend::scheduleVersionChangeOperation(int64_t requestedVersion, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, const IDBDatabaseMetadata& metadata)
 {
-    scheduleTask(IDBDatabaseBackend::VersionChangeOperation::create(this, transactionId, requestedVersion, callbacks, databaseCallbacks), IDBDatabaseBackend::VersionChangeAbortOperation::create(this, String::number(metadata.version), metadata.version));
+    scheduleTask(IDBDatabaseBackend::VersionChangeOperation::create(this, requestedVersion, callbacks, databaseCallbacks), IDBDatabaseBackend::VersionChangeAbortOperation::create(this, String::number(metadata.version), metadata.version));
 }
 
 void IDBTransactionBackend::scheduleCreateIndexOperation(int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
@@ -333,7 +324,7 @@ void IDBTransactionBackend::scheduleGetOperation(const IDBDatabaseMetadata& meta
 
 void IDBTransactionBackend::schedulePutOperation(const IDBObjectStoreMetadata& objectStoreMetadata, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBKey> key, IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
 {
-    scheduleTask(PutOperation::create(this, database().id(), objectStoreMetadata, value, key, putMode, callbacks, indexIds, indexKeys));
+    scheduleTask(PutOperation::create(this, objectStoreMetadata, value, key, putMode, callbacks, indexIds, indexKeys));
 }
 
 void IDBTransactionBackend::scheduleSetIndexesReadyOperation(size_t indexCount)
@@ -343,22 +334,22 @@ void IDBTransactionBackend::scheduleSetIndexesReadyOperation(size_t indexCount)
 
 void IDBTransactionBackend::scheduleOpenCursorOperation(int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IndexedDB::CursorDirection direction, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
 {
-    scheduleTask(OpenCursorOperation::create(this, database().id(), objectStoreId, indexId, keyRange, direction, cursorType, taskType, callbacks));
+    scheduleTask(OpenCursorOperation::create(this, objectStoreId, indexId, keyRange, direction, cursorType, taskType, callbacks));
 }
 
 void IDBTransactionBackend::scheduleCountOperation(int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
 {
-    scheduleTask(CountOperation::create(this, database().id(), objectStoreId, indexId, keyRange, callbacks));
+    scheduleTask(CountOperation::create(this, objectStoreId, indexId, keyRange, callbacks));
 }
 
 void IDBTransactionBackend::scheduleDeleteRangeOperation(int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
 {
-    scheduleTask(DeleteRangeOperation::create(this, database().id(), objectStoreId, keyRange, callbacks));
+    scheduleTask(DeleteRangeOperation::create(this, objectStoreId, keyRange, callbacks));
 }
 
-void IDBTransactionBackend::scheduleClearOperation(int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
+void IDBTransactionBackend::scheduleClearObjectStoreOperation(int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
 {
-    scheduleTask(ClearOperation::create(this, database().id(), objectStoreId, callbacks));
+    scheduleTask(ClearObjectStoreOperation::create(this, objectStoreId, callbacks));
 }
 
 PassRefPtr<IDBCursorBackend> IDBTransactionBackend::createCursorBackend(IDBBackingStoreCursorInterface& cursor, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, int64_t objectStoreId)
index 3f5eeb7..cfc413a 100644 (file)
@@ -32,7 +32,6 @@
 #include "IDBDatabaseBackend.h"
 #include "IDBDatabaseError.h"
 #include "IDBOperation.h"
-#include "IDBTransactionBackend.h"
 #include "Timer.h"
 #include <wtf/Deque.h>
 #include <wtf/HashSet.h>
@@ -64,13 +63,12 @@ public:
 
     void addPreemptiveEvent()  { m_pendingPreemptiveEvents++; }
     void didCompletePreemptiveEvent()  { m_pendingPreemptiveEvents--; ASSERT(m_pendingPreemptiveEvents >= 0); }
-    IDBBackingStoreTransactionInterface& deprecatedBackingStoreTransaction();
 
     IDBDatabaseBackend& database() const  { return *m_database; }
 
     void scheduleCreateObjectStoreOperation(const IDBObjectStoreMetadata&);
     void scheduleDeleteObjectStoreOperation(const IDBObjectStoreMetadata&);
-    void scheduleVersionChangeOperation(int64_t transactionId, int64_t requestedVersion, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, const IDBDatabaseMetadata&);
+    void scheduleVersionChangeOperation(int64_t requestedVersion, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, const IDBDatabaseMetadata&);
     void scheduleCreateIndexOperation(int64_t objectStoreId, const IDBIndexMetadata&);
     void scheduleDeleteIndexOperation(int64_t objectStoreId, const IDBIndexMetadata&);
     void scheduleGetOperation(const IDBDatabaseMetadata&, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, IndexedDB::CursorType, PassRefPtr<IDBCallbacks>);
@@ -79,7 +77,7 @@ public:
     void scheduleOpenCursorOperation(int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, IndexedDB::CursorDirection, IndexedDB::CursorType, IDBDatabaseBackend::TaskType, PassRefPtr<IDBCallbacks>);
     void scheduleCountOperation(int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>);
     void scheduleDeleteRangeOperation(int64_t objectStoreId, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>);
-    void scheduleClearOperation(int64_t objectStoreId, PassRefPtr<IDBCallbacks>);
+    void scheduleClearObjectStoreOperation(int64_t objectStoreId, PassRefPtr<IDBCallbacks>);
 
     PassRefPtr<IDBCursorBackend> createCursorBackend(IDBBackingStoreCursorInterface&, IndexedDB::CursorType, IDBDatabaseBackend::TaskType, int64_t objectStoreId);
 
index 29f42fa..fd46c7c 100644 (file)
 #include "IDBIndexWriter.h"
 #include "IDBKeyRange.h"
 #include "IDBRecordIdentifier.h"
+#include "IDBServerConnection.h"
 #include "Logging.h"
 #include <wtf/text/CString.h>
 
 #if ENABLE(INDEXED_DATABASE)
 
-namespace WebCore {
-
-class CallOnDestruct {
-public:
-    CallOnDestruct(std::function<void()> callback)
-        : m_callback(callback)
-    { }
-
-    ~CallOnDestruct()
-    {
-        m_callback();
-    }
+#define STANDARD_DATABASE_ERROR_CALLBACK std::function<void(PassRefPtr<IDBDatabaseError>)> operationCallback = \
+    [operation, completionCallback](PassRefPtr<IDBDatabaseError> error) { \
+        if (error) \
+            operation->m_transaction->abort(error); \
+        completionCallback(); \
+    };
 
-private:
-    std::function<void()> m_callback;
-};
+namespace WebCore {
 
 void CreateObjectStoreOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "CreateObjectStoreOperation");
-    if (!m_transaction->database().serverConnection().deprecatedBackingStore()->createObjectStore(m_transaction->deprecatedBackingStoreTransaction(), m_transaction->database().id(), m_objectStoreMetadata.id, m_objectStoreMetadata.name, m_objectStoreMetadata.keyPath, m_objectStoreMetadata.autoIncrement)) {
-        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error creating object store '%s'.", m_objectStoreMetadata.name.utf8().data()));
-        m_transaction->abort(error.release());
-        return;
-    }
+
+    RefPtr<CreateObjectStoreOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().createObjectStore(*m_transaction, *this, operationCallback);
 }
 
 void CreateIndexOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "CreateIndexOperation");
-    if (!m_transaction->database().serverConnection().deprecatedBackingStore()->createIndex(m_transaction->deprecatedBackingStoreTransaction(), m_transaction->database().id(), m_objectStoreId, m_indexMetadata.id, m_indexMetadata.name, m_indexMetadata.keyPath, m_indexMetadata.unique, m_indexMetadata.multiEntry)) {
-        m_transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error when trying to create index '%s'.", m_indexMetadata.name.utf8().data())));
-        return;
-    }
+
+    RefPtr<CreateIndexOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().createIndex(*m_transaction, *this, operationCallback);
 }
 
 void CreateIndexAbortOperation::perform()
 {
     LOG(StorageAPI, "CreateIndexAbortOperation");
-    m_transaction->database().removeIndex(m_objectStoreId, m_indexId);
+    m_transaction->database().removeIndex(m_objectStoreID, m_indexID);
 }
 
 void DeleteIndexOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "DeleteIndexOperation");
-    bool ok = m_transaction->database().serverConnection().deprecatedBackingStore()->deleteIndex(m_transaction->deprecatedBackingStoreTransaction(), m_transaction->database().id(), m_objectStoreId, m_indexMetadata.id);
-    if (!ok) {
-        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting index '%s'.", m_indexMetadata.name.utf8().data()));
-        m_transaction->abort(error);
-    }
+
+    RefPtr<DeleteIndexOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().deleteIndex(*m_transaction, *this, operationCallback);
 }
 
 void DeleteIndexAbortOperation::perform()
 {
     LOG(StorageAPI, "DeleteIndexAbortOperation");
-    m_transaction->database().addIndex(m_objectStoreId, m_indexMetadata, IDBIndexMetadata::InvalidId);
+    m_transaction->database().addIndex(m_objectStoreID, m_indexMetadata, IDBIndexMetadata::InvalidId);
 }
 
 void GetOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "GetOperation");
 
-    RefPtr<IDBKey> key;
-
-    if (m_keyRange->isOnlyKey())
-        key = m_keyRange->lower();
-    else {
-        RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor;
-        if (m_indexId == IDBIndexMetadata::InvalidId) {
-            ASSERT(m_cursorType != IndexedDB::CursorKeyOnly);
-            // ObjectStore Retrieval Operation
-            backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openObjectStoreCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IndexedDB::CursorNext);
-        } else {
-            if (m_cursorType == IndexedDB::CursorKeyOnly) {
-                // Index Value Retrieval Operation
-                backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openIndexKeyCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IndexedDB::CursorNext);
-            } else {
-                // Index Referenced Value Retrieval Operation
-                backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openIndexCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IndexedDB::CursorNext);
-            }
-        }
-
-        if (!backingStoreCursor) {
-            m_callbacks->onSuccess();
-            return;
-        }
-
-        key = backingStoreCursor->key();
-    }
-
-    RefPtr<IDBKey> primaryKey;
-    bool ok;
-    if (m_indexId == IDBIndexMetadata::InvalidId) {
-        // Object Store Retrieval Operation
-        Vector<char> value;
-        ok = m_transaction->database().serverConnection().deprecatedBackingStore()->getRecord(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, *key, value);
-        if (!ok) {
-            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
-            return;
-        }
-
-        if (value.isEmpty()) {
-            m_callbacks->onSuccess();
-            return;
-        }
-
-        if (m_autoIncrement && !m_keyPath.isNull()) {
-            m_callbacks->onSuccess(SharedBuffer::adoptVector(value), key, m_keyPath);
-            return;
-        }
-
-        m_callbacks->onSuccess(SharedBuffer::adoptVector(value));
-        return;
-
-    }
-
-    // From here we are dealing only with indexes.
-    ok = m_transaction->database().serverConnection().deprecatedBackingStore()->getPrimaryKeyViaIndex(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, *key, primaryKey);
-    if (!ok) {
-        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
-        return;
-    }
-    if (!primaryKey) {
-        m_callbacks->onSuccess();
-        return;
-    }
-    if (m_cursorType == IndexedDB::CursorKeyOnly) {
-        // Index Value Retrieval Operation
-        m_callbacks->onSuccess(primaryKey.get());
-        return;
-    }
-
-    // Index Referenced Value Retrieval Operation
-    Vector<char> value;
-    ok = m_transaction->database().serverConnection().deprecatedBackingStore()->getRecord(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, *primaryKey, value);
-    if (!ok) {
-        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
-        return;
-    }
-
-    if (value.isEmpty()) {
-        m_callbacks->onSuccess();
-        return;
-    }
-    if (m_autoIncrement && !m_keyPath.isNull()) {
-        m_callbacks->onSuccess(SharedBuffer::adoptVector(value), primaryKey, m_keyPath);
-        return;
-    }
-    m_callbacks->onSuccess(SharedBuffer::adoptVector(value));
+    RefPtr<GetOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().get(*m_transaction, *this, operationCallback);
 }
 
 void PutOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "PutOperation");
     ASSERT(m_transaction->mode() != IndexedDB::TransactionReadOnly);
-    ASSERT(m_indexIds.size() == m_indexKeys.size());
-    bool keyWasGenerated = false;
-
-    RefPtr<IDBKey> key;
-    if (m_putMode != IDBDatabaseBackend::CursorUpdate && m_objectStore.autoIncrement && !m_key) {
-        RefPtr<IDBKey> autoIncKey = m_transaction->database().serverConnection().deprecatedBackingStore()->generateKey(*m_transaction, m_databaseId, m_objectStore.id);
-        keyWasGenerated = true;
-        if (!autoIncKey->isValid()) {
-            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
-            return;
-        }
-        key = autoIncKey;
-    } else
-        key = m_key;
-
-    ASSERT(key);
-    ASSERT(key->isValid());
-
-    RefPtr<IDBRecordIdentifier> recordIdentifier;
-    if (m_putMode == IDBDatabaseBackend::AddOnly) {
-        bool ok = m_transaction->database().serverConnection().deprecatedBackingStore()->keyExistsInObjectStore(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStore.id, *key, recordIdentifier);
-        if (!ok) {
-            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
-            return;
-        }
-        if (recordIdentifier) {
-            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
-            return;
-        }
-    }
-
-    Vector<RefPtr<IDBIndexWriter>> indexWriters;
-    String errorMessage;
-    bool obeysConstraints = false;
-    bool backingStoreSuccess = m_transaction->database().serverConnection().deprecatedBackingStore()->makeIndexWriters(m_transaction->id(), m_databaseId, m_objectStore, *key, keyWasGenerated, m_indexIds, m_indexKeys, indexWriters, &errorMessage, obeysConstraints);
-    if (!backingStoreSuccess) {
-        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
-        return;
-    }
-    if (!obeysConstraints) {
-        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
-        return;
-    }
-
-    // Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
-    backingStoreSuccess = m_transaction->database().serverConnection().deprecatedBackingStore()->putRecord(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStore.id, *key, m_value, recordIdentifier.get());
-    if (!backingStoreSuccess) {
-        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
-        return;
-    }
-
-    for (size_t i = 0; i < indexWriters.size(); ++i) {
-        IDBIndexWriter* indexWriter = indexWriters[i].get();
-        indexWriter->writeIndexKeys(recordIdentifier.get(), *m_transaction->database().serverConnection().deprecatedBackingStore(), m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStore.id);
-    }
-
-    if (m_objectStore.autoIncrement && m_putMode != IDBDatabaseBackend::CursorUpdate && key->type() == IDBKey::NumberType) {
-        bool ok = m_transaction->database().serverConnection().deprecatedBackingStore()->updateKeyGenerator(*m_transaction, m_databaseId, m_objectStore.id, *key, !keyWasGenerated);
-        if (!ok) {
-            m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
-            return;
-        }
-    }
-
-    m_callbacks->onSuccess(key.release());
+    ASSERT(m_indexIDs.size() == m_indexKeys.size());
+
+    RefPtr<PutOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().put(*m_transaction, *this, operationCallback);
 }
 
 void SetIndexesReadyOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "SetIndexesReadyOperation");
+
     for (size_t i = 0; i < m_indexCount; ++i)
         m_transaction->didCompletePreemptiveEvent();
+
+    callOnMainThread(completionCallback);
 }
 
 void OpenCursorOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "OpenCursorOperation");
 
-    // The frontend has begun indexing, so this pauses the transaction
-    // until the indexing is complete. This can't happen any earlier
-    // because we don't want to switch to early mode in case multiple
-    // indexes are being created in a row, with put()'s in between.
-    if (m_taskType == IDBDatabaseBackend::PreemptiveTask)
-        m_transaction->addPreemptiveEvent();
-
-    RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor;
-    if (m_indexId == IDBIndexMetadata::InvalidId) {
-        ASSERT(m_cursorType != IndexedDB::CursorKeyOnly);
-        backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openObjectStoreCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), m_direction);
-    } else {
-        ASSERT(m_taskType == IDBDatabaseBackend::NormalTask);
-        if (m_cursorType == IndexedDB::CursorKeyOnly)
-            backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openIndexKeyCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), m_direction);
-        else
-            backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openIndexCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), m_direction);
-    }
-
-    if (!backingStoreCursor) {
-        m_callbacks->onSuccess(static_cast<SharedBuffer*>(0));
-        return;
-    }
-
-    IDBDatabaseBackend::TaskType taskType(static_cast<IDBDatabaseBackend::TaskType>(m_taskType));
-
-    RefPtr<IDBCursorBackend> cursor = m_transaction->createCursorBackend(*backingStoreCursor, m_cursorType, taskType, m_objectStoreId);
-    m_callbacks->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
+    RefPtr<OpenCursorOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().openCursor(*m_transaction, *this, operationCallback);
 }
 
 void CountOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "CountOperation");
-    uint32_t count = 0;
-    RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor;
-
-    if (m_indexId == IDBIndexMetadata::InvalidId)
-        backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openObjectStoreKeyCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IndexedDB::CursorNext);
-    else
-        backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openIndexKeyCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_indexId, m_keyRange.get(), IndexedDB::CursorNext);
-    if (!backingStoreCursor) {
-        m_callbacks->onSuccess(count);
-        return;
-    }
-
-    do {
-        ++count;
-    } while (backingStoreCursor->continueFunction(0));
-
-    m_callbacks->onSuccess(count);
+
+    RefPtr<CountOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().count(*m_transaction, *this, operationCallback);
 }
 
 void DeleteRangeOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "DeleteRangeOperation");
-    RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor = m_transaction->database().serverConnection().deprecatedBackingStore()->openObjectStoreCursor(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, m_keyRange.get(), IndexedDB::CursorNext);
-    if (backingStoreCursor) {
-        do {
-            if (!m_transaction->database().serverConnection().deprecatedBackingStore()->deleteRecord(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId, backingStoreCursor->recordIdentifier())) {
-                m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error deleting data in range"));
-                return;
-            }
-        } while (backingStoreCursor->continueFunction(0));
-    }
-
-    m_callbacks->onSuccess();
+
+    RefPtr<DeleteRangeOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().deleteRange(*m_transaction, *this, operationCallback);
 }
 
-void ClearOperation::perform(std::function<void()> completionCallback)
+void ClearObjectStoreOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
-    LOG(StorageAPI, "ObjectStoreClearOperation");
-    if (!m_transaction->database().serverConnection().deprecatedBackingStore()->clearObjectStore(m_transaction->deprecatedBackingStoreTransaction(), m_databaseId, m_objectStoreId)) {
-        m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error clearing object store"));
-        return;
-    }
-    m_callbacks->onSuccess();
+    LOG(StorageAPI, "ClearObjectStoreOperation");
+
+    RefPtr<ClearObjectStoreOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().clearObjectStore(*m_transaction, *this, operationCallback);
 }
 
 void DeleteObjectStoreOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "DeleteObjectStoreOperation");
-    bool ok = m_transaction->database().serverConnection().deprecatedBackingStore()->deleteObjectStore(m_transaction->deprecatedBackingStoreTransaction(), m_transaction->database().id(), m_objectStoreMetadata.id);
-    if (!ok) {
-        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting object store '%s'.", m_objectStoreMetadata.name.utf8().data()));
-        m_transaction->abort(error);
-    }
+
+    RefPtr<DeleteObjectStoreOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().deleteObjectStore(*m_transaction, *this, operationCallback);
 }
 
 void IDBDatabaseBackend::VersionChangeOperation::perform(std::function<void()> completionCallback)
 {
-    CallOnDestruct callOnDestruct(completionCallback);
-
     LOG(StorageAPI, "VersionChangeOperation");
-    IDBDatabaseBackend& database = m_transaction->database();
-    int64_t databaseId = database.id();
-    uint64_t oldVersion = database.metadata().version;
-
-    // FIXME: Database versions are now of type uint64_t, but this code expected int64_t.
-    ASSERT(m_version > (int64_t)oldVersion);
-    database.setCurrentVersion(m_version);
-    if (!database.serverConnection().deprecatedBackingStore()->updateIDBDatabaseVersion(m_transaction->deprecatedBackingStoreTransaction(), databaseId, database.metadata().version)) {
-        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error writing data to stable storage when updating version.");
-        m_callbacks->onError(error);
-        m_transaction->abort(error);
-        return;
-    }
-    ASSERT(!database.hasPendingSecondHalfOpen());
-    database.setPendingSecondHalfOpen(IDBPendingOpenCall::create(*m_callbacks, *m_databaseCallbacks, m_transactionId, m_version));
-    m_callbacks->onUpgradeNeeded(oldVersion, &database, database.metadata());
+
+    RefPtr<IDBDatabaseBackend::VersionChangeOperation> operation(this);
+    STANDARD_DATABASE_ERROR_CALLBACK;
+
+    m_transaction->database().serverConnection().changeDatabaseVersion(*m_transaction, *this, operationCallback);
 }
 
 void CreateObjectStoreAbortOperation::perform()
 {
     LOG(StorageAPI, "CreateObjectStoreAbortOperation");
-    m_transaction->database().removeObjectStore(m_objectStoreId);
+    m_transaction->database().removeObjectStore(m_objectStoreID);
 }
 
 void DeleteObjectStoreAbortOperation::perform()
index c4e39b3..92baa30 100644 (file)
 
 #include "IDBDatabaseBackend.h"
 #include "IDBOperation.h"
-#include "IDBServerConnection.h"
 #include "IDBTransactionBackend.h"
 
 #if ENABLE(INDEXED_DATABASE)
 
 namespace WebCore {
 
+class IDBServerConnection;
+
 class CreateObjectStoreOperation : public IDBOperation {
 public:
     static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, const IDBObjectStoreMetadata& objectStoreMetadata)
@@ -42,6 +43,9 @@ public:
         return adoptRef(new CreateObjectStoreOperation(transaction, objectStoreMetadata));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    const IDBObjectStoreMetadata& objectStoreMetadata() const { return m_objectStoreMetadata; }
+
 private:
     CreateObjectStoreOperation(IDBTransactionBackend* transaction, const IDBObjectStoreMetadata& objectStoreMetadata)
         : m_transaction(transaction)
@@ -60,6 +64,9 @@ public:
         return adoptRef(new DeleteObjectStoreOperation(transaction, objectStoreMetadata));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    const IDBObjectStoreMetadata& objectStoreMetadata() const { return m_objectStoreMetadata; }
+
 private:
     DeleteObjectStoreOperation(IDBTransactionBackend* transaction, const IDBObjectStoreMetadata& objectStoreMetadata)
         : m_transaction(transaction)
@@ -73,15 +80,19 @@ private:
 
 class IDBDatabaseBackend::VersionChangeOperation : public IDBOperation {
 public:
-    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t transactionId, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)
+    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)
     {
-        return adoptRef(new VersionChangeOperation(transaction, transactionId, version, callbacks, databaseCallbacks));
+        return adoptRef(new VersionChangeOperation(transaction, version, callbacks, databaseCallbacks));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t version() const { return m_version; }
+    IDBCallbacks* callbacks() const { return m_callbacks.get(); }
+    IDBDatabaseCallbacks* databaseCallbacks() const { return m_databaseCallbacks.get(); }
+
 private:
-    VersionChangeOperation(IDBTransactionBackend* transaction, int64_t transactionId, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)
+    VersionChangeOperation(IDBTransactionBackend* transaction, int64_t version, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks)
         : m_transaction(transaction)
-        , m_transactionId(transactionId)
         , m_version(version)
         , m_callbacks(callbacks)
         , m_databaseCallbacks(databaseCallbacks)
@@ -89,7 +100,6 @@ private:
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    int64_t m_transactionId;
     int64_t m_version;
     RefPtr<IDBCallbacks> m_callbacks;
     RefPtr<IDBDatabaseCallbacks> m_databaseCallbacks;
@@ -105,12 +115,12 @@ public:
 private:
     CreateObjectStoreAbortOperation(IDBTransactionBackend* transaction, int64_t objectStoreId)
         : m_transaction(transaction)
-        , m_objectStoreId(objectStoreId)
+        , m_objectStoreID(objectStoreId)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_objectStoreId;
+    const int64_t m_objectStoreID;
 };
 
 class DeleteObjectStoreAbortOperation : public IDBSynchronousOperation {
@@ -158,16 +168,20 @@ public:
         return adoptRef(new CreateIndexOperation(transaction, objectStoreId, indexMetadata));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    const IDBIndexMetadata& idbIndexMetadata() const { return m_indexMetadata; }
+
 private:
     CreateIndexOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
         : m_transaction(transaction)
-        , m_objectStoreId(objectStoreId)
+        , m_objectStoreID(objectStoreId)
         , m_indexMetadata(indexMetadata)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_objectStoreId;
+    const int64_t m_objectStoreID;
     const IDBIndexMetadata m_indexMetadata;
 };
 
@@ -181,14 +195,14 @@ public:
 private:
     CreateIndexAbortOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, int64_t indexId)
         : m_transaction(transaction)
-        , m_objectStoreId(objectStoreId)
-        , m_indexId(indexId)
+        , m_objectStoreID(objectStoreId)
+        , m_indexID(indexId)
     {
     }
 
     const RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_objectStoreId;
-    const int64_t m_indexId;
+    const int64_t m_objectStoreID;
+    const int64_t m_indexID;
 };
 
 class DeleteIndexOperation : public IDBOperation {
@@ -198,16 +212,20 @@ public:
         return adoptRef(new DeleteIndexOperation(transaction, objectStoreId, indexMetadata));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    const IDBIndexMetadata& idbIndexMetadata() const { return m_indexMetadata; }
+
 private:
     DeleteIndexOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
         : m_transaction(transaction)
-        , m_objectStoreId(objectStoreId)
+        , m_objectStoreID(objectStoreId)
         , m_indexMetadata(indexMetadata)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_objectStoreId;
+    const int64_t m_objectStoreID;
     const IDBIndexMetadata m_indexMetadata;
 };
 
@@ -221,13 +239,13 @@ public:
 private:
     DeleteIndexAbortOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata)
         : m_transaction(transaction)
-        , m_objectStoreId(objectStoreId)
+        , m_objectStoreID(objectStoreId)
         , m_indexMetadata(indexMetadata)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_objectStoreId;
+    const int64_t m_objectStoreID;
     const IDBIndexMetadata m_indexMetadata;
 };
 
@@ -238,12 +256,20 @@ public:
         return adoptRef(new GetOperation(transaction, metadata, objectStoreId, indexId, keyRange, cursorType, callbacks));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    int64_t indexID() const { return m_indexID; }
+    IndexedDB::CursorType cursorType() const { return m_cursorType; }
+    IDBKeyRange* keyRange() const { return m_keyRange.get(); }
+    RefPtr<IDBCallbacks> callbacks() const { return m_callbacks.get(); }
+    bool autoIncrement() const { return m_autoIncrement; }
+    IDBKeyPath keyPath() const { return m_keyPath; }
+
 private:
     GetOperation(IDBTransactionBackend* transaction, const IDBDatabaseMetadata& metadata, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IndexedDB::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks)
         : m_transaction(transaction)
-        , m_databaseId(metadata.id)
-        , m_objectStoreId(objectStoreId)
-        , m_indexId(indexId)
+        , m_objectStoreID(objectStoreId)
+        , m_indexID(indexId)
         , m_keyPath(metadata.objectStores.get(objectStoreId).keyPath)
         , m_autoIncrement(metadata.objectStores.get(objectStoreId).autoIncrement)
         , m_keyRange(keyRange)
@@ -255,9 +281,8 @@ private:
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_databaseId;
-    const int64_t m_objectStoreId;
-    const int64_t m_indexId;
+    const int64_t m_objectStoreID;
+    const int64_t m_indexID;
     const IDBKeyPath m_keyPath;
     const bool m_autoIncrement;
     const RefPtr<IDBKeyRange> m_keyRange;
@@ -267,33 +292,40 @@ private:
 
 class PutOperation : public IDBOperation {
 public:
-    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBKey> key, IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
+    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, const IDBObjectStoreMetadata& objectStore, PassRefPtr<SharedBuffer> value, PassRefPtr<IDBKey> key, IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
     {
-        return adoptRef(new PutOperation(transaction, databaseId, objectStore, value, key, putMode, callbacks, indexIds, indexKeys));
+        return adoptRef(new PutOperation(transaction, objectStore, value, key, putMode, callbacks, indexIds, indexKeys));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    IDBDatabaseBackend::PutMode putMode() const { return m_putMode; }
+    const IDBObjectStoreMetadata& objectStore() const { return m_objectStore; }
+    IDBKey* key() const { return m_key.get(); }
+    const Vector<int64_t>& indexIDs() const { return m_indexIDs; }
+    const Vector<IndexKeys>& indexKeys() const { return m_indexKeys; }
+    IDBCallbacks* callbacks() const { return m_callbacks.get(); }
+    SharedBuffer* value() const { return m_value.get(); }
+
 private:
-    PutOperation(IDBTransactionBackend* transaction, int64_t databaseId, const IDBObjectStoreMetadata& objectStore, PassRefPtr<SharedBuffer>& value, PassRefPtr<IDBKey> key, IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
+    PutOperation(IDBTransactionBackend* transaction, const IDBObjectStoreMetadata& objectStore, PassRefPtr<SharedBuffer>& value, PassRefPtr<IDBKey> key, IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBCallbacks> callbacks, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
         : m_transaction(transaction)
-        , m_databaseId(databaseId)
         , m_objectStore(objectStore)
         , m_value(value)
         , m_key(key)
         , m_putMode(putMode)
         , m_callbacks(callbacks)
-        , m_indexIds(indexIds)
+        , m_indexIDs(indexIds)
         , m_indexKeys(indexKeys)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_databaseId;
     const IDBObjectStoreMetadata m_objectStore;
     const RefPtr<SharedBuffer> m_value;
     const RefPtr<IDBKey> m_key;
     const IDBDatabaseBackend::PutMode m_putMode;
     const RefPtr<IDBCallbacks> m_callbacks;
-    const Vector<int64_t> m_indexIds;
+    const Vector<int64_t> m_indexIDs;
     const Vector<IndexKeys> m_indexKeys;
 };
 
@@ -317,17 +349,26 @@ private:
 
 class OpenCursorOperation : public IDBOperation {
 public:
-    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IndexedDB::CursorDirection direction, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
+    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IndexedDB::CursorDirection direction, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
     {
-        return adoptRef(new OpenCursorOperation(transaction, databaseId, objectStoreId, indexId, keyRange, direction, cursorType, taskType, callbacks));
+        return adoptRef(new OpenCursorOperation(transaction, objectStoreId, indexId, keyRange, direction, cursorType, taskType, callbacks));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    int64_t indexID() const { return m_indexID; }
+    IndexedDB::CursorDirection direction() const { return m_direction; }
+    IndexedDB::CursorType cursorType() const { return m_cursorType; }
+    IDBDatabaseBackend::TaskType taskType() const { return m_taskType; }
+    IDBKeyRange* keyRange() const { return m_keyRange.get(); }
+    IndexedDB::CursorDirection cursorDirection() const { return m_direction; }
+    IDBCallbacks* callbacks() const { return m_callbacks.get(); }
+
 private:
-    OpenCursorOperation(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IndexedDB::CursorDirection direction, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
+    OpenCursorOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, IndexedDB::CursorDirection direction, IndexedDB::CursorType cursorType, IDBDatabaseBackend::TaskType taskType, PassRefPtr<IDBCallbacks> callbacks)
         : m_transaction(transaction)
-        , m_databaseId(databaseId)
-        , m_objectStoreId(objectStoreId)
-        , m_indexId(indexId)
+        , m_objectStoreID(objectStoreId)
+        , m_indexID(indexId)
         , m_keyRange(keyRange)
         , m_direction(direction)
         , m_cursorType(cursorType)
@@ -337,9 +378,8 @@ private:
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_databaseId;
-    const int64_t m_objectStoreId;
-    const int64_t m_indexId;
+    const int64_t m_objectStoreID;
+    const int64_t m_indexID;
     const PassRefPtr<IDBKeyRange> m_keyRange;
     const IndexedDB::CursorDirection m_direction;
     const IndexedDB::CursorType m_cursorType;
@@ -349,73 +389,81 @@ private:
 
 class CountOperation : public IDBOperation {
 public:
-    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
+    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     {
-        return adoptRef(new CountOperation(transaction, databaseId, objectStoreId, indexId, keyRange, callbacks));
+        return adoptRef(new CountOperation(transaction, objectStoreId, indexId, keyRange, callbacks));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    int64_t indexID() const { return m_indexID; }
+    IDBKeyRange* keyRange() const { return m_keyRange.get(); }
+    IDBCallbacks* callbacks() const { return m_callbacks.get(); }
 private:
-    CountOperation(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
+    CountOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, int64_t indexId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
         : m_transaction(transaction)
-        , m_databaseId(databaseId)
-        , m_objectStoreId(objectStoreId)
-        , m_indexId(indexId)
+        , m_objectStoreID(objectStoreId)
+        , m_indexID(indexId)
         , m_keyRange(keyRange)
         , m_callbacks(callbacks)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_databaseId;
-    const int64_t m_objectStoreId;
-    const int64_t m_indexId;
+    const int64_t m_objectStoreID;
+    const int64_t m_indexID;
     const RefPtr<IDBKeyRange> m_keyRange;
     const RefPtr<IDBCallbacks> m_callbacks;
 };
 
 class DeleteRangeOperation : public IDBOperation {
 public:
-    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
+    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
     {
-        return adoptRef(new DeleteRangeOperation(transaction, databaseId, objectStoreId, keyRange, callbacks));
+        return adoptRef(new DeleteRangeOperation(transaction, objectStoreId, keyRange, callbacks));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    IDBCallbacks* callbacks() const { return m_callbacks.get(); }
+    IDBKeyRange* keyRange() const { return m_keyRange.get(); }
+
 private:
-    DeleteRangeOperation(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
+    DeleteRangeOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, PassRefPtr<IDBKeyRange> keyRange, PassRefPtr<IDBCallbacks> callbacks)
         : m_transaction(transaction)
-        , m_databaseId(databaseId)
-        , m_objectStoreId(objectStoreId)
+        , m_objectStoreID(objectStoreId)
         , m_keyRange(keyRange)
         , m_callbacks(callbacks)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_databaseId;
-    const int64_t m_objectStoreId;
+    const int64_t m_objectStoreID;
     const RefPtr<IDBKeyRange> m_keyRange;
     const RefPtr<IDBCallbacks> m_callbacks;
 };
 
-class ClearOperation : public IDBOperation {
+class ClearObjectStoreOperation : public IDBOperation {
 public:
-    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
+    static PassRefPtr<IDBOperation> create(IDBTransactionBackend* transaction, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
     {
-        return adoptRef(new ClearOperation(transaction, databaseId, objectStoreId, callbacks));
+        return adoptRef(new ClearObjectStoreOperation(transaction, objectStoreId, callbacks));
     }
     virtual void perform(std::function<void()> successCallback) OVERRIDE FINAL;
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+    IDBCallbacks* callbacks() const { return m_callbacks.get(); }
+
 private:
-    ClearOperation(IDBTransactionBackend* transaction, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
+    ClearObjectStoreOperation(IDBTransactionBackend* transaction, int64_t objectStoreId, PassRefPtr<IDBCallbacks> callbacks)
         : m_transaction(transaction)
-        , m_databaseId(databaseId)
-        , m_objectStoreId(objectStoreId)
+        , m_objectStoreID(objectStoreId)
         , m_callbacks(callbacks)
     {
     }
 
     RefPtr<IDBTransactionBackend> m_transaction;
-    const int64_t m_databaseId;
-    const int64_t m_objectStoreId;
+    const int64_t m_objectStoreID;
     const RefPtr<IDBCallbacks> m_callbacks;
 };
 
index 0ebd2e6..0605469 100644 (file)
@@ -1922,11 +1922,6 @@ void IDBBackingStoreLevelDB::establishBackingStoreTransaction(int64_t transactio
     m_backingStoreTransactions.set(transactionID, IDBBackingStoreTransactionLevelDB::create(transactionID, this));
 }
 
-IDBBackingStoreTransactionInterface* IDBBackingStoreLevelDB::deprecatedBackingStoreTransaction(int64_t transactionID)
-{
-    return m_backingStoreTransactions.get(transactionID);
-}
-
 void IDBBackingStoreLevelDB::removeBackingStoreTransaction(IDBBackingStoreTransactionLevelDB* transaction)
 {
     ASSERT(m_backingStoreTransactions.contains(transaction->transactionID()));
index 3da4fb3..0c69500 100644 (file)
@@ -110,7 +110,6 @@ public:
 
     static int compareIndexKeys(const LevelDBSlice&, const LevelDBSlice&);
 
-    IDBBackingStoreTransactionInterface* deprecatedBackingStoreTransaction(int64_t transactionID);
     void removeBackingStoreTransaction(IDBBackingStoreTransactionLevelDB*);
 
 protected:
index b5cf821..90cb227 100644 (file)
 
 #include "IDBBackingStoreLevelDB.h"
 #include "IDBBackingStoreTransactionLevelDB.h"
+#include "IDBCursorBackend.h"
 #include "IDBIndexWriter.h"
 #include <wtf/MainThread.h>
 
+#define ASYNC_COMPLETION_CALLBACK(callback, arg) \
+    callOnMainThread([callback, arg]() { \
+        callback(arg); \
+    });
+
+#define EMPTY_ASYNC_COMPLETION_CALLBACK(callback) \
+    callOnMainThread([callback]() { \
+        callback(0); \
+    });
+
 namespace WebCore {
 
 IDBServerConnectionLevelDB::IDBServerConnectionLevelDB(IDBBackingStoreLevelDB* backingStore)
@@ -51,13 +62,6 @@ IDBBackingStoreInterface* IDBServerConnectionLevelDB::deprecatedBackingStore()
     return m_backingStore.get();
 }
 
-IDBBackingStoreTransactionInterface* IDBServerConnectionLevelDB::deprecatedBackingStoreTransaction(int64_t transactionID)
-{
-    if (!m_backingStore)
-        return 0;
-    return m_backingStore->deprecatedBackingStoreTransaction(transactionID);
-}
-
 bool IDBServerConnectionLevelDB::isClosed()
 {
     return m_closed;
@@ -181,11 +185,386 @@ void IDBServerConnectionLevelDB::setIndexKeys(int64_t transactionID, int64_t dat
         indexWriter->writeIndexKeys(recordIdentifier.get(), *m_backingStore, *backingStoreTransaction, databaseID, objectStoreID);
     }
 
-    callOnMainThread([completionCallback]() {
-        completionCallback(0);
-    });
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::createObjectStore(IDBTransactionBackend& transaction, const CreateObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    String objectStoreName = operation.objectStoreMetadata().name;
+
+    if (!m_backingStore->createObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStoreMetadata().id, objectStoreName, operation.objectStoreMetadata().keyPath, operation.objectStoreMetadata().autoIncrement)) {
+        callOnMainThread([completionCallback, objectStoreName]() {
+            completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error creating object store '%s'.", objectStoreName.utf8().data())));
+        });
+        return;
+    }
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::createIndex(IDBTransactionBackend& transaction, const CreateIndexOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    const IDBIndexMetadata& indexMetadata = operation.idbIndexMetadata();
+    if (!m_backingStore->createIndex(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), indexMetadata.id, indexMetadata.name, indexMetadata.keyPath, indexMetadata.unique, indexMetadata.multiEntry)) {
+        callOnMainThread([completionCallback, indexMetadata]() {
+            completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error when trying to create index '%s'.", indexMetadata.name.utf8().data())));
+        });
+        return;
+    }
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::deleteIndex(IDBTransactionBackend& transaction, const DeleteIndexOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    const IDBIndexMetadata& indexMetadata = operation.idbIndexMetadata();
+    if (!m_backingStore->deleteIndex(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), indexMetadata.id)) {
+        callOnMainThread([completionCallback, indexMetadata]() {
+            completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting index '%s'.", indexMetadata.name.utf8().data())));
+        });
+        return;
+    }
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
 }
 
+void IDBServerConnectionLevelDB::get(IDBTransactionBackend& transaction, const GetOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    RefPtr<IDBKey> key;
+
+    if (operation.keyRange()->isOnlyKey())
+        key = operation.keyRange()->lower();
+    else {
+        RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor;
+        if (operation.indexID() == IDBIndexMetadata::InvalidId) {
+            ASSERT(operation.cursorType() != IndexedDB::CursorKeyOnly);
+            // ObjectStore Retrieval Operation
+            backingStoreCursor = m_backingStore->openObjectStoreCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), IndexedDB::CursorNext);
+        } else {
+            if (operation.cursorType() == IndexedDB::CursorKeyOnly) {
+                // Index Value Retrieval Operation
+                backingStoreCursor = m_backingStore->openIndexKeyCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), IndexedDB::CursorNext);
+            } else {
+                // Index Referenced Value Retrieval Operation
+                backingStoreCursor = m_backingStore->openIndexCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), IndexedDB::CursorNext);
+            }
+        }
+
+        if (!backingStoreCursor) {
+            operation.callbacks()->onSuccess();
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+
+        key = backingStoreCursor->key();
+    }
+
+    RefPtr<IDBKey> primaryKey;
+    bool ok;
+    if (operation.indexID() == IDBIndexMetadata::InvalidId) {
+        // Object Store Retrieval Operation
+        Vector<char> value;
+        ok = m_backingStore->getRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), *key, value);
+        if (!ok) {
+            operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+
+        if (value.isEmpty()) {
+            operation.callbacks()->onSuccess();
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+
+        if (operation.autoIncrement() && !operation.keyPath().isNull()) {
+            operation.callbacks()->onSuccess(SharedBuffer::adoptVector(value), key, operation.keyPath());
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+
+        operation.callbacks()->onSuccess(SharedBuffer::adoptVector(value));
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+
+    }
+
+    // From here we are dealing only with indexes.
+    ok = m_backingStore->getPrimaryKeyViaIndex(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), *key, primaryKey);
+    if (!ok) {
+        operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+    if (!primaryKey) {
+        operation.callbacks()->onSuccess();
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+    if (operation.cursorType() == IndexedDB::CursorKeyOnly) {
+        // Index Value Retrieval Operation
+        operation.callbacks()->onSuccess(primaryKey.get());
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+
+    // Index Referenced Value Retrieval Operation
+    Vector<char> value;
+    ok = m_backingStore->getRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), *primaryKey, value);
+    if (!ok) {
+        operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+
+    if (value.isEmpty()) {
+        operation.callbacks()->onSuccess();
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+    if (operation.autoIncrement() && !operation.keyPath().isNull()) {
+        operation.callbacks()->onSuccess(SharedBuffer::adoptVector(value), primaryKey, operation.keyPath());
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+    operation.callbacks()->onSuccess(SharedBuffer::adoptVector(value));
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::put(IDBTransactionBackend& transaction, const PutOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    bool keyWasGenerated = false;
+
+    RefPtr<IDBKey> key;
+    if (operation.putMode() != IDBDatabaseBackend::CursorUpdate && operation.objectStore().autoIncrement && !operation.key()) {
+        RefPtr<IDBKey> autoIncKey = m_backingStore->generateKey(transaction, transaction.database().id(), operation.objectStore().id);
+        keyWasGenerated = true;
+        if (!autoIncKey->isValid()) {
+            operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Maximum key generator value reached."));
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+        key = autoIncKey;
+    } else
+        key = operation.key();
+
+    ASSERT(key);
+    ASSERT(key->isValid());
+
+    RefPtr<IDBRecordIdentifier> recordIdentifier;
+    if (operation.putMode() == IDBDatabaseBackend::AddOnly) {
+        bool ok = m_backingStore->keyExistsInObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStore().id, *key, recordIdentifier);
+        if (!ok) {
+            operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error checking key existence."));
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+        if (recordIdentifier) {
+            operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, "Key already exists in the object store."));
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+    }
+
+    Vector<RefPtr<IDBIndexWriter>> indexWriters;
+    String errorMessage;
+    bool obeysConstraints = false;
+    bool backingStoreSuccess = m_backingStore->makeIndexWriters(transaction.id(), transaction.database().id(), operation.objectStore(), *key, keyWasGenerated, operation.indexIDs(), operation.indexKeys(), indexWriters, &errorMessage, obeysConstraints);
+    if (!backingStoreSuccess) {
+        operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error updating index keys."));
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+    if (!obeysConstraints) {
+        operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::ConstraintError, errorMessage));
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+
+    // Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
+    backingStoreSuccess = m_backingStore->putRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStore().id, *key, operation.value(), recordIdentifier.get());
+    if (!backingStoreSuccess) {
+        operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
+        EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+        return;
+    }
+
+    for (size_t i = 0; i < indexWriters.size(); ++i) {
+        IDBIndexWriter* indexWriter = indexWriters[i].get();
+        indexWriter->writeIndexKeys(recordIdentifier.get(), *m_backingStore, *backingStoreTransaction, transaction.database().id(), operation.objectStore().id);
+    }
+
+    if (operation.objectStore().autoIncrement && operation.putMode() != IDBDatabaseBackend::CursorUpdate && key->type() == IDBKey::NumberType) {
+        bool ok = m_backingStore->updateKeyGenerator(transaction, transaction.database().id(), operation.objectStore().id, *key, !keyWasGenerated);
+        if (!ok) {
+            operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error updating key generator."));
+            EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+            return;
+        }
+    }
+
+    operation.callbacks()->onSuccess(key.release());
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::openCursor(IDBTransactionBackend& transaction, const OpenCursorOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    // The frontend has begun indexing, so this pauses the transaction
+    // until the indexing is complete. This can't happen any earlier
+    // because we don't want to switch to early mode in case multiple
+    // indexes are being created in a row, with put()'s in between.
+    if (operation.taskType() == IDBDatabaseBackend::PreemptiveTask)
+        transaction.addPreemptiveEvent();
+
+    RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor;
+    if (operation.indexID() == IDBIndexMetadata::InvalidId) {
+        ASSERT(operation.cursorType() != IndexedDB::CursorKeyOnly);
+        backingStoreCursor = m_backingStore->openObjectStoreCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), operation.direction());
+    } else {
+        ASSERT(operation.taskType() == IDBDatabaseBackend::NormalTask);
+        if (operation.cursorType() == IndexedDB::CursorKeyOnly)
+            backingStoreCursor = m_backingStore->openIndexKeyCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), operation.direction());
+        else
+            backingStoreCursor = m_backingStore->openIndexCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), operation.direction());
+    }
+
+    if (!backingStoreCursor) {
+        operation.callbacks()->onSuccess(static_cast<SharedBuffer*>(0));
+        callOnMainThread([completionCallback]() {
+            completionCallback(0);
+        });
+        return;
+    }
+
+    IDBDatabaseBackend::TaskType taskType(static_cast<IDBDatabaseBackend::TaskType>(operation.taskType()));
+
+    RefPtr<IDBCursorBackend> cursor = transaction.createCursorBackend(*backingStoreCursor, operation.cursorType(), taskType, operation.objectStoreID());
+    operation.callbacks()->onSuccess(cursor, cursor->key(), cursor->primaryKey(), cursor->value());
+
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::count(IDBTransactionBackend& transaction, const CountOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    uint32_t count = 0;
+    RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor;
+
+    if (operation.indexID() == IDBIndexMetadata::InvalidId)
+        backingStoreCursor = m_backingStore->openObjectStoreKeyCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), IndexedDB::CursorNext);
+    else
+        backingStoreCursor = m_backingStore->openIndexKeyCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.indexID(), operation.keyRange(), IndexedDB::CursorNext);
+    if (!backingStoreCursor) {
+        operation.callbacks()->onSuccess(count);
+        callOnMainThread([completionCallback]() {
+            completionCallback(0);
+        });
+        return;
+    }
+
+    do {
+        ++count;
+    } while (backingStoreCursor->continueFunction(0));
+
+    operation.callbacks()->onSuccess(count);
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::deleteRange(IDBTransactionBackend& transaction, const DeleteRangeOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    RefPtr<IDBBackingStoreCursorInterface> backingStoreCursor = m_backingStore->openObjectStoreCursor(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), operation.keyRange(), IndexedDB::CursorNext);
+    if (backingStoreCursor) {
+        do {
+            if (!m_backingStore->deleteRecord(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID(), backingStoreCursor->recordIdentifier())) {
+                operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error deleting data in range"));
+                callOnMainThread([completionCallback]() {
+                    completionCallback(0);
+                });
+                return;
+            }
+        } while (backingStoreCursor->continueFunction(0));
+    }
+
+    operation.callbacks()->onSuccess();
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::clearObjectStore(IDBTransactionBackend& transaction, const ClearObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    if (!m_backingStore->clearObjectStore(*backingStoreTransaction, transaction.database().id(), operation.objectStoreID())) {
+        operation.callbacks()->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error clearing object store"));
+        callOnMainThread([completionCallback]() {
+            completionCallback(0);
+        });
+        return;
+    }
+    operation.callbacks()->onSuccess();
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::deleteObjectStore(IDBTransactionBackend& transaction, const DeleteObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    const IDBObjectStoreMetadata& objectStoreMetadata = operation.objectStoreMetadata();
+
+    if (!m_backingStore->deleteObjectStore(*backingStoreTransaction, transaction.database().id(), objectStoreMetadata.id)) {
+        callOnMainThread([completionCallback, objectStoreMetadata]() {
+            completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, String::format("Internal error deleting object store '%s'.", objectStoreMetadata.name.utf8().data())));
+        });
+        return;
+    }
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
+
+void IDBServerConnectionLevelDB::changeDatabaseVersion(IDBTransactionBackend& transaction, const IDBDatabaseBackend::VersionChangeOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+{
+    IDBBackingStoreTransactionLevelDB* backingStoreTransaction = m_backingStoreTransactions.get(transaction.id());
+    ASSERT(backingStoreTransaction);
+
+    IDBDatabaseBackend& database = transaction.database();
+    int64_t databaseId = database.id();
+    uint64_t oldVersion = database.metadata().version;
+
+    // FIXME: Database versions are now of type uint64_t, but this code expected int64_t.
+    ASSERT(operation.version() > (int64_t)oldVersion);
+    database.setCurrentVersion(operation.version());
+    if (!m_backingStore->updateIDBDatabaseVersion(*backingStoreTransaction, databaseId, database.metadata().version)) {
+        RefPtr<IDBDatabaseError> error = IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Error writing data to stable storage when updating version.");
+        operation.callbacks()->onError(error);
+        ASYNC_COMPLETION_CALLBACK(completionCallback, error);
+        return;
+    }
+    ASSERT(!database.hasPendingSecondHalfOpen());
+    database.setPendingSecondHalfOpen(IDBPendingOpenCall::create(*operation.callbacks(), *operation.databaseCallbacks(), transaction.id(), operation.version()));
+    operation.callbacks()->onUpgradeNeeded(oldVersion, &database, database.metadata());
+
+    EMPTY_ASYNC_COMPLETION_CALLBACK(completionCallback);
+}
 
 } // namespace WebCore
 
index 6c48b12..d9deee5 100644 (file)
@@ -48,7 +48,6 @@ public:
     // FIXME: For now, server connection provides a synchronous accessor to the in-process backing store objects.
     // This is temporary and will be removed soon.
     virtual IDBBackingStoreInterface* deprecatedBackingStore() OVERRIDE;
-    virtual IDBBackingStoreTransactionInterface* deprecatedBackingStoreTransaction(int64_t transactionID) OVERRIDE;
 
     virtual bool isClosed() OVERRIDE;
 
@@ -65,6 +64,17 @@ public:
     virtual void rollbackTransaction(int64_t transactionID, std::function<void()> completionCallback) OVERRIDE;
     virtual void setIndexKeys(int64_t transactionID, int64_t databaseID, int64_t objectStoreID, const IDBObjectStoreMetadata&, IDBKey& primaryKey, const Vector<int64_t>& indexIDs, const Vector<Vector<RefPtr<IDBKey>>>& indexKeys, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback);
 
+    virtual void createObjectStore(IDBTransactionBackend&, const CreateObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void createIndex(IDBTransactionBackend&, const CreateIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void deleteIndex(IDBTransactionBackend&, const DeleteIndexOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void get(IDBTransactionBackend&, const GetOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void put(IDBTransactionBackend&, const PutOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void openCursor(IDBTransactionBackend&, const OpenCursorOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void count(IDBTransactionBackend&, const CountOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void deleteRange(IDBTransactionBackend&, const DeleteRangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void clearObjectStore(IDBTransactionBackend&, const ClearObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
+    virtual void changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback) OVERRIDE;
 private:
     IDBServerConnectionLevelDB(IDBBackingStoreLevelDB*);
 
index 595f857..cce93e2 100644 (file)
                93B70D6309EB0C7C009D8468 /* JSDOMBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B70D4709EB0C7C009D8468 /* JSDOMBinding.cpp */; };
                93B70D6409EB0C7C009D8468 /* JSDOMBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B70D4809EB0C7C009D8468 /* JSDOMBinding.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93B70D6909EB0C7C009D8468 /* JSEventListener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B70D4D09EB0C7C009D8468 /* JSEventListener.cpp */; };
-               93B70D6A09EB0C7C009D8468 /* JSEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B70D4E09EB0C7C009D8468 /* JSEventListener.h */; };
+               93B70D6A09EB0C7C009D8468 /* JSEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B70D4E09EB0C7C009D8468 /* JSEventListener.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93B70D6B09EB0C7C009D8468 /* JSPluginElementFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B70D4F09EB0C7C009D8468 /* JSPluginElementFunctions.cpp */; };
                93B70D6C09EB0C7C009D8468 /* JSPluginElementFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 93B70D5009EB0C7C009D8468 /* JSPluginElementFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                93B70D6F09EB0C7C009D8468 /* ScriptController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B70D5309EB0C7C009D8468 /* ScriptController.cpp */; };
                BCE32B9E1517C22700F542EC /* RenderMultiColumnSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE32B9D1517C22700F542EC /* RenderMultiColumnSet.cpp */; };
                BCE3BEC20D222B1D007E06E4 /* TagNodeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE3BEC00D222B1D007E06E4 /* TagNodeList.cpp */; };
                BCE3BEC30D222B1D007E06E4 /* TagNodeList.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE3BEC10D222B1D007E06E4 /* TagNodeList.h */; };
-               BCE4389C140B1BA8005E437E /* JSDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE4389B140B1BA7005E437E /* JSDictionary.h */; };
+               BCE4389C140B1BA8005E437E /* JSDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE4389B140B1BA7005E437E /* JSDictionary.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BCE438A2140C0DC0005E437E /* JSDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE438A1140C0DBF005E437E /* JSDictionary.cpp */; };
                BCE4413312F748E2009B84B8 /* RenderCombineText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCE4413112F748E2009B84B8 /* RenderCombineText.cpp */; };
                BCE4413412F748E2009B84B8 /* RenderCombineText.h in Headers */ = {isa = PBXBuildFile; fileRef = BCE4413212F748E2009B84B8 /* RenderCombineText.h */; };
index 712691b..851dff4 100644 (file)
@@ -1,3 +1,12 @@
+2013-11-15  Brady Eidson  <beidson@apple.com>
+
+        Move execution of IDBTransactionBackendOperations to the IDBServerConnection
+        https://bugs.webkit.org/show_bug.cgi?id=124385
+
+        Reviewed by Tim Horton.
+
+        * WebProcess/Databases/IndexedDB/WebProcessIDBDatabaseBackend.h:
+
 2013-11-15  Peter Molnar  <pmolnar.u-szeged@partner.samsung.com>
 
         Fixed incorrectly placed NETWORK_PROCESS guard in NetworkConnectionToWebProcess.cpp
index 19e6de3..cef0253 100644 (file)
@@ -28,6 +28,7 @@
 #define WebProcessIDBDatabaseBackend_h
 
 #include "MessageSender.h"
+#include <WebCore/IDBBackingStoreInterface.h>
 #include <WebCore/IDBDatabaseBackend.h>
 
 #if ENABLE(INDEXED_DATABASE)