IDB: delete object store support
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 17 Jan 2014 01:20:12 +0000 (01:20 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 17 Jan 2014 01:20:12 +0000 (01:20 +0000)
<rdar://problem/15779641> and https://bugs.webkit.org/show_bug.cgi?id=127123

Reviewed by Alexey Proskuryakov.

Source/WebCore:

* Modules/indexeddb/IDBTransactionBackendOperations.h:
(WebCore::DeleteObjectStoreOperation::transaction):

Source/WebKit2:

Pipe through Web -> Database -> Web process messaging for delete object store.
Perform dropping the object store in the backing store.

* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::deleteObjectStore):
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h:
* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in:

* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::didDeleteObjectStore):
(WebKit::UniqueIDBDatabase::deleteObjectStore):
(WebKit::UniqueIDBDatabase::deleteObjectStoreInBackingStore):
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:

* DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createObjectStore):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:

* WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
(WebKit::WebIDBServerConnection::deleteObjectStore):
(WebKit::WebIDBServerConnection::didDeleteObjectStore):
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
* WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:

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

14 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBTransactionBackendOperations.h
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in

index e0badd3..036fa39 100644 (file)
@@ -1,3 +1,13 @@
+2014-01-16  Brady Eidson  <beidson@apple.com>
+
+        IDB: delete object store support
+        <rdar://problem/15779641> and https://bugs.webkit.org/show_bug.cgi?id=127123
+
+        Reviewed by Alexey Proskuryakov.
+
+        * Modules/indexeddb/IDBTransactionBackendOperations.h:
+        (WebCore::DeleteObjectStoreOperation::transaction):
+
 2014-01-16  Alexey Proskuryakov  <ap@apple.com>
 
         More non-Mac build fix.
index a0deb1b..4906ddc 100644 (file)
@@ -65,6 +65,7 @@ public:
     }
     virtual void perform(std::function<void()> successCallback) override final;
 
+    IDBTransactionBackend* transaction() const { return m_transaction.get(); }
     const IDBObjectStoreMetadata& objectStoreMetadata() const { return m_objectStoreMetadata; }
 
 private:
index 48e0420..74c7557 100644 (file)
@@ -1,3 +1,36 @@
+2014-01-16  Brady Eidson  <beidson@apple.com>
+
+        IDB: delete object store support
+        <rdar://problem/15779641> and https://bugs.webkit.org/show_bug.cgi?id=127123
+
+        Reviewed by Alexey Proskuryakov.
+
+        Pipe through Web -> Database -> Web process messaging for delete object store.
+        Perform dropping the object store in the backing store.
+
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
+        (WebKit::DatabaseProcessIDBConnection::deleteObjectStore):
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.h:
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.messages.in:
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::didDeleteObjectStore):
+        (WebKit::UniqueIDBDatabase::deleteObjectStore):
+        (WebKit::UniqueIDBDatabase::deleteObjectStoreInBackingStore):
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createObjectStore):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
+
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.cpp:
+        (WebKit::WebIDBServerConnection::deleteObjectStore):
+        (WebKit::WebIDBServerConnection::didDeleteObjectStore):
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.h:
+        * WebProcess/Databases/IndexedDB/WebIDBServerConnection.messages.in:
+
 2014-01-16  Alexey Proskuryakov  <ap@apple.com>
 
         [Mac] [iOS] Add support for CFHTTPCookieStorageAcceptPolicyExclusivelyFromMainDocumentDomain
index 9699b65..5196d48 100644 (file)
@@ -166,6 +166,17 @@ void DatabaseProcessIDBConnection::createObjectStore(uint64_t requestID, int64_t
     });
 }
 
