Modern IDB: deleteObjectStore support.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Oct 2015 22:08:51 +0000 (22:08 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Oct 2015 22:08:51 +0000 (22:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150673

Reviewed by Alex Christensen.

Source/JavaScriptCore:

* runtime/VM.h:

Source/WebCore:

Tests: storage/indexeddb/modern/deleteobjectstore-1.html
       storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html
       storage/indexeddb/modern/idbobjectstore-get-failures.html

* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::deleteObjectStore):
(WebCore::IDBClient::IDBConnectionToServer::didDeleteObjectStore):
* Modules/indexeddb/client/IDBConnectionToServer.h:
* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:

* Modules/indexeddb/client/IDBDatabaseImpl.cpp:
(WebCore::IDBClient::IDBDatabase::deleteObjectStore):
(WebCore::IDBClient::IDBDatabase::willCommitTransaction):
(WebCore::IDBClient::IDBDatabase::willAbortTransaction):
(WebCore::IDBClient::IDBDatabase::commitTransaction): Deleted.
(WebCore::IDBClient::IDBDatabase::abortTransaction): Deleted.
* Modules/indexeddb/client/IDBDatabaseImpl.h:

* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::markAsDeleted):
* Modules/indexeddb/client/IDBObjectStoreImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::IDBTransaction):
(WebCore::IDBClient::IDBTransaction::abort):
(WebCore::IDBClient::IDBTransaction::abortOnServer):
(WebCore::IDBClient::IDBTransaction::commit):
(WebCore::IDBClient::IDBTransaction::commitOnServer):
(WebCore::IDBClient::IDBTransaction::deleteObjectStore):
(WebCore::IDBClient::IDBTransaction::deleteObjectStoreOnServer):
(WebCore::IDBClient::IDBTransaction::didDeleteObjectStoreOnServer):
(WebCore::IDBClient::IDBTransaction::activate):
(WebCore::IDBClient::IDBTransaction::activationTimerFired): Deleted.
(WebCore::IDBClient::IDBTransaction::createObjectStoreOnServer): Deleted.
(WebCore::IDBClient::IDBTransaction::didCreateObjectStoreOnServer): Deleted.
(WebCore::IDBClient::IDBTransaction::getRecordOnServer): Deleted.
(WebCore::IDBClient::IDBTransaction::putOrAddOnServer): Deleted.
* Modules/indexeddb/client/IDBTransactionImpl.h:

* Modules/indexeddb/client/TransactionOperation.h:
(WebCore::IDBClient::TransactionOperation::completed):
(WebCore::IDBClient::createTransactionOperation):

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/IDBConnectionToClient.cpp:
(WebCore::IDBServer::IDBConnectionToClient::didDeleteObjectStore):
* Modules/indexeddb/server/IDBConnectionToClient.h:
* Modules/indexeddb/server/IDBConnectionToClientDelegate.h:

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::deleteObjectStore):
* Modules/indexeddb/server/IDBServer.h:

* Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
(WebCore::IDBServer::MemoryBackingStoreTransaction::objectStoreDeleted):
(WebCore::IDBServer::MemoryBackingStoreTransaction::abort):
(WebCore::IDBServer::MemoryBackingStoreTransaction::finish):
* Modules/indexeddb/server/MemoryBackingStoreTransaction.h:

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::createObjectStore):
(WebCore::IDBServer::MemoryIDBBackingStore::deleteObjectStore):
(WebCore::IDBServer::MemoryIDBBackingStore::restoreObjectStoreForVersionChangeAbort):
(WebCore::IDBServer::MemoryIDBBackingStore::takeObjectStoreByName):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::performCreateObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::performDeleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformDeleteObjectStore):
(WebCore::IDBServer::UniqueIDBDatabase::createObjectStore): Deleted.
* Modules/indexeddb/server/UniqueIDBDatabase.h:

* Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseConnection::didDeleteObjectStore):
* Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:

* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
(WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteObjectStore):
* Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:

* Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
(WebCore::IDBDatabaseInfo::deleteObjectStore):
* Modules/indexeddb/shared/IDBDatabaseInfo.h:

* Modules/indexeddb/shared/IDBResultData.cpp:
(WebCore::IDBResultData::deleteObjectStoreSuccess):
* Modules/indexeddb/shared/IDBResultData.h:

* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::didDeleteObjectStore):
(WebCore::InProcessIDBServer::deleteObjectStore):
* Modules/indexeddb/shared/InProcessIDBServer.h:

LayoutTests:

* storage/indexeddb/modern/deleteobjectstore-1-expected.txt: Added.
* storage/indexeddb/modern/deleteobjectstore-1.html: Added.
* storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt: Added.
* storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html: Added.
* storage/indexeddb/modern/idbobjectstore-get-failures-expected.txt: Added.
* storage/indexeddb/modern/idbobjectstore-get-failures.html: Added.

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

