Modern IDB: IDBObjectStore.deleteIndex() support.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Nov 2015 19:57:18 +0000 (19:57 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Nov 2015 19:57:18 +0000 (19:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150911

Reviewed by Alex Christensen.

Source/WebCore:

Tests: storage/indexeddb/modern/deleteindex-1.html
       storage/indexeddb/modern/deleteindex-2.html

* Modules/indexeddb/client/IDBConnectionToServer.cpp:
(WebCore::IDBClient::IDBConnectionToServer::deleteIndex):
(WebCore::IDBClient::IDBConnectionToServer::didDeleteIndex):
* Modules/indexeddb/client/IDBConnectionToServer.h:
* Modules/indexeddb/client/IDBConnectionToServerDelegate.h:

* Modules/indexeddb/client/IDBDatabaseImpl.cpp:
(WebCore::IDBClient::IDBDatabase::didDeleteIndexInfo):
* Modules/indexeddb/client/IDBDatabaseImpl.h:

* Modules/indexeddb/client/IDBIndexImpl.cpp:
(WebCore::IDBClient::IDBIndex::markAsDeleted):
* Modules/indexeddb/client/IDBIndexImpl.h:

* Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
(WebCore::IDBClient::IDBObjectStore::index):
(WebCore::IDBClient::IDBObjectStore::deleteIndex):

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::deleteIndex):
(WebCore::IDBClient::IDBTransaction::deleteIndexOnServer):
(WebCore::IDBClient::IDBTransaction::didDeleteIndexOnServer):
* Modules/indexeddb/client/IDBTransactionImpl.h:

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

* Modules/indexeddb/server/IDBBackingStore.h:

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

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

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

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

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

* Modules/indexeddb/server/MemoryObjectStore.cpp:
(WebCore::IDBServer::MemoryObjectStore::maybeRestoreDeletedIndex):
(WebCore::IDBServer::MemoryObjectStore::takeIndexByName):
(WebCore::IDBServer::MemoryObjectStore::deleteIndex):
* Modules/indexeddb/server/MemoryObjectStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
(WebCore::IDBServer::UniqueIDBDatabase::performDeleteIndex):
(WebCore::IDBServer::UniqueIDBDatabase::didPerformDeleteIndex):
* Modules/indexeddb/server/UniqueIDBDatabase.h:

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

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

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

* Modules/indexeddb/shared/IDBIndexInfo.cpp:
(WebCore::IDBIndexInfo::loggingString):
* Modules/indexeddb/shared/IDBIndexInfo.h:

* Modules/indexeddb/shared/IDBObjectStoreInfo.cpp:
(WebCore::IDBObjectStoreInfo::hasIndex):
(WebCore::IDBObjectStoreInfo::deleteIndex):
(WebCore::IDBObjectStoreInfo::loggingString):
* Modules/indexeddb/shared/IDBObjectStoreInfo.h:

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

* Modules/indexeddb/shared/InProcessIDBServer.cpp:
(WebCore::InProcessIDBServer::didDeleteIndex):
(WebCore::InProcessIDBServer::createIndex):
(WebCore::InProcessIDBServer::deleteIndex):
* Modules/indexeddb/shared/InProcessIDBServer.h:

LayoutTests:

* storage/indexeddb/modern/deleteindex-1-expected.txt: Added.
* storage/indexeddb/modern/deleteindex-1.html: Added.
* storage/indexeddb/modern/deleteindex-2-expected.txt: Added.
* storage/indexeddb/modern/deleteindex-2.html: Added.
* storage/indexeddb/modern/index-get-count-failures.html:

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

49 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/modern/deleteindex-1-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/deleteindex-1.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/deleteindex-2-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/deleteindex-2.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/modern/index-get-count-failures-expected.txt
LayoutTests/storage/indexeddb/modern/index-get-count-failures.html
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/IDBIndexImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h
Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.cpp
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/MemoryIndex.cpp
Source/WebCore/Modules/indexeddb/server/MemoryIndex.h
Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp
Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.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/IDBIndexInfo.cpp
Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.h
Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp
Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.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 f98a188..7f960a8 100644 (file)
@@ -1,3 +1,16 @@
+2015-11-19  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: IDBObjectStore.deleteIndex() support.
+        https://bugs.webkit.org/show_bug.cgi?id=150911
+
+        Reviewed by Alex Christensen.
+
+        * storage/indexeddb/modern/deleteindex-1-expected.txt: Added.
+        * storage/indexeddb/modern/deleteindex-1.html: Added.
+        * storage/indexeddb/modern/deleteindex-2-expected.txt: Added.
+        * storage/indexeddb/modern/deleteindex-2.html: Added.
+        * storage/indexeddb/modern/index-get-count-failures.html:
+
 2015-11-19  Brian Burg  <bburg@apple.com>
 
         REGRESSION(r8780): Backwards delete by word incorrectly appends deleted text to kill ring, should be prepend
diff --git a/LayoutTests/storage/indexeddb/modern/deleteindex-1-expected.txt b/LayoutTests/storage/indexeddb/modern/deleteindex-1-expected.txt
new file mode 100644 (file)
index 0000000..601ac86
--- /dev/null
@@ -0,0 +1,13 @@
+This tests deleting an index and then committing the transaction.
+Initial upgrade needed: Old version - 0 New version - 1
+Count is: 2
+Cursor at record: A / 1
+Cursor at record: A / 2
+Cursor at record: undefined / undefined
+Deleted the index
+Initial upgrade versionchange transaction complete
+Object store has indexes:
+Unable to get index from object store (it shouldn't exist)
+Transaction complete
+Done
+
diff --git a/LayoutTests/storage/indexeddb/modern/deleteindex-1.html b/LayoutTests/storage/indexeddb/modern/deleteindex-1.html
new file mode 100644 (file)
index 0000000..8bf78fd
--- /dev/null
@@ -0,0 +1,113 @@
+This tests deleting an index and then committing the transaction.<br>
+<div id="logger"></div>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    log("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function log(message)
+{
+    document.getElementById("logger").innerHTML += message + "<br>";
+}
+
+var index;
+var objectStore;
+var database;
+
+function checkIndexValues()
+{
+    var countRequest = index.count();
+    countRequest.onsuccess = function() {
+        log("Count is: " + countRequest.result);
+    }
+
+    var cursorRequest = index.openCursor();
+    cursorRequest.onsuccess = function() {
+        var cursor = cursorRequest.result;
+        log("Cursor at record: " + cursor.key + " / " + cursor.primaryKey);
+        
+        if (cursor.key != undefined)
+            cursor.continue();
+        else {
+            objectStore.deleteIndex("TestIndex1");
+            log("Deleted the index");
+        }
+    }
+    cursorRequest.onerror = function(e) {
+        log("Unexpected error opening or iterating cursor");
+        logCursor(cursorRequest.result);
+        done();
+    } 
+}
+
+var createRequest = window.indexedDB.open("DeleteIndex1Database", 1);
+createRequest.onupgradeneeded = function(event) {
+    log("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    database = event.target.result;
+    objectStore = database.createObjectStore("TestObjectStore");
+    objectStore.put({ bar: "A" }, 1);
+    objectStore.put({ bar: "A" }, 2);
+
+    index = objectStore.createIndex("TestIndex1", "bar");
+    
+    checkIndexValues();
+    
+    versionTransaction.onabort = function(event) {
+        log("Initial upgrade versionchange transaction unexpected abort");
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        log("Initial upgrade versionchange transaction complete");
+        continueTest();
+    }
+
+    versionTransaction.onerror = function(event) {
+        log("Initial upgrade versionchange transaction unexpected error" + event);
+        done();
+    }
+}
+
+function continueTest() {
+    var transaction = database.transaction("TestObjectStore");
+    objectStore = transaction.objectStore("TestObjectStore");
+
+    var names = objectStore.indexNames;
+    log("Object store has indexes:")
+    for (var i = 0; i < names.length; ++i)
+        log(names[i]);
+    
+    try {
+        objectStore.index("TestIndex1");
+    } catch(e) {
+        log("Unable to get index from object store (it shouldn't exist)");
+    }
+
+    transaction.onabort = function(event) {
+        log("Transaction unexpected abort");
+        done();
+    }
+
+    transaction.oncomplete = function(event) {
+        log("Transaction complete");
+        done();
+    }
+
+    transaction.onerror = function(event) {
+        log("Transaction unexpected error" + event);
+        done();
+    }
+}
+
+</script>
diff --git a/LayoutTests/storage/indexeddb/modern/deleteindex-2-expected.txt b/LayoutTests/storage/indexeddb/modern/deleteindex-2-expected.txt
new file mode 100644 (file)
index 0000000..cbc58ea
--- /dev/null
@@ -0,0 +1,19 @@
+This tests deleting an index and then aborting the transaction.
+Initial upgrade needed: Old version - 0 New version - 1
+Count is: 2
+Cursor at record: A / 1
+Cursor at record: A / 2
+Cursor at record: undefined / undefined
+Initial upgrade versionchange transaction complete
+Second upgrade needed: Old version - 1 New version - 2
+Deleted the index
+Aborted the transaction
+Second upgrade versionchange transaction abort
+Third upgrade needed: Old version - 1 New version - 3
+Count is: 2
+Cursor at record: A / 1
+Cursor at record: A / 2
+Cursor at record: undefined / undefined
+Third upgrade versionchange transaction complete
+Done
+
diff --git a/LayoutTests/storage/indexeddb/modern/deleteindex-2.html b/LayoutTests/storage/indexeddb/modern/deleteindex-2.html
new file mode 100644 (file)
index 0000000..c8015f5
--- /dev/null
@@ -0,0 +1,138 @@
+This tests deleting an index and then aborting the transaction.<br>
+<div id="logger"></div>
+<script>
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    log("Done");
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function log(message)
+{
+    document.getElementById("logger").innerHTML += message + "<br>";
+}
+
+var index;
+var objectStore;
+var database;
+
+function checkIndexValues()
+{
+    var countRequest = index.count();
+    countRequest.onsuccess = function() {
+        log("Count is: " + countRequest.result);
+    }
+
+    var cursorRequest = index.openCursor();
+    cursorRequest.onsuccess = function() {
+        var cursor = cursorRequest.result;
+        log("Cursor at record: " + cursor.key + " / " + cursor.primaryKey);
+        
+        if (cursor.key != undefined)
+            cursor.continue();
+    }
+    cursorRequest.onerror = function(e) {
+        log("Unexpected error opening or iterating cursor");
+        logCursor(cursorRequest.result);
+        done();
+    } 
+}
+
+var createRequest = window.indexedDB.open("DeleteIndex2Database", 1);
+createRequest.onupgradeneeded = function(event) {
+    log("Initial upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    database = event.target.result;
+    objectStore = database.createObjectStore("TestObjectStore");
+    objectStore.put({ bar: "A" }, 1);
+    objectStore.put({ bar: "A" }, 2);
+
+    index = objectStore.createIndex("TestIndex1", "bar");
+    
+    checkIndexValues();
+    
+    versionTransaction.onabort = function(event) {
+        log("Initial upgrade versionchange transaction unexpected abort");
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        log("Initial upgrade versionchange transaction complete");
+        database.close();
+        continueTest1();
+    }
+
+    versionTransaction.onerror = function(event) {
+        log("Initial upgrade versionchange transaction unexpected error" + event);
+        done();
+    }
+}
+
+function continueTest1() {
+    var createRequest = window.indexedDB.open("DeleteIndex2Database", 2);
+    createRequest.onupgradeneeded = function(event) {
+        log("Second upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+        database = event.target.result;
+        var versionTransaction = createRequest.transaction;
+        objectStore = versionTransaction.objectStore("TestObjectStore");
+        objectStore.deleteIndex("TestIndex1");
+        log("Deleted the index");
+        versionTransaction.abort();
+        log("Aborted the transaction");
+
+        versionTransaction.onabort = function(event) {
+            log("Second upgrade versionchange transaction abort");
+            database.close();
+            continueTest2();
+        }
+
+        versionTransaction.oncomplete = function(event) {
+            log("Second upgrade versionchange transaction unexpected complete");
+            done();
+        }
+
+        versionTransaction.onerror = function(event) {
+            log("Second upgrade versionchange transaction unexpected error" + event);
+            done();
+        }
+    }
+}
+
+function continueTest2() {
+    var createRequest = window.indexedDB.open("DeleteIndex2Database", 3);
+    createRequest.onupgradeneeded = function(event) {
+        log("Third upgrade needed: Old version - " + event.oldVersion + " New version - " + event.newVersion);
+
+        var versionTransaction = createRequest.transaction;
+        objectStore = versionTransaction.objectStore("TestObjectStore");
+        index = objectStore.index("TestIndex1");
+    
+        checkIndexValues();    
+        
+        versionTransaction.onabort = function(event) {
+            log("Third upgrade versionchange transaction unexpected abort");
+            done();
+        }
+
+        versionTransaction.oncomplete = function(event) {
+            log("Third upgrade versionchange transaction complete");
+            done();
+        }
+
+        versionTransaction.onerror = function(event) {
+            log("Third upgrade versionchange transaction unexpected error" + event);
+            done();
+        }
+    }
+}
+
+</script>
index bcf00a5..f7646d4 100644 (file)
@@ -3,6 +3,10 @@ Initial upgrade needed: Old version - 0 New version - 1
 Failed to get with a null key
 Failed to getKey with a null key
 Failed to count with a null range
+Failed to get with deleted IDBIndex
+Failed to getKey with deleted IDBIndex
+Failed to count with deleted IDBIndex
+Failed to delete a nonexistent IDBIndex
 Failed to get with deleted IDBObjectStore
 Failed to getKey with deleted IDBObjectStore
 Failed to count with deleted IDBObjectStore
index e429e1a..f2faf38 100644 (file)
@@ -49,27 +49,31 @@ createRequest.onupgradeneeded = function(event) {
         log("Failed to count with a null range");
     }
     
-    // FIXME: once IDBObjectStore.deleteIndex() is implemented, try these
-    // https://bugs.webkit.org/show_bug.cgi?id=150911
-    // objectStore.deleteIndex("TestIndex");
-    // 
-    // try {
-    //     index.get("test");
-    // } catch(e) {
-    //     log("Failed to get with deleted IDBIndex");
-    // }
-    // 
-    // try {
-    //     index.getKey("test");
-    // } catch(e) {
-    //     log("Failed to getKey with deleted IDBIndex");
-    // }
-    // 
-    // try {
-    //     index.count();
-    // } catch(e) {
-    //     log("Failed to count with deleted IDBIndex");
-    // }
+    objectStore.deleteIndex("TestIndex");
+    
+    try {
+        index.get("test");
+    } catch(e) {
+        log("Failed to get with deleted IDBIndex");
+    }
+    
+    try {
+        index.getKey("test");
+    } catch(e) {
+        log("Failed to getKey with deleted IDBIndex");
+    }
+    
+    try {
+        index.count();
+    } catch(e) {
+        log("Failed to count with deleted IDBIndex");
+    }
+    
+    try {
+        objectStore.deleteIndex("TestIndex");
+    } catch(e) {
+        log("Failed to delete a nonexistent IDBIndex");
+    }
 
     database.deleteObjectStore("TestObjectStore");
     try {
index 41127b0..f0e64ba 100644 (file)
@@ -1,3 +1,108 @@
+2015-11-19  Brady Eidson  <beidson@apple.com>
+
+        Modern IDB: IDBObjectStore.deleteIndex() support.
+        https://bugs.webkit.org/show_bug.cgi?id=150911
+
+        Reviewed by Alex Christensen.
+
+        Tests: storage/indexeddb/modern/deleteindex-1.html
+               storage/indexeddb/modern/deleteindex-2.html
+
+        * Modules/indexeddb/client/IDBConnectionToServer.cpp:
+        (WebCore::IDBClient::IDBConnectionToServer::deleteIndex):
+        (WebCore::IDBClient::IDBConnectionToServer::didDeleteIndex):
+        * Modules/indexeddb/client/IDBConnectionToServer.h:
+        * Modules/indexeddb/client/IDBConnectionToServerDelegate.h:
+
+        * Modules/indexeddb/client/IDBDatabaseImpl.cpp:
+        (WebCore::IDBClient::IDBDatabase::didDeleteIndexInfo):
+        * Modules/indexeddb/client/IDBDatabaseImpl.h:
+
+        * Modules/indexeddb/client/IDBIndexImpl.cpp:
+        (WebCore::IDBClient::IDBIndex::markAsDeleted):
+        * Modules/indexeddb/client/IDBIndexImpl.h:
+
+        * Modules/indexeddb/client/IDBObjectStoreImpl.cpp:
+        (WebCore::IDBClient::IDBObjectStore::index):
+        (WebCore::IDBClient::IDBObjectStore::deleteIndex):
+
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::deleteIndex):
+        (WebCore::IDBClient::IDBTransaction::deleteIndexOnServer):
+        (WebCore::IDBClient::IDBTransaction::didDeleteIndexOnServer):
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+
+        * Modules/indexeddb/client/TransactionOperation.h:
+        (WebCore::IDBClient::createTransactionOperation):
+
+        * Modules/indexeddb/server/IDBBackingStore.h:
+
+        * Modules/indexeddb/server/IDBConnectionToClient.cpp:
+        (WebCore::IDBServer::IDBConnectionToClient::didDeleteIndex):
+        * Modules/indexeddb/server/IDBConnectionToClient.h:
+        * Modules/indexeddb/server/IDBConnectionToClientDelegate.h:
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::deleteIndex):
+        * Modules/indexeddb/server/IDBServer.h:
+
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp:
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::indexDeleted):
+        (WebCore::IDBServer::MemoryBackingStoreTransaction::abort):
+        * Modules/indexeddb/server/MemoryBackingStoreTransaction.h:
+
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::deleteIndex):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+
+        * Modules/indexeddb/server/MemoryIndex.cpp:
+        (WebCore::IDBServer::MemoryIndex::clearIndexValueStore):
+        * Modules/indexeddb/server/MemoryIndex.h:
+
+        * Modules/indexeddb/server/MemoryObjectStore.cpp:
+        (WebCore::IDBServer::MemoryObjectStore::maybeRestoreDeletedIndex):
+        (WebCore::IDBServer::MemoryObjectStore::takeIndexByName):
+        (WebCore::IDBServer::MemoryObjectStore::deleteIndex):
+        * Modules/indexeddb/server/MemoryObjectStore.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::deleteIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::performDeleteIndex):
+        (WebCore::IDBServer::UniqueIDBDatabase::didPerformDeleteIndex):
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseConnection::didDeleteIndex):
+        * Modules/indexeddb/server/UniqueIDBDatabaseConnection.h:
+
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabaseTransaction::deleteIndex):
+        * Modules/indexeddb/server/UniqueIDBDatabaseTransaction.h:
+
+        * Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
+        (WebCore::IDBDatabaseInfo::loggingString):
+        * Modules/indexeddb/shared/IDBDatabaseInfo.h:
+
+        * Modules/indexeddb/shared/IDBIndexInfo.cpp:
+        (WebCore::IDBIndexInfo::loggingString):
+        * Modules/indexeddb/shared/IDBIndexInfo.h:
+
+        * Modules/indexeddb/shared/IDBObjectStoreInfo.cpp:
+        (WebCore::IDBObjectStoreInfo::hasIndex):
+        (WebCore::IDBObjectStoreInfo::deleteIndex):
+        (WebCore::IDBObjectStoreInfo::loggingString):
+        * Modules/indexeddb/shared/IDBObjectStoreInfo.h:
+
+        * Modules/indexeddb/shared/IDBResultData.cpp:
+        (WebCore::IDBResultData::deleteIndexSuccess):
+        * Modules/indexeddb/shared/IDBResultData.h:
+
+        * Modules/indexeddb/shared/InProcessIDBServer.cpp:
+        (WebCore::InProcessIDBServer::didDeleteIndex):
+        (WebCore::InProcessIDBServer::createIndex):
+        (WebCore::InProcessIDBServer::deleteIndex):
+        * Modules/indexeddb/shared/InProcessIDBServer.h:
+
 2015-11-19  Brian Burg  <bburg@apple.com>
 
         REGRESSION(r8780): Backwards delete by word incorrectly appends deleted text to kill ring, should be prepend