+void DatabaseProcessIDBConnection::deleteObjectStore(uint64_t requestID, int64_t transactionID, int64_t objectStoreID)
+{
+    ASSERT(m_uniqueIDBDatabase);
+
+    LOG(IDB, "DatabaseProcess deleteObjectStore request ID %llu, object store id %lli", requestID, objectStoreID);
+    RefPtr<DatabaseProcessIDBConnection> connection(this);
+    m_uniqueIDBDatabase->deleteObjectStore(IDBTransactionIdentifier(*this, transactionID), objectStoreID, [connection, requestID](bool success) {
+        connection->send(Messages::WebIDBServerConnection::DidDeleteObjectStore(requestID, success));
+    });
+}
+
 IPC::Connection* DatabaseProcessIDBConnection::messageSenderConnection()
 {
     return m_connection->connection();
index b69b755..4d6fa53 100644 (file)
@@ -70,6 +70,7 @@ private:
     void rollbackTransaction(uint64_t requestID, int64_t transactionID);
     void changeDatabaseVersion(uint64_t requestID, int64_t transactionID, uint64_t newVersion);
     void createObjectStore(uint64_t requestID, int64_t transactionID, WebCore::IDBObjectStoreMetadata);
+    void deleteObjectStore(uint64_t requestID, int64_t transactionID, int64_t objectStoreID);
 
     Ref<DatabaseToWebProcessConnection> m_connection;
     uint64_t m_serverConnectionIdentifier;
index 63a200e..d3d6584 100644 (file)
@@ -34,6 +34,7 @@ messages -> DatabaseProcessIDBConnection LegacyReceiver {
     
     ChangeDatabaseVersion(uint64_t requestID, int64_t transactionID, uint64_t newVersion)
     CreateObjectStore(uint64_t requestID, int64_t transactionID, WebCore::IDBObjectStoreMetadata objectStoreMetadata)
+    DeleteObjectStore(uint64_t requestID, int64_t transactionID, int64_t objectStoreID)
 }
 
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
index 38c0db6..7778112 100644 (file)
@@ -321,6 +321,11 @@ void UniqueIDBDatabase::didCreateObjectStore(uint64_t requestID, bool success)
     didCompleteBoolRequest(requestID, success);
 }
 
+void UniqueIDBDatabase::didDeleteObjectStore(uint64_t requestID, bool success)
+{
+    didCompleteBoolRequest(requestID, success);
+}
+
 void UniqueIDBDatabase::didCompleteBoolRequest(uint64_t requestID, bool success)
 {
     RefPtr<AsyncRequest> request = m_pendingDatabaseTasks.take(requestID);
@@ -357,6 +362,33 @@ void UniqueIDBDatabase::createObjectStore(const IDBTransactionIdentifier& identi
     postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::createObjectStoreInBackingStore, requestID, identifier, metadata));
 }
 
+void UniqueIDBDatabase::deleteObjectStore(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, std::function<void(bool)> successCallback)
+{
+    ASSERT(isMainThread());
+
+    if (!m_acceptingNewRequests) {
+        successCallback(false);
+        return;
+    }
+
+    ASSERT(m_metadata->objectStores.contains(objectStoreID));
+    IDBObjectStoreMetadata metadata = m_metadata->objectStores.take(objectStoreID);
+
+    RefPtr<AsyncRequest> request = AsyncRequestImpl<bool>::create([this, metadata, successCallback](bool success) {
+        if (!success)
+            m_metadata->objectStores.set(metadata.id, metadata);
+        successCallback(success);
+    }, [this, metadata, successCallback]() {
+        m_metadata->objectStores.set(metadata.id, metadata);
+        successCallback(false);
+    });
+
+    uint64_t requestID = request->requestID();
+    m_pendingDatabaseTasks.add(requestID, request.release());
+
+    postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::deleteObjectStoreInBackingStore, requestID, identifier, objectStoreID));
+}
+
 void UniqueIDBDatabase::openBackingStoreTransaction(const IDBTransactionIdentifier& identifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode mode)
 {
     ASSERT(!isMainThread());
@@ -427,6 +459,16 @@ void UniqueIDBDatabase::createObjectStoreInBackingStore(uint64_t requestID, cons
     postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didCreateObjectStore, requestID, success));
 }
 