42 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/modern/deleteobjectstore-1-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/deleteobjectstore-1.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/idbobjectstore-get-failures-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/idbobjectstore-get-failures.html [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/VM.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.cpp
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServer.h
Source/WebCore/Modules/indexeddb/client/IDBConnectionToServerDelegate.h
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.h
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h
Source/WebCore/Modules/indexeddb/client/TransactionOperation.h
Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.cpp
Source/WebCore/Modules/indexeddb/server/IDBConnectionToClient.h
Source/WebCore/Modules/indexeddb/server/IDBConnectionToClientDelegate.h
Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
Source/WebCore/Modules/indexeddb/server/IDBServer.h
Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp
Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.h
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.h
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp
Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h
Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp
Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h
Source/WebCore/Modules/indexeddb/shared/IDBResultData.cpp
Source/WebCore/Modules/indexeddb/shared/IDBResultData.h
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp
Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h

index c233610..c4a31cf 100644 (file)
@@ -1,3 +1,17 @@
+2015-10-29  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: deleteObjectStore support.
+        https://bugs.webkit.org/show_bug.cgi?id=150673
+
+        Reviewed by Alex Christensen.
+
+        * storage/indexeddb/modern/deleteobjectstore-1-expected.txt: Added.
+        * storage/indexeddb/modern/deleteobjectstore-1.html: Added.
+        * storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt: Added.
+        * storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html: Added.
+        * storage/indexeddb/modern/idbobjectstore-get-failures-expected.txt: Added.
+        * storage/indexeddb/modern/idbobjectstore-get-failures.html: Added.
+
 2015-10-29  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         Date input values should not overlap with menu list dropdown button on iOS
diff --git a/LayoutTests/storage/indexeddb/modern/deleteobjectstore-1-expected.txt b/LayoutTests/storage/indexeddb/modern/deleteobjectstore-1-expected.txt
new file mode 100644 (file)
index 0000000..debb2bb
--- /dev/null
@@ -0,0 +1,22 @@
+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: Second upgrade needed: Old version - 1 New version - 2
+ALERT: Deleting object store
+ALERT: Second version change transaction abort
+ALERT: Success opening database connection - Starting final transaction
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Value gotten was AH AH AH AH AH
+ALERT: Final transaction complete
+ALERT: Done
+This test creates an object store then populates it, then commits that transaction.
+It then deletes it, but aborts that transaction.
+Finally it checks to make sure everything from step 1 is there as expected.
+
diff --git a/LayoutTests/storage/indexeddb/modern/deleteobjectstore-1.html b/LayoutTests/storage/indexeddb/modern/deleteobjectstore-1.html
new file mode 100644 (file)
index 0000000..f0b3b97
--- /dev/null
@@ -0,0 +1,141 @@
+This test creates an object store then populates it, then commits that transaction.<br>
+It then deletes it, but aborts that transaction.<br>
+Finally it checks to make sure everything from step 1 is there as expected.<br>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var createRequest = window.indexedDB.open("DeleteObjectStore1Database", 1);
+
+createRequest.onupgradeneeded = function(event) {
+    alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    var database = event.target.result;
+    var objectStore = database.createObjectStore("TestObjectStore");
+    for (var i = 0; i < 10; ++i)
+        objectStore.put("AH AH AH AH AH", i + " puts");
+
+    versionTransaction.onabort = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected aborted");
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        alert("Initial upgrade versionchange transaction complete");
+        continueTest1();
+        database.close();
+    }
+
+    versionTransaction.onerror = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected error" + event);
+        done();
+    }
+}
+
+function getChecker(event) {
+    alert("Value gotten was " + event.target.result);
+}
+
+function continueTest1()
+{
+    var openRequest = window.indexedDB.open("DeleteObjectStore1Database", 2);
+
+    openRequest.onerror = function(event) {
+        alert("Request unexpected error - " + event);
+        done();
+    }
+    openRequest.onblocked = function(event) {
+        alert("Request unexpected blocked - " + event);
+        done();
+    }
+    openRequest.onsuccess = function(event) {
+        alert("Request unexpected success - " + event);
+        done();
+    }
+
+    openRequest.onupgradeneeded = function(event) {
+        alert("Second upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+        var versionTransaction = openRequest.transaction;
+        var database = event.target.result;
+        var objectStore = versionTransaction.objectStore("TestObjectStore");
+        
+        alert("Deleting object store");        
+        database.deleteObjectStore("TestObjectStore");
+
+        versionTransaction.abort();
+
+        versionTransaction.onabort = function(event) {
+            alert("Second version change transaction abort");
+            continueTest2();
+            database.close();
+        }
+
+        versionTransaction.oncomplete = function(event) {
+            alert("Second version change transaction unexpected complete");
+            done();
+        }
+
+        versionTransaction.onerror = function(event) {
+            alert("Second version change transaction unexpected error - " + event);
+            done();
+        }
+    }
+}
+
+function continueTest2()
+{
+    var openRequest = window.indexedDB.open("DeleteObjectStore1Database", 1);
+
+    openRequest.onerror = function(event) {
+        alert("Request unexpected error - " + event);
+        done();
+    }
+    openRequest.onblocked = function(event) {
+        alert("Request unexpected blocked - " + event);
+        done();
+    }
+    openRequest.onupgradeneeded = function(event) {
+        alert("Request unexpected upgradeneeded - " + event);
+        done();
+    }
+
+    openRequest.onsuccess = function(event) {
+        alert("Success opening database connection - Starting final transaction");
+        var database = event.target.result;
+        var transaction = database.transaction("TestObjectStore", "readwrite");
+        var objectStore = transaction.objectStore("TestObjectStore");
+    
+        var request;
+        for (var i = 0; i < 10; ++i) {
+            request = objectStore.get(i + " puts");
+            request.onsuccess = getChecker;
+        }
+
+        transaction.onabort = function(event) {
+            alert("Final transaction unexpected abort");
+            done();
+        }
+
+        transaction.oncomplete = function(event) {
+            alert("Final transaction complete");
+            done();
+        }
+
+        transaction.onerror = function(event) {
+            alert("Final transaction unexpected error - " + event);
+            done();
+        }
+    }
+}
+</script>
diff --git a/LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt b/LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures-expected.txt
new file mode 100644 (file)
index 0000000..27ffa74
--- /dev/null
@@ -0,0 +1,11 @@
+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: readwrite put success - about to try to delete an objectstore
+ALERT: Failed to deleteObjectStore without a versionchange transaction - Error: InvalidStateError: DOM Exception 11
+ALERT: readwrite transaction complete
+ALERT: Second upgrade needed: Old version - 1 New version - 2
+ALERT: Failed to deleteObjectStore with a non-existent objectstore - Error: NotFoundError: DOM IDBDatabase Exception 8
+ALERT: Failed to deleteObjectStore with an in-progress versionchange transaction that is inactive - Error: TransactionInactiveError: DOM IDBDatabase Exception 0
+ALERT: Second version change transaction complete
+ALERT: Done
+This tests some obvious failures that can happen while calling IDBDatabase.deleteObjectStore()
diff --git a/LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html b/LayoutTests/storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html
new file mode 100644 (file)
index 0000000..7d30d41
--- /dev/null
@@ -0,0 +1,137 @@
+This tests some obvious failures that can happen while calling IDBDatabase.deleteObjectStore()
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var createRequest = window.indexedDB.open("IDBDatabaseDeleteObjectStoreFailuresDatabase", 1);
+var database;
+
+createRequest.onupgradeneeded = function(event) {
+    alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    database = event.target.result;
+    var objectStore = database.createObjectStore("TestObjectStore");
+    var request = objectStore.put("bar", "foo");
+
+    versionTransaction.onabort = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected aborted");
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        alert("Initial upgrade versionchange transaction complete");
+        continueTest1();
+    }
+
+    versionTransaction.onerror = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected error" + event);
+        done();
+    }
+}
+
+function continueTest1()
+{
+    var transaction = database.transaction("TestObjectStore", "readwrite");
+    var objectStore = transaction.objectStore("TestObjectStore");
+    var request = objectStore.put("baz", "foo");
+
+    request.onsuccess = function() {
+        alert("readwrite put success - about to try to delete an objectstore");
+        try {
+            database.deleteObjectStore("TestObjectStore");
+        } catch(e) {
+            alert("Failed to deleteObjectStore without a versionchange transaction - " + e);
+        }
+    }
+    
+    transaction.onabort = function(event) {
+        alert("readwrite transaction unexpected aborted");
+        done();
+    }
+
+    transaction.oncomplete = function(event) {
+        alert("readwrite transaction complete");
+        continueTest2();
+        database.close();
+    }
+
+    transaction.onerror = function(event) {
+        alert("readwrite transaction unexpected error" + event);
+        done();
+    }
+}
+
+function continueTest2()
+{
+    var openRequest = window.indexedDB.open("IDBDatabaseDeleteObjectStoreFailuresDatabase", 2);
+
+    openRequest.onerror = function(event) {
+        alert("Request unexpected error - " + event);
+        done();
+    }
+    openRequest.onblocked = function(event) {
+        alert("Request unexpected blocked - " + event);
+        done();
+    }
+    openRequest.onsuccess = function(event) {
+        alert("Request unexpected success - " + event);
+        done();
+    }
+
+    openRequest.onupgradeneeded = function(event) {
+        alert("Second upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+    
+        var versionTransaction = openRequest.transaction;
+        database = event.target.result;
+
+        try {
+            database.deleteObjectStore("NonexistentObjectStore");
+        } catch(e) {
+            alert("Failed to deleteObjectStore with a non-existent objectstore - " + e);
+        }
+        
+        // Queue up a whole bunch of puts to keep the transaction alive for awhile
+        var objectStore = versionTransaction.objectStore("TestObjectStore");
+        for (var i = 0; i < 10; ++i)
+            objectStore.put("AH AH AH AH AH", i + " puts");
+        
+        // After the versionChange transaction becomes inactive, but while it's still in-progress, try to delete the objectstore
+        var tryInactiveDelete = function() 
+        {
+            try {
+                database.deleteObjectStore("TestObjectStore");
+            } catch(e) {
+                alert("Failed to deleteObjectStore with an in-progress versionchange transaction that is inactive - " + e);
+            }
+        }
+        
+        setTimeout(tryInactiveDelete, 0);
+
+        versionTransaction.onabort = function(event) {
+            alert("Second version change transaction unexpected abort");
+            done();
+        }
+
+        versionTransaction.oncomplete = function(event) {
+            alert("Second version change transaction complete");
+            done();
+        }
+
+        versionTransaction.onerror = function(event) {
+            alert("Second version change transaction unexpected error - " + event);
+            done();
+        }
+    }
+}
+</script>
diff --git a/LayoutTests/storage/indexeddb/modern/idbobjectstore-get-failures-expected.txt b/LayoutTests/storage/indexeddb/modern/idbobjectstore-get-failures-expected.txt
new file mode 100644 (file)
index 0000000..9f24fce
--- /dev/null
@@ -0,0 +1,8 @@
+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: Failed to get record from object store with an invalid key
+ALERT: Failed to get record from object store that has been deleted
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: Failed to get record from object store while the transaction is inactive
+ALERT: readonly transaction complete
+ALERT: Done
+This tests some obvious failures that can happen while calling IDBObjectStore.get().
diff --git a/LayoutTests/storage/indexeddb/modern/idbobjectstore-get-failures.html b/LayoutTests/storage/indexeddb/modern/idbobjectstore-get-failures.html
new file mode 100644 (file)
index 0000000..080b78e
--- /dev/null
@@ -0,0 +1,98 @@
+This tests some obvious failures that can happen while calling IDBObjectStore.get().
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+var createRequest = window.indexedDB.open("IDBObjectStoreGetFailuresDatabase", 1);
+var database;
+
+createRequest.onupgradeneeded = function(event) {
+    alert("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    database = event.target.result;
+    var objectStore = database.createObjectStore("TestObjectStore");
+    var request = objectStore.put("bar", "foo");
+
+    request.onsuccess = function() {
+        try {
+            objectStore.get(NaN);
+        } catch(e) {
+            alert("Failed to get record from object store with an invalid key");
+        }
+        
+        database.deleteObjectStore("TestObjectStore");
+        
+        try {
+            objectStore.get("foo");
+        } catch(e) {
+            alert("Failed to get record from object store that has been deleted");
+        } 
+
+        // Recreate the objectstore because we'll need it in phase 2.
+        var objectStore = database.createObjectStore("TestObjectStore");
+        objectStore.put("bar", "foo");    
+    }
+    
+    versionTransaction.onabort = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected aborted");
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        alert("Initial upgrade versionchange transaction complete");
+        continueTest1();
+    }
+
+    versionTransaction.onerror = function(event) {
+        alert("Initial upgrade versionchange transaction unexpected error" + event);
+        done();
+    }
+}
+
+function continueTest1()
+{
+    var transaction = database.transaction("TestObjectStore", "readonly");
+    var objectStore = transaction.objectStore("TestObjectStore");
+
+    // Queue up a whole bunch of gets to keep the transaction alive for awhile
+    for (var i = 0; i < 10; ++i)
+        objectStore.get("foo");
+
+    var getWhileInactive = function() {
+        try {
+            objectStore.get("foo");
+        } catch(e) {
+            alert("Failed to get record from object store while the transaction is inactive");
+        } 
+    }
+    
+    setTimeout(getWhileInactive, 0);
+    
+    transaction.onabort = function(event) {
+        alert("readonly transaction unexpected abort" + event);
+        done();
+    }
+
+    transaction.oncomplete = function(event) {
+        alert("readonly transaction complete");
+        done();
+    }
+
+    transaction.onerror = function(event) {
+        alert("readonly transaction unexpected error" + event);
+        done();
+    }
+}
+
+</script>
index d1f5a66..e1d413c 100644 (file)
@@ -1,3 +1,12 @@
+2015-10-29  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: deleteObjectStore support.
+        https://bugs.webkit.org/show_bug.cgi?id=150673
+
+        Reviewed by Alex Christensen.
+
+        * runtime/VM.h:
+
 2015-10-29  Mark Lam  <mark.lam@apple.com>
 
         cdjs-tests.yaml/main.js.ftl fails due to FTL ArithSub code for supporting UntypedUse operands.
index e4ccd7e..ef31b75 100644 (file)
@@ -556,7 +556,7 @@ public:
     JSLock& apiLock() { return *m_apiLock; }
     CodeCache* codeCache() { return m_codeCache.get(); }
 
-    void whenIdle(std::function<void()>);
+    JS_EXPORT_PRIVATE void whenIdle(std::function<void()>);
 
     JS_EXPORT_PRIVATE void deleteAllCode();
 
index f8242c2..d2ca796 100644 (file)
@@ -1,3 +1,106 @@
+2015-10-29  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: deleteObjectStore support.
+        https://bugs.webkit.org/show_bug.cgi?id=150673
+
+        Reviewed by Alex Christensen.
+
+        Tests: storage/indexeddb/modern/deleteobjectstore-1.html
+               storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html
+               storage/indexeddb/modern/idbobjectstore-get-failures.html
+
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::deleteObjectStore):
+        (WebCore::IDBClient::IDBConnectionToServer::didDeleteObjectStore):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+
+        * Modules/indexeddb/client/IDBDatabaseImpl.cpp:
+        (WebCore::IDBClient::IDBDatabase::deleteObjectStore):
+        (WebCore::IDBClient::IDBDatabase::willCommitTransaction):
+        (WebCore::IDBClient::IDBDatabase::willAbortTransaction):
+        (WebCore::IDBClient::IDBDatabase::commitTransaction): Deleted.
+        (WebCore::IDBClient::IDBDatabase::abortTransaction): Deleted.
+        * Modules/indexeddb/client/IDBDatabaseImpl.h:
+
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::markAsDeleted):
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::IDBTransaction):
+        (WebCore::IDBClient::IDBTransaction::abort):
+        (WebCore::IDBClient::IDBTransaction::abortOnServer):
+        (WebCore::IDBClient::IDBTransaction::commit):
+        (WebCore::IDBClient::IDBTransaction::commitOnServer):
+        (WebCore::IDBClient::IDBTransaction::deleteObjectStore):
+        (WebCore::IDBClient::IDBTransaction::deleteObjectStoreOnServer):
+        (WebCore::IDBClient::IDBTransaction::didDeleteObjectStoreOnServer):
+        (WebCore::IDBClient::IDBTransaction::activate):
+        (WebCore::IDBClient::IDBTransaction::activationTimerFired): Deleted.
+        (WebCore::IDBClient::IDBTransaction::createObjectStoreOnServer): Deleted.
+        (WebCore::IDBClient::IDBTransaction::didCreateObjectStoreOnServer): Deleted.
+        (WebCore::IDBClient::IDBTransaction::getRecordOnServer): Deleted.
+        (WebCore::IDBClient::IDBTransaction::putOrAddOnServer): Deleted.
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+        
+        * Modules/indexeddb/client/TransactionOperation.h:
+        (WebCore::IDBClient::TransactionOperation::completed):
+        (WebCore::IDBClient::createTransactionOperation):
+        
+        * Modules/indexeddb/server/IDBBackingStore.h:
+        
+        * Modules/indexeddb/server/IDBConnectionToClient.cpp:
+        (WebCore::IDBServer::IDBConnectionToClient::didDeleteObjectStore):
+        * Modules/indexeddb/server/IDBConnectionToClient.h:
+        * Modules/indexeddb/server/IDBConnectionToClientDelegate.h:
+        
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::deleteObjectStore):
+        * Modules/indexeddb/server/IDBServer.h:
+        
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::objectStoreDeleted):
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::abort):
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::finish):
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.h:
+        
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::createObjectStore):
+        (WebCore::IDBServer::MemoryIDBBackingStore::deleteObjectStore):
+        (WebCore::IDBServer::MemoryIDBBackingStore::restoreObjectStoreForVersionChangeAbort):
+        (WebCore::IDBServer::MemoryIDBBackingStore::takeObjectStoreByName):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+        
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::performCreateObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::performDeleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformDeleteObjectStore):
+        (WebCore::IDBServer::UniqueIDBDatabase::createObjectStore): Deleted.
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didDeleteObjectStore):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+        
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteObjectStore):
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
+        
+        * Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
+        (WebCore::IDBDatabaseInfo::deleteObjectStore):
+        * Modules/indexeddb/shared/IDBDatabaseInfo.h:
+        
+        * Modules/indexeddb/shared/IDBResultData.cpp:
+        (WebCore::IDBResultData::deleteObjectStoreSuccess):
+        * Modules/indexeddb/shared/IDBResultData.h:
+        
+        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+        (WebCore::InProcessIDBServer::didDeleteObjectStore):
+        (WebCore::InProcessIDBServer::deleteObjectStore):
+        * Modules/indexeddb/shared/InProcessIDBServer.h:
+
 2015-10-29  Simon Fraser  <simon.fraser@apple.com>
 
         Very slow typing on pages with wheel event handlers on the body, and deep content