index 274fba7..6e3b542 100644 (file)
@@ -155,6 +155,21 @@ void IDBConnectionToServer::didCreateIndex(const IDBResultData& resultData)
     completeOperation(resultData);
 }
 
+void IDBConnectionToServer::deleteIndex(TransactionOperation& operation, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    LOG(IndexedDB, "IDBConnectionToServer::deleteIndex");
+
+    saveOperation(operation);
+
+    m_delegate->deleteIndex(IDBRequestData(operation), objectStoreIdentifier, indexName);
+}
+
+void IDBConnectionToServer::didDeleteIndex(const IDBResultData& resultData)
+{
+    LOG(IndexedDB, "IDBConnectionToServer::didDeleteIndex");
+    completeOperation(resultData);
+}
+
 void IDBConnectionToServer::putOrAdd(TransactionOperation& operation, RefPtr<IDBKey>& key, RefPtr<SerializedScriptValue>& value, const IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     LOG(IndexedDB, "IDBConnectionToServer::putOrAdd");
index 1cdce73..2061d13 100644 (file)
@@ -74,6 +74,9 @@ public:
     void createIndex(TransactionOperation&, const IDBIndexInfo&);
     void didCreateIndex(const IDBResultData&);
 
+    void deleteIndex(TransactionOperation&, uint64_t objectStoreIdentifier, const String& indexName);
+    void didDeleteIndex(const IDBResultData&);
+
     void putOrAdd(TransactionOperation&, RefPtr<IDBKey>&, RefPtr<SerializedScriptValue>&, const IndexedDB::ObjectStoreOverwriteMode);
     void didPutOrAdd(const IDBResultData&);
 
index f9b8c9c..0b9090e 100644 (file)
@@ -63,6 +63,7 @@ public:
     virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) = 0;
     virtual void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier) = 0;
     virtual void createIndex(const IDBRequestData&, const IDBIndexInfo&) = 0;
