IDB: Support IDBFactory.deleteDatabase()
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Feb 2014 19:55:25 +0000 (19:55 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 2 Feb 2014 19:55:25 +0000 (19:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=128060

Reviewed by Filip Pizlo and Maciej Stachowiak (filesystem parts also Tim Hatcher and Simon Fraser)

Source/WebCore:

* Modules/indexeddb/IDBDatabaseBackend.cpp:
(WebCore::IDBDatabaseBackend::deleteDatabaseAsync):

* Modules/indexeddb/IDBFactory.cpp:
(WebCore::IDBFactory::deleteDatabase):

Change factory-level deleteDatabase to take opening and main frame origins:
* Modules/indexeddb/IDBFactoryBackendInterface.h:
* Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp:
(WebCore::IDBFactoryBackendLevelDB::deleteDatabase):
* Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h:

* Modules/indexeddb/IDBServerConnection.h:
* Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:

* WebCore.exp.in:

Source/WebKit2:

* DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
(WebKit::DatabaseProcessIDBConnection::deleteDatabase):

* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::calculateAbsoluteDatabaseFilename): Central place to
  calculate the database filename.
(WebKit::UniqueIDBDatabase::unregisterConnection):
(WebKit::UniqueIDBDatabase::shutdown): Pass shutdown type along.
(WebKit::UniqueIDBDatabase::shutdownBackingStore): If this is a delete shutdown, delete the DB.
(WebKit::UniqueIDBDatabase::didShutdownBackingStore):
(WebKit::UniqueIDBDatabase::deleteDatabase):
(WebKit::UniqueIDBDatabase::postMainThreadTask): All some tasks to bypass the no-more-request restriction.
(WebKit::UniqueIDBDatabase::postDatabaseTask): Ditto.
* DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:

* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::~UniqueIDBDatabaseBackingStoreSQLite):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::getOrEstablishMetadata): Use
  calculateAbsoluteDatabaseFilename from UniqueIDBDatabase.

* WebProcess/Databases/IndexedDB/WebIDBFactoryBackend.cpp:
(WebKit::WebIDBFactoryBackend::open): Update logging channel.
(WebKit::WebIDBFactoryBackend::deleteDatabase): Implement.
* WebProcess/Databases/IndexedDB/WebIDBFactoryBackend.h:

* Shared/WebCrossThreadCopier.h:

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

17 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp
Source/WebCore/Modules/indexeddb/IDBFactory.cpp
Source/WebCore/Modules/indexeddb/IDBFactoryBackendInterface.h
Source/WebCore/Modules/indexeddb/IDBServerConnection.h
Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp
Source/WebCore/Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h
Source/WebCore/Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h
Source/WebCore/WebCore.exp.in
Source/WebKit2/ChangeLog
Source/WebKit2/DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp
Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.h
Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp
Source/WebKit2/Shared/WebCrossThreadCopier.h
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBFactoryBackend.cpp
Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBFactoryBackend.h

index b3c75af..9d32ee3 100644 (file)
@@ -1,3 +1,27 @@
+2014-02-02  Brady Eidson  <beidson@apple.com>
+
+        IDB: Support IDBFactory.deleteDatabase()
+        https://bugs.webkit.org/show_bug.cgi?id=128060
+
+        Reviewed by Filip Pizlo and Maciej Stachowiak (filesystem parts also Tim Hatcher and Simon Fraser)
+
+        * Modules/indexeddb/IDBDatabaseBackend.cpp:
+        (WebCore::IDBDatabaseBackend::deleteDatabaseAsync):
+
+        * Modules/indexeddb/IDBFactory.cpp:
+        (WebCore::IDBFactory::deleteDatabase):
+
+        Change factory-level deleteDatabase to take opening and main frame origins:
+        * Modules/indexeddb/IDBFactoryBackendInterface.h:
+        * Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.cpp:
+        (WebCore::IDBFactoryBackendLevelDB::deleteDatabase):
+        * Modules/indexeddb/leveldb/IDBFactoryBackendLevelDB.h:
+
+        * Modules/indexeddb/IDBServerConnection.h:
+        * Modules/indexeddb/leveldb/IDBServerConnectionLevelDB.h:
+
+        * WebCore.exp.in:
+
 2014-02-02  Zalan Bujtas  <zalan@apple.com>
 
         Subpixel rendering: Introduce device pixel snapping helper functions.
