From 9ee97a6949ba20695939778230d77a3192a3e7dd Mon Sep 17 00:00:00 2001 From: "beidson@apple.com" Date: Fri, 24 Jan 2014 23:05:51 +0000 Subject: [PATCH] IDB: Support createIndex/deleteIndex and https://bugs.webkit.org/show_bug.cgi?id=127585 Reviewed by Tim Horton. * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp: (WebKit::UniqueIDBDatabase::createIndex): (WebKit::UniqueIDBDatabase::deleteIndex): (WebKit::UniqueIDBDatabase::createIndexInBackingStore): (WebKit::UniqueIDBDatabase::deleteIndexInBackingStore): * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h: * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp: (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore): Also drop all associated indexes. (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createIndex): (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex): * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h: git-svn-id: https://svn.webkit.org/repository/webkit/trunk@162727 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- Source/WebKit2/ChangeLog | 20 +++++ .../IndexedDB/UniqueIDBDatabase.cpp | 55 +++++++++--- .../IndexedDB/UniqueIDBDatabaseBackingStore.h | 2 + .../sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp | 98 +++++++++++++++++++++- .../sqlite/UniqueIDBDatabaseBackingStoreSQLite.h | 2 + 5 files changed, 163 insertions(+), 14 deletions(-) diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index 5807066..9eddd18 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,23 @@ +2014-01-24 Brady Eidson + + IDB: Support createIndex/deleteIndex + and https://bugs.webkit.org/show_bug.cgi?id=127585 + + Reviewed by Tim Horton. + + * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp: + (WebKit::UniqueIDBDatabase::createIndex): + (WebKit::UniqueIDBDatabase::deleteIndex): + (WebKit::UniqueIDBDatabase::createIndexInBackingStore): + (WebKit::UniqueIDBDatabase::deleteIndexInBackingStore): + + * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h: + * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp: + (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore): Also drop all associated indexes. + (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createIndex): + (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex): + * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h: + 2014-01-24 Víctor Manuel Jáquez Leal [GTK] youtube HTML5 videos in fullscreen, after , can't go fullscreen again diff --git a/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp b/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp index 1d4288e..eab13f8 100644 --- a/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp +++ b/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp @@ -433,7 +433,7 @@ void UniqueIDBDatabase::clearObjectStore(const IDBTransactionIdentifier& identif postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::clearObjectStoreInBackingStore, requestID, identifier, objectStoreID)); } -void UniqueIDBDatabase::createIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata& indexMetadata, std::function successCallback) +void UniqueIDBDatabase::createIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata& metadata, std::function successCallback) { ASSERT(isMainThread()); @@ -443,17 +443,28 @@ void UniqueIDBDatabase::createIndex(const IDBTransactionIdentifier& identifier, } ASSERT(m_metadata->objectStores.contains(objectStoreID)); - - RefPtr request = AsyncRequestImpl::create([this, successCallback](bool success) { + ASSERT(!m_metadata->objectStores.get(objectStoreID).indexes.contains(metadata.id)); + m_metadata->objectStores.get(objectStoreID).indexes.set(metadata.id, metadata); + int64_t addedIndexID = metadata.id; + + RefPtr request = AsyncRequestImpl::create([this, objectStoreID, addedIndexID, successCallback](bool success) { + if (!success) { + auto objectStoreFind = m_metadata->objectStores.find(objectStoreID); + if (objectStoreFind != m_metadata->objectStores.end()) + objectStoreFind->value.indexes.remove(addedIndexID); + } successCallback(success); - }, [this, successCallback]() { + }, [this, objectStoreID, addedIndexID, successCallback]() { + auto objectStoreFind = m_metadata->objectStores.find(objectStoreID); + if (objectStoreFind != m_metadata->objectStores.end()) + objectStoreFind->value.indexes.remove(addedIndexID); successCallback(false); }); uint64_t requestID = request->requestID(); m_pendingDatabaseTasks.add(requestID, request.release()); - postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::createIndexInBackingStore, requestID, identifier, objectStoreID, indexMetadata)); + postDatabaseTask(createAsyncTask(*this, &UniqueIDBDatabase::createIndexInBackingStore, requestID, identifier, objectStoreID, metadata)); } void UniqueIDBDatabase::deleteIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, int64_t indexID, std::function successCallback) @@ -468,9 +479,19 @@ void UniqueIDBDatabase::deleteIndex(const IDBTransactionIdentifier& identifier, ASSERT(m_metadata->objectStores.contains(objectStoreID)); ASSERT(m_metadata->objectStores.get(objectStoreID).indexes.contains(indexID)); - RefPtr request = AsyncRequestImpl::create([this, successCallback](bool success) { + IDBIndexMetadata metadata = m_metadata->objectStores.get(objectStoreID).indexes.take(indexID); + + RefPtr request = AsyncRequestImpl::create([this, objectStoreID, metadata, successCallback](bool success) { + if (!success) { + auto objectStoreFind = m_metadata->objectStores.find(objectStoreID); + if (objectStoreFind != m_metadata->objectStores.end()) + objectStoreFind->value.indexes.set(metadata.id, metadata); + } successCallback(success); - }, [this, successCallback]() { + }, [this, objectStoreID, metadata, successCallback]() { + auto objectStoreFind = m_metadata->objectStores.find(objectStoreID); + if (objectStoreFind != m_metadata->objectStores.end()) + objectStoreFind->value.indexes.set(metadata.id, metadata); successCallback(false); }); @@ -616,16 +637,24 @@ void UniqueIDBDatabase::clearObjectStoreInBackingStore(uint64_t requestID, const postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didClearObjectStore, requestID, success)); } -void UniqueIDBDatabase::createIndexInBackingStore(uint64_t requestID, const IDBTransactionIdentifier&, int64_t objectStoreID, const WebCore::IDBIndexMetadata&) +void UniqueIDBDatabase::createIndexInBackingStore(uint64_t requestID, const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata& metadata) { - // FIXME: Actually create in the backing store. - postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didCreateIndex, requestID, false)); + ASSERT(!isMainThread()); + ASSERT(m_backingStore); + + bool success = m_backingStore->createIndex(identifier, objectStoreID, metadata); + + postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didCreateIndex, requestID, success)); } -void UniqueIDBDatabase::deleteIndexInBackingStore(uint64_t requestID, const IDBTransactionIdentifier&, int64_t objectStoreID, int64_t indexID) +void UniqueIDBDatabase::deleteIndexInBackingStore(uint64_t requestID, const IDBTransactionIdentifier& identifier, int64_t objectStoreID, int64_t indexID) { - // FIXME: Actually delete from the backing store. - postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didDeleteIndex, requestID, false)); + ASSERT(!isMainThread()); + ASSERT(m_backingStore); + + bool success = m_backingStore->deleteIndex(identifier, objectStoreID, indexID); + + postMainThreadTask(createAsyncTask(*this, &UniqueIDBDatabase::didDeleteIndex, requestID, success)); } void UniqueIDBDatabase::putRecordInBackingStore(uint64_t requestID, const IDBTransactionIdentifier& transaction, const IDBObjectStoreMetadata& objectStoreMetadata, const IDBKeyData& keyData, const Vector& value, int64_t putMode, const Vector& indexIDs, const Vector>& indexKeys) diff --git a/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h b/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h index a313f07..673b456 100644 --- a/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h +++ b/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h @@ -60,6 +60,8 @@ public: virtual bool createObjectStore(const IDBTransactionIdentifier&, const WebCore::IDBObjectStoreMetadata&) = 0; virtual bool deleteObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID) = 0; virtual bool clearObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID) = 0; + virtual bool createIndex(const IDBTransactionIdentifier&, int64_t objectStoreID, const WebCore::IDBIndexMetadata&) = 0; + virtual bool deleteIndex(const IDBTransactionIdentifier&, int64_t objectStoreID, int64_t indexID) = 0; virtual PassRefPtr generateKey(const IDBTransactionIdentifier&, int64_t objectStoreID) = 0; virtual bool keyExistsInObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) = 0; diff --git a/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp b/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp index 5486b84..b6d93d9 100644 --- a/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp +++ b/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp @@ -413,6 +413,7 @@ bool UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore(const IDBTransaction return false; } + // Delete the ObjectStore record { SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM ObjectStoreInfo WHERE id = ?;")); if (sql.prepare() != SQLResultOk @@ -422,8 +423,34 @@ bool UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore(const IDBTransaction return false; } } + + // Delete all associated Index records { - // FIXME: Execute SQL here to drop all records and indexes related to this object store. + Vector indexIDs; + SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id FROM IndexInfo WHERE objectStoreID = ?;")); + if (sql.prepare() != SQLResultOk + || sql.bindInt64(1, objectStoreID) != SQLResultOk) { + LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg()); + return false; + } + + int resultCode; + while ((resultCode = sql.step()) == SQLResultRow) + indexIDs.append(sql.getColumnInt64(0)); + + if (resultCode != SQLResultDone) { + LOG_ERROR("Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg()); + return false; + } + + for (auto indexID : indexIDs) { + if (!deleteIndex(identifier, objectStoreID, indexID)) + return false; + } + } + + { + // FIXME: Execute SQL here to drop all records related to this object store. } return true; @@ -459,6 +486,75 @@ bool UniqueIDBDatabaseBackingStoreSQLite::clearObjectStore(const IDBTransactionI return true; } +bool UniqueIDBDatabaseBackingStoreSQLite::createIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, const WebCore::IDBIndexMetadata& metadata) +{ + ASSERT(!isMainThread()); + ASSERT(m_sqliteDB); + ASSERT(m_sqliteDB->isOpen()); + + SQLiteIDBTransaction* transaction = m_transactions.get(identifier); + if (!transaction || !transaction->inProgress()) { + LOG_ERROR("Attempt to create index without an established, in-progress transaction"); + return false; + } + if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) { + LOG_ERROR("Attempt to create index during a non-version-change transaction"); + return false; + } + + RefPtr keyPathBlob = serializeIDBKeyPath(metadata.keyPath); + if (!keyPathBlob) { + LOG_ERROR("Unable to serialize IDBKeyPath to save in database"); + return false; + } + + SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);")); + if (sql.prepare() != SQLResultOk + || sql.bindInt64(1, metadata.id) != SQLResultOk + || sql.bindText(2, metadata.name) != SQLResultOk + || sql.bindInt64(3, objectStoreID) != SQLResultOk + || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLResultOk + || sql.bindInt(5, metadata.unique) != SQLResultOk + || sql.bindInt(6, metadata.multiEntry) != SQLResultOk + || sql.step() != SQLResultDone) { + LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", metadata.name.utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg()); + return false; + } + + return true; +} + +bool UniqueIDBDatabaseBackingStoreSQLite::deleteIndex(const IDBTransactionIdentifier& identifier, int64_t objectStoreID, int64_t indexID) +{ + ASSERT(!isMainThread()); + ASSERT(m_sqliteDB); + ASSERT(m_sqliteDB->isOpen()); + + SQLiteIDBTransaction* transaction = m_transactions.get(identifier); + if (!transaction || !transaction->inProgress()) { + LOG_ERROR("Attempt to delete index without an established, in-progress transaction"); + return false; + } + if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) { + LOG_ERROR("Attempt to delete index during a non-version-change transaction"); + return false; + } + + { + SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;")); + if (sql.prepare() != SQLResultOk + || sql.bindInt64(1, indexID) != SQLResultOk + || sql.bindInt64(2, objectStoreID) != SQLResultOk + || sql.step() != SQLResultDone) { + LOG_ERROR("Could not delete index id %lli from IndexInfo table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg()); + return false; + } + } + + // FIXME () - Once we store records against indexes, delete them here. + return true; +} + PassRefPtr UniqueIDBDatabaseBackingStoreSQLite::generateKey(const IDBTransactionIdentifier&, int64_t objectStoreID) { // FIXME (): Implement diff --git a/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h b/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h index 222e24f..9d82b14 100644 --- a/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h +++ b/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h @@ -64,6 +64,8 @@ public: virtual bool createObjectStore(const IDBTransactionIdentifier&, const WebCore::IDBObjectStoreMetadata&) override; virtual bool deleteObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID) override; virtual bool clearObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID) override; + virtual bool createIndex(const IDBTransactionIdentifier&, int64_t objectStoreID, const WebCore::IDBIndexMetadata&) override; + virtual bool deleteIndex(const IDBTransactionIdentifier&, int64_t objectStoreID, int64_t indexID) override; virtual PassRefPtr generateKey(const IDBTransactionIdentifier&, int64_t objectStoreID) override; virtual bool keyExistsInObjectStore(const IDBTransactionIdentifier&, int64_t objectStoreID, const WebCore::IDBKey&, bool& keyExists) override; -- 1.8.3.1