+    virtual void deleteIndex(const IDBRequestData&, uint64_t objectStoreIdentifier, const String& indexName) = 0;
     virtual void putOrAdd(const IDBRequestData&, IDBKey*, SerializedScriptValue&, const IndexedDB::ObjectStoreOverwriteMode) = 0;
     virtual void getRecord(const IDBRequestData&, const IDBKeyRangeData&) = 0;
     virtual void getCount(const IDBRequestData&, const IDBKeyRangeData&) = 0;
index 61b177c..ae6c0dd 100644 (file)
@@ -341,6 +341,13 @@ void IDBDatabase::didCreateIndexInfo(const IDBIndexInfo& info)
     objectStore->addExistingIndex(info);
 }
 
+void IDBDatabase::didDeleteIndexInfo(const IDBIndexInfo& info)
+{
+    auto* objectStore = m_info.infoForExistingObjectStore(info.objectStoreIdentifier());
+    ASSERT(objectStore);
+    objectStore->deleteIndex(info.name());
+}
+
 } // namespace IDBClient
 } // namespace WebCore
 
index 2a30680..6a917cd 100644 (file)
@@ -85,6 +85,7 @@ public:
     IDBConnectionToServer& serverConnection() { return m_serverConnection.get(); }
 
     void didCreateIndexInfo(const IDBIndexInfo&);