index f771e97..d058f41 100644 (file)
@@ -109,6 +109,21 @@ void IDBConnectionToServer::didCreateObjectStore(const IDBResultData& resultData
     completeOperation(resultData);
 }
 
+void IDBConnectionToServer::deleteObjectStore(TransactionOperation& operation, const String& objectStoreName)
+{
+    LOG(IndexedDB, "IDBConnectionToServer::deleteObjectStore");
+
+    saveOperation(operation);
+
+    m_delegate->deleteObjectStore(IDBRequestData(operation), objectStoreName);
+}
+
+void IDBConnectionToServer::didDeleteObjectStore(const IDBResultData& resultData)
+{
+    LOG(IndexedDB, "IDBConnectionToServer::didDeleteObjectStore");
+    completeOperation(resultData);
+}
+
 void IDBConnectionToServer::putOrAdd(TransactionOperation& operation, RefPtr<IDBKey>& key, RefPtr<SerializedScriptValue>& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     LOG(IndexedDB, "IDBConnectionToServer::putOrAdd");
index ee454e7..52911e7 100644 (file)
@@ -64,6 +64,9 @@ public:
     void createObjectStore(TransactionOperation&, const IDBObjectStoreInfo&);
     void didCreateObjectStore(const IDBResultData&);
 
+    void deleteObjectStore(TransactionOperation&, const String& objectStoreName);
+    void didDeleteObjectStore(const IDBResultData&);
+
     void putOrAdd(TransactionOperation&, RefPtr<IDBKey>&, RefPtr<SerializedScriptValue>&, const IndexedDB::ObjectStoreOverwriteMode);
     void didPutOrAdd(const IDBResultData&);
 
index 9ea5ca6..eada736 100644 (file)
@@ -28,6 +28,8 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include <wtf/text/WTFString.h>
+
 namespace WebCore {
 
 class IDBKey;
@@ -53,6 +55,7 @@ public:
     virtual void abortTransaction(IDBResourceIdentifier&) = 0;
     virtual void commitTransaction(IDBResourceIdentifier&) = 0;
     virtual void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) = 0;
+    virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) = 0;
     virtual void putOrAdd(const IDBRequestData&, IDBKey*, SerializedScriptValue&, const IndexedDB::ObjectStoreOverwriteMode) = 0;
     virtual void getRecord(const IDBRequestData&, IDBKey*) = 0;
     virtual void establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo&) = 0;