+void UniqueIDBDatabase::deleteObjectStoreInBackingStore(uint64_t requestID, const IDBTransactionIdentifier& identifier, int64_t objectStoreID)
+{
+    ASSERT(!isMainThread());
+    ASSERT(m_backingStore);
+
+    bool success = m_backingStore->deleteObjectStore(identifier, objectStoreID);
+
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didDeleteObjectStore, requestID, success));
+}
+
 String UniqueIDBDatabase::absoluteDatabaseDirectory() const
 {
     ASSERT(isMainThread());
index d679d11..bedcd58 100644 (file)
@@ -75,6 +75,7 @@ public:
 
     void changeDatabaseVersion(const IDBTransactionIdentifier&, uint64_t newVersion, std::function<void(bool)> successCallback);
     void createObjectStore(const IDBTransactionIdentifier&, const WebCore::IDBObjectStoreMetadata&, std::function<void(bool)> successCallback);
+    void deleteObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID, std::function<void(bool)> successCallback);
 
 private:
     UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier&);
@@ -115,6 +116,7 @@ private:
 
     void changeDatabaseVersionInBackingStore(uint64_t requestID, const IDBTransactionIdentifier&, uint64_t newVersion);
     void createObjectStoreInBackingStore(uint64_t requestID, const IDBTransactionIdentifier&, const WebCore::IDBObjectStoreMetadata&);
+    void deleteObjectStoreInBackingStore(uint64_t requestID, const IDBTransactionIdentifier&, int64_t objectStoreID);
 
     void shutdownBackingStore();
 
@@ -124,6 +126,7 @@ private:
     void didCompleteTransactionOperation(const IDBTransactionIdentifier&, bool success);
     void didChangeDatabaseVersion(uint64_t requestID, bool success);
     void didCreateObjectStore(uint64_t requestID, bool success);
+    void didDeleteObjectStore(uint64_t requestID, bool success);
     void didShutdownBackingStore();
     void didCompleteBoolRequest(uint64_t requestID, bool success);
 
index 25fa1f7..abf183d 100644 (file)
@@ -54,6 +54,7 @@ public:
 
     virtual bool changeDatabaseVersion(const IDBTransactionIdentifier&, uint64_t newVersion) = 0;
     virtual bool createObjectStore(const IDBTransactionIdentifier&, const WebCore::IDBObjectStoreMetadata&) = 0;
+    virtual bool deleteObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID) = 0;
 };
 
 } // namespace WebKit
index 0b05bf4..9dc82b6 100644 (file)
@@ -325,7 +325,7 @@ bool UniqueIDBDatabaseBackingStoreSQLite::changeDatabaseVersion(const IDBTransac
 
     SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
     if (!transaction || !transaction->inProgress()) {
-        LOG_ERROR("Attempt to change database version with an establish, in-progress transaction");
+        LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
         return false;
     }
     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
@@ -354,7 +354,7 @@ bool UniqueIDBDatabaseBackingStoreSQLite::createObjectStore(const IDBTransaction
 
     SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
     if (!transaction || !transaction->inProgress()) {
-        LOG_ERROR("Attempt to change database version with an establish, in-progress transaction");
+        LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
         return false;
     }
     if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
@@ -376,13 +376,46 @@ bool UniqueIDBDatabaseBackingStoreSQLite::createObjectStore(const IDBTransaction
         || sql.bindInt(4, metadata.autoIncrement) != SQLResultOk
         || sql.bindInt64(5, metadata.maxIndexId) != SQLResultOk
         || sql.step() != SQLResultDone) {
-        LOG_ERROR("Could not add object store '%s' to in ObjectStoreInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        LOG_ERROR("Could not add object store '%s' to ObjectStoreInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
         return false;
     }
 
     return true;
 }
 
+bool UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore(const IDBTransactionIdentifier& identifier, int64_t objectStoreID)
+{
+    ASSERT(!isMainThread());
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB->isOpen());
+
+    SQLiteIDBTransaction* transaction = m_transactions.get(identifier);
+    if (!transaction || !transaction->inProgress()) {
+        LOG_ERROR("Attempt to change database version with an established, in-progress transaction");
+        return false;
+    }
+    if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
+        LOG_ERROR("Attempt to change database version during a non version-change transaction");
+        return false;
+    }
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;"));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR("Could not delete object store id %lli from ObjectStoreInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            return false;
+        }
+    }
+    {
+        // FIXME: Execute SQL here to drop all records and indexes related to this object store.
+    }
+
+    return true;
+}
+
+
 } // namespace WebKit
 
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)
index 2514308..891c98d 100644 (file)
@@ -62,6 +62,7 @@ public:
 
     virtual bool changeDatabaseVersion(const IDBTransactionIdentifier&, uint64_t newVersion) override;
     virtual bool createObjectStore(const IDBTransactionIdentifier&, const WebCore::IDBObjectStoreMetadata&) override;