+    void didDeleteIndexInfo(const IDBIndexInfo&);
 
 private:
     IDBDatabase(ScriptExecutionContext&, IDBConnectionToServer&, const IDBResultData&);
index 24ced82..5cb9982 100644 (file)
@@ -327,6 +327,11 @@ RefPtr<WebCore::IDBRequest> IDBIndex::doGetKey(ScriptExecutionContext& context,
     return transaction.requestGetKey(context, *this, range);
 }
 
+void IDBIndex::markAsDeleted()
+{
+    m_deleted = true;
+}
+
 } // namespace IDBClient
 } // namespace WebCore
 
index 1704ddb..47f8f84 100644 (file)
@@ -78,6 +78,8 @@ public:
     const IDBIndexInfo& info() const { return m_info; }
 
     IDBObjectStore& modernObjectStore() { return m_objectStore.get(); }
+
+    void markAsDeleted();
     bool isDeleted() const { return m_deleted; }
 
 private:
index bdf6a42..1072ac3 100644 (file)
@@ -424,6 +424,8 @@ RefPtr<WebCore::IDBIndex> IDBObjectStore::createIndex(ScriptExecutionContext* co
 
     // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side.
     Ref<IDBIndex> index = m_transaction->createIndex(*this, info);
+    m_referencedIndexes.set(name, &index.get());
+
     return WTF::move(index);
 }
 
@@ -441,6 +443,11 @@ RefPtr<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, Excepti
         return nullptr;
     }
 
+    if (!m_transaction->isActive()) {
+        ec = static_cast<ExceptionCode>(IDBExceptionCode::TransactionInactiveError);
+        return nullptr;
+    }
+
     auto iterator = m_referencedIndexes.find(indexName);
     if (iterator != m_referencedIndexes.end())
         return iterator->value;
@@ -457,9 +464,40 @@ RefPtr<WebCore::IDBIndex> IDBObjectStore::index(const String& indexName, Excepti
     return WTF::move(index);
 }
 
-void IDBObjectStore::deleteIndex(const String&, ExceptionCode&)
+void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec)
 {
-    RELEASE_ASSERT_NOT_REACHED();
+    LOG(IndexedDB, "IDBObjectStore::deleteIndex %s", name.utf8().data());
+
+    if (m_deleted) {
+        ec = static_cast<ExceptionCode>(IDBExceptionCode::InvalidStateError);
+        return;
+    }
+
+    if (!m_transaction->isVersionChange()) {
+        ec = static_cast<ExceptionCode>(IDBExceptionCode::InvalidStateError);
+        return;
+    }
+
+    if (!m_transaction->isActive()) {
+        ec = static_cast<ExceptionCode>(IDBExceptionCode::TransactionInactiveError);
+        return;
+    }
+
+    if (!m_info.hasIndex(name)) {
+        ec = IDBDatabaseException::NotFoundError;
+        return;
+    }
+
+    auto* info = m_info.infoForExistingIndex(name);
+    ASSERT(info);
+    m_transaction->database().didDeleteIndexInfo(*info);
+
+    m_info.deleteIndex(name);
+
+    if (auto index = m_referencedIndexes.take(name))
+        index->markAsDeleted();
+
+    m_transaction->deleteIndex(m_info.identifier(), name);
 }
 
 RefPtr<WebCore::IDBRequest> IDBObjectStore::count(ScriptExecutionContext* context, ExceptionCode& ec)
index 72fd2f1..9bcb51c 100644 (file)
@@ -751,6 +751,30 @@ void IDBTransaction::didDeleteObjectStoreOnServer(const IDBResultData& resultDat
     ASSERT_UNUSED(resultData, resultData.type() == IDBResultType::DeleteObjectStoreSuccess);
 }
 