index 1154a91..40f007c 100644 (file)
@@ -178,9 +178,27 @@ RefPtr<WebCore::IDBTransaction> IDBDatabase::transaction(ScriptExecutionContext*
     return transaction(context, objectStores, mode, ec);
 }
 
-void IDBDatabase::deleteObjectStore(const String&, ExceptionCode&)
+void IDBDatabase::deleteObjectStore(const String& objectStoreName, ExceptionCode& ec)
 {
-    ASSERT_NOT_REACHED();
+    LOG(IndexedDB, "IDBDatabase::deleteObjectStore");
+
+    if (!m_versionChangeTransaction) {
+        ec = INVALID_STATE_ERR;
+        return;
+    }
+
+    if (!m_versionChangeTransaction->isActive()) {
+        ec = IDBDatabaseException::TransactionInactiveError;
+        return;
+    }
+
+    if (!m_info.hasObjectStore(objectStoreName)) {
+        ec = IDBDatabaseException::NotFoundError;
+        return;
+    }
+
+    m_info.deleteObjectStore(objectStoreName);
+    m_versionChangeTransaction->deleteObjectStore(objectStoreName);
 }
 
 void IDBDatabase::close()
@@ -239,15 +257,13 @@ void IDBDatabase::didStartTransaction(IDBTransaction& transaction)
     m_activeTransactions.set(transaction.info().identifier(), &transaction);
 }
 
-void IDBDatabase::commitTransaction(IDBTransaction& transaction)
+void IDBDatabase::willCommitTransaction(IDBTransaction& transaction)
 {
-    LOG(IndexedDB, "IDBDatabase::commitTransaction");
+    LOG(IndexedDB, "IDBDatabase::willCommitTransaction");
 
     auto refTransaction = m_activeTransactions.take(transaction.info().identifier());
     ASSERT(refTransaction);
     m_committingTransactions.set(transaction.info().identifier(), WTF::move(refTransaction));
-
-    m_serverConnection->commitTransaction(transaction);
 }
 
 void IDBDatabase::didCommitTransaction(IDBTransaction& transaction)
@@ -260,15 +276,13 @@ void IDBDatabase::didCommitTransaction(IDBTransaction& transaction)
     didCommitOrAbortTransaction(transaction);
 }
 
-void IDBDatabase::abortTransaction(IDBTransaction& transaction)
+void IDBDatabase::willAbortTransaction(IDBTransaction& transaction)
 {
-    LOG(IndexedDB, "IDBDatabase::abortTransaction");
+    LOG(IndexedDB, "IDBDatabase::willAbortTransaction");
 
     auto refTransaction = m_activeTransactions.take(transaction.info().identifier());
     ASSERT(refTransaction);
     m_abortingTransactions.set(transaction.info().identifier(), WTF::move(refTransaction));
-
-    m_serverConnection->abortTransaction(transaction);
 }
 
 void IDBDatabase::didAbortTransaction(IDBTransaction& transaction)
index 1f86256..97535c9 100644 (file)
@@ -75,9 +75,9 @@ public:
     Ref<IDBTransaction> startVersionChangeTransaction(const IDBTransactionInfo&);
     void didStartTransaction(IDBTransaction&);
 
-    void commitTransaction(IDBTransaction&);
+    void willCommitTransaction(IDBTransaction&);
     void didCommitTransaction(IDBTransaction&);
-    void abortTransaction(IDBTransaction&);
+    void willAbortTransaction(IDBTransaction&);
     void didAbortTransaction(IDBTransaction&);
 
     void fireVersionChangeEvent(uint64_t requestedVersion);
index 89c206b..ac58e55 100644 (file)
@@ -294,6 +294,11 @@ RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext*, const
     RELEASE_ASSERT_NOT_REACHED();
 }
 
+void IDBObjectStore::markAsDeleted()
+{
+    m_deleted = true;
+}
+
 } // namespace IDBClient
 } // namespace WebCore
 
index 9839260..dc27cef 100644 (file)
@@ -75,6 +75,8 @@ public:
     virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&) override final;
     virtual RefPtr<WebCore::IDBRequest> count(ScriptExecutionContext*, const Deprecated::ScriptValue& key, ExceptionCode&) override final;
 
+    void markAsDeleted();
+
     const IDBObjectStoreInfo& info() const { return m_info; }
 
 private:
index d80527a..f08c242 100644 (file)
@@ -36,6 +36,7 @@
 #include "IDBObjectStore.h"
 #include "IDBRequestImpl.h"
 #include "IDBResultData.h"
+#include "JSDOMWindowBase.h"
 #include "Logging.h"
 #include "ScriptExecutionContext.h"
 #include "TransactionOperation.h"