index 13ed9e5..999a167 100644 (file)
@@ -555,13 +555,13 @@ bool IDBDatabaseBackend::isDeleteDatabaseBlocked()
     return connectionCount();
 }
 
-void IDBDatabaseBackend::deleteDatabaseAsync(PassRefPtr<IDBCallbacks> callbacks)
+void IDBDatabaseBackend::deleteDatabaseAsync(PassRefPtr<IDBCallbacks> prpCallbacks)
 {
     ASSERT(!isDeleteDatabaseBlocked());
 
     RefPtr<IDBDatabaseBackend> self(this);
+    RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     m_serverConnection->deleteDatabase(m_metadata.name, [self, callbacks](bool success) {
-        ASSERT(self->m_deleteCallbacksWaitingCompletion.contains(callbacks));
         self->m_deleteCallbacksWaitingCompletion.remove(callbacks);
 
         // If this IDBDatabaseBackend was closed while waiting for deleteDatabase to complete, no point in performing any callbacks.
index 7c73d84..821ffc5 100644 (file)
@@ -161,7 +161,7 @@ PassRefPtr<IDBOpenDBRequest> IDBFactory::deleteDatabase(ScriptExecutionContext*
     }
 
     RefPtr<IDBOpenDBRequest> request = IDBOpenDBRequest::create(context, 0, 0, 0, IndexedDB::VersionNullness::Null);
-    m_backend->deleteDatabase(name, request, context->securityOrigin(), context, getIndexedDBDatabasePath(context));
+    m_backend->deleteDatabase(name, *context->securityOrigin(), *context->topOrigin(), request, context, getIndexedDBDatabasePath(context));
     return request;
 }
 
index 3c7c593..221e2c0 100644 (file)
@@ -61,7 +61,7 @@ public:
 
     virtual void getDatabaseNames(PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) = 0;
     virtual void open(const String& name, uint64_t version, int64_t transactionId, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin) = 0;
-    virtual void deleteDatabase(const String& name, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) = 0;
+    virtual void deleteDatabase(const String& name, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin, PassRefPtr<IDBCallbacks>, ScriptExecutionContext*, const String& dataDir) = 0;
 
     virtual void removeIDBDatabaseBackend(const String& uniqueIdentifier) = 0;
 
index 0c21b62..ea55168 100644 (file)
@@ -59,13 +59,11 @@ public:
 
     typedef std::function<void (bool success)> BoolCallbackFunction;
 
-    // Factory-level operations
-    virtual void deleteDatabase(const String& name, BoolCallbackFunction successCallback) = 0;
-
     // Database-level operations
     typedef std::function<void (const IDBDatabaseMetadata&, bool success)> GetIDBDatabaseMetadataFunction;
     virtual void getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction) = 0;
     virtual void close() = 0;
+    virtual void deleteDatabase(const String& name, BoolCallbackFunction successCallback) = 0;
 
     // Transaction-level operations
     virtual void openTransaction(int64_t transactionID, const HashSet<int64_t>& objectStoreIds, IndexedDB::TransactionMode, BoolCallbackFunction successCallback) = 0;
index 3541fa8..1f1caa8 100644 (file)
@@ -103,10 +103,10 @@ void IDBFactoryBackendLevelDB::getDatabaseNames(PassRefPtr<IDBCallbacks> callbac
     callbacks->onSuccess(databaseNames.release());
 }
 
-void IDBFactoryBackendLevelDB::deleteDatabase(const String& name, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<SecurityOrigin> securityOrigin, ScriptExecutionContext*, const String& dataDirectory)
+void IDBFactoryBackendLevelDB::deleteDatabase(const String& name, const SecurityOrigin& openingOrigin, const SecurityOrigin&, PassRefPtr<IDBCallbacks> callbacks, ScriptExecutionContext*, const String& dataDirectory)
 {
     LOG(StorageAPI, "IDBFactoryBackendLevelDB::deleteDatabase");
-    const String uniqueIdentifier = computeUniqueIdentifier(name, *securityOrigin);
+    const String uniqueIdentifier = computeUniqueIdentifier(name, openingOrigin);
 
     IDBDatabaseBackendMap::iterator it = m_databaseBackendMap.find(uniqueIdentifier);
     if (it != m_databaseBackendMap.end()) {
@@ -117,7 +117,7 @@ void IDBFactoryBackendLevelDB::deleteDatabase(const String& name, PassRefPtr<IDB
     }
 
     // FIXME: Everything from now on should be done on another thread.
-    RefPtr<IDBBackingStoreLevelDB> backingStore = openBackingStore(*securityOrigin, dataDirectory);
+    RefPtr<IDBBackingStoreLevelDB> backingStore = openBackingStore(openingOrigin, dataDirectory);
     if (!backingStore) {
         callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error opening backing store for indexedDB.deleteDatabase."));
         return;
index 0040460..d169bb0 100644 (file)
@@ -61,7 +61,7 @@ public:
     virtual void getDatabaseNames(PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) override final;
     virtual void open(const String& name, uint64_t version, int64_t transactionId, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin) override final;
 
-    virtual void deleteDatabase(const String& name, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String& dataDir) override final;
+    virtual void deleteDatabase(const String& name, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin, PassRefPtr<IDBCallbacks>, ScriptExecutionContext*, const String& dataDir) override final;
 
 protected:
     virtual PassRefPtr<IDBBackingStoreLevelDB> openBackingStore(const SecurityOrigin&, const String& dataDir);
index 69df779..dbc8c91 100644 (file)
@@ -48,12 +48,10 @@ public:
 
     virtual bool isClosed() override;
 
-    // Factory-level operations
-    virtual void deleteDatabase(const String& name, BoolCallbackFunction successCallback) override;
-
     // Database-level operations
     virtual void getOrEstablishIDBDatabaseMetadata(GetIDBDatabaseMetadataFunction) override;
     virtual void close() override;
+    virtual void deleteDatabase(const String& name, BoolCallbackFunction successCallback) override;
 
     // Transaction-level operations
     virtual void openTransaction(int64_t transactionID, const HashSet<int64_t>& objectStoreIds, IndexedDB::TransactionMode, BoolCallbackFunction successCallback) override;
index a7e2993..dfcaf55 100644 (file)
@@ -3103,6 +3103,7 @@ __ZN7WebCore10IDBKeyDataC1EPKNS_6IDBKeyE
 __ZN7WebCore10IDBKeyPathC1ERKN3WTF6StringE
 __ZN7WebCore10IDBKeyPathC1ERKN3WTF6VectorINS1_6StringELm0ENS1_15CrashOnOverflowEEE
 __ZN7WebCore10IDBKeyPath6decodeERNS_12KeyedDecoderERS0_
+__ZN7WebCore18IDBDatabaseBackend14deleteDatabaseEN3WTF10PassRefPtrINS_12IDBCallbacksEEE
 __ZN7WebCore18IDBDatabaseBackend14openConnectionEN3WTF10PassRefPtrINS_12IDBCallbacksEEENS2_INS_20IDBDatabaseCallbacksEEExy
 __ZN7WebCore18IDBDatabaseBackend6createERKN3WTF6StringES4_PNS_26IDBFactoryBackendInterfaceERNS_19IDBServerConnectionE
 __ZN7WebCore18IDBDatabaseBackendD1Ev
index c3937ab..fbe4477 100644 (file)
@@ -1,3 +1,37 @@
+2014-02-02  Brady Eidson  <beidson@apple.com>
+
+        IDB: Support IDBFactory.deleteDatabase()
+        https://bugs.webkit.org/show_bug.cgi?id=128060
+
+        Reviewed by Filip Pizlo and Maciej Stachowiak (filesystem parts also Tim Hatcher and Simon Fraser)
+
+        * DatabaseProcess/IndexedDB/DatabaseProcessIDBConnection.cpp:
+        (WebKit::DatabaseProcessIDBConnection::deleteDatabase):
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::calculateAbsoluteDatabaseFilename): Central place to
+          calculate the database filename.
+        (WebKit::UniqueIDBDatabase::unregisterConnection):
+        (WebKit::UniqueIDBDatabase::shutdown): Pass shutdown type along. 
+        (WebKit::UniqueIDBDatabase::shutdownBackingStore): If this is a delete shutdown, delete the DB.
+        (WebKit::UniqueIDBDatabase::didShutdownBackingStore): 
+        (WebKit::UniqueIDBDatabase::deleteDatabase):
+        (WebKit::UniqueIDBDatabase::postMainThreadTask): All some tasks to bypass the no-more-request restriction.
+        (WebKit::UniqueIDBDatabase::postDatabaseTask): Ditto.
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.h:
+
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::~UniqueIDBDatabaseBackingStoreSQLite):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::getOrEstablishMetadata): Use 
+          calculateAbsoluteDatabaseFilename from UniqueIDBDatabase.
+
+        * WebProcess/Databases/IndexedDB/WebIDBFactoryBackend.cpp:
+        (WebKit::WebIDBFactoryBackend::open): Update logging channel.
+        (WebKit::WebIDBFactoryBackend::deleteDatabase): Implement.
+        * WebProcess/Databases/IndexedDB/WebIDBFactoryBackend.h:
+
+        * Shared/WebCrossThreadCopier.h:
+
 2014-02-01  Darin Adler  <darin@apple.com>
 
         More characters -> deprecatedCharacters (based on more EWS complaints)
index 2dbfeef..7d84074 100644 (file)
@@ -81,10 +81,19 @@ void DatabaseProcessIDBConnection::getOrEstablishIDBDatabaseMetadata(uint64_t re
 
 void DatabaseProcessIDBConnection::deleteDatabase(uint64_t requestID, const String& databaseName)
 {
+    ASSERT(m_uniqueIDBDatabase);
+
     LOG(IDB, "DatabaseProcess deleteDatabase request ID %llu", requestID);
 
-    // FIXME: Implement
-    send(Messages::WebIDBServerConnection::DidDeleteDatabase(requestID, false));
+    if (databaseName != m_uniqueIDBDatabase->identifier().databaseName()) {
+        LOG_ERROR("Request to delete database name that doesn't match with this database connection's database name");
+        send(Messages::WebIDBServerConnection::DidDeleteDatabase(requestID, false));
+    }
+
+    RefPtr<DatabaseProcessIDBConnection> connection(this);
+    m_uniqueIDBDatabase->deleteDatabase([connection, requestID](bool success) {
+        connection->send(Messages::WebIDBServerConnection::DidDeleteDatabase(requestID, success));
+    });
 }
 
 void DatabaseProcessIDBConnection::openTransaction(uint64_t requestID, int64_t transactionID, const Vector<int64_t>& objectStoreIDs, uint64_t intMode)
index 429bce6..ff68583 100644 (file)
@@ -33,6 +33,7 @@
 #include "DataReference.h"
 #include "DatabaseProcess.h"
 #include "DatabaseProcessIDBConnection.h"
+#include "Logging.h"
 #include "UniqueIDBDatabaseBackingStoreSQLite.h"
 #include "WebCrossThreadCopier.h"
 #include <WebCore/FileSystem.h>
@@ -47,6 +48,11 @@ using namespace WebCore;
 
 namespace WebKit {
 
+String UniqueIDBDatabase::calculateAbsoluteDatabaseFilename(const String& absoluteDatabaseDirectory)
+{
+    return pathByAppendingComponent(absoluteDatabaseDirectory, "IndexedDB.sqlite3");
+}
+
 UniqueIDBDatabase::UniqueIDBDatabase(const UniqueIDBDatabaseIdentifier& identifier)
     : m_identifier(identifier)
     , m_acceptingNewRequests(true)
@@ -106,15 +112,18 @@ void UniqueIDBDatabase::unregisterConnection(DatabaseProcessIDBConnection& conne
     m_connections.remove(&connection);
 
     if (m_connections.isEmpty()) {
-        shutdown();
+        shutdown(UniqueIDBDatabaseShutdownType::NormalShutdown);
         DatabaseProcess::shared().removeUniqueIDBDatabase(*this);
     }
 }
 
-void UniqueIDBDatabase::shutdown()
+void UniqueIDBDatabase::shutdown(UniqueIDBDatabaseShutdownType type)
 {
     ASSERT(isMainThread());
 
+    if (!m_acceptingNewRequests)
+        return;
+
     m_acceptingNewRequests = false;
 
     {
@@ -135,28 +144,66 @@ void UniqueIDBDatabase::shutdown()
 
     for (const auto& it : m_pendingDatabaseTasks)
         it.value->requestAborted();
+
+    m_pendingMetadataRequests.clear();
+    m_pendingTransactionRequests.clear();
+    m_pendingDatabaseTasks.clear();
         
     // Balanced by an adoptRef in ::didShutdownBackingStore()
     ref();
 
-    DatabaseProcess::shared().queue().dispatch(bind(&UniqueIDBDatabase::shutdownBackingStore, this));
+    postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::shutdownBackingStore, type, absoluteDatabaseDirectory()), DatabaseTaskType::Shutdown);
 }
 
-void UniqueIDBDatabase::shutdownBackingStore()
+void UniqueIDBDatabase::shutdownBackingStore(UniqueIDBDatabaseShutdownType type, const String& databaseDirectory)
 {
     ASSERT(!isMainThread());
-    if (m_backingStore)
-        m_backingStore.clear();
 
-    RunLoop::main()->dispatch(bind(&UniqueIDBDatabase::didShutdownBackingStore, this));
+    m_backingStore.clear();
+
+    if (type == UniqueIDBDatabaseShutdownType::DeleteShutdown) {
+        String dbFilename = UniqueIDBDatabase::calculateAbsoluteDatabaseFilename(databaseDirectory);
+        LOG(IDB, "UniqueIDBDatabase::shutdownBackingStore deleting file '%s' on disk", dbFilename.utf8().data());
+        deleteFile(dbFilename);
+        deleteEmptyDirectory(databaseDirectory);
+    }
+
+    postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didShutdownBackingStore, type), DatabaseTaskType::Shutdown);
 }
 