+void IDBTransaction::deleteIndex(uint64_t objectStoreIdentifier, const String& indexName)
+{
+    LOG(IndexedDB, "IDBTransaction::deleteIndex");
+
+    ASSERT(isVersionChange());
+
+    auto operation = createTransactionOperation(*this, &IDBTransaction::didDeleteIndexOnServer, &IDBTransaction::deleteIndexOnServer, objectStoreIdentifier, indexName);
+    scheduleOperation(WTF::move(operation));
+}
+
+void IDBTransaction::deleteIndexOnServer(TransactionOperation& operation, const uint64_t& objectStoreIdentifier, const String& indexName)
+{
+    LOG(IndexedDB, "IDBTransaction::deleteIndexOnServer");
+    ASSERT(isVersionChange());
+
+    serverConnection().deleteIndex(operation, objectStoreIdentifier, indexName);
+}
+
+void IDBTransaction::didDeleteIndexOnServer(const IDBResultData& resultData)
+{
+    LOG(IndexedDB, "IDBTransaction::didDeleteIndexOnServer");
+    ASSERT_UNUSED(resultData, resultData.type() == IDBResultType::DeleteIndexSuccess);
+}
+
 void IDBTransaction::operationDidComplete(TransactionOperation& operation)
 {
     ASSERT(m_transactionOperationMap.get(operation.identifier()) == &operation);
index 5c3f66e..379a39b 100644 (file)
@@ -109,6 +109,7 @@ public:
     void iterateCursor(IDBCursor&, const IDBKeyData&, unsigned long count);
 
     void deleteObjectStore(const String& objectStoreName);
+    void deleteIndex(uint64_t objectStoreIdentifier, const String& indexName);
 
     void addRequest(IDBRequest&);
     void removeRequest(IDBRequest&);
@@ -165,6 +166,9 @@ private:
     void deleteObjectStoreOnServer(TransactionOperation&, const String& objectStoreName);
     void didDeleteObjectStoreOnServer(const IDBResultData&);
 
+    void deleteIndexOnServer(TransactionOperation&, const uint64_t& objectStoreIdentifier, const String& indexName);
+    void didDeleteIndexOnServer(const IDBResultData&);
+
     Ref<IDBRequest> doRequestOpenCursor(ScriptExecutionContext&, Ref<IDBCursor>&&);
     void openCursorOnServer(TransactionOperation&, const IDBCursorInfo&);
     void didOpenCursorOnServer(IDBRequest&, const IDBResultData&);
index 5951f7f..ea9dce0 100644 (file)
@@ -138,6 +138,18 @@ RefPtr<TransactionOperation> createTransactionOperation(
     return adoptRef(operation);
 }
 
+template<typename MP1, typename P1, typename MP2, typename P2>
+RefPtr<TransactionOperation> createTransactionOperation(
+    IDBTransaction& transaction,
+    void (IDBTransaction::*complete)(const IDBResultData&),
+    void (IDBTransaction::*perform)(TransactionOperation&, MP1, MP2),
+    const P1& parameter1,
+    const P2& parameter2)
+{
+    auto operation = new TransactionOperationImpl<MP1, MP2>(transaction, complete, perform, parameter1, parameter2);
+    return adoptRef(operation);
+}
+
 template<typename MP1, typename P1>
 RefPtr<TransactionOperation> createTransactionOperation(
     IDBTransaction& transaction,
index efdc6e2..ff6eaa4 100644 (file)
@@ -64,6 +64,7 @@ public:
     virtual IDBError deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName) = 0;
     virtual IDBError clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier) = 0;
     virtual IDBError createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&) = 0;
+    virtual IDBError deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& indexName) = 0;
     virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) = 0;
     virtual IDBError deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&) = 0;
     virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) = 0;
index 02e1d1b..da3bd0a 100644 (file)
@@ -83,6 +83,11 @@ void IDBConnectionToClient::didCreateIndex(const IDBResultData& result)
     m_delegate->didCreateIndex(result);
 }
 
+void IDBConnectionToClient::didDeleteIndex(const IDBResultData& result)
+{
+    m_delegate->didDeleteIndex(result);
+}
+
 void IDBConnectionToClient::didPutOrAdd(const IDBResultData& result)
 {
     m_delegate->didPutOrAdd(result);
index ef880c6..5ee2b33 100644 (file)
@@ -56,6 +56,7 @@ public:
     void didDeleteObjectStore(const IDBResultData&);
     void didClearObjectStore(const IDBResultData&);
     void didCreateIndex(const IDBResultData&);
+    void didDeleteIndex(const IDBResultData&);
     void didPutOrAdd(const IDBResultData&);
     void didGetRecord(const IDBResultData&);
     void didGetCount(const IDBResultData&);
index 3a8f16e..c70621b 100644 (file)
@@ -52,6 +52,7 @@ public:
     virtual void didDeleteObjectStore(const IDBResultData&) = 0;
     virtual void didClearObjectStore(const IDBResultData&) = 0;
     virtual void didCreateIndex(const IDBResultData&) = 0;
+    virtual void didDeleteIndex(const IDBResultData&) = 0;
     virtual void didPutOrAdd(const IDBResultData&) = 0;
     virtual void didGetRecord(const IDBResultData&) = 0;
     virtual void didGetCount(const IDBResultData&) = 0;
index c6378ee..dbdbd98 100644 (file)
@@ -203,6 +203,18 @@ void IDBServer::createIndex(const IDBRequestData& requestData, const IDBIndexInf
     transaction->createIndex(requestData, info);
 }
 
+void IDBServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    LOG(IndexedDB, "IDBServer::deleteIndex");
+
+    auto transaction = m_transactions.get(requestData.transactionIdentifier());
+    if (!transaction)
+        return;
+
+    ASSERT(transaction->isVersionChange());
+    transaction->deleteIndex(requestData, objectStoreIdentifier, indexName);
+}
+
 void IDBServer::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode)
 {
     LOG(IndexedDB, "IDBServer::putOrAdd");
index fa586c0..940fb92 100644 (file)
@@ -64,6 +64,7 @@ public:
     void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
     void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier);
     void createIndex(const IDBRequestData&, const IDBIndexInfo&);
+    void deleteIndex(const IDBRequestData&, uint64_t objectStoreIdentifier, const String& indexName);
     void putOrAdd(const IDBRequestData&, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode);
     void getRecord(const IDBRequestData&, const IDBKeyRangeData&);
     void getCount(const IDBRequestData&, const IDBKeyRangeData&);
index 48a9272..be38072 100644 (file)
@@ -86,6 +86,16 @@ void MemoryBackingStoreTransaction::addExistingIndex(MemoryIndex& index)
     m_indexes.add(&index);
 }
 
+void MemoryBackingStoreTransaction::indexDeleted(std::unique_ptr<MemoryIndex> index)
+{
+    ASSERT(index);
+    m_indexes.remove(index.get());
+
+    auto addResult = m_deletedIndexes.add(index->info().name(), nullptr);
+    if (addResult.isNewEntry)
+        addResult.iterator->value = WTF::move(index);
+}
+
 void MemoryBackingStoreTransaction::addExistingObjectStore(MemoryObjectStore& objectStore)
 {
     LOG(IndexedDB, "MemoryBackingStoreTransaction::addExistingObjectStore");
@@ -170,7 +180,7 @@ void MemoryBackingStoreTransaction::abort()
 
     TemporaryChange<bool> change(m_isAborting, true);
 
-    // This loop moves the underlying unique_ptrs from out of the m_deleteObjectStores map,
+    // This loop moves the underlying unique_ptrs from out of the m_deletedObjectStores map,
     // but the entries in the map still remain.
     for (auto& objectStore : m_deletedObjectStores.values()) {
         MemoryObjectStore* rawObjectStore = objectStore.get();
@@ -214,6 +224,16 @@ void MemoryBackingStoreTransaction::abort()
         }
     }
 
+    // This loop moves the underlying unique_ptrs from out of the m_deletedIndexes map,
+    // but the entries in the map still remain.
+    for (auto& index : m_deletedIndexes.values()) {
+        MemoryObjectStore& objectStore = index->objectStore();
+        objectStore.maybeRestoreDeletedIndex(WTF::move(index));
+    }
+
+    // This clears the entries from the map.
+    m_deletedIndexes.clear();
+
     finish();
 
     for (auto objectStore : m_versionChangeAddedObjectStores)
