https://bugs.webkit.org/show_bug.cgi?id=88467
Reviewed by Tony Chang.
Source/WebCore:
Define a new type (IDBDatabaseMetadata) that captures the "schema" of an
IDB database (name, version, properties of stores, properties of indexes).
Add a method for the front end to request this from the back end once up
front to avoid later calls (which may be slow IPC calls in ports). Implement
IDB spec logic that the metadata should be frozen for a particular IDBDatabase
connection, and only change within a version change transaction, and the spec's
funky requirement for aborted version change transactions.
Test: storage/indexeddb/metadata.html
* Modules/indexeddb/IDBDatabase.cpp:
(WebCore::IDBDatabase::IDBDatabase): Fetch metadata from back end when connection is created.
(WebCore::IDBDatabase::transactionCreated):
(WebCore::IDBDatabase::transactionFinished): Update metadata at the end of a transaction in
case it was rolled back.
(WebCore::IDBDatabase::objectStoreNames): Move implementation to front-end.
(WebCore):
(WebCore::IDBDatabase::createObjectStore): Update local copy of metadata.
(WebCore::IDBDatabase::deleteObjectStore): Update local copy of metadata.
* Modules/indexeddb/IDBDatabase.h:
(WebCore::IDBDatabase::name): Move implementation to front-end.
(WebCore::IDBDatabase::version): Move implementation to front-end.
(IDBDatabase):
(WebCore::IDBDatabase::metadata):
* Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
(WebCore::IDBDatabaseBackendImpl::metadata): Construct a metadata snapshot.
(WebCore):
* Modules/indexeddb/IDBDatabaseBackendImpl.h:
(IDBDatabaseBackendImpl):
* Modules/indexeddb/IDBDatabaseBackendInterface.h:
(WebCore):
(IDBDatabaseBackendInterface):
* Modules/indexeddb/IDBIndex.cpp: Store a copy of the metadata, which will never
change during the lifetime of the index.
(WebCore::IDBIndex::IDBIndex):
* Modules/indexeddb/IDBIndex.h:
(WebCore::IDBIndex::create):
(WebCore::IDBIndex::name): Move implementation to front-end.
(WebCore::IDBIndex::objectStore): Return RefPtr (unrelated tidying).
(WebCore::IDBIndex::keyPath): Move implementation to front-end.
(WebCore::IDBIndex::unique): Move implementation to front-end.
(WebCore::IDBIndex::multiEntry): Move implementation to front-end.
(IDBIndex):
* Modules/indexeddb/IDBIndexBackendImpl.cpp:
(WebCore::IDBIndexBackendImpl::metadata): Construct a metadata snapshot.
(WebCore):
* Modules/indexeddb/IDBIndexBackendImpl.h:
(IDBIndexBackendImpl):
* Modules/indexeddb/IDBMetadata.h: Added new structs.
(WebCore):
(WebCore::IDBDatabaseMetadata::IDBDatabaseMetadata):
(IDBDatabaseMetadata):
(WebCore::IDBObjectStoreMetadata::IDBObjectStoreMetadata):
(IDBObjectStoreMetadata):
(WebCore::IDBIndexMetadata::IDBIndexMetadata):
(IDBIndexMetadata):
* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::IDBObjectStore): Store a "live" copy of the metadata, and
and copy in case of an aborted version change transaction.
(WebCore::IDBObjectStore::indexNames): Move implementation to front-end.
(WebCore::IDBObjectStore::createIndex): Update metadata to include new index.
(WebCore::IDBObjectStore::index): Pass along metadata to instance constructor.
(WebCore::IDBObjectStore::deleteIndex): Delete index from metadata.
* Modules/indexeddb/IDBObjectStore.h:
(WebCore::IDBObjectStore::create):
(WebCore::IDBObjectStore::name): Move implementation to front-end.
(WebCore::IDBObjectStore::keyPath): Move implementation to front-end.
(WebCore::IDBObjectStore::transaction): Return RefPtr (unrelated tidying).
(WebCore::IDBObjectStore::autoIncrement): Move implementation to front-end.
(WebCore::IDBObjectStore::metadata): Allow copying the metadata, in case of abort.
(WebCore::IDBObjectStore::resetMetadata): Allow setting the metadata, in case of abort.
(IDBObjectStore):
* Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::metadata): Construct a metadata snapshot.
(WebCore):
* Modules/indexeddb/IDBObjectStoreBackendImpl.h:
(WebCore):
(IDBObjectStoreBackendImpl):
* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::objectStore): Pass along metadata to instance constructor.
(WebCore::IDBTransaction::objectStoreCreated): Track stores changed during transaction.
(WebCore::IDBTransaction::objectStoreDeleted):Track stores changed during transaction.
(WebCore::IDBTransaction::onAbort): Revert stores metadata potentially changed during transaction.
* Modules/indexeddb/IDBTransaction.h:
(IDBTransaction):
* WebCore.gypi:
Source/WebKit/chromium:
Add conversions to/from WebCore IDB metadata type and plumbing for routing the
IDBDatabaseBackendInterface::metadata() call through the public API..
* WebKit.gyp: New file added.
* public/WebIDBMetadata.h: Conversion functions.
(WebCore):
(WebIDBMetadata):
* src/IDBDatabaseBackendProxy.cpp: Plumbing.
(WebKit::IDBDatabaseBackendProxy::metadata):
(WebKit):
* src/IDBDatabaseBackendProxy.h: Plumbing.
(IDBDatabaseBackendProxy):
* src/WebIDBDatabaseImpl.cpp: Plumbing.
(WebKit::WebIDBDatabaseImpl::metadata):
(WebKit):
* src/WebIDBDatabaseImpl.h: Plumbing.
(WebKit):
(WebIDBDatabaseImpl):
* src/WebIDBMetadata.cpp: Added - conversion functions.
(WebKit):
(WebKit::WebIDBMetadata::WebIDBMetadata):
(WebKit::WebIDBMetadata::operator IDBDatabaseMetadata):
LayoutTests:
* storage/indexeddb/metadata-expected.txt: Added.
* storage/indexeddb/metadata.html: Added.
* storage/indexeddb/resources/metadata.js: Added.
(test):
(firstOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
(firstOpen.request.onsuccess.request.onsuccess):
(firstOpen.request.onsuccess):
(firstOpen):
(secondOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
(secondOpen.request.onsuccess.request.onsuccess):
(secondOpen.request.onsuccess):
(secondOpen):
(thirdOpen.request.onsuccess.request.onsuccess.trans.onabort):
(thirdOpen.request.onsuccess.request.onsuccess):
(thirdOpen.request.onsuccess):
(thirdOpen):
(fourthOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
(fourthOpen.request.onsuccess.request.onsuccess):
(fourthOpen.request.onsuccess):
(fourthOpen):
(checkState):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@121059
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-06-22 Joshua Bell <jsbell@chromium.org>
+
+ IndexedDB: Snapshot metadata in front end to avoid IPC round-trips
+ https://bugs.webkit.org/show_bug.cgi?id=88467
+
+ Reviewed by Tony Chang.
+
+ * storage/indexeddb/metadata-expected.txt: Added.
+ * storage/indexeddb/metadata.html: Added.
+ * storage/indexeddb/resources/metadata.js: Added.
+ (test):
+ (firstOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
+ (firstOpen.request.onsuccess.request.onsuccess):
+ (firstOpen.request.onsuccess):
+ (firstOpen):
+ (secondOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
+ (secondOpen.request.onsuccess.request.onsuccess):
+ (secondOpen.request.onsuccess):
+ (secondOpen):
+ (thirdOpen.request.onsuccess.request.onsuccess.trans.onabort):
+ (thirdOpen.request.onsuccess.request.onsuccess):
+ (thirdOpen.request.onsuccess):
+ (thirdOpen):
+ (fourthOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
+ (fourthOpen.request.onsuccess.request.onsuccess):
+ (fourthOpen.request.onsuccess):
+ (fourthOpen):
+ (checkState):
+
2012-06-22 Jon Lee <jonlee@apple.com>
editing/spelling/grammar-edit-word.html fails on WK2 bots
--- /dev/null
+Test IndexedDB database metadata mutation/snapshotting
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
+
+dbname = self.location.pathname
+request = indexedDB.deleteDatabase(dbname)
+
+firstOpen():
+request = indexedDB.open(dbname)
+connection1 = request.result
+request = connection1.setVersion('1')
+trans = request.result
+connection1store1 = connection1.createObjectStore('store1')
+connection1store1.createIndex('index1', 'path')
+PASS connection1.version is "1"
+PASS connection1.objectStoreNames.length is 1
+PASS connection1store1.indexNames.length is 1
+Connection's properties should be snapshotted on close
+connection1.close()
+
+secondOpen():
+request = indexedDB.open(dbname)
+connection2 = request.result
+request = connection2.setVersion('2')
+trans = request.result
+connection2.createObjectStore('store2')
+connection2store1 = trans.objectStore('store1')
+connection2store1.createIndex('index2', 'path')
+PASS connection2.version is "2"
+PASS connection2.objectStoreNames.length is 2
+PASS connection2store1.indexNames.length is 2
+Connection's properties should be snapshotted on close
+connection2.close()
+
+thirdOpen():
+request = indexedDB.open(dbname)
+connection3 = request.result
+request = connection3.setVersion('3')
+trans = request.result
+connection3.createObjectStore('store3')
+connection3store1 = trans.objectStore('store1')
+connection3store1.createIndex('index3', 'path')
+PASS connection3.version is "3"
+PASS connection3.objectStoreNames.length is 3
+PASS connection3store1.indexNames.length is 3
+Connection's properties should be reverted on abort
+trans.abort()
+Connection's properties should be snapshotted on close
+connection3.close()
+
+fourthOpen():
+request = indexedDB.open(dbname)
+connection4 = request.result
+request = connection4.setVersion('4')
+trans = request.result
+connection4.createObjectStore('store4')
+connection4store1 = trans.objectStore('store1')
+connection4store1.createIndex('index4', 'path')
+PASS connection4.version is "4"
+PASS connection4.objectStoreNames.length is 3
+PASS connection4store1.indexNames.length is 3
+Connection's properties should be snapshotted on close
+connection4.close()
+
+checkState():
+PASS connection1.version is "1"
+PASS connection1.objectStoreNames.length is 1
+PASS connection1store1.indexNames.length is 1
+
+PASS connection2.version is "2"
+PASS connection2.objectStoreNames.length is 2
+PASS connection2store1.indexNames.length is 2
+
+PASS connection3.version is "2"
+PASS connection3.objectStoreNames.length is 2
+PASS connection3store1.indexNames.length is 2
+
+PASS connection4.version is "4"
+PASS connection4.objectStoreNames.length is 3
+PASS connection4store1.indexNames.length is 3
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
--- /dev/null
+<html>
+<head>
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/shared.js"></script>
+</head>
+<body>
+<script src="resources/metadata.js"></script>
+<script src="../../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
--- /dev/null
+if (this.importScripts) {
+ importScripts('../../../fast/js/resources/js-test-pre.js');
+ importScripts('shared.js');
+}
+
+description("Test IndexedDB database metadata mutation/snapshotting");
+
+function test()
+{
+ removeVendorPrefixes();
+ evalAndLog("dbname = self.location.pathname");
+ evalAndLog("request = indexedDB.deleteDatabase(dbname)");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = firstOpen;
+}
+
+function firstOpen()
+{
+ debug("");
+ debug("firstOpen():");
+ evalAndLog("request = indexedDB.open(dbname)");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("connection1 = request.result");
+ evalAndLog("request = connection1.setVersion('1')");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("trans = request.result");
+ evalAndLog("connection1store1 = connection1.createObjectStore('store1')");
+ evalAndLog("connection1store1.createIndex('index1', 'path')");
+
+ shouldBeEqualToString("connection1.version", "1");
+ shouldBe("connection1.objectStoreNames.length", "1");
+ shouldBe("connection1store1.indexNames.length", "1");
+
+ trans.onabort = unexpectedAbortCallback;
+ trans.oncomplete = function() {
+ debug("Connection's properties should be snapshotted on close");
+ evalAndLog("connection1.close()");
+ secondOpen();
+ };
+ };
+ };
+}
+
+function secondOpen()
+{
+ debug("");
+ debug("secondOpen():");
+ evalAndLog("request = indexedDB.open(dbname)");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("connection2 = request.result");
+ evalAndLog("request = connection2.setVersion('2')");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("trans = request.result");
+ evalAndLog("connection2.createObjectStore('store2')");
+ evalAndLog("connection2store1 = trans.objectStore('store1')");
+ evalAndLog("connection2store1.createIndex('index2', 'path')");
+
+ shouldBeEqualToString("connection2.version", "2");
+ shouldBe("connection2.objectStoreNames.length", "2");
+ shouldBe("connection2store1.indexNames.length", "2");
+
+ trans.onabort = unexpectedAbortCallback;
+ trans.oncomplete = function() {
+ debug("Connection's properties should be snapshotted on close");
+ evalAndLog("connection2.close()");
+ thirdOpen();
+ };
+ };
+ };
+}
+
+function thirdOpen()
+{
+ debug("");
+ debug("thirdOpen():");
+ evalAndLog("request = indexedDB.open(dbname)");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("connection3 = request.result");
+ evalAndLog("request = connection3.setVersion('3')");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("trans = request.result");
+ evalAndLog("connection3.createObjectStore('store3')");
+ evalAndLog("connection3store1 = trans.objectStore('store1')");
+ evalAndLog("connection3store1.createIndex('index3', 'path')");
+
+ shouldBeEqualToString("connection3.version", "3");
+ shouldBe("connection3.objectStoreNames.length", "3");
+ shouldBe("connection3store1.indexNames.length", "3");
+
+ trans.oncomplete = unexpectedCompleteCallback;
+ trans.onabort = function() {
+ debug("Connection's properties should be snapshotted on close");
+ evalAndLog("connection3.close()");
+ fourthOpen();
+ };
+ debug("Connection's properties should be reverted on abort");
+ evalAndLog("trans.abort()");
+ };
+ };
+}
+
+function fourthOpen()
+{
+ debug("");
+ debug("fourthOpen():");
+ evalAndLog("request = indexedDB.open(dbname)");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("connection4 = request.result");
+ evalAndLog("request = connection4.setVersion('4')");
+ request.onerror = unexpectedErrorCallback;
+ request.onsuccess = function() {
+ evalAndLog("trans = request.result");
+ evalAndLog("connection4.createObjectStore('store4')");
+ evalAndLog("connection4store1 = trans.objectStore('store1')");
+ evalAndLog("connection4store1.createIndex('index4', 'path')");
+
+ shouldBeEqualToString("connection4.version", "4");
+ shouldBe("connection4.objectStoreNames.length", "3");
+ shouldBe("connection4store1.indexNames.length", "3");
+
+ trans.onabort = unexpectedAbortCallback;
+ trans.oncomplete = function() {
+ debug("Connection's properties should be snapshotted on close");
+ evalAndLog("connection4.close()");
+ checkState();
+ };
+ };
+ };
+}
+
+function checkState()
+{
+ debug("");
+ debug("checkState():");
+
+ shouldBeEqualToString("connection1.version", "1");
+ shouldBe("connection1.objectStoreNames.length", "1");
+ shouldBe("connection1store1.indexNames.length", "1");
+ debug("");
+
+ shouldBeEqualToString("connection2.version", "2");
+ shouldBe("connection2.objectStoreNames.length", "2");
+ shouldBe("connection2store1.indexNames.length", "2");
+ debug("");
+
+ shouldBeEqualToString("connection3.version", "2");
+ shouldBe("connection3.objectStoreNames.length", "2");
+ shouldBe("connection3store1.indexNames.length", "2");
+ debug("");
+
+ shouldBeEqualToString("connection4.version", "4");
+ shouldBe("connection4.objectStoreNames.length", "3");
+ shouldBe("connection4store1.indexNames.length", "3");
+ debug("");
+
+ finishJSTest();
+}
+
+test();
+2012-06-22 Joshua Bell <jsbell@chromium.org>
+
+ IndexedDB: Snapshot metadata in front end to avoid IPC round-trips
+ https://bugs.webkit.org/show_bug.cgi?id=88467
+
+ Reviewed by Tony Chang.
+
+ Define a new type (IDBDatabaseMetadata) that captures the "schema" of an
+ IDB database (name, version, properties of stores, properties of indexes).
+ Add a method for the front end to request this from the back end once up
+ front to avoid later calls (which may be slow IPC calls in ports). Implement
+ IDB spec logic that the metadata should be frozen for a particular IDBDatabase
+ connection, and only change within a version change transaction, and the spec's
+ funky requirement for aborted version change transactions.
+
+ Test: storage/indexeddb/metadata.html
+
+ * Modules/indexeddb/IDBDatabase.cpp:
+ (WebCore::IDBDatabase::IDBDatabase): Fetch metadata from back end when connection is created.
+ (WebCore::IDBDatabase::transactionCreated):
+ (WebCore::IDBDatabase::transactionFinished): Update metadata at the end of a transaction in
+ case it was rolled back.
+ (WebCore::IDBDatabase::objectStoreNames): Move implementation to front-end.
+ (WebCore):
+ (WebCore::IDBDatabase::createObjectStore): Update local copy of metadata.
+ (WebCore::IDBDatabase::deleteObjectStore): Update local copy of metadata.
+ * Modules/indexeddb/IDBDatabase.h:
+ (WebCore::IDBDatabase::name): Move implementation to front-end.
+ (WebCore::IDBDatabase::version): Move implementation to front-end.
+ (IDBDatabase):
+ (WebCore::IDBDatabase::metadata):
+ * Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
+ (WebCore::IDBDatabaseBackendImpl::metadata): Construct a metadata snapshot.
+ (WebCore):
+ * Modules/indexeddb/IDBDatabaseBackendImpl.h:
+ (IDBDatabaseBackendImpl):
+ * Modules/indexeddb/IDBDatabaseBackendInterface.h:
+ (WebCore):
+ (IDBDatabaseBackendInterface):
+ * Modules/indexeddb/IDBIndex.cpp: Store a copy of the metadata, which will never
+ change during the lifetime of the index.
+ (WebCore::IDBIndex::IDBIndex):
+ * Modules/indexeddb/IDBIndex.h:
+ (WebCore::IDBIndex::create):
+ (WebCore::IDBIndex::name): Move implementation to front-end.
+ (WebCore::IDBIndex::objectStore): Return RefPtr (unrelated tidying).
+ (WebCore::IDBIndex::keyPath): Move implementation to front-end.
+ (WebCore::IDBIndex::unique): Move implementation to front-end.
+ (WebCore::IDBIndex::multiEntry): Move implementation to front-end.
+ (IDBIndex):
+ * Modules/indexeddb/IDBIndexBackendImpl.cpp:
+ (WebCore::IDBIndexBackendImpl::metadata): Construct a metadata snapshot.
+ (WebCore):
+ * Modules/indexeddb/IDBIndexBackendImpl.h:
+ (IDBIndexBackendImpl):
+ * Modules/indexeddb/IDBMetadata.h: Added new structs.
+ (WebCore):
+ (WebCore::IDBDatabaseMetadata::IDBDatabaseMetadata):
+ (IDBDatabaseMetadata):
+ (WebCore::IDBObjectStoreMetadata::IDBObjectStoreMetadata):
+ (IDBObjectStoreMetadata):
+ (WebCore::IDBIndexMetadata::IDBIndexMetadata):
+ (IDBIndexMetadata):
+ * Modules/indexeddb/IDBObjectStore.cpp:
+ (WebCore::IDBObjectStore::IDBObjectStore): Store a "live" copy of the metadata, and
+ and copy in case of an aborted version change transaction.
+ (WebCore::IDBObjectStore::indexNames): Move implementation to front-end.
+ (WebCore::IDBObjectStore::createIndex): Update metadata to include new index.
+ (WebCore::IDBObjectStore::index): Pass along metadata to instance constructor.
+ (WebCore::IDBObjectStore::deleteIndex): Delete index from metadata.
+ * Modules/indexeddb/IDBObjectStore.h:
+ (WebCore::IDBObjectStore::create):
+ (WebCore::IDBObjectStore::name): Move implementation to front-end.
+ (WebCore::IDBObjectStore::keyPath): Move implementation to front-end.
+ (WebCore::IDBObjectStore::transaction): Return RefPtr (unrelated tidying).
+ (WebCore::IDBObjectStore::autoIncrement): Move implementation to front-end.
+ (WebCore::IDBObjectStore::metadata): Allow copying the metadata, in case of abort.
+ (WebCore::IDBObjectStore::resetMetadata): Allow setting the metadata, in case of abort.
+ (IDBObjectStore):
+ * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::IDBObjectStoreBackendImpl::metadata): Construct a metadata snapshot.
+ (WebCore):
+ * Modules/indexeddb/IDBObjectStoreBackendImpl.h:
+ (WebCore):
+ (IDBObjectStoreBackendImpl):
+ * Modules/indexeddb/IDBTransaction.cpp:
+ (WebCore::IDBTransaction::objectStore): Pass along metadata to instance constructor.
+ (WebCore::IDBTransaction::objectStoreCreated): Track stores changed during transaction.
+ (WebCore::IDBTransaction::objectStoreDeleted):Track stores changed during transaction.
+ (WebCore::IDBTransaction::onAbort): Revert stores metadata potentially changed during transaction.
+ * Modules/indexeddb/IDBTransaction.h:
+ (IDBTransaction):
+ * WebCore.gypi:
+
2012-06-20 Mark Hahnenberg <mhahnenberg@apple.com>
JSLock should be per-JSGlobalData
// We pass a reference of this object before it can be adopted.
relaxAdoptionRequirement();
m_databaseCallbacks = IDBDatabaseCallbacksImpl::create(this);
+ m_metadata = m_backend->metadata();
}
IDBDatabase::~IDBDatabase()
if (transaction->isVersionChange()) {
ASSERT(!m_versionChangeTransaction);
m_versionChangeTransaction = transaction;
+ m_metadata = m_backend->metadata();
}
}
if (transaction->isVersionChange()) {
ASSERT(m_versionChangeTransaction == transaction);
m_versionChangeTransaction = 0;
+ m_metadata = m_backend->metadata();
}
if (m_closePending && m_transactions.isEmpty())
closeConnection();
}
+PassRefPtr<DOMStringList> IDBDatabase::objectStoreNames() const
+{
+ RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
+ for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator it = m_metadata.objectStores.begin(); it != m_metadata.objectStores.end(); ++it)
+ objectStoreNames->append(it->first);
+ objectStoreNames->sort();
+ return objectStoreNames.release();
+}
+
PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec)
{
if (!m_versionChangeTransaction) {
return 0;
}
- RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(objectStoreBackend.release(), m_versionChangeTransaction.get());
+ IDBObjectStoreMetadata metadata(name, keyPath, autoIncrement);
+ RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, objectStoreBackend.release(), m_versionChangeTransaction.get());
+ m_metadata.objectStores.set(name, metadata);
+
m_versionChangeTransaction->objectStoreCreated(name, objectStore);
return objectStore.release();
}
}
m_backend->deleteObjectStore(name, m_versionChangeTransaction->backend(), ec);
- if (!ec)
+ if (!ec) {
m_versionChangeTransaction->objectStoreDeleted(name);
+ m_metadata.objectStores.remove(name);
+ }
}
PassRefPtr<IDBVersionChangeRequest> IDBDatabase::setVersion(ScriptExecutionContext* context, const String& version, ExceptionCode& ec)
#include "EventTarget.h"
#include "IDBDatabaseBackendInterface.h"
#include "IDBDatabaseCallbacksImpl.h"
+#include "IDBMetadata.h"
#include "IDBObjectStore.h"
#include "IDBTransaction.h"
#include <wtf/PassRefPtr.h>
void transactionFinished(IDBTransaction*);
// Implement the IDL
- String name() const { return m_backend->name(); }
- String version() const { return m_backend->version(); }
- PassRefPtr<DOMStringList> objectStoreNames() const { return m_backend->objectStoreNames(); }
+ const String name() const { return m_metadata.name; }
+ const String version() const { return m_metadata.version; }
+ PassRefPtr<DOMStringList> objectStoreNames() const;
// FIXME: Try to modify the code generator so this is unneeded.
PassRefPtr<IDBObjectStore> createObjectStore(const String& name, ExceptionCode& ec) { return createObjectStore(name, Dictionary(), ec); }
virtual ScriptExecutionContext* scriptExecutionContext() const;
void registerFrontendCallbacks();
+ const IDBDatabaseMetadata metadata() const { return m_metadata; }
void enqueueEvent(PassRefPtr<Event>);
bool dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) { return EventTarget::dispatchEvent(event, ec); }
virtual bool dispatchEvent(PassRefPtr<Event>);
void closeConnection();
+ IDBDatabaseMetadata m_metadata;
RefPtr<IDBDatabaseBackendInterface> m_backend;
RefPtr<IDBTransaction> m_versionChangeTransaction;
HashSet<IDBTransaction*> m_transactions;
return m_backingStore;
}
+IDBDatabaseMetadata IDBDatabaseBackendImpl::metadata() const
+{
+ IDBDatabaseMetadata metadata(m_name, m_version);
+ for (ObjectStoreMap::const_iterator it = m_objectStores.begin(); it != m_objectStores.end(); ++it)
+ metadata.objectStores.set(it->first, it->second->metadata());
+ return metadata;
+}
+
PassRefPtr<DOMStringList> IDBDatabaseBackendImpl::objectStoreNames() const
{
RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
void openConnection(PassRefPtr<IDBCallbacks>);
void deleteDatabase(PassRefPtr<IDBCallbacks>);
+ virtual IDBDatabaseMetadata metadata() const;
virtual String name() const { return m_name; }
virtual String version() const { return m_version; }
virtual PassRefPtr<DOMStringList> objectStoreNames() const;
class IDBKeyPath;
class IDBObjectStoreBackendInterface;
class IDBTransactionBackendInterface;
+struct IDBDatabaseMetadata;
typedef int ExceptionCode;
public:
virtual ~IDBDatabaseBackendInterface() { }
+ virtual IDBDatabaseMetadata metadata() const = 0;
virtual String name() const = 0;
virtual String version() const = 0;
virtual PassRefPtr<DOMStringList> objectStoreNames() const = 0;
static const unsigned short defaultDirection = IDBCursor::NEXT;
-IDBIndex::IDBIndex(PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
- : m_backend(backend)
+IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
+ : m_metadata(metadata)
+ , m_backend(backend)
, m_objectStore(objectStore)
, m_transaction(transaction)
, m_deleted(false)
#include "IDBIndexBackendInterface.h"
#include "IDBKeyPath.h"
#include "IDBKeyRange.h"
+#include "IDBMetadata.h"
+#include "IDBObjectStore.h"
#include "IDBRequest.h"
#include "PlatformString.h"
#include <wtf/Forward.h>
class IDBIndex : public RefCounted<IDBIndex> {
public:
- static PassRefPtr<IDBIndex> create(PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
+ static PassRefPtr<IDBIndex> create(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
{
- return adoptRef(new IDBIndex(backend, objectStore, transaction));
+ return adoptRef(new IDBIndex(metadata, backend, objectStore, transaction));
}
~IDBIndex();
// Implement the IDL
- String name() const { return m_backend->name(); }
- IDBObjectStore* objectStore() const { return m_objectStore.get(); }
- PassRefPtr<IDBAny> keyPath() const { return m_backend->keyPath(); }
- bool unique() const { return m_backend->unique(); }
- bool multiEntry() const { return m_backend->multiEntry(); }
+ const String name() const { return m_metadata.name; }
+ PassRefPtr<IDBObjectStore> objectStore() const { return m_objectStore; }
+ PassRefPtr<IDBAny> keyPath() const { return m_metadata.keyPath; }
+ bool unique() const { return m_metadata.unique; }
+ bool multiEntry() const { return m_metadata.multiEntry; }
// FIXME: Try to modify the code generator so this is unneeded.
PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, ExceptionCode& ec) { return openCursor(context, static_cast<IDBKeyRange*>(0), ec); }
void markDeleted() { m_deleted = true; }
private:
- IDBIndex(PassRefPtr<IDBIndexBackendInterface>, IDBObjectStore*, IDBTransaction*);
+ IDBIndex(const IDBIndexMetadata&, PassRefPtr<IDBIndexBackendInterface>, IDBObjectStore*, IDBTransaction*);
+ IDBIndexMetadata m_metadata;
RefPtr<IDBIndexBackendInterface> m_backend;
RefPtr<IDBObjectStore> m_objectStore;
RefPtr<IDBTransaction> m_transaction;
#include "IDBDatabaseException.h"
#include "IDBKey.h"
#include "IDBKeyRange.h"
+#include "IDBMetadata.h"
#include "IDBObjectStoreBackendImpl.h"
#include "IDBTracing.h"
{
}
+IDBIndexMetadata IDBIndexBackendImpl::metadata() const
+{
+ return IDBIndexMetadata(m_name, m_keyPath, m_unique, m_multiEntry);
+}
+
void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
{
IDB_TRACE("IDBIndexBackendImpl::openCursorInternal");
#include "IDBDatabaseBackendImpl.h"
#include "IDBIndexBackendInterface.h"
#include "IDBKeyPath.h"
+#include "IDBMetadata.h"
namespace WebCore {
bool addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey = 0);
// Implements IDBIndexBackendInterface.
+ virtual IDBIndexMetadata metadata() const;
virtual String name() { return m_name; }
virtual IDBKeyPath keyPath() { return m_keyPath; }
virtual bool unique() { return m_unique; }
--- /dev/null
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IDBMetadata_h
+#define IDBMetadata_h
+
+#include "IDBKeyPath.h"
+#include "PlatformString.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+namespace WebCore {
+
+struct IDBObjectStoreMetadata;
+struct IDBIndexMetadata;
+
+struct IDBDatabaseMetadata {
+ IDBDatabaseMetadata() { }
+ IDBDatabaseMetadata(const String& name, const String& version)
+ : name(name)
+ , version(version) { }
+ String name;
+ String version;
+
+ typedef HashMap<String, IDBObjectStoreMetadata> ObjectStoreMap;
+ ObjectStoreMap objectStores;
+};
+
+struct IDBObjectStoreMetadata {
+ IDBObjectStoreMetadata() { }
+ IDBObjectStoreMetadata(const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
+ : name(name)
+ , keyPath(keyPath)
+ , autoIncrement(autoIncrement) { }
+ String name;
+ IDBKeyPath keyPath;
+ bool autoIncrement;
+
+ typedef HashMap<String, IDBIndexMetadata> IndexMap;
+ IndexMap indexes;
+};
+
+struct IDBIndexMetadata {
+ IDBIndexMetadata() { }
+ IDBIndexMetadata(const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry)
+ : name(name)
+ , keyPath(keyPath)
+ , unique(unique)
+ , multiEntry(multiEntry) { }
+ String name;
+ IDBKeyPath keyPath;
+ bool unique;
+ bool multiEntry;
+};
+
+}
+
+#endif // ENABLE(INDEXED_DATABASE)
+
+#endif // IDBMetadata_h
#include "DOMStringList.h"
#include "IDBAny.h"
+#include "IDBDatabase.h"
#include "IDBDatabaseException.h"
#include "IDBIndex.h"
#include "IDBKey.h"
static const unsigned short defaultDirection = IDBCursor::NEXT;
-IDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
- : m_backend(idbObjectStore)
+IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
+ : m_metadata(metadata)
+ , m_backend(idbObjectStore)
, m_transaction(transaction)
, m_deleted(false)
{
relaxAdoptionRequirement();
}
-String IDBObjectStore::name() const
-{
- IDB_TRACE("IDBObjectStore::name");
- return m_backend->name();
-}
-
-PassRefPtr<IDBAny> IDBObjectStore::keyPath() const
-{
- IDB_TRACE("IDBObjectStore::keyPath");
- return m_backend->keyPath();
-}
-
PassRefPtr<DOMStringList> IDBObjectStore::indexNames() const
{
IDB_TRACE("IDBObjectStore::indexNames");
- return m_backend->indexNames();
-}
-
-IDBTransaction* IDBObjectStore::transaction() const
-{
- IDB_TRACE("IDBObjectStore::transaction");
- return m_transaction.get();
-}
-
-bool IDBObjectStore::autoIncrement() const
-{
- IDB_TRACE("IDBObjectStore::autoIncrement");
- return m_backend->autoIncrement();
+ RefPtr<DOMStringList> indexNames = DOMStringList::create();
+ for (IDBObjectStoreMetadata::IndexMap::const_iterator it = m_metadata.indexes.begin(); it != m_metadata.indexes.end(); ++it)
+ indexNames->append(it->first);
+ indexNames->sort();
+ return indexNames.release();
}
PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
if (ec)
return 0;
- RefPtr<IDBIndex> index = IDBIndex::create(indexBackend.release(), this, m_transaction.get());
+ IDBIndexMetadata metadata(name, keyPath, unique, multiEntry);
+ RefPtr<IDBIndex> index = IDBIndex::create(metadata, indexBackend.release(), this, m_transaction.get());
m_indexMap.set(name, index);
+ m_metadata.indexes.set(name, metadata);
return index.release();
}
if (ec)
return 0;
- RefPtr<IDBIndex> index = IDBIndex::create(indexBackend.release(), this, m_transaction.get());
+ IDBObjectStoreMetadata::IndexMap::const_iterator mdit = m_metadata.indexes.find(name);
+ ASSERT(mdit != m_metadata.indexes.end());
+
+ RefPtr<IDBIndex> index = IDBIndex::create(mdit->second, indexBackend.release(), this, m_transaction.get());
m_indexMap.set(name, index);
return index.release();
}
it->second->markDeleted();
m_indexMap.remove(name);
}
+
+ ASSERT(m_metadata.indexes.contains(name));
+ m_metadata.indexes.remove(name);
}
}
#include "IDBIndex.h"
#include "IDBKey.h"
#include "IDBKeyRange.h"
+#include "IDBMetadata.h"
#include "IDBObjectStoreBackendInterface.h"
#include "IDBRequest.h"
#include "IDBTransaction.h"
class IDBObjectStore : public RefCounted<IDBObjectStore> {
public:
- static PassRefPtr<IDBObjectStore> create(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
+ static PassRefPtr<IDBObjectStore> create(const IDBObjectStoreMetadata& metadata, PassRefPtr<IDBObjectStoreBackendInterface> backend, IDBTransaction* transaction)
{
- return adoptRef(new IDBObjectStore(idbObjectStore, transaction));
+ return adoptRef(new IDBObjectStore(metadata, backend, transaction));
}
~IDBObjectStore() { }
// Implement the IDBObjectStore IDL
- String name() const;
- PassRefPtr<IDBAny> keyPath() const;
+ const String name() const { return m_metadata.name; }
+ PassRefPtr<IDBAny> keyPath() const { return m_metadata.keyPath; }
PassRefPtr<DOMStringList> indexNames() const;
- IDBTransaction* transaction() const;
- bool autoIncrement() const;
+ PassRefPtr<IDBTransaction> transaction() const { return m_transaction; }
+ bool autoIncrement() const { return m_metadata.autoIncrement; }
PassRefPtr<IDBRequest> add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return add(context, value, 0, ec); }
PassRefPtr<IDBRequest> put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return put(context, value, 0, ec); }
void markDeleted() { m_deleted = true; }
void transactionFinished();
+ IDBObjectStoreMetadata metadata() const { return m_metadata; }
+ void setMetadata(const IDBObjectStoreMetadata& metadata) { m_metadata = metadata; }
+
private:
- IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*);
+ IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*);
void removeTransactionFromPendingList();
+ IDBObjectStoreMetadata m_metadata;
RefPtr<IDBObjectStoreBackendInterface> m_backend;
RefPtr<IDBTransaction> m_transaction;
bool m_deleted;
{
}
+IDBObjectStoreMetadata IDBObjectStoreBackendImpl::metadata() const
+{
+ IDBObjectStoreMetadata metadata(m_name, m_keyPath, m_autoIncrement);
+ for (IndexMap::const_iterator it = m_indexes.begin(); it != m_indexes.end(); ++it)
+ metadata.indexes.set(it->first, it->second->metadata());
+ return metadata;
+}
+
PassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const
{
RefPtr<DOMStringList> indexNames = DOMStringList::create();
#include "IDBDatabaseBackendImpl.h"
#include "IDBKeyPath.h"
+#include "IDBMetadata.h"
#include "IDBObjectStoreBackendInterface.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
class IDBIndexBackendImpl;
class IDBTransactionBackendInterface;
class ScriptExecutionContext;
+struct IDBObjectStoreMetadata;
class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface {
public:
}
void setId(int64_t id) { m_id = id; }
+ virtual IDBObjectStoreMetadata metadata() const;
virtual String name() const { return m_name; }
virtual IDBKeyPath keyPath() const { return m_keyPath; }
virtual PassRefPtr<DOMStringList> indexNames() const;
if (ec)
return 0;
- RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(objectStoreBackend, this);
+ const IDBDatabaseMetadata& metadata = m_database->metadata();
+ IDBDatabaseMetadata::ObjectStoreMap::const_iterator mdit = metadata.objectStores.find(name);
+ ASSERT(mdit != metadata.objectStores.end());
+
+ RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(mdit->second, objectStoreBackend, this);
objectStoreCreated(name, objectStore);
return objectStore.release();
}
-void IDBTransaction::objectStoreCreated(const String& name, PassRefPtr<IDBObjectStore> objectStore)
+void IDBTransaction::objectStoreCreated(const String& name, PassRefPtr<IDBObjectStore> prpObjectStore)
{
ASSERT(!m_transactionFinished);
+ RefPtr<IDBObjectStore> objectStore = prpObjectStore;
m_objectStoreMap.set(name, objectStore);
+ if (isVersionChange())
+ m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
}
void IDBTransaction::objectStoreDeleted(const String& name)
{
ASSERT(!m_transactionFinished);
+ ASSERT(isVersionChange());
IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
if (it != m_objectStoreMap.end()) {
RefPtr<IDBObjectStore> objectStore = it->second;
m_objectStoreMap.remove(name);
objectStore->markDeleted();
+ m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
}
}
request->abort();
}
+ if (isVersionChange()) {
+ for (IDBObjectStoreMetadataMap::iterator it = m_objectStoreCleanupMap.begin(); it != m_objectStoreCleanupMap.end(); ++it)
+ it->first->setMetadata(it->second);
+ }
+ m_objectStoreCleanupMap.clear();
closeOpenCursors();
m_database->transactionFinished(this);
void IDBTransaction::onComplete()
{
ASSERT(!m_transactionFinished);
+ m_objectStoreCleanupMap.clear();
closeOpenCursors();
m_database->transactionFinished(this);
#include "EventListener.h"
#include "EventNames.h"
#include "EventTarget.h"
+#include "IDBMetadata.h"
#include "IDBTransactionBackendInterface.h"
#include "IDBTransactionCallbacks.h"
#include <wtf/HashSet.h>
typedef HashMap<String, RefPtr<IDBObjectStore> > IDBObjectStoreMap;
IDBObjectStoreMap m_objectStoreMap;
+ typedef HashMap<RefPtr<IDBObjectStore>, IDBObjectStoreMetadata> IDBObjectStoreMetadataMap;
+ IDBObjectStoreMetadataMap m_objectStoreCleanupMap;
+
HashSet<IDBCursor*> m_openCursors;
EventTargetData m_eventTargetData;
'Modules/indexeddb/IDBLevelDBCoding.h',
'Modules/indexeddb/IDBLevelDBBackingStore.cpp',
'Modules/indexeddb/IDBLevelDBBackingStore.h',
+ 'Modules/indexeddb/IDBMetadata.h',
'Modules/indexeddb/IDBObjectStore.cpp',
'Modules/indexeddb/IDBObjectStore.h',
'Modules/indexeddb/IDBObjectStoreBackendImpl.cpp',
BCC5BDFE0C0E93110011C2DB /* JSCSSStyleSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSCSSStyleSheet.cpp; sourceTree = "<group>"; };
BCC5BDFF0C0E93110011C2DB /* JSCSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSCSSStyleSheet.h; sourceTree = "<group>"; };
BCC64F600DCFB84E0081EF3B /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = sourcecode.javascript; name = English; path = English.lproj/localizedStrings.js; sourceTree = SOURCE_ROOT; };
+ BCC65145159294C300ACC9E4 /* IDBMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IDBMetadata.h; path = Modules/indexeddb/IDBMetadata.h; sourceTree = "<group>"; };
BCC8CFCA0986CD2400140BF2 /* ColorData.gperf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ColorData.gperf; sourceTree = "<group>"; };
BCCBAD3A0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLCollectionCustom.cpp; sourceTree = "<group>"; };
BCCBAD3E0C18C14200CE890F /* JSHTMLCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLCollection.cpp; sourceTree = "<group>"; };
9712A58D15004EDA0048AF10 /* IDBLevelDBBackingStore.h */,
9712A58E15004EDA0048AF10 /* IDBLevelDBCoding.cpp */,
9712A58F15004EDA0048AF10 /* IDBLevelDBCoding.h */,
+ BCC65145159294C300ACC9E4 /* IDBMetadata.h */,
9712A59015004EDA0048AF10 /* IDBObjectStore.cpp */,
9712A59115004EDA0048AF10 /* IDBObjectStore.h */,
9712A59215004EDA0048AF10 /* IDBObjectStore.idl */,
+2012-06-22 Joshua Bell <jsbell@chromium.org>
+
+ IndexedDB: Snapshot metadata in front end to avoid IPC round-trips
+ https://bugs.webkit.org/show_bug.cgi?id=88467
+
+ Reviewed by Tony Chang.
+
+ Add conversions to/from WebCore IDB metadata type and plumbing for routing the
+ IDBDatabaseBackendInterface::metadata() call through the public API..
+
+ * WebKit.gyp: New file added.
+ * public/WebIDBMetadata.h: Conversion functions.
+ (WebCore):
+ (WebIDBMetadata):
+ * src/IDBDatabaseBackendProxy.cpp: Plumbing.
+ (WebKit::IDBDatabaseBackendProxy::metadata):
+ (WebKit):
+ * src/IDBDatabaseBackendProxy.h: Plumbing.
+ (IDBDatabaseBackendProxy):
+ * src/WebIDBDatabaseImpl.cpp: Plumbing.
+ (WebKit::WebIDBDatabaseImpl::metadata):
+ (WebKit):
+ * src/WebIDBDatabaseImpl.h: Plumbing.
+ (WebKit):
+ (WebIDBDatabaseImpl):
+ * src/WebIDBMetadata.cpp: Added - conversion functions.
+ (WebKit):
+ (WebKit::WebIDBMetadata::WebIDBMetadata):
+ (WebKit::WebIDBMetadata::operator IDBDatabaseMetadata):
+
2012-06-22 Fady Samuel <fsamuel@chromium.org>
[Chromium] Browser Plugin: Expose advanceFocus to WebKit API so that guests can advance focus of theirs embedders
'src/WebIDBKey.cpp',
'src/WebIDBKeyPath.cpp',
'src/WebIDBKeyRange.cpp',
+ 'src/WebIDBMetadata.cpp',
'src/WebIDBObjectStoreImpl.cpp',
'src/WebIDBObjectStoreImpl.h',
'src/WebIDBTransactionImpl.cpp',
#include "platform/WebString.h"
#include "platform/WebVector.h"
+namespace WebCore {
+struct IDBDatabaseMetadata;
+}
+
namespace WebKit {
struct WebIDBMetadata {
, unique(false)
, multiEntry(false) { }
};
+
+#if WEBKIT_IMPLEMENTATION
+ WebIDBMetadata(const WebCore::IDBDatabaseMetadata&);
+ operator WebCore::IDBDatabaseMetadata() const;
+#endif
};
#include "DOMStringList.h"
#include "IDBCallbacks.h"
#include "IDBDatabaseCallbacks.h"
+#include "IDBMetadata.h"
#include "IDBObjectStoreBackendProxy.h"
#include "IDBTransactionBackendProxy.h"
#include "WebDOMStringList.h"
{
}
+IDBDatabaseMetadata IDBDatabaseBackendProxy::metadata() const
+{
+ return m_webIDBDatabase->metadata();
+}
+
String IDBDatabaseBackendProxy::name() const
{
return m_webIDBDatabase->name();
static PassRefPtr<WebCore::IDBDatabaseBackendInterface> create(PassOwnPtr<WebIDBDatabase>);
virtual ~IDBDatabaseBackendProxy();
+ virtual WebCore::IDBDatabaseMetadata metadata() const;
virtual String name() const;
virtual String version() const;
virtual PassRefPtr<WebCore::DOMStringList> objectStoreNames() const;
#include "IDBCallbacksProxy.h"
#include "IDBDatabaseBackendInterface.h"
#include "IDBDatabaseCallbacksProxy.h"
+#include "IDBMetadata.h"
#include "IDBTransactionBackendInterface.h"
#include "WebIDBCallbacks.h"
#include "WebIDBDatabaseCallbacks.h"
+#include "WebIDBMetadata.h"
#include "WebIDBObjectStoreImpl.h"
#include "WebIDBTransactionImpl.h"
{
}
+WebIDBMetadata WebIDBDatabaseImpl::metadata() const
+{
+ return m_databaseBackend->metadata();
+}
+
WebString WebIDBDatabaseImpl::name() const
{
return m_databaseBackend->name();
class IDBDatabaseCallbacksProxy;
class WebIDBDatabaseCallbacks;
+class WebIDBDatabaseMetadata;
class WebIDBObjectStore;
class WebIDBTransaction;
WebIDBDatabaseImpl(WTF::PassRefPtr<WebCore::IDBDatabaseBackendInterface>);
virtual ~WebIDBDatabaseImpl();
+ virtual WebIDBMetadata metadata() const;
virtual WebString name() const;
virtual WebString version() const;
virtual WebDOMStringList objectStoreNames() const;
--- /dev/null
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebIDBMetadata.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBMetadata.h"
+#include "WebIDBKeyPath.h"
+#include "platform/WebString.h"
+#include "platform/WebVector.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebIDBMetadata::WebIDBMetadata(const WebCore::IDBDatabaseMetadata& metadata)
+{
+ name = metadata.name;
+ version = metadata.version;
+ objectStores = WebVector<ObjectStore>(static_cast<size_t>(metadata.objectStores.size()));
+
+ size_t i = 0;
+ for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator storeIterator = metadata.objectStores.begin(); storeIterator != metadata.objectStores.end(); ++storeIterator) {
+ const IDBObjectStoreMetadata& objectStore = storeIterator->second;
+ ObjectStore webObjectStore;
+ webObjectStore.name = objectStore.name;
+ webObjectStore.keyPath = objectStore.keyPath;
+ webObjectStore.autoIncrement = objectStore.autoIncrement;
+ webObjectStore.indexes = WebVector<Index>(static_cast<size_t>(objectStore.indexes.size()));
+
+ size_t j = 0;
+ for (IDBObjectStoreMetadata::IndexMap::const_iterator indexIterator = objectStore.indexes.begin(); indexIterator != objectStore.indexes.end(); ++indexIterator) {
+ const IDBIndexMetadata& index = indexIterator->second;
+ Index webIndex;
+ webIndex.name = index.name;
+ webIndex.keyPath = index.keyPath;
+ webIndex.unique = index.unique;
+ webIndex.multiEntry = index.multiEntry;
+ webObjectStore.indexes[j++] = webIndex;
+ }
+ objectStores[i++] = webObjectStore;
+ }
+}
+
+WebIDBMetadata::operator IDBDatabaseMetadata() const
+{
+ IDBDatabaseMetadata db(name, version);
+ for (size_t i = 0; i < objectStores.size(); ++i) {
+ const ObjectStore webObjectStore = objectStores[i];
+ IDBObjectStoreMetadata objectStore(webObjectStore.name, webObjectStore.keyPath, webObjectStore.autoIncrement);
+
+ for (size_t j = 0; j < webObjectStore.indexes.size(); ++j) {
+ const Index webIndex = webObjectStore.indexes[j];
+ IDBIndexMetadata index(webIndex.name, webIndex.keyPath, webIndex.unique, webIndex.multiEntry);
+ objectStore.indexes.set(index.name, index);
+ }
+ db.objectStores.set(objectStore.name, objectStore);
+ }
+ return db;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(INDEXED_DATABASE)