Source/WebCore/ChangeLog

 12012-06-19 Joshua Bell <jsbell@chromium.org>
 2
 3 IndexedDB: Snapshot metadata in front end to avoid IPC round-trips
 4 https://bugs.webkit.org/show_bug.cgi?id=88467
 5
 6 Reviewed by Tony Chang.
 7
 8 Define a new type (IDBDatabaseMetadata) that captures the "schema" of an
 9 IDB database (name, version, properties of stores, properties of indexes).
 10 Add a method for the front end to request this from the back end once up
 11 front to avoid later calls (which may be slow IPC calls in ports). Implement
 12 IDB spec logic that the metadata should be frozen for a particular IDBDatabase
 13 connection, and only change within a version change transaction, and the spec's
 14 funky requirement for aborted version change transactions.
 15
 16 Test: storage/indexeddb/metadata.html
 17
 18 * Modules/indexeddb/IDBDatabase.cpp:
 19 (WebCore::IDBDatabase::IDBDatabase): Fetch metadata from back end when connection is created.
 20 (WebCore::IDBDatabase::transactionCreated):
 21 (WebCore::IDBDatabase::transactionFinished): Update metadata at the end of a transaction in
 22 case it was rolled back.
 23 (WebCore::IDBDatabase::objectStoreNames): Move implementation to front-end.
 24 (WebCore):
 25 (WebCore::IDBDatabase::createObjectStore): Update local copy of metadata.
 26 (WebCore::IDBDatabase::deleteObjectStore): Update local copy of metadata.
 27 * Modules/indexeddb/IDBDatabase.h:
 28 (WebCore::IDBDatabase::name): Move implementation to front-end.
 29 (WebCore::IDBDatabase::version): Move implementation to front-end.
 30 (IDBDatabase):
 31 (WebCore::IDBDatabase::metadata):
 32 * Modules/indexeddb/IDBDatabaseBackendImpl.cpp:
 33 (WebCore::IDBDatabaseBackendImpl::metadata): Construct a metadata snapshot.
 34 (WebCore):
 35 * Modules/indexeddb/IDBDatabaseBackendImpl.h:
 36 (IDBDatabaseBackendImpl):
 37 * Modules/indexeddb/IDBDatabaseBackendInterface.h:
 38 (WebCore):
 39 (IDBDatabaseBackendInterface):
 40 * Modules/indexeddb/IDBIndex.cpp: Store a copy of the metadata, which will never
 41 change during the lifetime of the index.
 42 (WebCore::IDBIndex::IDBIndex):
 43 * Modules/indexeddb/IDBIndex.h:
 44 (WebCore::IDBIndex::create):
 45 (WebCore::IDBIndex::name): Move implementation to front-end.
 46 (WebCore::IDBIndex::objectStore): Return RefPtr (unrelated tidying).
 47 (WebCore::IDBIndex::keyPath): Move implementation to front-end.
 48 (WebCore::IDBIndex::unique): Move implementation to front-end.
 49 (WebCore::IDBIndex::multiEntry): Move implementation to front-end.
 50 (IDBIndex):
 51 * Modules/indexeddb/IDBIndexBackendImpl.cpp:
 52 (WebCore::IDBIndexBackendImpl::metadata): Construct a metadata snapshot.
 53 (WebCore):
 54 * Modules/indexeddb/IDBIndexBackendImpl.h:
 55 (IDBIndexBackendImpl):
 56 * Modules/indexeddb/IDBMetadata.h: Added new structs.
 57 (WebCore):
 58 (WebCore::IDBDatabaseMetadata::IDBDatabaseMetadata):
 59 (IDBDatabaseMetadata):
 60 (WebCore::IDBObjectStoreMetadata::IDBObjectStoreMetadata):
 61 (IDBObjectStoreMetadata):
 62 (WebCore::IDBIndexMetadata::IDBIndexMetadata):
 63 (IDBIndexMetadata):
 64 * Modules/indexeddb/IDBObjectStore.cpp:
 65 (WebCore::IDBObjectStore::IDBObjectStore): Store a "live" copy of the metadata, and
 66 and copy in case of an aborted version change transaction.
 67 (WebCore::IDBObjectStore::indexNames): Move implementation to front-end.
 68 (WebCore::IDBObjectStore::createIndex): Update metadata to include new index.
 69 (WebCore::IDBObjectStore::index): Pass along metadata to instance constructor.
 70 (WebCore::IDBObjectStore::deleteIndex): Delete index from metadata.
 71 * Modules/indexeddb/IDBObjectStore.h:
 72 (WebCore::IDBObjectStore::create):
 73 (WebCore::IDBObjectStore::name): Move implementation to front-end.
 74 (WebCore::IDBObjectStore::keyPath): Move implementation to front-end.
 75 (WebCore::IDBObjectStore::transaction): Return RefPtr (unrelated tidying).
 76 (WebCore::IDBObjectStore::autoIncrement): Move implementation to front-end.
 77 (WebCore::IDBObjectStore::metadata): Allow copying the metadata, in case of abort.
 78 (WebCore::IDBObjectStore::resetMetadata): Allow setting the metadata, in case of abort.
 79 (IDBObjectStore):
 80 * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
 81 (WebCore::IDBObjectStoreBackendImpl::metadata): Construct a metadata snapshot.
 82 (WebCore):
 83 * Modules/indexeddb/IDBObjectStoreBackendImpl.h:
 84 (WebCore):
 85 (IDBObjectStoreBackendImpl):
 86 * Modules/indexeddb/IDBTransaction.cpp:
 87 (WebCore::IDBTransaction::objectStore): Pass along metadata to instance constructor.
 88 (WebCore::IDBTransaction::objectStoreCreated): Track stores changed during transaction.
 89 (WebCore::IDBTransaction::objectStoreDeleted):Track stores changed during transaction.
 90 (WebCore::IDBTransaction::onAbort): Revert stores metadata potentially changed during transaction.
 91 * Modules/indexeddb/IDBTransaction.h:
 92 (IDBTransaction):
 93 * WebCore.gypi:
 94
1952012-06-22 Amy Ousterhout <aousterh@chromium.org>
296
397 Renamed DeviceOrientation to DeviceOrientationData