index a28c362..4c2cf7e 100644 (file)
@@ -68,6 +68,7 @@ public:
 
     void addNewIndex(MemoryIndex&);
     void addExistingIndex(MemoryIndex&);
+    void indexDeleted(std::unique_ptr<MemoryIndex>);
 
     void abort();
     void commit();
index 9cb98c6..d8632b1 100644 (file)
@@ -201,6 +201,21 @@ IDBError MemoryIDBBackingStore::createIndex(const IDBResourceIdentifier& transac
     return objectStore->createIndex(*rawTransaction, info);
 }
 
+IDBError MemoryIDBBackingStore::deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    LOG(IndexedDB, "MemoryIDBBackingStore::deleteIndex");
+
+    auto rawTransaction = m_transactions.get(transactionIdentifier);
+    ASSERT(rawTransaction);
+    ASSERT(rawTransaction->isVersionChange());
+
+    auto* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
+    if (!objectStore)
+        return IDBError(IDBExceptionCode::ConstraintError);
+
+    return objectStore->deleteIndex(*rawTransaction, indexName);
+}
+
 void MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort(MemoryObjectStore& objectStore)
 {
     LOG(IndexedDB, "MemoryIDBBackingStore::removeObjectStoreForVersionChangeAbort");
index d17c7c3..0ec5743 100644 (file)
@@ -56,6 +56,7 @@ public:
     virtual IDBError deleteObjectStore(const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName) override final;
     virtual IDBError clearObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier) override final;
     virtual IDBError createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&) override final;
+    virtual IDBError deleteIndex(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& indexName) override final;
     virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) override final;
     virtual IDBError deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&) override final;
     virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) override final;
index 516651a..f80d91b 100644 (file)
@@ -93,6 +93,14 @@ void MemoryIndex::notifyCursorsOfAllRecordsChanged()
     ASSERT(m_cleanCursors.isEmpty());
 }
 
+void MemoryIndex::clearIndexValueStore()
+{
+    ASSERT(m_objectStore.writeTransaction());
+    ASSERT(m_objectStore.writeTransaction()->isAborting());
+
+    m_records = nullptr;
+}
+
 void MemoryIndex::replaceIndexValueStore(std::unique_ptr<IndexValueStore>&& valueStore)
 {
     ASSERT(m_objectStore.writeTransaction());
index a8924b1..f045bcc 100644 (file)
@@ -71,6 +71,7 @@ public:
     void removeRecord(const IDBKeyData&, const IndexKey&);
 
     void objectStoreCleared();
+    void clearIndexValueStore();
     void replaceIndexValueStore(std::unique_ptr<IndexValueStore>&&);
 
     MemoryIndexCursor* maybeOpenCursor(const IDBCursorInfo&);
index d5da53d..da35204 100644 (file)
@@ -102,6 +102,59 @@ IDBError MemoryObjectStore::createIndex(MemoryBackingStoreTransaction& transacti
     return { };
 }
 
+void MemoryObjectStore::maybeRestoreDeletedIndex(std::unique_ptr<MemoryIndex> index)
+{
+    LOG(IndexedDB, "MemoryObjectStore::maybeRestoreDeletedIndex");
+
+    ASSERT(index);
+
+    if (m_info.hasIndex(index->info().name()))
+        return;
+
+    m_info.addExistingIndex(index->info());
+
+    ASSERT(!m_indexesByIdentifier.contains(index->info().identifier()));
+    index->clearIndexValueStore();
+    auto error = populateIndexWithExistingRecords(*index);
+
+    // Since this index was installed in the object store before this transaction started,
+    // assuming things were in a valid state then, we should definitely be able to successfully
+    // repopulate the index with the object store's pre-transaction records.
+    ASSERT_UNUSED(error, error.isNull());
+
+    registerIndex(WTF::move(index));
+}
+
+std::unique_ptr<MemoryIndex> MemoryObjectStore::takeIndexByName(const String& name)
+{
+    auto rawIndex = m_indexesByName.take(name);
+    if (!rawIndex)
+        return nullptr;
+
+    auto index = m_indexesByIdentifier.take(rawIndex->info().identifier());
+    ASSERT(index);
+
+    return index;
+}
+
+IDBError MemoryObjectStore::deleteIndex(MemoryBackingStoreTransaction& transaction, const String& indexName)
+{
+    LOG(IndexedDB, "MemoryObjectStore::deleteIndex");
+
+    if (!m_writeTransaction || !m_writeTransaction->isVersionChange() || m_writeTransaction != &transaction)
+        return IDBError(IDBExceptionCode::ConstraintError);
+    
+    auto index = takeIndexByName(indexName);
+    ASSERT(index);
+    if (!index)
+        return IDBError(IDBExceptionCode::ConstraintError);
+
+    m_info.deleteIndex(indexName);
+    transaction.indexDeleted(WTF::move(index));
+
+    return { };
+}
+
 bool MemoryObjectStore::containsRecord(const IDBKeyData& key)
 {
     if (!m_keyValueStore)
index d58b772..b994660 100644 (file)
@@ -66,6 +66,8 @@ public:
     MemoryBackingStoreTransaction* writeTransaction() { return m_writeTransaction; }
 
     IDBError createIndex(MemoryBackingStoreTransaction&, const IDBIndexInfo&);
+    IDBError deleteIndex(MemoryBackingStoreTransaction&, const String& indexName);
+    void registerIndex(std::unique_ptr<MemoryIndex>&&);
 
     bool containsRecord(const IDBKeyData&);
     void deleteRecord(const IDBKeyData&);
@@ -91,6 +93,8 @@ public:
 
     MemoryIndex* indexForIdentifier(uint64_t);
 
+    void maybeRestoreDeletedIndex(std::unique_ptr<MemoryIndex>);
+
 private:
     MemoryObjectStore(const IDBObjectStoreInfo&);
 
@@ -103,6 +107,8 @@ private:
     void updateCursorsForPutRecord(std::set<IDBKeyData>::iterator);
     void updateCursorsForDeleteRecord(const IDBKeyData&);
 
+    std::unique_ptr<MemoryIndex> takeIndexByName(const String& name);
+
     IDBObjectStoreInfo m_info;
 
     MemoryBackingStoreTransaction* m_writeTransaction { nullptr };
@@ -111,7 +117,6 @@ private:
     std::unique_ptr<KeyValueMap> m_keyValueStore;
     std::unique_ptr<std::set<IDBKeyData>> m_orderedKeys;
 
-    void registerIndex(std::unique_ptr<MemoryIndex>&&);
     void unregisterIndex(MemoryIndex&);
     HashMap<uint64_t, std::unique_ptr<MemoryIndex>> m_indexesByIdentifier;
     HashMap<String, MemoryIndex*> m_indexesByName;
index 79318d2..b06dc0c 100644 (file)
@@ -373,6 +373,41 @@ void UniqueIDBDatabase::didPerformCreateIndex(uint64_t callbackIdentifier, const
     performErrorCallback(callbackIdentifier, error);
 }
 
+void UniqueIDBDatabase::deleteIndex(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& indexName, ErrorCallback callback)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex");
+
+    uint64_t callbackID = storeCallback(callback);
+    m_server.postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performDeleteIndex, callbackID, transaction.info().identifier(), objectStoreIdentifier, indexName));
+}
+
+void UniqueIDBDatabase::performDeleteIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    ASSERT(!isMainThread());
+    LOG(IndexedDB, "(db) UniqueIDBDatabase::performDeleteIndex");
+
+    ASSERT(m_backingStore);
+    m_backingStore->deleteIndex(transactionIdentifier, objectStoreIdentifier, indexName);
+
+    IDBError error;
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformDeleteIndex, callbackIdentifier, error, objectStoreIdentifier, indexName));
+}
+
+void UniqueIDBDatabase::didPerformDeleteIndex(uint64_t callbackIdentifier, const IDBError& error, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    ASSERT(isMainThread());
+    LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformDeleteIndex");
+
+    if (error.isNull()) {
+        auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier);
+        if (objectStoreInfo)
+            objectStoreInfo->deleteIndex(indexName);
+    }
+
+    performErrorCallback(callbackIdentifier, error);
+}
+
 void UniqueIDBDatabase::putOrAdd(const IDBRequestData& requestData, const IDBKeyData& keyData, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback)
 {
     ASSERT(isMainThread());
index acb471f..591ba70 100644 (file)
@@ -79,6 +79,7 @@ public:
     void deleteObjectStore(UniqueIDBDatabaseTransaction&, const String& objectStoreName, ErrorCallback);
     void clearObjectStore(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, ErrorCallback);
     void createIndex(UniqueIDBDatabaseTransaction&, const IDBIndexInfo&, ErrorCallback);
+    void deleteIndex(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String& indexName, ErrorCallback);
     void putOrAdd(const IDBRequestData&, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback);
     void getRecord(const IDBRequestData&, const IDBKeyRangeData&, GetResultCallback);
     void getCount(const IDBRequestData&, const IDBKeyRangeData&, CountCallback);
@@ -114,6 +115,7 @@ private:
     void performDeleteObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const String& objectStoreName);
     void performClearObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier);
     void performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&);