@@ -58,13 +59,19 @@ IDBTransaction::IDBTransaction(IDBDatabase& database, const IDBTransactionInfo&
     relaxAdoptionRequirement();
 
     if (m_info.mode() == IndexedDB::TransactionMode::VersionChange) {
-        m_activationTimer = std::make_unique<Timer>(*this, &IDBTransaction::activationTimerFired);
-        m_activationTimer->startOneShot(0);
         m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_database->info());
-        m_state = IndexedDB::TransactionState::Inactive;
         m_startedOnServer = true;
-    } else
+    } else {
+        activate();
+
+        RefPtr<IDBTransaction> self;
+        JSC::VM& vm = JSDOMWindowBase::commonVM();
+        vm.whenIdle([self, this]() {
+            deactivate();
+        });
+
         establishOnServer();
+    }
 
     suspendIfNeeded();
 }
@@ -157,8 +164,16 @@ void IDBTransaction::abort(ExceptionCode& ec)
     }
 
     m_state = IndexedDB::TransactionState::Aborting;
+    m_database->willAbortTransaction(*this);
+
+    auto operation = createTransactionOperation(*this, nullptr, &IDBTransaction::abortOnServer);
+    scheduleOperation(WTF::move(operation));
+}
 
-    m_database->abortTransaction(*this);
+void IDBTransaction::abortOnServer(TransactionOperation&)
+{
+    LOG(IndexedDB, "IDBTransaction::abortOnServer");
+    serverConnection().abortTransaction(*this);
 }
 
 const char* IDBTransaction::activeDOMObjectName() const
@@ -191,12 +206,6 @@ bool IDBTransaction::isFinishedOrFinishing() const
         || m_state == IndexedDB::TransactionState::Finished;
 }
 
-void IDBTransaction::activationTimerFired()
-{
-    scheduleOperationTimer();
-    m_activationTimer = nullptr;
-}
-
 void IDBTransaction::scheduleOperation(RefPtr<TransactionOperation>&& operation)
 {
     ASSERT(!m_transactionOperationMap.contains(operation->identifier()));
@@ -235,12 +244,19 @@ void IDBTransaction::commit()
 {
     LOG(IndexedDB, "IDBTransaction::commit");
 
-    if (isFinishedOrFinishing())
-        return;
+    ASSERT(!isFinishedOrFinishing());
 
     m_state = IndexedDB::TransactionState::Committing;
+    m_database->willCommitTransaction(*this);
+
+    auto operation = createTransactionOperation(*this, nullptr, &IDBTransaction::commitOnServer);
+    scheduleOperation(WTF::move(operation));
+}
 
-    m_database->commitTransaction(*this);
+void IDBTransaction::commitOnServer(TransactionOperation&)
+{
+    LOG(IndexedDB, "IDBTransaction::commitOnServer");
+    serverConnection().commitTransaction(*this);
 }
 
 void IDBTransaction::finishAbortOrCommit()
@@ -359,9 +375,6 @@ void IDBTransaction::createObjectStoreOnServer(TransactionOperation& operation,
 
     ASSERT(isVersionChange());
 
-    if (isFinishedOrFinishing())
-        return;
-
     m_database->serverConnection().createObjectStore(operation, info);
 }
 
@@ -370,8 +383,6 @@ void IDBTransaction::didCreateObjectStoreOnServer(const IDBResultData& resultDat
     LOG(IndexedDB, "IDBTransaction::didCreateObjectStoreOnServer");
 
     ASSERT_UNUSED(resultData, resultData.type() == IDBResultType::CreateObjectStoreSuccess);
-
-    scheduleOperationTimer();
 }
 
 Ref<IDBRequest> IDBTransaction::requestGetRecord(ScriptExecutionContext& context, IDBObjectStore& objectStore, IDBKey& key)
@@ -392,8 +403,6 @@ void IDBTransaction::getRecordOnServer(TransactionOperation& operation, RefPtr<I
 {
     LOG(IndexedDB, "IDBTransaction::getRecordOnServer");
 
-    ASSERT(!isFinishedOrFinishing());
-
     serverConnection().getRecord(operation, key);
 }
 
@@ -424,7 +433,6 @@ void IDBTransaction::putOrAddOnServer(TransactionOperation& operation, RefPtr<ID
 {
     LOG(IndexedDB, "IDBTransaction::putOrAddOnServer");
 
-    ASSERT(!isFinishedOrFinishing());
     ASSERT(!isReadOnly());
 
     serverConnection().putOrAdd(operation, key, value, overwriteMode);
@@ -438,6 +446,33 @@ void IDBTransaction::didPutOrAddOnServer(IDBRequest& request, const IDBResultDat
     request.requestCompleted(resultData);
 }
 
+void IDBTransaction::deleteObjectStore(const String& objectStoreName)
+{
+    LOG(IndexedDB, "IDBTransaction::deleteObjectStore");
+
+    ASSERT(isVersionChange());
+
+    if (auto objectStore = m_referencedObjectStores.take(objectStoreName))
+        objectStore->markAsDeleted();
+
+    auto operation = createTransactionOperation(*this, &IDBTransaction::didDeleteObjectStoreOnServer, &IDBTransaction::deleteObjectStoreOnServer, objectStoreName);
+    scheduleOperation(WTF::move(operation));
+}
+
+void IDBTransaction::deleteObjectStoreOnServer(TransactionOperation& operation, const String& objectStoreName)
+{
+    LOG(IndexedDB, "IDBTransaction::deleteObjectStoreOnServer");
+    ASSERT(isVersionChange());
+
+    serverConnection().deleteObjectStore(operation, objectStoreName);
+}
+
+void IDBTransaction::didDeleteObjectStoreOnServer(const IDBResultData& resultData)
+{
+    LOG(IndexedDB, "IDBTransaction::didDeleteObjectStoreOnServer");
+    ASSERT_UNUSED(resultData, resultData.type() == IDBResultType::DeleteObjectStoreSuccess);
+}
+
 void IDBTransaction::establishOnServer()
 {
     LOG(IndexedDB, "IDBTransaction::establishOnServer");
@@ -447,7 +482,9 @@ void IDBTransaction::establishOnServer()
 
 void IDBTransaction::activate()
 {
-    ASSERT(!isFinishedOrFinishing());
+    if (isFinishedOrFinishing())
+        return;
+
     m_state = IndexedDB::TransactionState::Active;
 }
 
index 97d039a..b33b654 100644 (file)
@@ -90,11 +90,15 @@ public:
     Ref<IDBRequest> requestPutOrAdd(ScriptExecutionContext&, IDBObjectStore&, IDBKey*, SerializedScriptValue&, IndexedDB::ObjectStoreOverwriteMode);
     Ref<IDBRequest> requestGetRecord(ScriptExecutionContext&, IDBObjectStore&, IDBKey&);
 
+    void deleteObjectStore(const String& objectStoreName);
+
     IDBConnectionToServer& serverConnection();
 
     void activate();
     void deactivate();
 
+    void scheduleOperationTimer();
+
 private:
     IDBTransaction(IDBDatabase&, const IDBTransactionInfo&);
 
@@ -105,14 +109,15 @@ private:
     void finishAbortOrCommit();
 
     void scheduleOperation(RefPtr<TransactionOperation>&&);
-    void scheduleOperationTimer();
     void operationTimerFired();
-    void activationTimerFired();
 
     void fireOnComplete();
     void fireOnAbort();
     void enqueueEvent(Ref<Event>);
 
+    void commitOnServer(TransactionOperation&);
+    void abortOnServer(TransactionOperation&);
+
     void createObjectStoreOnServer(TransactionOperation&, const IDBObjectStoreInfo&);
     void didCreateObjectStoreOnServer(const IDBResultData&);
 
@@ -122,13 +127,16 @@ private:
     void getRecordOnServer(TransactionOperation&, RefPtr<IDBKey>);
     void didGetRecordOnServer(IDBRequest&, const IDBResultData&);
 
+    void deleteObjectStoreOnServer(TransactionOperation&, const String& objectStoreName);
+    void didDeleteObjectStoreOnServer(const IDBResultData&);
+
     void establishOnServer();
 
     Ref<IDBDatabase> m_database;
     IDBTransactionInfo m_info;
     std::unique_ptr<IDBDatabaseInfo> m_originalDatabaseInfo;
 
-    IndexedDB::TransactionState m_state { IndexedDB::TransactionState::Active };
+    IndexedDB::TransactionState m_state { IndexedDB::TransactionState::Inactive };
     bool m_startedOnServer { false };
 
     IDBError m_idbError;
index 9ddd5d7..87d055c 100644 (file)
@@ -48,6 +48,7 @@ public:
     void completed(const IDBResultData& data)
     {
         m_completeFunction(data);
+        m_transaction->scheduleOperationTimer();
     }
 
     const IDBResourceIdentifier& identifier() const { return m_identifier; }
@@ -84,7 +85,8 @@ public:
         };
 
         m_completeFunction = [self, this, completeMethod](const IDBResultData& resultData) {
-            (&m_transaction.get()->*completeMethod)(resultData);
+            if (completeMethod)
+                (&m_transaction.get()->*completeMethod)(resultData);
         };
     }
 
@@ -100,11 +102,21 @@ public:
 
         RefPtr<IDBRequest> refRequest(&request);
         m_completeFunction = [self, this, refRequest, completeMethod](const IDBResultData& resultData) {
-            (&m_transaction.get()->*completeMethod)(*refRequest, resultData);
+            if (completeMethod)
+                (&m_transaction.get()->*completeMethod)(*refRequest, resultData);
         };
     }
 };
 
+inline RefPtr<TransactionOperation> createTransactionOperation(
+    IDBTransaction& transaction,
+    void (IDBTransaction::*complete)(const IDBResultData&),
+    void (IDBTransaction::*perform)(TransactionOperation&))
+{
+    auto operation = new TransactionOperationImpl<>(transaction, complete, perform);
+    return adoptRef(operation);
+}
+
 template<typename MP1, typename P1>
 RefPtr<TransactionOperation> createTransactionOperation(
     IDBTransaction& transaction,
index 87c84b9..830c214 100644 (file)
@@ -52,6 +52,7 @@ public:
     virtual IDBError commitTransaction(const IDBResourceIdentifier& transactionIdentifier) = 0;
 
     virtual IDBError createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&) = 0;
+    virtual IDBError deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName) = 0;
     virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) = 0;
     virtual IDBError deleteRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&) = 0;
     virtual IDBError putRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) = 0;