-void UniqueIDBDatabase::didShutdownBackingStore()
+void UniqueIDBDatabase::didShutdownBackingStore(UniqueIDBDatabaseShutdownType type)
 {
     ASSERT(isMainThread());
 
     // Balanced by a ref in ::shutdown()
     RefPtr<UniqueIDBDatabase> protector(adoptRef(this));
+
+    if (m_pendingShutdownTask)
+        m_pendingShutdownTask->completeRequest(type);
+
+    m_pendingShutdownTask = nullptr;
+}
+
+void UniqueIDBDatabase::deleteDatabase(std::function<void(bool)> successCallback)
+{
+    if (!m_acceptingNewRequests) {
+        // Someone else has already shutdown this database, so we can't request a delete.
+        callOnMainThread([successCallback]() {
+            successCallback(false);
+        });
+        return;
+    }
+
+    RefPtr<UniqueIDBDatabase> protector(this);
+    m_pendingShutdownTask = AsyncRequestImpl<UniqueIDBDatabaseShutdownType>::create([this, protector, successCallback](UniqueIDBDatabaseShutdownType type) {
+        // If the shutdown just completed was a Delete shutdown then we succeeded.
+        // If not report failure instead of trying again.
+        successCallback(type == UniqueIDBDatabaseShutdownType::DeleteShutdown);
+    }, [this, protector, successCallback]() {
+        successCallback(false);
+    });
+
+    shutdown(UniqueIDBDatabaseShutdownType::DeleteShutdown);
 }
 
 void UniqueIDBDatabase::getOrEstablishIDBDatabaseMetadata(std::function<void(bool, const IDBDatabaseMetadata&)> completionCallback)