Source/WebKit/chromium/ChangeLog

 12012-06-19 Joshua Bell <jsbell@chromium.org>
 2
 3 IndexedDB: Snapshot metadata in front end to avoid IPC round-trips
 4 https://bugs.webkit.org/show_bug.cgi?id=88467
 5
 6 Reviewed by Tony Chang.
 7
 8 Add conversions to/from WebCore IDB metadata type and plumbing for routing the
 9 IDBDatabaseBackendInterface::metadata() call through the public API..
 10
 11 * WebKit.gyp: New file added.
 12 * public/WebIDBMetadata.h: Conversion functions.
 13 (WebCore):
 14 (WebIDBMetadata):
 15 * src/IDBDatabaseBackendProxy.cpp: Plumbing.
 16 (WebKit::IDBDatabaseBackendProxy::metadata):
 17 (WebKit):
 18 * src/IDBDatabaseBackendProxy.h: Plumbing.
 19 (IDBDatabaseBackendProxy):
 20 * src/WebIDBDatabaseImpl.cpp: Plumbing.
 21 (WebKit::WebIDBDatabaseImpl::metadata):
 22 (WebKit):
 23 * src/WebIDBDatabaseImpl.h: Plumbing.
 24 (WebKit):
 25 (WebIDBDatabaseImpl):
 26 * src/WebIDBMetadata.cpp: Added - conversion functions.
 27 (WebKit):
 28 (WebKit::WebIDBMetadata::WebIDBMetadata):
 29 (WebKit::WebIDBMetadata::operator IDBDatabaseMetadata):
 30
1312012-06-22 Amy Ousterhout <aousterh@chromium.org>
232
333 Renamed DeviceOrientation to DeviceOrientationData

Source/WebCore/Modules/indexeddb/IDBDatabase.cpp

@@IDBDatabase::IDBDatabase(ScriptExecutionContext* context, PassRefPtr<IDBDatabase
6464 // We pass a reference of this object before it can be adopted.
6565 relaxAdoptionRequirement();
6666 m_databaseCallbacks = IDBDatabaseCallbacksImpl::create(this);
 67 m_metadata = m_backend->metadata();
6768}
6869
6970IDBDatabase::~IDBDatabase()

@@void IDBDatabase::transactionCreated(IDBTransaction* transaction)
8182 if (transaction->isVersionChange()) {
8283 ASSERT(!m_versionChangeTransaction);
8384 m_versionChangeTransaction = transaction;
 85 m_metadata = m_backend->metadata();
8486 }
8587}
8688

@@void IDBDatabase::transactionFinished(IDBTransaction* transaction)
9395 if (transaction->isVersionChange()) {
9496 ASSERT(m_versionChangeTransaction == transaction);
9597 m_versionChangeTransaction = 0;
 98 m_metadata = m_backend->metadata();
9699 }
97100
98101 if (m_closePending && m_transactions.isEmpty())
99102 closeConnection();
100103}
101104
 105PassRefPtr<DOMStringList> IDBDatabase::objectStoreNames() const
 106{
 107 RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();
 108 for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator it = m_metadata.objectStores.begin(); it != m_metadata.objectStores.end(); ++it)
 109 objectStoreNames->append(it->first);
 110 objectStoreNames->sort();
 111 return objectStoreNames.release();
 112}
 113
102114PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, const Dictionary& options, ExceptionCode& ec)
103115{
104116 if (!m_versionChangeTransaction) {

@@PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co
136148 return 0;
137149 }
138150
139  RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(objectStoreBackend.release(), m_versionChangeTransaction.get());
 151 IDBObjectStoreMetadata metadata(name, keyPath, autoIncrement);
 152 RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(metadata, objectStoreBackend.release(), m_versionChangeTransaction.get());
 153 m_metadata.objectStores.set(name, metadata);
 154
140155 m_versionChangeTransaction->objectStoreCreated(name, objectStore);
141156 return objectStore.release();
142157}

@@void IDBDatabase::deleteObjectStore(const String& name, ExceptionCode& ec)
149164 }
150165
151166 m_backend->deleteObjectStore(name, m_versionChangeTransaction->backend(), ec);
152  if (!ec)
 167 if (!ec) {
153168 m_versionChangeTransaction->objectStoreDeleted(name);
 169 m_metadata.objectStores.remove(name);
 170 }
154171}
155172
156173PassRefPtr<IDBVersionChangeRequest> IDBDatabase::setVersion(ScriptExecutionContext* context, const String& version, ExceptionCode& ec)

Source/WebCore/Modules/indexeddb/IDBDatabase.h

3333#include "EventTarget.h"
3434#include "IDBDatabaseBackendInterface.h"
3535#include "IDBDatabaseCallbacksImpl.h"
 36#include "IDBMetadata.h"
3637#include "IDBObjectStore.h"
3738#include "IDBTransaction.h"
3839#include <wtf/PassRefPtr.h>

@@public:
5758 void transactionFinished(IDBTransaction*);
5859
5960 // Implement the IDL
60  String name() const { return m_backend->name(); }
61  String version() const { return m_backend->version(); }
62  PassRefPtr<DOMStringList> objectStoreNames() const { return m_backend->objectStoreNames(); }
 61 const String name() const { return m_metadata.name; }
 62 const String version() const { return m_metadata.version; }
 63 PassRefPtr<DOMStringList> objectStoreNames() const;
6364
6465 // FIXME: Try to modify the code generator so this is unneeded.
6566 PassRefPtr<IDBObjectStore> createObjectStore(const String& name, ExceptionCode& ec) { return createObjectStore(name, Dictionary(), ec); }

@@public:
8788 virtual ScriptExecutionContext* scriptExecutionContext() const;
8889
8990 void registerFrontendCallbacks();
 91 const IDBDatabaseMetadata metadata() const { return m_metadata; }
9092 void enqueueEvent(PassRefPtr<Event>);
9193 bool dispatchEvent(PassRefPtr<Event> event, ExceptionCode& ec) { return EventTarget::dispatchEvent(event, ec); }
9294 virtual bool dispatchEvent(PassRefPtr<Event>);

@@private:
105107
106108 void closeConnection();
107109
 110 IDBDatabaseMetadata m_metadata;
108111 RefPtr<IDBDatabaseBackendInterface> m_backend;
109112 RefPtr<IDBTransaction> m_versionChangeTransaction;
110113 HashSet<IDBTransaction*> m_transactions;

Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp

@@PassRefPtr<IDBBackingStore> IDBDatabaseBackendImpl::backingStore() const
134134 return m_backingStore;
135135}
136136
 137IDBDatabaseMetadata IDBDatabaseBackendImpl::metadata() const
 138{
 139 IDBDatabaseMetadata metadata(m_name, m_version);
 140 for (ObjectStoreMap::const_iterator it = m_objectStores.begin(); it != m_objectStores.end(); ++it)
 141 metadata.objectStores.set(it->first, it->second->metadata());
 142 return metadata;
 143}
 144