index 4546928..d68d486 100644 (file)
@@ -68,6 +68,11 @@ void IDBConnectionToClient::didCreateObjectStore(const IDBResultData& result)
     m_delegate->didCreateObjectStore(result);
 }
 
+void IDBConnectionToClient::didDeleteObjectStore(const IDBResultData& result)
+{
+    m_delegate->didDeleteObjectStore(result);
+}
+
 void IDBConnectionToClient::didPutOrAdd(const IDBResultData& result)
 {
     m_delegate->didPutOrAdd(result);
index 72dd2b2..355cbd1 100644 (file)
@@ -53,6 +53,7 @@ public:
     void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
     void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&);
     void didCreateObjectStore(const IDBResultData&);
+    void didDeleteObjectStore(const IDBResultData&);
     void didPutOrAdd(const IDBResultData&);
     void didGetRecord(const IDBResultData&);
 
index 22446a7..662383a 100644 (file)
@@ -49,6 +49,7 @@ public:
     virtual void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) = 0;
     virtual void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) = 0;
     virtual void didCreateObjectStore(const IDBResultData&) = 0;
+    virtual void didDeleteObjectStore(const IDBResultData&) = 0;
     virtual void didPutOrAdd(const IDBResultData&) = 0;
     virtual void didGetRecord(const IDBResultData&) = 0;
 
index 33ea49c..02bdebd 100644 (file)
@@ -168,6 +168,18 @@ void IDBServer::createObjectStore(const IDBRequestData& requestData, const IDBOb
     transaction->createObjectStore(requestData, info);
 }
 
+void IDBServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
+{
+    LOG(IndexedDB, "IDBServer::deleteObjectStore");
+
+    auto transaction = m_transactions.get(requestData.transactionIdentifier());
+    if (!transaction)
+        return;
+
+    ASSERT(transaction->isVersionChange());
+    transaction->deleteObjectStore(requestData, objectStoreName);
+}
+
 void IDBServer::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     LOG(IndexedDB, "IDBServer::putOrAdd");
index 93b8c0c..31d873b 100644 (file)
@@ -60,6 +60,7 @@ public:
     void abortTransaction(const IDBResourceIdentifier&);
     void commitTransaction(const IDBResourceIdentifier&);
     void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&);
+    void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
     void putOrAdd(const IDBRequestData&, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode);
     void getRecord(const IDBRequestData&, const IDBKeyData&);
     void establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo&);
index 34241b3..dc3b6e9 100644 (file)
@@ -80,6 +80,17 @@ void MemoryBackingStoreTransaction::addExistingObjectStore(MemoryObjectStore& ob
     objectStore.writeTransactionStarted(*this);
 }
 
+void MemoryBackingStoreTransaction::objectStoreDeleted(std::unique_ptr<MemoryObjectStore> objectStore)
+{
+    ASSERT(objectStore);
+    ASSERT(m_objectStores.contains(objectStore.get()));
+    m_objectStores.remove(objectStore.get());
+
+    auto addResult = m_deletedObjectStores.add(objectStore->info().name(), nullptr);
+    if (addResult.isNewEntry)
+        addResult.iterator->value = WTF::move(objectStore);
+}
+
 void MemoryBackingStoreTransaction::recordValueChanged(MemoryObjectStore& objectStore, const IDBKeyData& key)
 {
     ASSERT(m_objectStores.contains(&objectStore));
@@ -106,6 +117,19 @@ void MemoryBackingStoreTransaction::abort()
 
     TemporaryChange<bool> change(m_isAborting, true);
 
+    // This loop moves the underlying unique_ptrs from out of the m_deleteObjectStores map,
+    // but the entries in the map still remain.
+    for (auto& objectStore : m_deletedObjectStores.values()) {
+        MemoryObjectStore* rawObjectStore = objectStore.get();
+        m_backingStore.restoreObjectStoreForVersionChangeAbort(WTF::move(objectStore));
+
+        ASSERT(!m_objectStores.contains(rawObjectStore));
+        m_objectStores.add(rawObjectStore);
+    }
+
+    // This clears the entries from the map.
+    m_deletedObjectStores.clear();
+
     if (m_originalDatabaseInfo) {
         ASSERT(m_info.mode() == IndexedDB::TransactionMode::VersionChange);
         m_backingStore.setDatabaseInfo(*m_originalDatabaseInfo);
@@ -145,7 +169,9 @@ void MemoryBackingStoreTransaction::finish()
     if (!isWriting())
         return;
 
-    for (auto objectStore : m_objectStores)
+    for (auto& objectStore : m_objectStores)
+        objectStore->writeTransactionFinished(*this);
+    for (auto& objectStore : m_deletedObjectStores.values())
         objectStore->writeTransactionFinished(*this);
 }
 
index 4652c21..b7977cd 100644 (file)
@@ -58,6 +58,7 @@ public:
     void addNewObjectStore(MemoryObjectStore&);
     void addExistingObjectStore(MemoryObjectStore&);
     void recordValueChanged(MemoryObjectStore&, const IDBKeyData&);
+    void objectStoreDeleted(std::unique_ptr<MemoryObjectStore>);
 
     void abort();
     void commit();
@@ -78,6 +79,7 @@ private:
     HashSet<MemoryObjectStore*> m_objectStores;
     HashSet<MemoryObjectStore*> m_versionChangeAddedObjectStores;
 
+    HashMap<String, std::unique_ptr<MemoryObjectStore>> m_deletedObjectStores;
     HashMap<MemoryObjectStore*, std::unique_ptr<KeyValueMap>> m_originalValues;
 
 };