+    void performDeleteIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& indexName);
     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 IDBKeyRangeData&);
     void performGetIndexRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&);
@@ -129,6 +131,7 @@ private:
     void didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError&, const String& objectStoreName);
     void didPerformClearObjectStore(uint64_t callbackIdentifier, const IDBError&);
     void didPerformCreateIndex(uint64_t callbackIdentifier, const IDBError&, const IDBIndexInfo&);
+    void didPerformDeleteIndex(uint64_t callbackIdentifier, const IDBError&, uint64_t objectStoreIdentifier, const String& indexName);
     void didPerformPutOrAdd(uint64_t callbackIdentifier, const IDBError&, const IDBKeyData&);
     void didPerformGetRecord(uint64_t callbackIdentifier, const IDBError&, const IDBGetResult&);
     void didPerformGetCount(uint64_t callbackIdentifier, const IDBError&, uint64_t);
index dfe8a00..cc8a15b 100644 (file)
@@ -160,6 +160,13 @@ void UniqueIDBDatabaseConnection::didCreateIndex(const IDBResultData& resultData
     m_connectionToClient.didCreateIndex(resultData);
 }
 
+void UniqueIDBDatabaseConnection::didDeleteIndex(const IDBResultData& resultData)
+{
+    LOG(IndexedDB, "UniqueIDBDatabaseConnection::didDeleteIndex");
+
+    m_connectionToClient.didDeleteIndex(resultData);
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index 731408d..c5452d7 100644 (file)
@@ -70,6 +70,7 @@ public:
     void didDeleteObjectStore(const IDBResultData&);
     void didClearObjectStore(const IDBResultData&);
     void didCreateIndex(const IDBResultData&);
+    void didDeleteIndex(const IDBResultData&);
 
 private:
     UniqueIDBDatabaseConnection(UniqueIDBDatabase&, IDBConnectionToClient&);
index effb38c..b0b51e0 100644 (file)
@@ -163,6 +163,23 @@ void UniqueIDBDatabaseTransaction::createIndex(const IDBRequestData& requestData
     });
 }
 