137145PassRefPtr<DOMStringList> IDBDatabaseBackendImpl::objectStoreNames() const
138146{
139147 RefPtr<DOMStringList> objectStoreNames = DOMStringList::create();

Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h

@@public:
5858 void openConnection(PassRefPtr<IDBCallbacks>);
5959 void deleteDatabase(PassRefPtr<IDBCallbacks>);
6060
 61 virtual IDBDatabaseMetadata metadata() const;
6162 virtual String name() const { return m_name; }
6263 virtual String version() const { return m_version; }
6364 virtual PassRefPtr<DOMStringList> objectStoreNames() const;

Source/WebCore/Modules/indexeddb/IDBDatabaseBackendInterface.h

@@class IDBDatabaseCallbacks;
4141class IDBKeyPath;
4242class IDBObjectStoreBackendInterface;
4343class IDBTransactionBackendInterface;
 44struct IDBDatabaseMetadata;
4445
4546typedef int ExceptionCode;
4647

@@class IDBDatabaseBackendInterface : public ThreadSafeRefCounted<IDBDatabaseBacke
5253public:
5354 virtual ~IDBDatabaseBackendInterface() { }
5455
 56 virtual IDBDatabaseMetadata metadata() const = 0;
5557 virtual String name() const = 0;
5658 virtual String version() const = 0;
5759 virtual PassRefPtr<DOMStringList> objectStoreNames() const = 0;

Source/WebCore/Modules/indexeddb/IDBIndex.cpp

@@namespace WebCore {
4242
4343static const unsigned short defaultDirection = IDBCursor::NEXT;
4444
45 IDBIndex::IDBIndex(PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
46  : m_backend(backend)
 45IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
 46 : m_metadata(metadata)
 47 , m_backend(backend)
4748 , m_objectStore(objectStore)
4849 , m_transaction(transaction)
4950 , m_deleted(false)

Source/WebCore/Modules/indexeddb/IDBIndex.h

3030#include "IDBIndexBackendInterface.h"
3131#include "IDBKeyPath.h"
3232#include "IDBKeyRange.h"
 33#include "IDBMetadata.h"
 34#include "IDBObjectStore.h"
3335#include "IDBRequest.h"
3436#include "PlatformString.h"
3537#include <wtf/Forward.h>

@@class IDBObjectStore;
4244
4345class IDBIndex : public RefCounted<IDBIndex> {
4446public:
45  static PassRefPtr<IDBIndex> create(PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
 47 static PassRefPtr<IDBIndex> create(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
4648 {
47  return adoptRef(new IDBIndex(backend, objectStore, transaction));
 49 return adoptRef(new IDBIndex(metadata, backend, objectStore, transaction));
4850 }
4951 ~IDBIndex();
5052
5153 // Implement the IDL
52  String name() const { return m_backend->name(); }
53  IDBObjectStore* objectStore() const { return m_objectStore.get(); }
54  PassRefPtr<IDBAny> keyPath() const { return m_backend->keyPath(); }
55  bool unique() const { return m_backend->unique(); }
56  bool multiEntry() const { return m_backend->multiEntry(); }
 54 const String name() const { return m_metadata.name; }
 55 PassRefPtr<IDBObjectStore> objectStore() const { return m_objectStore; }
 56 PassRefPtr<IDBAny> keyPath() const { return m_metadata.keyPath; }
 57 bool unique() const { return m_metadata.unique; }
 58 bool multiEntry() const { return m_metadata.multiEntry; }
5759
5860 // FIXME: Try to modify the code generator so this is unneeded.
5961 PassRefPtr<IDBRequest> openCursor(ScriptExecutionContext* context, ExceptionCode& ec) { return openCursor(context, static_cast<IDBKeyRange*>(0), ec); }

@@public:
8385 void markDeleted() { m_deleted = true; }
8486
8587private:
86  IDBIndex(PassRefPtr<IDBIndexBackendInterface>, IDBObjectStore*, IDBTransaction*);
 88 IDBIndex(const IDBIndexMetadata&, PassRefPtr<IDBIndexBackendInterface>, IDBObjectStore*, IDBTransaction*);
8789
 90 IDBIndexMetadata m_metadata;
8891 RefPtr<IDBIndexBackendInterface> m_backend;
8992 RefPtr<IDBObjectStore> m_objectStore;
9093 RefPtr<IDBTransaction> m_transaction;

Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp

3636#include "IDBDatabaseException.h"
3737#include "IDBKey.h"
3838#include "IDBKeyRange.h"
 39#include "IDBMetadata.h"
3940#include "IDBObjectStoreBackendImpl.h"
4041#include "IDBTracing.h"
4142

@@IDBIndexBackendImpl::~IDBIndexBackendImpl()
6768{
6869}
6970
 71IDBIndexMetadata IDBIndexBackendImpl::metadata() const
 72{
 73 return IDBIndexMetadata(m_name, m_keyPath, m_unique, m_multiEntry);
 74}
 75
7076void IDBIndexBackendImpl::openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl> index, PassRefPtr<IDBKeyRange> range, unsigned short untypedDirection, IDBCursorBackendInterface::CursorType cursorType, PassRefPtr<IDBCallbacks> callbacks, PassRefPtr<IDBTransactionBackendInterface> transaction)
7177{
7278 IDB_TRACE("IDBIndexBackendImpl::openCursorInternal");

Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h

3232#include "IDBDatabaseBackendImpl.h"
3333#include "IDBIndexBackendInterface.h"
3434#include "IDBKeyPath.h"
 35#include "IDBMetadata.h"
3536
3637namespace WebCore {
3738

@@public:
6364 bool addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey = 0);
6465
6566 // Implements IDBIndexBackendInterface.
 67 virtual IDBIndexMetadata metadata() const;
6668 virtual String name() { return m_name; }
6769 virtual IDBKeyPath keyPath() { return m_keyPath; }
6870 virtual bool unique() { return m_unique; }

Source/WebCore/Modules/indexeddb/IDBMetadata.h

 1/*
 2 * Copyright (C) 2012 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 *
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 14 * its contributors may be used to endorse or promote products derived
 15 * from this software without specific prior written permission.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY GOOGLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 */
 28
 29#ifndef IDBMetadata_h
 30#define IDBMetadata_h
 31
 32#include "IDBKeyPath.h"
 33#include "PlatformString.h"
 34#include <wtf/HashMap.h>
 35#include <wtf/text/StringHash.h>
 36
 37#if ENABLE(INDEXED_DATABASE)
 38
 39namespace WebCore {
 40
 41struct IDBObjectStoreMetadata;
 42struct IDBIndexMetadata;
 43
 44struct IDBDatabaseMetadata {
 45 IDBDatabaseMetadata() { }
 46 IDBDatabaseMetadata(const String& name, const String& version)
 47 : name(name)
 48 , version(version) { }
 49 String name;
 50 String version;
 51
 52 typedef HashMap<String, IDBObjectStoreMetadata> ObjectStoreMap;
 53 ObjectStoreMap objectStores;
 54};
 55
 56struct IDBObjectStoreMetadata {
 57 IDBObjectStoreMetadata() { }
 58 IDBObjectStoreMetadata(const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
 59 : name(name)
 60 , keyPath(keyPath)
 61 , autoIncrement(autoIncrement) { }
 62 String name;
 63 IDBKeyPath keyPath;
 64 bool autoIncrement;
 65
 66 typedef HashMap<String, IDBIndexMetadata> IndexMap;
 67 IndexMap indexes;
 68};
 69
 70struct IDBIndexMetadata {
 71 IDBIndexMetadata() { }
 72 IDBIndexMetadata(const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry)
 73 : name(name)
 74 , keyPath(keyPath)
 75 , unique(unique)
 76 , multiEntry(multiEntry) { }
 77 String name;
 78 IDBKeyPath keyPath;
 79 bool unique;
 80 bool multiEntry;
 81};
 82
 83}
 84
 85#endif // ENABLE(INDEXED_DATABASE)
 86
 87#endif // IDBMetadata_h

Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp

3030
3131#include "DOMStringList.h"
3232#include "IDBAny.h"
 33#include "IDBDatabase.h"
3334#include "IDBDatabaseException.h"
3435#include "IDBIndex.h"
3536#include "IDBKey.h"

@@namespace WebCore {
4445
4546static const unsigned short defaultDirection = IDBCursor::NEXT;
4647
47 IDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
48  : m_backend(idbObjectStore)
 48IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
 49 : m_metadata(metadata)
 50 , m_backend(idbObjectStore)
4951 , m_transaction(transaction)
5052 , m_deleted(false)
5153{

@@IDBObjectStore::IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface> idbObj
5557 relaxAdoptionRequirement();
5658}
5759
58 String IDBObjectStore::name() const
59 {
60  IDB_TRACE("IDBObjectStore::name");
61  return m_backend->name();
62 }
63 
64 PassRefPtr<IDBAny> IDBObjectStore::keyPath() const
65 {
66  IDB_TRACE("IDBObjectStore::keyPath");
67  return m_backend->keyPath();
68 }
69 
7060PassRefPtr<DOMStringList> IDBObjectStore::indexNames() const
7161{
7262 IDB_TRACE("IDBObjectStore::indexNames");
73  return m_backend->indexNames();
74 }
75 
76 IDBTransaction* IDBObjectStore::transaction() const
77 {
78  IDB_TRACE("IDBObjectStore::transaction");
79  return m_transaction.get();
80 }
81 
82 bool IDBObjectStore::autoIncrement() const
83 {
84  IDB_TRACE("IDBObjectStore::autoIncrement");
85  return m_backend->autoIncrement();
 63 RefPtr<DOMStringList> indexNames = DOMStringList::create();
 64 for (IDBObjectStoreMetadata::IndexMap::const_iterator it = m_metadata.indexes.begin(); it != m_metadata.indexes.end(); ++it)
 65 indexNames->append(it->first);
 66 indexNames->sort();
 67 return indexNames.release();
8668}
8769
8870PassRefPtr<IDBRequest> IDBObjectStore::get(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)

@@PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKe
279261 if (ec)
280262 return 0;
281263
282  RefPtr<IDBIndex> index = IDBIndex::create(indexBackend.release(), this, m_transaction.get());
 264 IDBIndexMetadata metadata(name, keyPath, unique, multiEntry);
 265 RefPtr<IDBIndex> index = IDBIndex::create(metadata, indexBackend.release(), this, m_transaction.get());
283266 m_indexMap.set(name, index);
 267 m_metadata.indexes.set(name, metadata);
284268
285269 return index.release();
286270}

@@PassRefPtr<IDBIndex> IDBObjectStore::index(const String& name, ExceptionCode& ec
306290 if (ec)
307291 return 0;
308292
309  RefPtr<IDBIndex> index = IDBIndex::create(indexBackend.release(), this, m_transaction.get());
 293 IDBObjectStoreMetadata::IndexMap::const_iterator mdit = m_metadata.indexes.find(name);
 294 ASSERT(mdit != m_metadata.indexes.end());
 295
 296 RefPtr<IDBIndex> index = IDBIndex::create(mdit->second, indexBackend.release(), this, m_transaction.get());
310297 m_indexMap.set(name, index);
311298 return index.release();
312299}

@@void IDBObjectStore::deleteIndex(const String& name, ExceptionCode& ec)
325312 it->second->markDeleted();
326313 m_indexMap.remove(name);
327314 }
 315
 316 ASSERT(m_metadata.indexes.contains(name));
 317 m_metadata.indexes.remove(name);
328318 }
329319}
330320

Source/WebCore/Modules/indexeddb/IDBObjectStore.h

3131#include "IDBIndex.h"
3232#include "IDBKey.h"
3333#include "IDBKeyRange.h"
 34#include "IDBMetadata.h"
3435#include "IDBObjectStoreBackendInterface.h"
3536#include "IDBRequest.h"
3637#include "IDBTransaction.h"

@@class IDBAny;
4950
5051class IDBObjectStore : public RefCounted<IDBObjectStore> {
5152public:
52  static PassRefPtr<IDBObjectStore> create(PassRefPtr<IDBObjectStoreBackendInterface> idbObjectStore, IDBTransaction* transaction)
 53 static PassRefPtr<IDBObjectStore> create(const IDBObjectStoreMetadata& metadata, PassRefPtr<IDBObjectStoreBackendInterface> backend, IDBTransaction* transaction)
5354 {
54  return adoptRef(new IDBObjectStore(idbObjectStore, transaction));
 55 return adoptRef(new IDBObjectStore(metadata, backend, transaction));
5556 }
5657 ~IDBObjectStore() { }
5758
5859 // Implement the IDBObjectStore IDL
59  String name() const;
60  PassRefPtr<IDBAny> keyPath() const;
 60 const String name() const { return m_metadata.name; }
 61 PassRefPtr<IDBAny> keyPath() const { return m_metadata.keyPath; }
6162 PassRefPtr<DOMStringList> indexNames() const;
62  IDBTransaction* transaction() const;
63  bool autoIncrement() const;
 63 PassRefPtr<IDBTransaction> transaction() const { return m_transaction; }
 64 bool autoIncrement() const { return m_metadata.autoIncrement; }
6465
6566 PassRefPtr<IDBRequest> add(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return add(context, value, 0, ec); }
6667 PassRefPtr<IDBRequest> put(ScriptExecutionContext* context, PassRefPtr<SerializedScriptValue> value, ExceptionCode& ec) { return put(context, value, 0, ec); }

@@public:
9798 void markDeleted() { m_deleted = true; }
9899 void transactionFinished();
99100
 101 IDBObjectStoreMetadata metadata() const { return m_metadata; }
 102 void setMetadata(const IDBObjectStoreMetadata& metadata) { m_metadata = metadata; }
 103
100104private:
101  IDBObjectStore(PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*);
 105 IDBObjectStore(const IDBObjectStoreMetadata&, PassRefPtr<IDBObjectStoreBackendInterface>, IDBTransaction*);
102106 void removeTransactionFromPendingList();
103107
 108 IDBObjectStoreMetadata m_metadata;
104109 RefPtr<IDBObjectStoreBackendInterface> m_backend;
105110 RefPtr<IDBTransaction> m_transaction;
106111 bool m_deleted;

Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp

@@IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(const IDBDatabaseBackendImp
7272{
7373}
7474
 75IDBObjectStoreMetadata IDBObjectStoreBackendImpl::metadata() const
 76{
 77 IDBObjectStoreMetadata metadata(m_name, m_keyPath, m_autoIncrement);
 78 for (IndexMap::const_iterator it = m_indexes.begin(); it != m_indexes.end(); ++it)
 79 metadata.indexes.set(it->first, it->second->metadata());
 80 return metadata;
 81}
 82
7583PassRefPtr<DOMStringList> IDBObjectStoreBackendImpl::indexNames() const
7684{
7785 RefPtr<DOMStringList> indexNames = DOMStringList::create();

Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h

2828
2929#include "IDBDatabaseBackendImpl.h"
3030#include "IDBKeyPath.h"
 31#include "IDBMetadata.h"
3132#include "IDBObjectStoreBackendInterface.h"
3233#include <wtf/HashMap.h>
3334#include <wtf/text/StringHash.h>

@@class IDBDatabaseBackendImpl;
4041class IDBIndexBackendImpl;
4142class IDBTransactionBackendInterface;
4243class ScriptExecutionContext;
 44struct IDBObjectStoreMetadata;
4345
4446class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface {
4547public:

@@public:
6163 }
6264 void setId(int64_t id) { m_id = id; }
6365
 66 virtual IDBObjectStoreMetadata metadata() const;
6467 virtual String name() const { return m_name; }
6568 virtual IDBKeyPath keyPath() const { return m_keyPath; }
6669 virtual PassRefPtr<DOMStringList> indexNames() const;

Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

@@PassRefPtr<IDBObjectStore> IDBTransaction::objectStore(const String& name, Excep
158158 if (ec)
159159 return 0;
160160
161  RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(objectStoreBackend, this);
 161 const IDBDatabaseMetadata& metadata = m_database->metadata();
 162 IDBDatabaseMetadata::ObjectStoreMap::const_iterator mdit = metadata.objectStores.find(name);
 163 ASSERT(mdit != metadata.objectStores.end());
 164
 165 RefPtr<IDBObjectStore> objectStore = IDBObjectStore::create(mdit->second, objectStoreBackend, this);
162166 objectStoreCreated(name, objectStore);
163167 return objectStore.release();
164168}
165169
166 void IDBTransaction::objectStoreCreated(const String& name, PassRefPtr<IDBObjectStore> objectStore)
 170void IDBTransaction::objectStoreCreated(const String& name, PassRefPtr<IDBObjectStore> prpObjectStore)
167171{
168172 ASSERT(!m_transactionFinished);
 173 RefPtr<IDBObjectStore> objectStore = prpObjectStore;
169174 m_objectStoreMap.set(name, objectStore);
 175 if (isVersionChange())
 176 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
170177}
171178
172179void IDBTransaction::objectStoreDeleted(const String& name)
173180{
174181 ASSERT(!m_transactionFinished);
 182 ASSERT(isVersionChange());
175183 IDBObjectStoreMap::iterator it = m_objectStoreMap.find(name);
176184 if (it != m_objectStoreMap.end()) {
177185 RefPtr<IDBObjectStore> objectStore = it->second;
178186 m_objectStoreMap.remove(name);
179187 objectStore->markDeleted();
 188 m_objectStoreCleanupMap.set(objectStore, objectStore->metadata());
180189 }
181190}
182191

@@void IDBTransaction::onAbort()
239248 request->abort();
240249 }
241250
 251 if (isVersionChange()) {
 252 for (IDBObjectStoreMetadataMap::iterator it = m_objectStoreCleanupMap.begin(); it != m_objectStoreCleanupMap.end(); ++it)
 253 it->first->setMetadata(it->second);
 254 }
 255 m_objectStoreCleanupMap.clear();
242256 closeOpenCursors();
243257 m_database->transactionFinished(this);
244258

@@void IDBTransaction::onAbort()
251265void IDBTransaction::onComplete()
252266{
253267 ASSERT(!m_transactionFinished);
 268 m_objectStoreCleanupMap.clear();
254269 closeOpenCursors();
255270 m_database->transactionFinished(this);
256271

Source/WebCore/Modules/indexeddb/IDBTransaction.h

3535#include "EventListener.h"
3636#include "EventNames.h"
3737#include "EventTarget.h"
 38#include "IDBMetadata.h"
3839#include "IDBTransactionBackendInterface.h"
3940#include "IDBTransactionCallbacks.h"
4041#include <wtf/HashSet.h>

@@private:
143144 typedef HashMap<String, RefPtr<IDBObjectStore> > IDBObjectStoreMap;
144145 IDBObjectStoreMap m_objectStoreMap;
145146
 147 typedef HashMap<RefPtr<IDBObjectStore>, IDBObjectStoreMetadata> IDBObjectStoreMetadataMap;
 148 IDBObjectStoreMetadataMap m_objectStoreCleanupMap;
 149
146150 HashSet<IDBCursor*> m_openCursors;
147151
148152 EventTargetData m_eventTargetData;

Source/WebCore/WebCore.gypi

14921492 'Modules/indexeddb/IDBLevelDBCoding.h',
14931493 'Modules/indexeddb/IDBLevelDBBackingStore.cpp',
14941494 'Modules/indexeddb/IDBLevelDBBackingStore.h',
 1495 'Modules/indexeddb/IDBMetadata.h',
14951496 'Modules/indexeddb/IDBObjectStore.cpp',
14961497 'Modules/indexeddb/IDBObjectStore.h',
14971498 'Modules/indexeddb/IDBObjectStoreBackendImpl.cpp',

Source/WebCore/WebCore.xcodeproj/project.pbxproj

1275912759 BCC5BDFE0C0E93110011C2DB /* JSCSSStyleSheet.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSCSSStyleSheet.cpp; sourceTree = "<group>"; };
1276012760 BCC5BDFF0C0E93110011C2DB /* JSCSSStyleSheet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSCSSStyleSheet.h; sourceTree = "<group>"; };
1276112761 BCC64F600DCFB84E0081EF3B /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = sourcecode.javascript; name = English; path = English.lproj/localizedStrings.js; sourceTree = SOURCE_ROOT; };
 12762 BCC65145159294C300ACC9E4 /* IDBMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IDBMetadata.h; path = Modules/indexeddb/IDBMetadata.h; sourceTree = "<group>"; };
1276212763 BCC8CFCA0986CD2400140BF2 /* ColorData.gperf */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ColorData.gperf; sourceTree = "<group>"; };
1276312764 BCCBAD3A0C18BFF800CE890F /* JSHTMLCollectionCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLCollectionCustom.cpp; sourceTree = "<group>"; };
1276412765 BCCBAD3E0C18C14200CE890F /* JSHTMLCollection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLCollection.cpp; sourceTree = "<group>"; };

1757017571 9712A58D15004EDA0048AF10 /* IDBLevelDBBackingStore.h */,
1757117572 9712A58E15004EDA0048AF10 /* IDBLevelDBCoding.cpp */,
1757217573 9712A58F15004EDA0048AF10 /* IDBLevelDBCoding.h */,
 17574 BCC65145159294C300ACC9E4 /* IDBMetadata.h */,
1757317575 9712A59015004EDA0048AF10 /* IDBObjectStore.cpp */,
1757417576 9712A59115004EDA0048AF10 /* IDBObjectStore.h */,
1757517577 9712A59215004EDA0048AF10 /* IDBObjectStore.idl */,

Source/WebKit/chromium/WebKit.gyp

561561 'src/WebIDBKey.cpp',
562562 'src/WebIDBKeyPath.cpp',
563563 'src/WebIDBKeyRange.cpp',
 564 'src/WebIDBMetadata.cpp',
564565 'src/WebIDBObjectStoreImpl.cpp',
565566 'src/WebIDBObjectStoreImpl.h',
566567 'src/WebIDBTransactionImpl.cpp',

Source/WebKit/chromium/public/WebIDBMetadata.h

3131#include "platform/WebString.h"
3232#include "platform/WebVector.h"
3333
 34namespace WebCore {
 35struct IDBDatabaseMetadata;
 36}
 37
3438namespace WebKit {
3539
3640struct WebIDBMetadata {

@@struct WebIDBMetadata {
6266 , unique(false)
6367 , multiEntry(false) { }
6468 };
 69
 70#if WEBKIT_IMPLEMENTATION
 71 WebIDBMetadata(const WebCore::IDBDatabaseMetadata&);
 72 operator WebCore::IDBDatabaseMetadata() const;
 73#endif
6574};
6675
6776

Source/WebKit/chromium/src/IDBDatabaseBackendProxy.cpp

3131#include "DOMStringList.h"
3232#include "IDBCallbacks.h"
3333#include "IDBDatabaseCallbacks.h"
 34#include "IDBMetadata.h"
3435#include "IDBObjectStoreBackendProxy.h"
3536#include "IDBTransactionBackendProxy.h"
3637#include "WebDOMStringList.h"

@@IDBDatabaseBackendProxy::~IDBDatabaseBackendProxy()
6061{
6162}
6263
 64IDBDatabaseMetadata IDBDatabaseBackendProxy::metadata() const
 65{
 66 return m_webIDBDatabase->metadata();
 67}
 68
6369String IDBDatabaseBackendProxy::name() const
6470{
6571 return m_webIDBDatabase->name();

Source/WebKit/chromium/src/IDBDatabaseBackendProxy.h

@@public:
4242 static PassRefPtr<WebCore::IDBDatabaseBackendInterface> create(PassOwnPtr<WebIDBDatabase>);
4343 virtual ~IDBDatabaseBackendProxy();
4444
 45 virtual WebCore::IDBDatabaseMetadata metadata() const;
4546 virtual String name() const;
4647 virtual String version() const;
4748 virtual PassRefPtr<WebCore::DOMStringList> objectStoreNames() const;

Source/WebKit/chromium/src/WebIDBDatabaseImpl.cpp

3232#include "IDBCallbacksProxy.h"
3333#include "IDBDatabaseBackendInterface.h"
3434#include "IDBDatabaseCallbacksProxy.h"
 35#include "IDBMetadata.h"
3536#include "IDBTransactionBackendInterface.h"
3637#include "WebIDBCallbacks.h"
3738#include "WebIDBDatabaseCallbacks.h"
 39#include "WebIDBMetadata.h"
3840#include "WebIDBObjectStoreImpl.h"
3941#include "WebIDBTransactionImpl.h"
4042

@@WebIDBDatabaseImpl::~WebIDBDatabaseImpl()
5153{
5254}
5355
 56WebIDBMetadata WebIDBDatabaseImpl::metadata() const
 57{
 58 return m_databaseBackend->metadata();
 59}
 60
5461WebString WebIDBDatabaseImpl::name() const
5562{
5663 return m_databaseBackend->name();

Source/WebKit/chromium/src/WebIDBDatabaseImpl.h

@@namespace WebKit {
4040
4141class IDBDatabaseCallbacksProxy;
4242class WebIDBDatabaseCallbacks;
 43class WebIDBDatabaseMetadata;
4344class WebIDBObjectStore;
4445class WebIDBTransaction;
4546

@@public:
4950 WebIDBDatabaseImpl(WTF::PassRefPtr<WebCore::IDBDatabaseBackendInterface>);
5051 virtual ~WebIDBDatabaseImpl();
5152
 53 virtual WebIDBMetadata metadata() const;
5254 virtual WebString name() const;
5355 virtual WebString version() const;
5456 virtual WebDOMStringList objectStoreNames() const;

Source/WebKit/chromium/src/WebIDBMetadata.cpp

 1/*
 2 * Copyright (C) 2012 Google Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 *
 8 * 1. Redistributions of source code must retain the above copyright
 9 * notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 * notice, this list of conditions and the following disclaimer in the
 12 * documentation and/or other materials provided with the distribution.
 13 *
 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "WebIDBMetadata.h"
 28
 29#if ENABLE(INDEXED_DATABASE)
 30
 31#include "IDBMetadata.h"
 32#include "WebIDBKeyPath.h"
 33#include "platform/WebString.h"
 34#include "platform/WebVector.h"
 35
 36using namespace WebCore;
 37
 38namespace WebKit {
 39
 40WebIDBMetadata::WebIDBMetadata(const WebCore::IDBDatabaseMetadata& metadata)
 41{
 42 name = metadata.name;
 43 version = metadata.version;
 44 objectStores = WebVector<ObjectStore>(static_cast<size_t>(metadata.objectStores.size()));
 45
 46 size_t i = 0;
 47 for (IDBDatabaseMetadata::ObjectStoreMap::const_iterator storeIterator = metadata.objectStores.begin(); storeIterator != metadata.objectStores.end(); ++storeIterator) {
 48 const IDBObjectStoreMetadata& objectStore = storeIterator->second;
 49 ObjectStore webObjectStore;
 50 webObjectStore.name = objectStore.name;
 51 webObjectStore.keyPath = objectStore.keyPath;
 52 webObjectStore.autoIncrement = objectStore.autoIncrement;
 53 webObjectStore.indexes = WebVector<Index>(static_cast<size_t>(objectStore.indexes.size()));
 54
 55 size_t j = 0;
 56 for (IDBObjectStoreMetadata::IndexMap::const_iterator indexIterator = objectStore.indexes.begin(); indexIterator != objectStore.indexes.end(); ++indexIterator) {
 57 const IDBIndexMetadata& index = indexIterator->second;
 58 Index webIndex;
 59 webIndex.name = index.name;
 60 webIndex.keyPath = index.keyPath;
 61 webIndex.unique = index.unique;
 62 webIndex.multiEntry = index.multiEntry;
 63 webObjectStore.indexes[j++] = webIndex;
 64 }
 65 objectStores[i++] = webObjectStore;
 66 }
 67}
 68
 69WebIDBMetadata::operator IDBDatabaseMetadata() const
 70{
 71 IDBDatabaseMetadata db(name, version);
 72 for (size_t i = 0; i < objectStores.size(); ++i) {
 73 const ObjectStore webObjectStore = objectStores[i];
 74 IDBObjectStoreMetadata objectStore(webObjectStore.name, webObjectStore.keyPath, webObjectStore.autoIncrement);
 75
 76 for (size_t j = 0; j < webObjectStore.indexes.size(); ++j) {
 77 const Index webIndex = webObjectStore.indexes[j];
 78 IDBIndexMetadata index(webIndex.name, webIndex.keyPath, webIndex.unique, webIndex.multiEntry);
 79 objectStore.indexes.set(index.name, index);
 80 }
 81 db.objectStores.set(objectStore.name, objectStore);
 82 }
 83 return db;
 84}
 85
 86} // namespace WebKit
 87
 88#endif // ENABLE(INDEXED_DATABASE)

LayoutTests/ChangeLog

 12012-06-19 Joshua Bell <jsbell@chromium.org>
 2
 3 IndexedDB: Snapshot metadata in front end to avoid IPC round-trips
 4 https://bugs.webkit.org/show_bug.cgi?id=88467
 5
 6 Reviewed by Tony Chang.
 7
 8 * storage/indexeddb/metadata-expected.txt: Added.
 9 * storage/indexeddb/metadata.html: Added.
 10 * storage/indexeddb/resources/metadata.js: Added.
 11 (test):
 12 (firstOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
 13 (firstOpen.request.onsuccess.request.onsuccess):
 14 (firstOpen.request.onsuccess):
 15 (firstOpen):
 16 (secondOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
 17 (secondOpen.request.onsuccess.request.onsuccess):
 18 (secondOpen.request.onsuccess):
 19 (secondOpen):
 20 (thirdOpen.request.onsuccess.request.onsuccess.trans.onabort):
 21 (thirdOpen.request.onsuccess.request.onsuccess):
 22 (thirdOpen.request.onsuccess):
 23 (thirdOpen):
 24 (fourthOpen.request.onsuccess.request.onsuccess.trans.oncomplete):
 25 (fourthOpen.request.onsuccess.request.onsuccess):
 26 (fourthOpen.request.onsuccess):
 27 (fourthOpen):
 28 (checkState):
 29
1302012-06-21 Vsevolod Vlasov <vsevik@chromium.org>
231
332 Web Inspector: Support separate script compilation and execution.

LayoutTests/storage/indexeddb/metadata-expected.txt

 1Test IndexedDB database metadata mutation/snapshotting
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6indexedDB = self.indexedDB || self.webkitIndexedDB || self.mozIndexedDB || self.msIndexedDB || self.OIndexedDB;
 7
 8dbname = self.location.pathname
 9request = indexedDB.deleteDatabase(dbname)
 10
 11firstOpen():
 12request = indexedDB.open(dbname)
 13connection1 = request.result
 14request = connection1.setVersion('1')
 15trans = request.result
 16connection1store1 = connection1.createObjectStore('store1')
 17connection1store1.createIndex('index1', 'path')
 18PASS connection1.version is "1"
 19PASS connection1.objectStoreNames.length is 1
 20PASS connection1store1.indexNames.length is 1
 21Connection's properties should be snapshotted on close
 22connection1.close()
 23
 24secondOpen():
 25request = indexedDB.open(dbname)
 26connection2 = request.result
 27request = connection2.setVersion('2')
 28trans = request.result
 29connection2.createObjectStore('store2')
 30connection2store1 = trans.objectStore('store1')
 31connection2store1.createIndex('index2', 'path')
 32PASS connection2.version is "2"
 33PASS connection2.objectStoreNames.length is 2
 34PASS connection2store1.indexNames.length is 2
 35Connection's properties should be snapshotted on close
 36connection2.close()
 37
 38thirdOpen():
 39request = indexedDB.open(dbname)
 40connection3 = request.result
 41request = connection3.setVersion('3')
 42trans = request.result
 43connection3.createObjectStore('store3')
 44connection3store1 = trans.objectStore('store1')
 45connection3store1.createIndex('index3', 'path')
 46PASS connection3.version is "3"
 47PASS connection3.objectStoreNames.length is 3
 48PASS connection3store1.indexNames.length is 3
 49Connection's properties should be reverted on abort
 50trans.abort()
 51Connection's properties should be snapshotted on close
 52connection3.close()
 53
 54fourthOpen():
 55request = indexedDB.open(dbname)
 56connection4 = request.result
 57request = connection4.setVersion('4')
 58trans = request.result
 59connection4.createObjectStore('store4')
 60connection4store1 = trans.objectStore('store1')
 61connection4store1.createIndex('index4', 'path')
 62PASS connection4.version is "4"
 63PASS connection4.objectStoreNames.length is 3
 64PASS connection4store1.indexNames.length is 3
 65Connection's properties should be snapshotted on close
 66connection4.close()
 67
 68checkState():
 69PASS connection1.version is "1"
 70PASS connection1.objectStoreNames.length is 1
 71PASS connection1store1.indexNames.length is 1
 72
 73PASS connection2.version is "2"
 74PASS connection2.objectStoreNames.length is 2
 75PASS connection2store1.indexNames.length is 2
 76
 77PASS connection3.version is "2"
 78PASS connection3.objectStoreNames.length is 2
 79PASS connection3store1.indexNames.length is 2
 80
 81PASS connection4.version is "4"
 82PASS connection4.objectStoreNames.length is 3
 83PASS connection4store1.indexNames.length is 3
 84
 85PASS successfullyParsed is true
 86
 87TEST COMPLETE
 88

LayoutTests/storage/indexeddb/metadata.html

 1<html>
 2<head>
 3<script src="../../fast/js/resources/js-test-pre.js"></script>
 4<script src="resources/shared.js"></script>
 5</head>
 6<body>
 7<script src="resources/metadata.js"></script>
 8<script src="../../fast/js/resources/js-test-post.js"></script>
 9</body>
 10</html>

LayoutTests/storage/indexeddb/resources/metadata.js

 1if (this.importScripts) {
 2 importScripts('../../../fast/js/resources/js-test-pre.js');
 3 importScripts('shared.js');
 4}
 5
 6description("Test IndexedDB database metadata mutation/snapshotting");
 7
 8function test()
 9{
 10 removeVendorPrefixes();
 11 evalAndLog("dbname = self.location.pathname");
 12 evalAndLog("request = indexedDB.deleteDatabase(dbname)");
 13 request.onerror = unexpectedErrorCallback;
 14 request.onsuccess = firstOpen;
 15}
 16
 17function firstOpen()
 18{
 19 debug("");
 20 debug("firstOpen():");
 21 evalAndLog("request = indexedDB.open(dbname)");
 22 request.onerror = unexpectedErrorCallback;
 23 request.onsuccess = function() {
 24 evalAndLog("connection1 = request.result");
 25 evalAndLog("request = connection1.setVersion('1')");
 26 request.onerror = unexpectedErrorCallback;
 27 request.onsuccess = function() {
 28 evalAndLog("trans = request.result");
 29 evalAndLog("connection1store1 = connection1.createObjectStore('store1')");
 30 evalAndLog("connection1store1.createIndex('index1', 'path')");
 31
 32 shouldBeEqualToString("connection1.version", "1");
 33 shouldBe("connection1.objectStoreNames.length", "1");
 34 shouldBe("connection1store1.indexNames.length", "1");
 35
 36 trans.onabort = unexpectedAbortCallback;
 37 trans.oncomplete = function() {
 38 debug("Connection's properties should be snapshotted on close");
 39 evalAndLog("connection1.close()");
 40 secondOpen();
 41 };
 42 };
 43 };
 44}
 45
 46function secondOpen()
 47{
 48 debug("");
 49 debug("secondOpen():");
 50 evalAndLog("request = indexedDB.open(dbname)");
 51 request.onerror = unexpectedErrorCallback;
 52 request.onsuccess = function() {
 53 evalAndLog("connection2 = request.result");
 54 evalAndLog("request = connection2.setVersion('2')");
 55 request.onerror = unexpectedErrorCallback;
 56 request.onsuccess = function() {
 57 evalAndLog("trans = request.result");
 58 evalAndLog("connection2.createObjectStore('store2')");
 59 evalAndLog("connection2store1 = trans.objectStore('store1')");
 60 evalAndLog("connection2store1.createIndex('index2', 'path')");
 61
 62 shouldBeEqualToString("connection2.version", "2");
 63 shouldBe("connection2.objectStoreNames.length", "2");
 64 shouldBe("connection2store1.indexNames.length", "2");
 65
 66 trans.onabort = unexpectedAbortCallback;
 67 trans.oncomplete = function() {
 68 debug("Connection's properties should be snapshotted on close");
 69 evalAndLog("connection2.close()");
 70 thirdOpen();
 71 };
 72 };
 73 };
 74}
 75
 76function thirdOpen()
 77{
 78 debug("");
 79 debug("thirdOpen():");
 80 evalAndLog("request = indexedDB.open(dbname)");
 81 request.onerror = unexpectedErrorCallback;
 82 request.onsuccess = function() {
 83 evalAndLog("connection3 = request.result");
 84 evalAndLog("request = connection3.setVersion('3')");
 85 request.onerror = unexpectedErrorCallback;
 86 request.onsuccess = function() {
 87 evalAndLog("trans = request.result");
 88 evalAndLog("connection3.createObjectStore('store3')");
 89 evalAndLog("connection3store1 = trans.objectStore('store1')");
 90 evalAndLog("connection3store1.createIndex('index3', 'path')");
 91
 92 shouldBeEqualToString("connection3.version", "3");
 93 shouldBe("connection3.objectStoreNames.length", "3");
 94 shouldBe("connection3store1.indexNames.length", "3");
 95
 96 trans.oncomplete = unexpectedCompleteCallback;
 97 trans.onabort = function() {
 98 debug("Connection's properties should be snapshotted on close");
 99 evalAndLog("connection3.close()");
 100 fourthOpen();
 101 };
 102 debug("Connection's properties should be reverted on abort");
 103 evalAndLog("trans.abort()");
 104 };
 105 };
 106}
 107
 108function fourthOpen()
 109{
 110 debug("");
 111 debug("fourthOpen():");
 112 evalAndLog("request = indexedDB.open(dbname)");
 113 request.onerror = unexpectedErrorCallback;
 114 request.onsuccess = function() {
 115 evalAndLog("connection4 = request.result");
 116 evalAndLog("request = connection4.setVersion('4')");
 117 request.onerror = unexpectedErrorCallback;
 118 request.onsuccess = function() {
 119 evalAndLog("trans = request.result");
 120 evalAndLog("connection4.createObjectStore('store4')");
 121 evalAndLog("connection4store1 = trans.objectStore('store1')");
 122 evalAndLog("connection4store1.createIndex('index4', 'path')");
 123
 124 shouldBeEqualToString("connection4.version", "4");
 125 shouldBe("connection4.objectStoreNames.length", "3");
 126 shouldBe("connection4store1.indexNames.length", "3");
 127
 128 trans.onabort = unexpectedAbortCallback;
 129 trans.oncomplete = function() {
 130 debug("Connection's properties should be snapshotted on close");
 131 evalAndLog("connection4.close()");
 132 checkState();
 133 };
 134 };
 135 };
 136}
 137
 138function checkState()
 139{
 140 debug("");
 141 debug("checkState():");
 142
 143 shouldBeEqualToString("connection1.version", "1");
 144 shouldBe("connection1.objectStoreNames.length", "1");
 145 shouldBe("connection1store1.indexNames.length", "1");
 146 debug("");
 147
 148 shouldBeEqualToString("connection2.version", "2");
 149 shouldBe("connection2.objectStoreNames.length", "2");
 150 shouldBe("connection2store1.indexNames.length", "2");
 151 debug("");
 152
 153 shouldBeEqualToString("connection3.version", "2");
 154 shouldBe("connection3.objectStoreNames.length", "2");
 155 shouldBe("connection3store1.indexNames.length", "2");
 156 debug("");
 157
 158 shouldBeEqualToString("connection4.version", "4");
 159 shouldBe("connection4.objectStoreNames.length", "3");
 160 shouldBe("connection4store1.indexNames.length", "3");
 161 debug("");
 162
 163 finishJSTest();
 164}
 165
 166test();