index 09b4536..19131e7 100644 (file)
@@ -117,7 +117,7 @@ IDBError MemoryIDBBackingStore::commitTransaction(const IDBResourceIdentifier& t
 
 IDBError MemoryIDBBackingStore::createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
 {
-    LOG(IndexedDB, "MemoryIDBBackingStore::createObjectStore");
+    LOG(IndexedDB, "MemoryIDBBackingStore::createObjectStore - adding OS %s with ID %llu", info.name().utf8().data(), info.identifier());
 
     ASSERT(m_databaseInfo);
     if (m_databaseInfo->hasObjectStore(info.name()))
@@ -138,6 +138,29 @@ IDBError MemoryIDBBackingStore::createObjectStore(const IDBResourceIdentifier& t
     return IDBError();
 }
 
+IDBError MemoryIDBBackingStore::deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName)
+{
+    LOG(IndexedDB, "MemoryIDBBackingStore::deleteObjectStore");
+
+    ASSERT(m_databaseInfo);
+    if (!m_databaseInfo->hasObjectStore(objectStoreName))
+        return IDBError(IDBExceptionCode::ConstraintError);
+
+    auto transaction = m_transactions.get(transactionIdentifier);
+    ASSERT(transaction);
+    ASSERT(transaction->isVersionChange());
+
+    auto objectStore = takeObjectStoreByName(objectStoreName);
+    ASSERT(objectStore);
+    if (!objectStore)
+        return IDBError(IDBExceptionCode::ConstraintError);
+
+    m_databaseInfo->deleteObjectStore(objectStoreName);
+    transaction->objectStoreDeleted(WTF::move(objectStore));
+
+    return IDBError();
+}
+
 void MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort(MemoryObjectStore& objectStore)
 {
     LOG(IndexedDB, "MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort");
@@ -148,6 +171,11 @@ void MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort(MemoryObjectS
     unregisterObjectStore(objectStore);
 }
 
+void MemoryIDBBackingStore::restoreObjectStoreForVersionChangeAbort(std::unique_ptr<MemoryObjectStore>&& objectStore)
+{
+    registerObjectStore(WTF::move(objectStore));
+}
+
 IDBError MemoryIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier&, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, bool& keyExists)
 {
     LOG(IndexedDB, "MemoryIDBBackingStore::keyExistsInObjectStore");
@@ -229,6 +257,18 @@ void MemoryIDBBackingStore::unregisterObjectStore(MemoryObjectStore& objectStore
     m_objectStoresByIdentifier.remove(objectStore.info().identifier());
 }
 
+std::unique_ptr<MemoryObjectStore> MemoryIDBBackingStore::takeObjectStoreByName(const String& name)
+{
+    auto rawObjectStore = m_objectStoresByName.take(name);
+    if (!rawObjectStore)
+        return nullptr;
+
+    auto objectStore = m_objectStoresByIdentifier.take(rawObjectStore->info().identifier());
+    ASSERT(objectStore);
+
+    return objectStore;
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index 64b77ad..9d692f5 100644 (file)
@@ -53,16 +53,20 @@ public:
     virtual IDBError abortTransaction(const IDBResourceIdentifier& transactionIdentifier) override final;
     virtual IDBError commitTransaction(const IDBResourceIdentifier& transactionIdentifier) override final;
     virtual IDBError createObjectStore(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&) override final;
+    virtual IDBError deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName) override final;
     virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) override final;
     virtual IDBError deleteRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&) override final;
     virtual IDBError putRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) override final;
     virtual IDBError getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, ThreadSafeDataBuffer& outValue) override final;
 
     void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&);
+    void restoreObjectStoreForVersionChangeAbort(std::unique_ptr<MemoryObjectStore>&&);
 
 private:
     MemoryIDBBackingStore(const IDBDatabaseIdentifier&);
 
+    std::unique_ptr<MemoryObjectStore> takeObjectStoreByName(const String& name);
+
     IDBDatabaseIdentifier m_identifier;
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
 
index 41c2d5f..37b2253 100644 (file)
@@ -237,19 +237,17 @@ void UniqueIDBDatabase::createObjectStore(UniqueIDBDatabaseTransaction& transact
     ASSERT(isMainThread());
     LOG(IndexedDB, "(main) UniqueIDBDatabase::createObjectStore");
 
-    ASSERT(m_backingStore);
-    m_backingStore->createObjectStore(transaction.info().identifier(), info);
-
     uint64_t callbackID = storeCallback(callback);
     m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info));
 }
 
-void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier&, const IDBObjectStoreInfo& info)
+void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info)
 {
     ASSERT(!isMainThread());
     LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateObjectStore");
 
-    // FIXME: Create object store in backing store, once that exists.
+    ASSERT(m_backingStore);
+    m_backingStore->createObjectStore(transactionIdentifier, info);
 
     IDBError error;
     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateObjectStore, callbackIdentifier, error, info));
@@ -266,6 +264,38 @@ void UniqueIDBDatabase::didPerformCreateObjectStore(uint64_t callbackIdentifier,
     performErrorCallback(callbackIdentifier, error);
 }
 
+void UniqueIDBDatabase::deleteObjectStore(UniqueIDBDatabaseTransaction& transaction, const String& objectStoreName, ErrorCallback callback)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore");
+
+    uint64_t callbackID = storeCallback(callback);
+    m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteObjectStore, callbackID, transaction.info().identifier(), objectStoreName));
+}
+
+void UniqueIDBDatabase::performDeleteObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName)
+{
+    ASSERT(!isMainThread());
+    LOG(IndexedDB, "(db) UniqueIDBDatabase::performDeleteObjectStore");
+
+    ASSERT(m_backingStore);
+    m_backingStore->deleteObjectStore(transactionIdentifier, objectStoreName);
+
+    IDBError error;
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformDeleteObjectStore, callbackIdentifier, error, objectStoreName));
+}
+
+void UniqueIDBDatabase::didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError& error, const String& objectStoreName)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformDeleteObjectStore");
+
+    if (error.isNull())
+        m_databaseInfo->deleteObjectStore(objectStoreName);
+
+    performErrorCallback(callbackIdentifier, error);
+}
+
 void UniqueIDBDatabase::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback)
 {
     ASSERT(isMainThread());
index f3b013e..6d3f072 100644 (file)
@@ -70,6 +70,7 @@ public:
     IDBServer& server() { return m_server; }
 
     void createObjectStore(UniqueIDBDatabaseTransaction&, const IDBObjectStoreInfo&, ErrorCallback);
+    void deleteObjectStore(UniqueIDBDatabaseTransaction&, const String& objectStoreName, ErrorCallback);
     void putOrAdd(const IDBRequestData&, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback);
     void getRecord(const IDBRequestData&, const IDBKeyData&, ValueDataCallback);
     void commitTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback);
@@ -98,6 +99,7 @@ private:
     void performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier);
     void beginTransactionInBackingStore(const IDBTransactionInfo&);
     void performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&);
+    void performDeleteObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName);
     void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode);
     void performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&);
     void performActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBTransactionInfo&);
@@ -105,6 +107,7 @@ private:
     // Main thread callbacks
     void didOpenBackingStore(const IDBDatabaseInfo&);
     void didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError&, const IDBObjectStoreInfo&);
+    void didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError&, const String& objectStoreName);
     void didPerformPutOrAdd(uint64_t callbackIdentifier, const IDBError&, const IDBKeyData&);
     void didPerformGetRecord(uint64_t callbackIdentifier, const IDBError&, const ThreadSafeDataBuffer&);
     void didPerformCommitTransaction(uint64_t callbackIdentifier, const IDBError&, const IDBResourceIdentifier& transactionIdentifier);