+    virtual bool deleteObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID) override;
 
 private:
     UniqueIDBDatabaseBackingStoreSQLite(const UniqueIDBDatabaseIdentifier&, const String& databaseDirectory);
index c92d3f2..d858ff8 100644 (file)
@@ -320,8 +320,33 @@ void WebIDBServerConnection::clearObjectStore(IDBTransactionBackend&, const Clea
 {
 }
 
-void WebIDBServerConnection::deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation&, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
+void WebIDBServerConnection::deleteObjectStore(IDBTransactionBackend&, const DeleteObjectStoreOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
 {
+    RefPtr<AsyncRequest> serverRequest = AsyncRequestImpl<PassRefPtr<IDBDatabaseError>>::create(completionCallback);
+
+    serverRequest->setAbortHandler([completionCallback]() {
+        completionCallback(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
+    });
+
+    uint64_t requestID = serverRequest->requestID();
+    ASSERT(!m_serverRequests.contains(requestID));
+    m_serverRequests.add(requestID, serverRequest.release());
+
+    LOG(IDB, "WebProcess deleteObjectStore request ID %llu", requestID);
+
+    send(Messages::DatabaseProcessIDBConnection::DeleteObjectStore(requestID, operation.transaction()->id(), operation.objectStoreMetadata().id));
+}
+
+void WebIDBServerConnection::didDeleteObjectStore(uint64_t requestID, bool success)
+{
+    LOG(IDB, "WebProcess didDeleteObjectStore request ID %llu", requestID);
+
+    RefPtr<AsyncRequest> serverRequest = m_serverRequests.take(requestID);
+
+    if (!serverRequest)
+        return;
+
+    serverRequest->completeRequest(success ? nullptr : IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Unknown error occured deleting object store"));
 }
 
 void WebIDBServerConnection::changeDatabaseVersion(IDBTransactionBackend&, const IDBDatabaseBackend::VersionChangeOperation& operation, std::function<void(PassRefPtr<IDBDatabaseError>)> completionCallback)
index d73f82b..562812c 100644 (file)
@@ -101,6 +101,7 @@ private:
     void didRollbackTransaction(uint64_t requestID, bool success);
     void didChangeDatabaseVersion(uint64_t requestID, bool success);
     void didCreateObjectStore(uint64_t requestID, bool success);
+    void didDeleteObjectStore(uint64_t requestID, bool success);
 
     uint64_t m_serverConnectionIdentifier;
 
index 42857ce..e2a0d50 100644 (file)
@@ -33,6 +33,7 @@ messages -> WebIDBServerConnection LegacyReceiver {
 
     DidChangeDatabaseVersion(uint64_t requestID, bool success)
     DidCreateObjectStore(uint64_t requestID, bool success)
+    DidDeleteObjectStore(uint64_t requestID, bool success)
 }
 
 #endif // ENABLE(INDEXED_DATABASE) && ENABLE(DATABASE_PROCESS)