@@ -1013,11 +1060,11 @@ String UniqueIDBDatabase::absoluteDatabaseDirectory() const
     return DatabaseProcess::shared().absoluteIndexedDatabasePathFromDatabaseRelativePath(m_databaseRelativeDirectory);
 }
 
-void UniqueIDBDatabase::postMainThreadTask(std::unique_ptr<AsyncTask> task)
+void UniqueIDBDatabase::postMainThreadTask(std::unique_ptr<AsyncTask> task, DatabaseTaskType taskType)
 {
     ASSERT(!isMainThread());
 
-    if (!m_acceptingNewRequests)
+    if (!m_acceptingNewRequests && taskType == DatabaseTaskType::Normal)
         return;
 
     MutexLocker locker(m_mainThreadTaskMutex);
@@ -1050,11 +1097,11 @@ void UniqueIDBDatabase::performNextMainThreadTask()
     task->performTask();
 }
 
-void UniqueIDBDatabase::postDatabaseTask(std::unique_ptr<AsyncTask> task)
+void UniqueIDBDatabase::postDatabaseTask(std::unique_ptr<AsyncTask> task, DatabaseTaskType taskType)
 {
     ASSERT(isMainThread());
 
-    if (!m_acceptingNewRequests)
+    if (!m_acceptingNewRequests && taskType == DatabaseTaskType::Normal)
         return;
 
     MutexLocker locker(m_databaseTaskMutex);
index ee48e54..22b33f4 100644 (file)
@@ -55,6 +55,11 @@ class UniqueIDBDatabaseBackingStore;
 
 struct SecurityOriginData;
 
+enum class UniqueIDBDatabaseShutdownType {
+    NormalShutdown,
+    DeleteShutdown
+};
+
 class UniqueIDBDatabase : public ThreadSafeRefCounted<UniqueIDBDatabase> {
 public:
     static PassRefPtr<UniqueIDBDatabase> create(const UniqueIDBDatabaseIdentifier& identifier)
@@ -64,11 +69,15 @@ public:
 
     ~UniqueIDBDatabase();
 
+    static String calculateAbsoluteDatabaseFilename(const String& absoluteDatabaseDirectory);
+
     const UniqueIDBDatabaseIdentifier& identifier() const { return m_identifier; }
 
     void registerConnection(DatabaseProcessIDBConnection&);
     void unregisterConnection(DatabaseProcessIDBConnection&);
 
+    void deleteDatabase(std::function<void(bool)> successCallback);
+
     void getOrEstablishIDBDatabaseMetadata(std::function<void(bool, const WebCore::IDBDatabaseMetadata&)> completionCallback);
 
     void openTransaction(const IDBIdentifier& transactionIdentifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode, std::function<void(bool)> successCallback);
@@ -107,8 +116,13 @@ private:
 
     String absoluteDatabaseDirectory() const;
 
-    void postDatabaseTask(std::unique_ptr<AsyncTask>);
-    void shutdown();
+    enum class DatabaseTaskType {
+        Normal,
+        Shutdown
+    };
+    void postDatabaseTask(std::unique_ptr<AsyncTask>, DatabaseTaskType = DatabaseTaskType::Normal);
+
+    void shutdown(UniqueIDBDatabaseShutdownType);
 
     // Method that attempts to make legal filenames from all legal database names
     String filenameForDatabaseName() const;
@@ -123,7 +137,7 @@ private:
     
     // To be called from the database workqueue thread only
     void performNextDatabaseTask();
-    void postMainThreadTask(std::unique_ptr<AsyncTask>);
+    void postMainThreadTask(std::unique_ptr<AsyncTask>, DatabaseTaskType = DatabaseTaskType::Normal);
     void openBackingStoreAndReadMetadata(const UniqueIDBDatabaseIdentifier&, const String& databaseDirectory);
     void openBackingStoreTransaction(const IDBIdentifier& transactionIdentifier, const Vector<int64_t>& objectStoreIDs, WebCore::IndexedDB::TransactionMode);
     void beginBackingStoreTransaction(const IDBIdentifier&);
@@ -145,7 +159,7 @@ private:
     void countInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&);
     void deleteRangeInBackingStore(uint64_t requestID, const IDBIdentifier& transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRangeData&);
 
-    void shutdownBackingStore();
+    void shutdownBackingStore(UniqueIDBDatabaseShutdownType, const String& databaseDirectory);
 
     // Callbacks from the database workqueue thread, to be performed on the main thread only
     void performNextMainThreadTask();
@@ -165,7 +179,7 @@ private:
     void didCountInBackingStore(uint64_t requestID, int64_t count, uint32_t errorCode, const String& errorMessage);
     void didDeleteRangeInBackingStore(uint64_t requestID, uint32_t errorCode, const String& errorMessage);
 
-    void didShutdownBackingStore();
+    void didShutdownBackingStore(UniqueIDBDatabaseShutdownType);
     void didCompleteBoolRequest(uint64_t requestID, bool success);
 
     bool m_acceptingNewRequests;
@@ -173,6 +187,7 @@ private:
     Deque<RefPtr<AsyncRequest>> m_pendingMetadataRequests;
     HashMap<IDBIdentifier, RefPtr<AsyncRequest>> m_pendingTransactionRequests;
     HashMap<uint64_t, RefPtr<AsyncRequest>> m_pendingDatabaseTasks;
+    RefPtr<AsyncRequest> m_pendingShutdownTask;
 
     std::unique_ptr<WebCore::IDBDatabaseMetadata> m_metadata;
     bool m_didGetMetadataFromBackingStore;
index 60c0e6f..7bbfda1 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "ArgumentDecoder.h"
 #include "IDBSerialization.h"
+#include "Logging.h"
 #include "SQLiteIDBCursor.h"
 #include "SQLiteIDBTransaction.h"
 #include <WebCore/FileSystem.h>
@@ -67,6 +68,9 @@ UniqueIDBDatabaseBackingStoreSQLite::UniqueIDBDatabaseBackingStoreSQLite(const U
 UniqueIDBDatabaseBackingStoreSQLite::~UniqueIDBDatabaseBackingStoreSQLite()
 {
     ASSERT(!isMainThread());
+
+    m_transactions.clear();
+    m_sqliteDB = nullptr;
 }
 
 std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata()
@@ -294,7 +298,8 @@ std::unique_ptr<IDBDatabaseMetadata> UniqueIDBDatabaseBackingStoreSQLite::getOrE
 {
     ASSERT(!isMainThread());
 
-    String dbFilename = pathByAppendingComponent(m_absoluteDatabaseDirectory, "IndexedDB.sqlite3");
+    String dbFilename = UniqueIDBDatabase::calculateAbsoluteDatabaseFilename(m_absoluteDatabaseDirectory);
+
     m_sqliteDB = openSQLiteDatabaseAtPath(dbFilename);
     if (!m_sqliteDB)
         return nullptr;
index 7dc5e3d..9a2ab30 100644 (file)
@@ -34,6 +34,8 @@
 namespace WebKit {
 class IDBIdentifier;
 class UniqueIDBDatabaseIdentifier;
+
+enum class UniqueIDBDatabaseShutdownType;
 }
 
 namespace WTF {
@@ -50,6 +52,14 @@ template<> struct CrossThreadCopierBase<false, false, WebKit::IDBIdentifier> {
     static WebKit::IDBIdentifier copy(const WebKit::IDBIdentifier&);
 };
 
+
+template<> struct CrossThreadCopierBase<false, false, WebKit::UniqueIDBDatabaseShutdownType> {
+    static WebKit::UniqueIDBDatabaseShutdownType copy(const WebKit::UniqueIDBDatabaseShutdownType& type)
+    {
+        return type;
+    }
+};
+
 template<> struct CrossThreadCopierBase<false, false, Vector<char>> {
     static Vector<char> copy(const Vector<char>&);
 };
index 7be7cfb..a471130 100644 (file)
@@ -74,7 +74,7 @@ void WebIDBFactoryBackend::getDatabaseNames(PassRefPtr<IDBCallbacks>, PassRefPtr
 void WebIDBFactoryBackend::open(const String& databaseName, uint64_t version, int64_t transactionId, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBDatabaseCallbacks> databaseCallbacks, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin)
 {
     ASSERT(isMainThread());
-    LOG(StorageAPI, "WebIDBFactoryBackend::open");
+    LOG(IDB, "WebIDBFactoryBackend::open");
 
     String databaseIdentifier = uniqueDatabaseIdentifier(databaseName, openingOrigin, mainFrameOrigin);
     if (databaseIdentifier.isNull()) {
@@ -95,9 +95,30 @@ void WebIDBFactoryBackend::open(const String& databaseName, uint64_t version, in
     databaseBackend->openConnection(callbacks, databaseCallbacks, transactionId, version);
 }
 
-void WebIDBFactoryBackend::deleteDatabase(const String&, PassRefPtr<IDBCallbacks>, PassRefPtr<SecurityOrigin>, ScriptExecutionContext*, const String&)
+void WebIDBFactoryBackend::deleteDatabase(const String& databaseName, const SecurityOrigin& openingOrigin, const SecurityOrigin& mainFrameOrigin, PassRefPtr<IDBCallbacks> callbacks, ScriptExecutionContext*, const String&)
 {
-    notImplemented();
+    ASSERT(isMainThread());
+    LOG(IDB, "WebIDBFactoryBackend::deleteDatabase");
+
+    String databaseIdentifier = uniqueDatabaseIdentifier(databaseName, openingOrigin, mainFrameOrigin);
+    if (databaseIdentifier.isNull()) {
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::InvalidAccessError, "Document is not allowed to use Indexed Databases"));
+        return;
+    }
+
+    // If there's already a connection to the database, delete it directly.
+    IDBDatabaseBackendMap::iterator it = sharedDatabaseBackendMap().find(databaseIdentifier);
+    if (it != sharedDatabaseBackendMap().end()) {
+        it->value->deleteDatabase(callbacks);
+        return;
+    }
+
+    RefPtr<IDBServerConnection> serverConnection = WebIDBServerConnection::create(databaseName, openingOrigin, mainFrameOrigin);
+    RefPtr<IDBDatabaseBackend> databaseBackend = IDBDatabaseBackend::create(databaseName, databaseIdentifier, this, *serverConnection);
+
+    sharedDatabaseBackendMap().set(databaseIdentifier, databaseBackend.get());
+    databaseBackend->deleteDatabase(callbacks);
+    sharedDatabaseBackendMap().remove(databaseIdentifier);
 }
 
 void WebIDBFactoryBackend::removeIDBDatabaseBackend(const String& identifier)
index 4a11194..db3a98e 100644 (file)
@@ -41,7 +41,7 @@ public:
 
     virtual void getDatabaseNames(PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::SecurityOrigin>, WebCore::ScriptExecutionContext*, const String& dataDir) override;
     virtual void open(const String& name, uint64_t version, int64_t transactionId, PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::IDBDatabaseCallbacks>, const WebCore::SecurityOrigin& openingOrigin, const WebCore::SecurityOrigin& mainFrameOrigin) override;
-    virtual void deleteDatabase(const String& name, PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::SecurityOrigin>, WebCore::ScriptExecutionContext*, const String& dataDir) override;
+    virtual void deleteDatabase(const String& name, const WebCore::SecurityOrigin& openingOrigin, const WebCore::SecurityOrigin& mainFrameOrigin, PassRefPtr<WebCore::IDBCallbacks>, WebCore::ScriptExecutionContext*, const String& dataDir) override;
 
     virtual void removeIDBDatabaseBackend(const String& uniqueIdentifier) override;