index 9b39181..4439bd2 100644 (file)
@@ -139,6 +139,13 @@ void UniqueIDBDatabaseConnection::didCreateObjectStore(const IDBResultData& resu
     m_connectionToClient.didCreateObjectStore(resultData);
 }
 
+void UniqueIDBDatabaseConnection::didDeleteObjectStore(const IDBResultData& resultData)
+{
+    LOG(IndexedDB, "UniqueIDBDatabaseConnection::didDeleteObjectStore");
+
+    m_connectionToClient.didDeleteObjectStore(resultData);
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index 29d7b10..4b5676a 100644 (file)
@@ -67,6 +67,7 @@ public:
     void didAbortTransaction(UniqueIDBDatabaseTransaction&, const IDBError&);
     void didCommitTransaction(UniqueIDBDatabaseTransaction&, const IDBError&);
     void didCreateObjectStore(const IDBResultData&);
+    void didDeleteObjectStore(const IDBResultData&);
 
 private:
     UniqueIDBDatabaseConnection(UniqueIDBDatabase&, IDBConnectionToClient&);
index 3a44dd2..5782ca8 100644 (file)
@@ -113,6 +113,24 @@ void UniqueIDBDatabaseTransaction::createObjectStore(const IDBRequestData& reque
     });
 }
 
+void UniqueIDBDatabaseTransaction::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
+{
+    LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteObjectStore");
+
+    ASSERT(isVersionChange());
+    ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
+
+    RefPtr<UniqueIDBDatabaseTransaction> self(this);
+    m_databaseConnection->database().deleteObjectStore(*this, objectStoreName, [this, self, requestData](const IDBError& error) {
+        LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteObjectStore (callback)");
+        if (error.isNull())
+            m_databaseConnection->didDeleteObjectStore(IDBResultData::deleteObjectStoreSuccess(requestData.requestIdentifier()));
+        else
+            m_databaseConnection->didDeleteObjectStore(IDBResultData::error(requestData.requestIdentifier(), error));
+    });
+}
+
+
 void UniqueIDBDatabaseTransaction::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     LOG(IndexedDB, "UniqueIDBDatabaseTransaction::putOrAdd");
index a561dbc..80a8fae 100644 (file)
@@ -63,6 +63,7 @@ public:
     void commit();
 
     void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&);
+    void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
     void putOrAdd(const IDBRequestData&, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode);
     void getRecord(const IDBRequestData&, const IDBKeyData&);
 
index 89b0dde..b4ab014 100644 (file)
@@ -106,6 +106,15 @@ Vector<String> IDBDatabaseInfo::objectStoreNames() const
     return WTF::move(names);
 }
 
+void IDBDatabaseInfo::deleteObjectStore(const String& objectStoreName)
+{
+    auto* info = infoForExistingObjectStore(objectStoreName);
+    if (!info)
+        return;
+
+    m_objectStoreMap.remove(info->identifier());
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index b6ac68a..cd59b42 100644 (file)
@@ -54,6 +54,8 @@ public:
 
     Vector<String> objectStoreNames() const;
 
+    void deleteObjectStore(const String& objectStoreName);
+
 private:
     IDBDatabaseInfo();
 
index 8dcb746..5a5c7c1 100644 (file)
@@ -93,6 +93,11 @@ IDBResultData IDBResultData::createObjectStoreSuccess(const IDBResourceIdentifie
     return { IDBResultType::CreateObjectStoreSuccess, requestIdentifier };
 }
 
+IDBResultData IDBResultData::deleteObjectStoreSuccess(const IDBResourceIdentifier& requestIdentifier)
+{
+    return { IDBResultType::DeleteObjectStoreSuccess, requestIdentifier };
+}
+
 IDBResultData IDBResultData::putOrAddSuccess(const IDBResourceIdentifier& requestIdentifier, const IDBKeyData& resultKey)
 {
     IDBResultData result(IDBResultType::PutOrAddSuccess, requestIdentifier);
index 8f293c9..b8054ad 100644 (file)
@@ -45,6 +45,7 @@ enum class IDBResultType {
     OpenDatabaseSuccess,
     OpenDatabaseUpgradeNeeded,
     CreateObjectStoreSuccess,
+    DeleteObjectStoreSuccess,
     PutOrAddSuccess,
     GetRecordSuccess,
 };
@@ -60,6 +61,7 @@ public:
     static IDBResultData openDatabaseSuccess(const IDBResourceIdentifier&, IDBServer::UniqueIDBDatabaseConnection&);
     static IDBResultData openDatabaseUpgradeNeeded(const IDBResourceIdentifier&, IDBServer::UniqueIDBDatabaseTransaction&);
     static IDBResultData createObjectStoreSuccess(const IDBResourceIdentifier&);
+    static IDBResultData deleteObjectStoreSuccess(const IDBResourceIdentifier&);
     static IDBResultData putOrAddSuccess(const IDBResourceIdentifier&, const IDBKeyData&);
     static IDBResultData getRecordSuccess(const IDBResourceIdentifier&, const ThreadSafeDataBuffer& valueData);
 
index c5de067..dc09a09 100644 (file)
@@ -127,6 +127,14 @@ void InProcessIDBServer::didCreateObjectStore(const IDBResultData& resultData)
     });
 }
 
+void InProcessIDBServer::didDeleteObjectStore(const IDBResultData& resultData)
+{
+    RefPtr<InProcessIDBServer> self(this);
+    RunLoop::current().dispatch([this, self, resultData] {
+        m_connectionToServer->didDeleteObjectStore(resultData);
+    });
+}
+
 void InProcessIDBServer::didPutOrAdd(const IDBResultData& resultData)
 {
     RefPtr<InProcessIDBServer> self(this);
@@ -167,6 +175,14 @@ void InProcessIDBServer::createObjectStore(const IDBRequestData& resultData, con
     });
 }
 
+void InProcessIDBServer::deleteObjectStore(const IDBRequestData& requestData, const String& objectStoreName)
+{
+    RefPtr<InProcessIDBServer> self(this);
+    RunLoop::current().dispatch([this, self, requestData, objectStoreName] {
+        m_server->deleteObjectStore(requestData, objectStoreName);
+    });
+}
+
 void InProcessIDBServer::putOrAdd(const IDBRequestData& requestData, IDBKey* key, SerializedScriptValue& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     RefPtr<InProcessIDBServer> self(this);
index d6f28a4..b6ac429 100644 (file)
@@ -59,6 +59,7 @@ public:
     virtual void abortTransaction(IDBResourceIdentifier&) override final;
     virtual void commitTransaction(IDBResourceIdentifier&) override final;
     virtual void createObjectStore(const IDBRequestData&, const IDBObjectStoreInfo&) override final;
+    virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) override final;
     virtual void putOrAdd(const IDBRequestData&, IDBKey*, SerializedScriptValue&, const IndexedDB::ObjectStoreOverwriteMode) override final;
     virtual void getRecord(const IDBRequestData&, IDBKey*) override final;
     virtual void establishTransaction(uint64_t databaseConnectionIdentifier, const IDBTransactionInfo&) override final;
@@ -71,6 +72,7 @@ public:
     virtual void didAbortTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) override final;
     virtual void didCommitTransaction(const IDBResourceIdentifier& transactionIdentifier, const IDBError&) override final;
     virtual void didCreateObjectStore(const IDBResultData&) override final;
+    virtual void didDeleteObjectStore(const IDBResultData&) override final;
     virtual void didPutOrAdd(const IDBResultData&) override final;
     virtual void didGetRecord(const IDBResultData&) override final;
     virtual void fireVersionChangeEvent(IDBServer::UniqueIDBDatabaseConnection&, uint64_t requestedVersion) override final;