+void UniqueIDBDatabaseTransaction::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteIndex");
+
+    ASSERT(isVersionChange());
+    ASSERT(m_transactionInfo.identifier() == requestData.transactionIdentifier());
+
+    RefPtr<UniqueIDBDatabaseTransaction> self(this);
+    m_databaseConnection->database().deleteIndex(*this, objectStoreIdentifier, indexName, [this, self, requestData](const IDBError& error) {
+        LOG(IndexedDB, "UniqueIDBDatabaseTransaction::createIndex (callback)");
+        if (error.isNull())
+            m_databaseConnection->didDeleteIndex(IDBResultData::deleteIndexSuccess(requestData.requestIdentifier()));
+        else
+            m_databaseConnection->didDeleteIndex(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 e1736d6..803929a 100644 (file)
@@ -70,6 +70,7 @@ public:
     void deleteObjectStore(const IDBRequestData&, const String& objectStoreName);
     void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier);
     void createIndex(const IDBRequestData&, const IDBIndexInfo&);
+    void deleteIndex(const IDBRequestData&, uint64_t objectStoreIdentifier, const String& indexName);
     void putOrAdd(const IDBRequestData&, const IDBKeyData&, const ThreadSafeDataBuffer& valueData, IndexedDB::ObjectStoreOverwriteMode);
     void getRecord(const IDBRequestData&, const IDBKeyRangeData&);
     void getCount(const IDBRequestData&, const IDBKeyRangeData&);
index cb169f0..ae4022b 100644 (file)
@@ -135,6 +135,17 @@ void IDBDatabaseInfo::deleteObjectStore(const String& objectStoreName)
     m_objectStoreMap.remove(info->identifier());
 }
 
+#ifndef NDEBUG
+String IDBDatabaseInfo::loggingString() const
+{
+    String top = makeString("Database: ", m_name, " version ", String::number(m_version), "\n");
+    for (auto objectStore : m_objectStoreMap.values())
+        top.append(makeString(objectStore.loggingString(1), "\n"));
+
+    return top; 
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index 203a693..b330345 100644 (file)
@@ -58,6 +58,10 @@ public:
 
     void deleteObjectStore(const String& objectStoreName);
 
+#ifndef NDEBUG
+    String loggingString() const;
+#endif
+
 private:
     IDBDatabaseInfo();
 
index 41cf9a9..e19a8f1 100644 (file)
@@ -49,6 +49,17 @@ IDBIndexInfo IDBIndexInfo::isolatedCopy() const
     return { m_identifier, m_objectStoreIdentifier, m_name.isolatedCopy(), m_keyPath.isolatedCopy(), m_unique, m_multiEntry };
 }
 
+#ifndef NDEBUG
+String IDBIndexInfo::loggingString(int indent) const
+{
+    String indentString;
+    for (int i = 0; i < indent; ++i)
+        indentString.append(" ");
+
+    return makeString(indentString, "Index: ", m_name, String::format(" (%" PRIu64 ") \n", m_identifier));
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index ed3f1a4..7fc56d2 100644 (file)
@@ -47,6 +47,10 @@ public:
     bool unique() const { return m_unique; }
     bool multiEntry() const { return m_multiEntry; }
 
+#ifndef NDEBUG
+    String loggingString(int indent = 0) const;
+#endif
+
 private:
     uint64_t m_identifier { 0 };
     uint64_t m_objectStoreIdentifier { 0 };
index 781a952..ff120d1 100644 (file)
@@ -69,6 +69,11 @@ bool IDBObjectStoreInfo::hasIndex(const String& name) const
     return false;
 }
 
+bool IDBObjectStoreInfo::hasIndex(uint64_t indexIdentifier) const
+{
+    return m_indexMap.contains(indexIdentifier);
+}
+
 IDBIndexInfo* IDBObjectStoreInfo::infoForExistingIndex(const String& name)
 {
     for (auto& index : m_indexMap.values()) {
@@ -99,6 +104,30 @@ Vector<String> IDBObjectStoreInfo::indexNames() const
     return names;
 }
 
+void IDBObjectStoreInfo::deleteIndex(const String& indexName)
+{
+    auto* info = infoForExistingIndex(indexName);
+    if (!info)
+        return;
+
+    m_indexMap.remove(info->identifier());
+}
+
+#ifndef NDEBUG
+String IDBObjectStoreInfo::loggingString(int indent) const
+{
+    String indentString;
+    for (int i = 0; i < indent; ++i)
+        indentString.append(" ");
+
+    String top = makeString(indentString, "Object store: ", m_name, String::format(" (%" PRIu64 ") \n", m_identifier));
+    for (auto index : m_indexMap.values())
+        top.append(makeString(index.loggingString(indent + 1), "\n"));
+
+    return top; 
+}
+#endif
+
 } // namespace WebCore
 
 #endif // ENABLE(INDEXED_DATABASE)
index 9404505..ffbd03e 100644 (file)
@@ -52,10 +52,17 @@ public:
     IDBIndexInfo createNewIndex(const String& name, const IDBKeyPath&, bool unique, bool multiEntry);
     void addExistingIndex(const IDBIndexInfo&);
     bool hasIndex(const String& name) const;
+    bool hasIndex(uint64_t indexIdentifier) const;
     IDBIndexInfo* infoForExistingIndex(const String& name);
 
     Vector<String> indexNames() const;
 
+    void deleteIndex(const String& indexName);
+
+#ifndef NDEBUG
+    String loggingString(int indent = 0) const;
+#endif
+
 private:
     uint64_t m_identifier { 0 };
     String m_name;
index c3d0716..2e3d6a0 100644 (file)
@@ -110,6 +110,11 @@ IDBResultData IDBResultData::createIndexSuccess(const IDBResourceIdentifier& req
     return { IDBResultType::CreateIndexSuccess, requestIdentifier };
 }
 
+IDBResultData IDBResultData::deleteIndexSuccess(const IDBResourceIdentifier& requestIdentifier)
+{
+    return { IDBResultType::DeleteIndexSuccess, requestIdentifier };
+}
+
 IDBResultData IDBResultData::putOrAddSuccess(const IDBResourceIdentifier& requestIdentifier, const IDBKeyData& resultKey)
 {
     IDBResultData result(IDBResultType::PutOrAddSuccess, requestIdentifier);
index 2ede7bc..141d3dd 100644 (file)
@@ -53,6 +53,7 @@ enum class IDBResultType {
     GetCountSuccess,
     DeleteRecordSuccess,
     CreateIndexSuccess,
+    DeleteIndexSuccess,
     OpenCursorSuccess,
     IterateCursorSuccess,
 };
@@ -71,6 +72,7 @@ public:
     static IDBResultData deleteObjectStoreSuccess(const IDBResourceIdentifier&);
     static IDBResultData clearObjectStoreSuccess(const IDBResourceIdentifier&);
     static IDBResultData createIndexSuccess(const IDBResourceIdentifier&);
+    static IDBResultData deleteIndexSuccess(const IDBResourceIdentifier&);
     static IDBResultData putOrAddSuccess(const IDBResourceIdentifier&, const IDBKeyData&);
     static IDBResultData getRecordSuccess(const IDBResourceIdentifier&, const IDBGetResult&);
     static IDBResultData getCountSuccess(const IDBResourceIdentifier&, uint64_t count);
index dbbc125..abe3f07 100644 (file)
@@ -152,6 +152,14 @@ void InProcessIDBServer::didCreateIndex(const IDBResultData& resultData)
     });
 }
 
+void InProcessIDBServer::didDeleteIndex(const IDBResultData& resultData)
+{
+    RefPtr<InProcessIDBServer> self(this);
+    RunLoop::current().dispatch([this, self, resultData] {
+        m_connectionToServer->didDeleteIndex(resultData);
+    });
+}
+
 void InProcessIDBServer::didPutOrAdd(const IDBResultData& resultData)
 {
     RefPtr<InProcessIDBServer> self(this);
@@ -240,11 +248,19 @@ void InProcessIDBServer::clearObjectStore(const IDBRequestData& requestData, uin
     });
 }
 
-void InProcessIDBServer::createIndex(const IDBRequestData& resultData, const IDBIndexInfo& info)
+void InProcessIDBServer::createIndex(const IDBRequestData& requestData, const IDBIndexInfo& info)
 {
     RefPtr<InProcessIDBServer> self(this);
-    RunLoop::current().dispatch([this, self, resultData, info] {
-        m_server->createIndex(resultData, info);
+    RunLoop::current().dispatch([this, self, requestData, info] {
+        m_server->createIndex(requestData, info);
+    });
+}
+
+void InProcessIDBServer::deleteIndex(const IDBRequestData& requestData, uint64_t objectStoreIdentifier, const String& indexName)
+{
+    RefPtr<InProcessIDBServer> self(this);
+    RunLoop::current().dispatch([this, self, requestData, objectStoreIdentifier, indexName] {
+        m_server->deleteIndex(requestData, objectStoreIdentifier, indexName);
     });
 }
 
index 7553e17..47d0906 100644 (file)
@@ -62,6 +62,7 @@ public:
     virtual void deleteObjectStore(const IDBRequestData&, const String& objectStoreName) override final;
     virtual void clearObjectStore(const IDBRequestData&, uint64_t objectStoreIdentifier) override final;
     virtual void createIndex(const IDBRequestData&, const IDBIndexInfo&) override final;
+    virtual void deleteIndex(const IDBRequestData&, uint64_t objectStoreIdentifier, const String& indexName) override final;
     virtual void putOrAdd(const IDBRequestData&, IDBKey*, SerializedScriptValue&, const IndexedDB::ObjectStoreOverwriteMode) override final;
     virtual void getRecord(const IDBRequestData&, const IDBKeyRangeData&) override final;
     virtual void getCount(const IDBRequestData&, const IDBKeyRangeData&) override final;
@@ -81,6 +82,7 @@ public:
     virtual void didDeleteObjectStore(const IDBResultData&) override final;
     virtual void didClearObjectStore(const IDBResultData&) override final;
     virtual void didCreateIndex(const IDBResultData&) override final;
+    virtual void didDeleteIndex(const IDBResultData&) override final;
     virtual void didPutOrAdd(const IDBResultData&) override final;
     virtual void didGetRecord(const IDBResultData&) override final;
     virtual void didGetCount(const IDBResultData&) override final;