https://bugs.webkit.org/show_bug.cgi?id=85298
Reviewed by Tony Chang, Kentaro Hara and James Robinson.
Source/WebCore:
Migrate from storing key paths as (nullable) Strings to a dedicated IDBKeyPath
type. Prep work for supporting array-type key paths: http://webkit.org/b/84207
Only functional change is handling of null/undefined parameters for key paths,
to align with IDB spec, covered by layout test.
Test: storage/indexeddb/keypath-basics.html
Test: WebKit/chromium/IDBLevelDBCodingTest.cpp
* Modules/indexeddb/IDBAny.cpp: Allow IDBAny to yield DOMStrings.
(WebCore::IDBAny::createString):
(WebCore):
(WebCore::IDBAny::string):
(WebCore::IDBAny::set):
* Modules/indexeddb/IDBAny.h:
(IDBAny):
* Modules/indexeddb/IDBBackingStore.h: Switch from String to IDBKeyPath.
(IDBBackingStore):
* Modules/indexeddb/IDBDatabase.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBDatabase::createObjectStore):
* Modules/indexeddb/IDBDatabaseBackendImpl.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBDatabaseBackendImpl::createObjectStore):
(WebCore::IDBDatabaseBackendImpl::loadObjectStores):
* Modules/indexeddb/IDBDatabaseBackendImpl.h: Switch from String to IDBKeyPath.
(IDBDatabaseBackendImpl):
* Modules/indexeddb/IDBDatabaseBackendInterface.h: Switch from String to IDBKeyPath.
(WebCore):
(IDBDatabaseBackendInterface):
* Modules/indexeddb/IDBIndex.h: Switch from String to IDBAny (via IDBKeyPath).
(WebCore::IDBIndex::keyPath):
* Modules/indexeddb/IDBIndex.idl: Switch from DOMString? to IDBAny.
* Modules/indexeddb/IDBIndexBackendImpl.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl):
* Modules/indexeddb/IDBIndexBackendImpl.h: Switch from String to IDBKeyPath.
(WebCore::IDBIndexBackendImpl::create):
(WebCore::IDBIndexBackendImpl::keyPath):
(IDBIndexBackendImpl):
* Modules/indexeddb/IDBIndexBackendInterface.h: Switch from String to IDBKeyPath.
(WebCore):
(IDBIndexBackendInterface):
* Modules/indexeddb/IDBKeyPath.cpp: Non-trivial method implementations.
(WebCore::IDBKeyPath::isValid):
(WebCore):
(WebCore::IDBKeyPath::operator PassRefPtr<IDBAny>):
* Modules/indexeddb/IDBKeyPath.h: Introduce IDBKeyPath type.
(IDBKeyPath):
(WebCore::IDBKeyPath::IDBKeyPath):
(WebCore::IDBKeyPath::type):
(WebCore::IDBKeyPath::array):
(WebCore::IDBKeyPath::string):
(WebCore::IDBKeyPath::isNull):
(WebCore):
* Modules/indexeddb/IDBKeyPathBackendImpl.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath):
(WebCore::IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
* Modules/indexeddb/IDBKeyPathBackendImpl.h: Switch from String to IDBKeyPath.
(WebCore):
(IDBKeyPathBackendImpl):
* Modules/indexeddb/IDBLevelDBBackingStore.cpp: Switch from String to IDBKeyPath, with back-compat.
(WebCore):
(WebCore::putIDBKeyPath):
(WebCore::IDBLevelDBBackingStore::getObjectStores):
(WebCore::IDBLevelDBBackingStore::createObjectStore):
(WebCore::IDBLevelDBBackingStore::getIndexes):
(WebCore::IDBLevelDBBackingStore::createIndex):
* Modules/indexeddb/IDBLevelDBBackingStore.h:
(IDBLevelDBBackingStore):
* Modules/indexeddb/IDBLevelDBCoding.cpp: New coding scheme for key paths (with back-compat).
(IDBLevelDBCoding):
(WebCore::IDBLevelDBCoding::encodeIDBKeyPath):
(WebCore::IDBLevelDBCoding::decodeIDBKeyPath):
* Modules/indexeddb/IDBLevelDBCoding.h: Add key-path-specific methods.
(WebCore):
(IDBLevelDBCoding):
* Modules/indexeddb/IDBObjectStore.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBObjectStore::keyPath):
(WebCore::IDBObjectStore::createIndex):
(WebCore):
* Modules/indexeddb/IDBObjectStore.h: Switch from String to IDBAny (via IDBKeyPath).
(IDBObjectStore):
* Modules/indexeddb/IDBObjectStore.idl: Switch from DOMString? to IDBAny.
* Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl):
(WebCore::fetchKeyFromKeyPath):
(WebCore::injectKeyIntoKeyPath):
(WebCore::IDBObjectStoreBackendImpl::createIndex):
(WebCore::IDBObjectStoreBackendImpl::loadIndexes):
* Modules/indexeddb/IDBObjectStoreBackendImpl.h: Switch from String to IDBKeyPath.
(WebCore::IDBObjectStoreBackendImpl::create):
(WebCore::IDBObjectStoreBackendImpl::keyPath):
(IDBObjectStoreBackendImpl):
* Modules/indexeddb/IDBObjectStoreBackendInterface.h: Switch from String to IDBKeyPath.
(WebCore):
(IDBObjectStoreBackendInterface):
* bindings/v8/Dictionary.cpp: Add getter for DOMString[] (i.e. Vector<String>)
(WebCore):
(WebCore::Dictionary::get):
* bindings/v8/Dictionary.h:
(Dictionary):
* bindings/v8/IDBBindingUtilities.cpp: Switch from String to IDBKeyPath.
(WebCore::createIDBKeyFromSerializedValueAndKeyPath):
(WebCore::injectIDBKeyIntoSerializedValue):
* bindings/v8/IDBBindingUtilities.h: Switch from String to IDBKeyPath.
(WebCore):
* bindings/v8/custom/V8IDBAnyCustom.cpp: Support String/DOMString.
(WebCore::toV8):
* dom/DOMStringList.h: Allow easy (const) access to strings.
(WebCore::DOMStringList::operator const Vector<String>&):
(DOMStringList):
* inspector/InspectorIndexedDBAgent.cpp: Temporary shim for non-strings: see http://webkit.org/b/84303
(WebCore):
* platform/chromium/PlatformSupport.h: Switch from String to IDBKeyPath.
(WebCore):
(PlatformSupport):
* storage/chromium/IDBKeyPathBackendImpl.cpp: Switch from String to IDBKeyPath.
(WebCore::IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath):
(WebCore::IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
Source/WebKit/chromium:
No functional changes, just finish migration from String to IDBKeyPath
for storing key paths, for eventual array support http://webkit.org/b/84207
* public/WebIDBDatabase.h: Remove temporary overload.
(WebKit):
(WebKit::WebIDBDatabase::objectStoreNames):
* public/WebIDBIndex.h: Remove temporary method.
(WebKit::WebIDBIndex::keyPath):
* public/WebIDBKeyPath.h: Remove obsolete methods, wrap WebCore::IDBKeyPath
(WebIDBKeyPath):
(WebKit::WebIDBKeyPath::WebIDBKeyPath):
* public/WebIDBObjectStore.h: Remove temporary method and overload.
(WebKit::WebIDBObjectStore::keyPath):
* public/platform/WebKitPlatformSupport.h: Remove temporary overloads.
(WebKit):
* src/AssertMatchingEnums.cpp: WebIDBKeyPath vs. IDBKeyPath enums.
* src/IDBDatabaseBackendProxy.cpp: Switch from String to IDBKeyPath.
(WebKit::IDBDatabaseBackendProxy::createObjectStore):
* src/IDBDatabaseBackendProxy.h: Switch from String to IDBKeyPath.
(IDBDatabaseBackendProxy):
* src/IDBIndexBackendProxy.cpp: Switch from String to IDBKeyPath.
(WebKit::IDBIndexBackendProxy::keyPath):
* src/IDBIndexBackendProxy.h: Switch from String to IDBKeyPath.
(IDBIndexBackendProxy):
* src/IDBObjectStoreBackendProxy.cpp: Switch from String to IDBKeyPath.
(WebKit::IDBObjectStoreBackendProxy::keyPath):
(WebKit::IDBObjectStoreBackendProxy::createIndex):
* src/IDBObjectStoreBackendProxy.h: Switch from String to IDBKeyPath.
(IDBObjectStoreBackendProxy):
* src/PlatformSupport.cpp: Switch from String to IDBKeyPath.
(WebCore::PlatformSupport::createIDBKeysFromSerializedValuesAndKeyPath):
(WebCore::PlatformSupport::injectIDBKeyIntoSerializedValue):
* src/WebIDBDatabaseImpl.cpp: Switch from String to IDBKeyPath.
(WebKit::WebIDBDatabaseImpl::createObjectStore):
* src/WebIDBDatabaseImpl.h: Remove temporary overload.
(WebIDBDatabaseImpl):
* src/WebIDBIndexImpl.cpp: Remove temporary method.
* src/WebIDBIndexImpl.h: Remove temporary method.
(WebIDBIndexImpl):
* src/WebIDBKeyPath.cpp: Remove most logic; just a wrapper for WebCore::IDBKeyPath.
(WebKit::WebIDBKeyPath::~WebIDBKeyPath):
(WebKit::WebIDBKeyPath::create):
(WebKit::WebIDBKeyPath::createNull):
(WebKit::WebIDBKeyPath::isValid):
(WebKit::WebIDBKeyPath::type):
(WebKit):
(WebKit::WebIDBKeyPath::array):
(WebKit::WebIDBKeyPath::string):
(WebKit::WebIDBKeyPath::WebIDBKeyPath):
(WebKit::WebIDBKeyPath::operator=):
(WebKit::WebIDBKeyPath::operator const WebCore::IDBKeyPath&):
* src/WebIDBObjectStoreImpl.cpp: Remove temporary method and overload.
(WebKit::WebIDBObjectStoreImpl::keyPath):
(WebKit::WebIDBObjectStoreImpl::createIndex):
* src/WebIDBObjectStoreImpl.h: Remove temporary method and overload.
(WebIDBObjectStoreImpl):
* tests/IDBBindingUtilitiesTest.cpp: Use IDBKeyPath.
(WebCore::checkKeyFromValueAndKeyPathInternal):
(WebCore::injectKey):
* tests/IDBLevelDBCodingTest.cpp: Added EncodeIDBKeyPath and DecodeIDBKeyPath tests.
(IDBLevelDBCoding::TEST):
(IDBLevelDBCoding):
* tests/IDBKeyPathTest.cpp:
(WebCore::checkKeyPath): Test IDBKeyPath validity.
LayoutTests:
* storage/indexeddb/keypath-basics-expected.txt:
* storage/indexeddb/resources/keypath-basics.js:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@117817
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
2012-05-21 Joshua Bell <jsbell@chromium.org>
+ IndexedDB: Store key paths in IDBKeyPath type instead of String
+ https://bugs.webkit.org/show_bug.cgi?id=85298
+
+ Reviewed by Tony Chang, Kentaro Hara and James Robinson.
+
+ * storage/indexeddb/keypath-basics-expected.txt:
+ * storage/indexeddb/resources/keypath-basics.js:
+
+2012-05-21 Joshua Bell <jsbell@chromium.org>
+
Move WebSQL tests in LayoutTests/storage to websql directory
https://bugs.webkit.org/show_bug.cgi?id=86138
db = event.target.result
request = db.setVersion('1')
Deleted all object stores.
-globalKeyPath = 'null'
-db.createObjectStore('name', {keyPath: globalKeyPath})
-Deleted all object stores.
-globalKeyPath = 'undefined'
-db.createObjectStore('name', {keyPath: globalKeyPath})
-Deleted all object stores.
-globalKeyPath = ''
-db.createObjectStore('name', {keyPath: globalKeyPath})
-Deleted all object stores.
-globalKeyPath = 'foo'
-db.createObjectStore('name', {keyPath: globalKeyPath})
-Deleted all object stores.
-globalKeyPath = 'foo.bar.baz'
-db.createObjectStore('name', {keyPath: globalKeyPath})
-Deleted all object stores.
-globalKeyPath = 'null'
-store = db.createObjectStore('storeName')
-store.createIndex('name', globalKeyPath)
-Deleted all object stores.
-globalKeyPath = 'undefined'
-store = db.createObjectStore('storeName')
-store.createIndex('name', globalKeyPath)
-Deleted all object stores.
-globalKeyPath = ''
-store = db.createObjectStore('storeName')
-store.createIndex('name', globalKeyPath)
-Deleted all object stores.
-globalKeyPath = 'foo'
-store = db.createObjectStore('storeName')
-store.createIndex('name', globalKeyPath)
-Deleted all object stores.
-globalKeyPath = 'foo.bar.baz'
-store = db.createObjectStore('storeName')
-store.createIndex('name', globalKeyPath)
+store = db.createObjectStore('name')
+PASS store.keyPath is null
+Deleted all object stores.
+store = db.createObjectStore('name', {keyPath: null})
+PASS store.keyPath is null
+index = store.createIndex('name', null)
+PASS index.keyPath is 'null'
+Deleted all object stores.
+store = db.createObjectStore('name', {keyPath: undefined})
+PASS store.keyPath is null
+index = store.createIndex('name', undefined)
+PASS index.keyPath is 'undefined'
+Deleted all object stores.
+store = db.createObjectStore('name', {keyPath: ''})
+PASS store.keyPath is ''
+index = store.createIndex('name', '')
+PASS index.keyPath is ''
+Deleted all object stores.
+store = db.createObjectStore('name', {keyPath: 'foo'})
+PASS store.keyPath is 'foo'
+index = store.createIndex('name', 'foo')
+PASS index.keyPath is 'foo'
+Deleted all object stores.
+store = db.createObjectStore('name', {keyPath: 'foo.bar.baz'})
+PASS store.keyPath is 'foo.bar.baz'
+index = store.createIndex('name', 'foo.bar.baz')
+PASS index.keyPath is 'foo.bar.baz'
Deleted all object stores.
Deleted all object stores.
globalKeyPath = '[]'
{
deleteAllObjectStores(db);
- testKeyPaths = [null, undefined, ''];
- testKeyPaths.forEach(function (keyPath) {
- globalKeyPath = keyPath;
- debug("globalKeyPath = '" + globalKeyPath + "'");
- evalAndLog("db.createObjectStore('name', {keyPath: globalKeyPath})");
- deleteAllObjectStores(db);
- });
+ evalAndLog("store = db.createObjectStore('name')");
+ shouldBeNull("store.keyPath");
+ deleteAllObjectStores(db);
- testKeyPaths = ['foo', 'foo.bar.baz'];
- testKeyPaths.forEach(function (keyPath) {
- globalKeyPath = keyPath;
- debug("globalKeyPath = '" + globalKeyPath + "'");
- evalAndLog("db.createObjectStore('name', {keyPath: globalKeyPath})");
- deleteAllObjectStores(db);
- });
+ testKeyPaths = [
+ { keyPath: "null", storeExpected: "null", indexExpected: "'null'" },
+ { keyPath: "undefined", storeExpected: "null", indexExpected: "'undefined'" },
+ { keyPath: "''", storeExpected: "''", indexExpected: "''" },
+ { keyPath: "'foo'", storeExpected: "'foo'", indexExpected: "'foo'" },
+ { keyPath: "'foo.bar.baz'", storeExpected: "'foo.bar.baz'", indexExpected: "'foo.bar.baz'" }
+ ];
- testKeyPaths = [null, undefined, '', 'foo', 'foo.bar.baz'];
- testKeyPaths.forEach(function (keyPath) {
- globalKeyPath = keyPath;
- debug("globalKeyPath = '" + globalKeyPath + "'");
- store = evalAndLog("store = db.createObjectStore('storeName')");
- evalAndLog("store.createIndex('name', globalKeyPath)");
+ testKeyPaths.forEach(function (testCase) {
+ evalAndLog("store = db.createObjectStore('name', {keyPath: " + testCase.keyPath + "})");
+ shouldBe("store.keyPath", testCase.storeExpected);
+ evalAndLog("index = store.createIndex('name', " + testCase.keyPath + ")");
+ shouldBe("index.keyPath", testCase.indexExpected);
deleteAllObjectStores(db);
});
finishJSTest();
}
-test();
\ No newline at end of file
+test();
+2012-05-21 Joshua Bell <jsbell@chromium.org>
+
+ IndexedDB: Store key paths in IDBKeyPath type instead of String
+ https://bugs.webkit.org/show_bug.cgi?id=85298
+
+ Reviewed by Tony Chang, Kentaro Hara and James Robinson.
+
+ Migrate from storing key paths as (nullable) Strings to a dedicated IDBKeyPath
+ type. Prep work for supporting array-type key paths: http://webkit.org/b/84207
+
+ Only functional change is handling of null/undefined parameters for key paths,
+ to align with IDB spec, covered by layout test.
+
+ Test: storage/indexeddb/keypath-basics.html
+ Test: WebKit/chromium/IDBLevelDBCodingTest.cpp
+
+ * Modules/indexeddb/IDBAny.cpp: Allow IDBAny to yield DOMStrings.
+ (WebCore::IDBAny::createString):
+ (WebCore):
+ (WebCore::IDBAny::string):
+ (WebCore::IDBAny::set):
+ * Modules/indexeddb/IDBAny.h:
+ (IDBAny):
+ * Modules/indexeddb/IDBBackingStore.h: Switch from String to IDBKeyPath.
+ (IDBBackingStore):
+ * Modules/indexeddb/IDBDatabase.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBDatabase::createObjectStore):
+ * Modules/indexeddb/IDBDatabaseBackendImpl.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBDatabaseBackendImpl::createObjectStore):
+ (WebCore::IDBDatabaseBackendImpl::loadObjectStores):
+ * Modules/indexeddb/IDBDatabaseBackendImpl.h: Switch from String to IDBKeyPath.
+ (IDBDatabaseBackendImpl):
+ * Modules/indexeddb/IDBDatabaseBackendInterface.h: Switch from String to IDBKeyPath.
+ (WebCore):
+ (IDBDatabaseBackendInterface):
+ * Modules/indexeddb/IDBIndex.h: Switch from String to IDBAny (via IDBKeyPath).
+ (WebCore::IDBIndex::keyPath):
+ * Modules/indexeddb/IDBIndex.idl: Switch from DOMString? to IDBAny.
+ * Modules/indexeddb/IDBIndexBackendImpl.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBIndexBackendImpl::IDBIndexBackendImpl):
+ * Modules/indexeddb/IDBIndexBackendImpl.h: Switch from String to IDBKeyPath.
+ (WebCore::IDBIndexBackendImpl::create):
+ (WebCore::IDBIndexBackendImpl::keyPath):
+ (IDBIndexBackendImpl):
+ * Modules/indexeddb/IDBIndexBackendInterface.h: Switch from String to IDBKeyPath.
+ (WebCore):
+ (IDBIndexBackendInterface):
+ * Modules/indexeddb/IDBKeyPath.cpp: Non-trivial method implementations.
+ (WebCore::IDBKeyPath::isValid):
+ (WebCore):
+ (WebCore::IDBKeyPath::operator PassRefPtr<IDBAny>):
+ * Modules/indexeddb/IDBKeyPath.h: Introduce IDBKeyPath type.
+ (IDBKeyPath):
+ (WebCore::IDBKeyPath::IDBKeyPath):
+ (WebCore::IDBKeyPath::type):
+ (WebCore::IDBKeyPath::array):
+ (WebCore::IDBKeyPath::string):
+ (WebCore::IDBKeyPath::isNull):
+ (WebCore):
+ * Modules/indexeddb/IDBKeyPathBackendImpl.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath):
+ (WebCore::IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
+ * Modules/indexeddb/IDBKeyPathBackendImpl.h: Switch from String to IDBKeyPath.
+ (WebCore):
+ (IDBKeyPathBackendImpl):
+ * Modules/indexeddb/IDBLevelDBBackingStore.cpp: Switch from String to IDBKeyPath, with back-compat.
+ (WebCore):
+ (WebCore::putIDBKeyPath):
+ (WebCore::IDBLevelDBBackingStore::getObjectStores):
+ (WebCore::IDBLevelDBBackingStore::createObjectStore):
+ (WebCore::IDBLevelDBBackingStore::getIndexes):
+ (WebCore::IDBLevelDBBackingStore::createIndex):
+ * Modules/indexeddb/IDBLevelDBBackingStore.h:
+ (IDBLevelDBBackingStore):
+ * Modules/indexeddb/IDBLevelDBCoding.cpp: New coding scheme for key paths (with back-compat).
+ (IDBLevelDBCoding):
+ (WebCore::IDBLevelDBCoding::encodeIDBKeyPath):
+ (WebCore::IDBLevelDBCoding::decodeIDBKeyPath):
+ * Modules/indexeddb/IDBLevelDBCoding.h: Add key-path-specific methods.
+ (WebCore):
+ (IDBLevelDBCoding):
+ * Modules/indexeddb/IDBObjectStore.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBObjectStore::keyPath):
+ (WebCore::IDBObjectStore::createIndex):
+ (WebCore):
+ * Modules/indexeddb/IDBObjectStore.h: Switch from String to IDBAny (via IDBKeyPath).
+ (IDBObjectStore):
+ * Modules/indexeddb/IDBObjectStore.idl: Switch from DOMString? to IDBAny.
+ * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl):
+ (WebCore::fetchKeyFromKeyPath):
+ (WebCore::injectKeyIntoKeyPath):
+ (WebCore::IDBObjectStoreBackendImpl::createIndex):
+ (WebCore::IDBObjectStoreBackendImpl::loadIndexes):
+ * Modules/indexeddb/IDBObjectStoreBackendImpl.h: Switch from String to IDBKeyPath.
+ (WebCore::IDBObjectStoreBackendImpl::create):
+ (WebCore::IDBObjectStoreBackendImpl::keyPath):
+ (IDBObjectStoreBackendImpl):
+ * Modules/indexeddb/IDBObjectStoreBackendInterface.h: Switch from String to IDBKeyPath.
+ (WebCore):
+ (IDBObjectStoreBackendInterface):
+ * bindings/v8/Dictionary.cpp: Add getter for DOMString[] (i.e. Vector<String>)
+ (WebCore):
+ (WebCore::Dictionary::get):
+ * bindings/v8/Dictionary.h:
+ (Dictionary):
+ * bindings/v8/IDBBindingUtilities.cpp: Switch from String to IDBKeyPath.
+ (WebCore::createIDBKeyFromSerializedValueAndKeyPath):
+ (WebCore::injectIDBKeyIntoSerializedValue):
+ * bindings/v8/IDBBindingUtilities.h: Switch from String to IDBKeyPath.
+ (WebCore):
+ * bindings/v8/custom/V8IDBAnyCustom.cpp: Support String/DOMString.
+ (WebCore::toV8):
+ * dom/DOMStringList.h: Allow easy (const) access to strings.
+ (WebCore::DOMStringList::operator const Vector<String>&):
+ (DOMStringList):
+ * inspector/InspectorIndexedDBAgent.cpp: Temporary shim for non-strings: see http://webkit.org/b/84303
+ (WebCore):
+ * platform/chromium/PlatformSupport.h: Switch from String to IDBKeyPath.
+ (WebCore):
+ (PlatformSupport):
+ * storage/chromium/IDBKeyPathBackendImpl.cpp: Switch from String to IDBKeyPath.
+ (WebCore::IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath):
+ (WebCore::IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue):
+
2012-05-21 Zhenyao Mo <zmo@google.com>
Restore WebGL's framebuffer binding after DrawingBuffer's prepareBackBuffer()
return idbAny.release();
}
+PassRefPtr<IDBAny> IDBAny::createString(const String& value)
+{
+ RefPtr<IDBAny> idbAny = adoptRef(new IDBAny());
+ idbAny->set(value);
+ return idbAny.release();
+}
+
IDBAny::IDBAny()
: m_type(UndefinedType)
{
return m_serializedScriptValue;
}
+const String& IDBAny::string()
+{
+ ASSERT(m_type == StringType);
+ return m_string;
+}
+
void IDBAny::setNull()
{
ASSERT(m_type == UndefinedType);
m_serializedScriptValue = value;
}
+void IDBAny::set(const String& value)
+{
+ ASSERT(m_type == UndefinedType);
+ m_type = StringType;
+ m_string = value;
+}
+
} // namespace WebCore
#endif
#if ENABLE(INDEXED_DATABASE)
+#include "PlatformString.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
public:
static PassRefPtr<IDBAny> createInvalid();
static PassRefPtr<IDBAny> createNull();
+ static PassRefPtr<IDBAny> createString(const String&);
template<typename T>
static PassRefPtr<IDBAny> create(T* idbObject)
{
IDBKeyType,
IDBObjectStoreType,
IDBTransactionType,
- SerializedScriptValueType
+ SerializedScriptValueType,
+ StringType,
};
Type type() const { return m_type; }
PassRefPtr<IDBObjectStore> idbObjectStore();
PassRefPtr<IDBTransaction> idbTransaction();
PassRefPtr<SerializedScriptValue> serializedScriptValue();
+ const String& string();
// Set can only be called once.
void setNull();
void set(PassRefPtr<IDBObjectStore>);
void set(PassRefPtr<IDBTransaction>);
void set(PassRefPtr<SerializedScriptValue>);
+ void set(const String&);
private:
IDBAny();
RefPtr<IDBObjectStore> m_idbObjectStore;
RefPtr<IDBTransaction> m_idbTransaction;
RefPtr<SerializedScriptValue> m_serializedScriptValue;
+ String m_string;
};
} // namespace WebCore
virtual bool updateIDBDatabaseMetaData(int64_t rowId, const String& version) = 0;
virtual bool deleteDatabase(const String& name) = 0;
- virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags) = 0;
- virtual bool createObjectStore(int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId) = 0;
+ virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags) = 0;
+ virtual bool createObjectStore(int64_t databaseId, const String& name, const IDBKeyPath&, bool autoIncrement, int64_t& assignedObjectStoreId) = 0;
virtual void deleteObjectStore(int64_t databaseId, int64_t objectStoreId) = 0;
class ObjectStoreRecordIdentifier : public RefCounted<ObjectStoreRecordIdentifier> {
};
virtual bool forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback&) = 0;
- virtual void getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags) = 0;
- virtual bool createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const String& keyPath, bool isUnique, bool isMultiEntry, int64_t& indexId) = 0;
+ virtual void getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags) = 0;
+ virtual bool createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry, int64_t& indexId) = 0;
virtual void deleteIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId) = 0;
virtual bool putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const ObjectStoreRecordIdentifier*) = 0;
virtual bool deleteIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const ObjectStoreRecordIdentifier*) = 0;
return 0;
}
- String keyPath;
- bool keyPathExists = options.getWithUndefinedOrNullCheck("keyPath", keyPath);
- if (keyPathExists && !IDBIsValidKeyPath(keyPath)) {
+ IDBKeyPath keyPath;
+ if (!options.isUndefinedOrNull()) {
+ String keyPathString;
+ if (options.getWithUndefinedOrNullCheck("keyPath", keyPathString))
+ keyPath = IDBKeyPath(keyPathString);
+ }
+
+ if (!keyPath.isNull() && !keyPath.isValid()) {
ec = IDBDatabaseException::NON_TRANSIENT_ERR;
return 0;
}
return objectStoreNames.release();
}
-PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
+PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendImpl::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transactionPtr, ExceptionCode& ec)
{
ASSERT(transactionPtr->mode() == IDBTransaction::VERSION_CHANGE);
{
Vector<int64_t> ids;
Vector<String> names;
- Vector<String> keyPaths;
+ Vector<IDBKeyPath> keyPaths;
Vector<bool> autoIncrementFlags;
m_backingStore->getObjectStores(m_id, ids, names, keyPaths, autoIncrementFlags);
virtual String version() const { return m_version; }
virtual PassRefPtr<DOMStringList> objectStoreNames() const;
- virtual PassRefPtr<IDBObjectStoreBackendInterface> createObjectStore(const String& name, const String& keyPath, bool autoIncrement, IDBTransactionBackendInterface*, ExceptionCode&);
+ virtual PassRefPtr<IDBObjectStoreBackendInterface> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, IDBTransactionBackendInterface*, ExceptionCode&);
virtual void deleteObjectStore(const String& name, IDBTransactionBackendInterface*, ExceptionCode&);
virtual void setVersion(const String& version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, ExceptionCode&);
virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* objectStoreNames, unsigned short mode, ExceptionCode&);
class Frame;
class IDBCallbacks;
class IDBDatabaseCallbacks;
+class IDBKeyPath;
class IDBObjectStoreBackendInterface;
class IDBTransactionBackendInterface;
virtual String version() const = 0;
virtual PassRefPtr<DOMStringList> objectStoreNames() const = 0;
- virtual PassRefPtr<IDBObjectStoreBackendInterface> createObjectStore(const String& name, const String& keyPath, bool autoIncrement, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
+ virtual PassRefPtr<IDBObjectStoreBackendInterface> createObjectStore(const String& name, const IDBKeyPath&, bool autoIncrement, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
virtual void deleteObjectStore(const String& name, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
virtual void setVersion(const String& version, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBDatabaseCallbacks>, ExceptionCode&) = 0;
virtual PassRefPtr<IDBTransactionBackendInterface> transaction(DOMStringList* storeNames, unsigned short mode, ExceptionCode&) = 0;
#include "IDBCursor.h"
#include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
#include "IDBKeyRange.h"
#include "IDBRequest.h"
#include "PlatformString.h"
// Implement the IDL
String name() const { return m_backend->name(); }
IDBObjectStore* objectStore() const { return m_objectStore.get(); }
- String keyPath() const { return m_backend->keyPath(); }
+ PassRefPtr<IDBAny> keyPath() const { return m_backend->keyPath(); }
bool unique() const { return m_backend->unique(); }
bool multiEntry() const { return m_backend->multiEntry(); }
] IDBIndex {
readonly attribute DOMString name;
readonly attribute IDBObjectStore objectStore;
- readonly attribute DOMString keyPath;
+ readonly attribute IDBAny keyPath;
readonly attribute boolean unique;
readonly attribute boolean multiEntry;
namespace WebCore {
-IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, int64_t id, const String& name, const String& keyPath, bool unique, bool multiEntry)
+IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, int64_t id, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry)
: m_backingStore(backingStore)
, m_databaseId(databaseId)
, m_objectStoreBackend(objectStoreBackend)
{
}
-IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, const String& name, const String& keyPath, bool unique, bool multiEntry)
+IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry)
: m_backingStore(backingStore)
, m_databaseId(databaseId)
, m_objectStoreBackend(objectStoreBackend)
#include "IDBCursorBackendInterface.h"
#include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
namespace WebCore {
class IDBIndexBackendImpl : public IDBIndexBackendInterface {
public:
- static PassRefPtr<IDBIndexBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, int64_t id, const String& name, const String& keyPath, bool unique, bool multiEntry)
+ static PassRefPtr<IDBIndexBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, int64_t id, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry)
{
return adoptRef(new IDBIndexBackendImpl(backingStore, databaseId, objectStoreBackend, id, name, keyPath, unique, multiEntry));
}
- static PassRefPtr<IDBIndexBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, const String& name, const String& keyPath, bool unique, bool multiEntry)
+ static PassRefPtr<IDBIndexBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, IDBObjectStoreBackendImpl* objectStoreBackend, const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry)
{
return adoptRef(new IDBIndexBackendImpl(backingStore, databaseId, objectStoreBackend, name, keyPath, unique, multiEntry));
}
// Implements IDBIndexBackendInterface.
virtual String name() { return m_name; }
- virtual String keyPath() { return m_keyPath; }
+ virtual IDBKeyPath keyPath() { return m_keyPath; }
virtual bool unique() { return m_unique; }
virtual bool multiEntry() { return m_multiEntry; }
virtual void getKey(PassRefPtr<IDBKey>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
private:
- IDBIndexBackendImpl(IDBBackingStore*, int64_t databaseId, IDBObjectStoreBackendImpl*, int64_t id, const String& name, const String& keyPath, bool unique, bool multiEntry);
- IDBIndexBackendImpl(IDBBackingStore*, int64_t databaseId, IDBObjectStoreBackendImpl*, const String& name, const String& keyPath, bool unique, bool multiEntry);
+ IDBIndexBackendImpl(IDBBackingStore*, int64_t databaseId, IDBObjectStoreBackendImpl*, int64_t id, const String& name, const IDBKeyPath&, bool unique, bool multiEntry);
+ IDBIndexBackendImpl(IDBBackingStore*, int64_t databaseId, IDBObjectStoreBackendImpl*, const String& name, const IDBKeyPath&, bool unique, bool multiEntry);
static void openCursorInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKeyRange>, unsigned short direction, IDBCursorBackendInterface::CursorType, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>);
static void countInternal(ScriptExecutionContext*, PassRefPtr<IDBIndexBackendImpl>, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendInterface>);
IDBObjectStoreBackendImpl* m_objectStoreBackend;
int64_t m_id;
String m_name;
- String m_keyPath;
+ IDBKeyPath m_keyPath;
bool m_unique;
bool m_multiEntry;
};
class IDBCallbacks;
class IDBKey;
+class IDBKeyPath;
class IDBKeyRange;
class IDBTransactionBackendInterface;
virtual ~IDBIndexBackendInterface() { }
virtual String name() = 0;
- virtual String keyPath() = 0;
+ virtual IDBKeyPath keyPath() = 0;
virtual bool unique() = 0;
virtual bool multiEntry() = 0;
#if ENABLE(INDEXED_DATABASE)
+#include "DOMStringList.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
}
}
+IDBKeyPath::IDBKeyPath(const String& string)
+ : m_type(StringType)
+ , m_string(string)
+{
+ ASSERT(!m_string.isNull());
+}
+
+IDBKeyPath::IDBKeyPath(const Vector<String>& array)
+ : m_type(ArrayType)
+ , m_array(array)
+{
+#ifndef NDEBUG
+ for (size_t i = 0; i < m_array.size(); ++i)
+ ASSERT(!m_array[i].isNull());
+#endif
+}
+
+bool IDBKeyPath::isValid() const
+{
+ switch (m_type) {
+ case NullType:
+ return false;
+
+ case StringType:
+ return IDBIsValidKeyPath(m_string);
+
+ case ArrayType:
+ for (size_t i = 0; i < m_array.size(); ++i) {
+ if (!IDBIsValidKeyPath(m_array[i]))
+ return false;
+ }
+ return true;
+ }
+ ASSERT_NOT_REACHED();
+ return false;
+}
+
+IDBKeyPath::operator PassRefPtr<IDBAny>() const
+{
+ switch (m_type) {
+ case NullType:
+ return IDBAny::createNull();
+ case StringType:
+ return IDBAny::createString(m_string);
+ case ArrayType:
+ RefPtr<DOMStringList> keyPaths = DOMStringList::create();
+ for (Vector<String>::const_iterator it = m_array.begin(); it != m_array.end(); ++it)
+ keyPaths->append(*it);
+ return IDBAny::create(static_cast<PassRefPtr<DOMStringList> >(keyPaths));
+ }
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
+
} // namespace WebCore
#endif // ENABLE(INDEXED_DATABASE)
#if ENABLE(INDEXED_DATABASE)
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
+#include "IDBAny.h"
+#include "PlatformString.h"
#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
namespace WebCore {
IDBKeyPathParseErrorDot,
};
-bool IDBIsValidKeyPath(const String&);
void IDBParseKeyPath(const String&, Vector<String>&, IDBKeyPathParseError&);
+class IDBKeyPath {
+public:
+ IDBKeyPath() : m_type(NullType) { }
+ IDBKeyPath(const String&);
+ IDBKeyPath(const Vector<String>& array);
+
+ enum Type {
+ NullType = 0,
+ StringType,
+ ArrayType
+ };
+
+ Type type() const { return m_type; }
+
+ const Vector<String>& array() const
+ {
+ ASSERT(m_type == ArrayType);
+ return m_array;
+ }
+
+ const String& string() const
+ {
+ ASSERT(m_type == StringType);
+ return m_string;
+ }
+
+ bool isNull() const { return m_type == NullType; }
+ bool isValid() const;
+ operator PassRefPtr<IDBAny>() const;
+
+private:
+ Type m_type;
+ String m_string;
+ Vector<String> m_array;
+};
+
} // namespace WebCore
#endif
namespace WebCore {
-void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>&, const String&, Vector<RefPtr<IDBKey>, 0>&)
+void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>&, const IDBKeyPath&, Vector<RefPtr<IDBKey>, 0>&)
{
// FIXME: Implement this method once JSC supports WireFormat for SerializedScriptValue.
}
-PassRefPtr<SerializedScriptValue> IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const String&)
+PassRefPtr<SerializedScriptValue> IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const IDBKeyPath&)
{
// FIXME: Implement this method once JSC supports WireFormat for SerializedScriptValue.
return PassRefPtr<SerializedScriptValue>();
namespace WebCore {
class IDBKey;
+class IDBKeyPath;
class SerializedScriptValue;
class IDBKeyPathBackendImpl {
public:
- static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const String& keyPath, Vector<RefPtr<IDBKey>, 0>& keys);
- static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const String& keyPath);
+ static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const IDBKeyPath&, Vector<RefPtr<IDBKey>, 0>& keys);
+ static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
};
}
#include <wtf/Assertions.h>
#include "FileSystem.h"
#include "IDBFactoryBackendImpl.h"
+#include "IDBKeyPath.h"
#include "IDBKeyRange.h"
#include "IDBLevelDBCoding.h"
#include "LevelDBComparator.h"
return true;
}
+template <typename DBOrTransaction>
+static bool putIDBKeyPath(DBOrTransaction* db, const Vector<char> key, const IDBKeyPath& value)
+{
+ if (!db->put(key, encodeIDBKeyPath(value)))
+ return false;
+ return true;
+}
+
static int compareKeys(const LevelDBSlice& a, const LevelDBSlice& b)
{
return compare(a, b);
return true;
}
-void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags)
+void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags)
{
const Vector<char> startKey = ObjectStoreMetaDataKey::encode(databaseId, 1, 0);
const Vector<char> stopKey = ObjectStoreMetaDataKey::encodeMaxKey(databaseId);
LOG_ERROR("Internal Indexed DB error.");
return;
}
- String keyPath = decodeString(it->value().begin(), it->value().end());
- bool hasKeyPath = true;
+ IDBKeyPath keyPath = decodeIDBKeyPath(it->value().begin(), it->value().end());
it->next();
if (!checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kAutoIncrement)) {
it->next(); // [optional] has key path (is not null)
if (checkObjectStoreAndMetaDataType(it.get(), stopKey, objectStoreId, ObjectStoreMetaDataKey::kHasKeyPath)) {
- hasKeyPath = decodeBool(it->value().begin(), it->value().end());
- if (!hasKeyPath && !keyPath.isEmpty()) {
+ bool hasKeyPath = decodeBool(it->value().begin(), it->value().end());
+ // This check accounts for two layers of legacy coding:
+ // (1) Initially, hasKeyPath was added to distinguish null vs. string.
+ // (2) Later, null vs. string vs. array was stored in the keyPath itself.
+ // So this check is only relevant for string-type keyPaths.
+ if (!hasKeyPath && (keyPath.type() == IDBKeyPath::StringType && !keyPath.string().isEmpty())) {
LOG_ERROR("Internal Indexed DB error.");
return;
}
+ if (!hasKeyPath)
+ keyPath = IDBKeyPath();
it->next();
}
foundIds.append(objectStoreId);
foundNames.append(objectStoreName);
- foundKeyPaths.append(hasKeyPath ? keyPath : String());
+ foundKeyPaths.append(keyPath);
foundAutoIncrementFlags.append(autoIncrement);
}
}
return objectStoreId;
}
-bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId)
+bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String& name, const IDBKeyPath& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId)
{
ASSERT(m_currentTransaction);
int64_t objectStoreId = getNewObjectStoreId(m_currentTransaction.get(), databaseId);
return false;
}
- ok = putString(m_currentTransaction.get(), keyPathKey, keyPath);
+ ok = putIDBKeyPath(m_currentTransaction.get(), keyPathKey, keyPath);
if (!ok) {
LOG_ERROR("Internal Indexed DB error.");
return false;
}
-void IDBLevelDBBackingStore::getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags)
+void IDBLevelDBBackingStore::getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags)
{
const Vector<char> startKey = IndexMetaDataKey::encode(databaseId, objectStoreId, 0, 0);
const Vector<char> stopKey = IndexMetaDataKey::encode(databaseId, objectStoreId + 1, 0, 0);
LOG_ERROR("Internal Indexed DB error.");
return;
}
- String keyPath = decodeString(it->value().begin(), it->value().end());
+ IDBKeyPath keyPath = decodeIDBKeyPath(it->value().begin(), it->value().end());
it->next(); // [optional] multiEntry flag
bool indexMultiEntry = false;
return indexId;
}
-bool IDBLevelDBBackingStore::createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const String& keyPath, bool isUnique, bool isMultiEntry, int64_t& indexId)
+bool IDBLevelDBBackingStore::createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath& keyPath, bool isUnique, bool isMultiEntry, int64_t& indexId)
{
ASSERT(m_currentTransaction);
indexId = getNewIndexId(m_currentTransaction.get(), databaseId, objectStoreId);
return false;
}
- ok = putString(m_currentTransaction.get(), keyPathKey, keyPath);
+ ok = putIDBKeyPath(m_currentTransaction.get(), keyPathKey, keyPath);
if (!ok) {
LOG_ERROR("Internal Indexed DB error.");
return false;
virtual bool updateIDBDatabaseMetaData(int64_t rowId, const String& version);
virtual bool deleteDatabase(const String& name);
- virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags);
- virtual bool createObjectStore(int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId);
+ virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags);
+ virtual bool createObjectStore(int64_t databaseId, const String& name, const IDBKeyPath&, bool autoIncrement, int64_t& assignedObjectStoreId);
virtual void deleteObjectStore(int64_t databaseId, int64_t objectStoreId);
virtual PassRefPtr<ObjectStoreRecordIdentifier> createInvalidRecordIdentifier();
virtual String getObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey&);
virtual bool forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback&);
- virtual void getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<String>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags);
- virtual bool createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const String& keyPath, bool isUnique, bool isMultiEntry, int64_t& indexId);
+ virtual void getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags);
+ virtual bool createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry, int64_t& indexId);
virtual void deleteIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId);
virtual bool putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const ObjectStoreRecordIdentifier*);
virtual bool deleteIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const ObjectStoreRecordIdentifier*);
#if USE(LEVELDB)
#include "IDBKey.h"
+#include "IDBKeyPath.h"
#include "LevelDBSlice.h"
#include <wtf/text/StringBuilder.h>
static const unsigned char kIDBKeyArrayTypeByte = 4;
static const unsigned char kIDBKeyMinKeyTypeByte = 5;
+static const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
+static const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
+
static const unsigned char kObjectStoreDataIndexId = 1;
static const unsigned char kExistsEntryIndexId = 2;
return compareEncodedIDBKeys(p, limitA, q, limitB);
}
+Vector<char> encodeIDBKeyPath(const IDBKeyPath& keyPath)
+{
+ // May be typed, or may be a raw string. An invalid leading
+ // byte is used to identify typed coding. New records are
+ // always written as typed.
+ Vector<char> ret;
+ ret.append(kIDBKeyPathTypeCodedByte1);
+ ret.append(kIDBKeyPathTypeCodedByte2);
+ ret.append(static_cast<char>(keyPath.type()));
+ switch (keyPath.type()) {
+ case IDBKeyPath::NullType:
+ break;
+ case IDBKeyPath::StringType:
+ ret.append(encodeStringWithLength(keyPath.string()));
+ break;
+ case IDBKeyPath::ArrayType: {
+ const Vector<String>& array = keyPath.array();
+ size_t count = array.size();
+ ret.append(encodeVarInt(count));
+ for (size_t i = 0; i < count; ++i)
+ ret.append(encodeStringWithLength(array[i]));
+ break;
+ }
+ }
+ return ret;
+}
+
+IDBKeyPath decodeIDBKeyPath(const char* p, const char* limit)
+{
+ // May be typed, or may be a raw string. An invalid leading
+ // byte sequence is used to identify typed coding. New records are
+ // always written as typed.
+ if (p == limit || (limit - p >= 2 && (*p != kIDBKeyPathTypeCodedByte1 || *(p + 1) != kIDBKeyPathTypeCodedByte2)))
+ return IDBKeyPath(decodeString(p, limit));
+ p += 2;
+
+ ASSERT(p != limit);
+ IDBKeyPath::Type type = static_cast<IDBKeyPath::Type>(*p++);
+ switch (type) {
+ case IDBKeyPath::NullType:
+ ASSERT(p == limit);
+ return IDBKeyPath();
+ case IDBKeyPath::StringType: {
+ String string;
+ p = decodeStringWithLength(p, limit, string);
+ ASSERT(p == limit);
+ return IDBKeyPath(string);
+ }
+ case IDBKeyPath::ArrayType: {
+ Vector<String> array;
+ int64_t count;
+ p = decodeVarInt(p, limit, count);
+ ASSERT(p);
+ ASSERT(count >= 0);
+ while (count--) {
+ String string;
+ p = decodeStringWithLength(p, limit, string);
+ ASSERT(p);
+ array.append(string);
+ }
+ ASSERT(p == limit);
+ return IDBKeyPath(array);
+ }
+ }
+ ASSERT_NOT_REACHED();
+ return IDBKeyPath();
+}
+
namespace {
template<typename KeyType>
int decodeAndCompare(const LevelDBSlice& a, const LevelDBSlice& b)
namespace WebCore {
class IDBKey;
+class IDBKeyPath;
class LevelDBSlice;
namespace IDBLevelDBCoding {
const char* decodeIDBKey(const char* p, const char* limit, RefPtr<IDBKey>& foundKey);
const char* extractEncodedIDBKey(const char* start, const char* limit, Vector<char>* result);
int compareEncodedIDBKeys(const Vector<char>&, const Vector<char>&);
+Vector<char> encodeIDBKeyPath(const IDBKeyPath&);
+IDBKeyPath decodeIDBKeyPath(const char*, const char*);
int compare(const LevelDBSlice&, const LevelDBSlice&, bool indexKeys = false);
return m_backend->name();
}
-String IDBObjectStore::keyPath() const
+PassRefPtr<IDBAny> IDBObjectStore::keyPath() const
{
IDB_TRACE("IDBObjectStore::keyPath");
return m_backend->keyPath();
PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const String& keyPath, const Dictionary& options, ExceptionCode& ec)
{
+ return createIndex(name, IDBKeyPath(keyPath), options, ec);
+}
+
+PassRefPtr<IDBIndex> IDBObjectStore::createIndex(const String& name, const IDBKeyPath& keyPath, const Dictionary& options, ExceptionCode& ec)
+{
IDB_TRACE("IDBObjectStore::createIndex");
- if (!IDBIsValidKeyPath(keyPath)) {
+ if (!keyPath.isValid()) {
ec = IDBDatabaseException::NON_TRANSIENT_ERR;
return 0;
}
// Implement the IDBObjectStore IDL
String name() const;
- String keyPath() const;
+ PassRefPtr<IDBAny> keyPath() const;
PassRefPtr<DOMStringList> indexNames() const;
IDBTransaction* transaction() const;
bool autoIncrement() const;
PassRefPtr<IDBRequest> clear(ScriptExecutionContext*, ExceptionCode&);
PassRefPtr<IDBIndex> createIndex(const String& name, const String& keyPath, const Dictionary&, ExceptionCode&);
+ PassRefPtr<IDBIndex> createIndex(const String&, const IDBKeyPath&, const Dictionary&, ExceptionCode&);
+
PassRefPtr<IDBIndex> index(const String& name, ExceptionCode&);
void deleteIndex(const String& name, ExceptionCode&);
Conditional=INDEXED_DATABASE
] IDBObjectStore {
readonly attribute [TreatReturnedNullStringAs=Null] DOMString name;
- readonly attribute [TreatReturnedNullStringAs=Null] DOMString keyPath;
+ readonly attribute IDBAny keyPath;
readonly attribute DOMStringList indexNames;
readonly attribute IDBTransaction transaction;
readonly attribute boolean autoIncrement;
{
}
-IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, int64_t id, const String& name, const String& keyPath, bool autoIncrement)
+IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, int64_t id, const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
: m_backingStore(backingStore)
, m_databaseId(databaseId)
, m_id(id)
loadIndexes();
}
-IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement)
+IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingStore, int64_t databaseId, const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
: m_backingStore(backingStore)
, m_databaseId(databaseId)
, m_id(InvalidId)
callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData));
}
-static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const String& keyPath)
+static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, const IDBKeyPath& keyPath)
{
IDB_TRACE("IDBObjectStoreBackendImpl::fetchKeyFromKeyPath");
+ ASSERT(!keyPath.isNull());
+
Vector<RefPtr<SerializedScriptValue> > values;
values.append(value);
Vector<RefPtr<IDBKey> > keys;
return keys[0].release();
}
-static PassRefPtr<SerializedScriptValue> injectKeyIntoKeyPath(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
+static PassRefPtr<SerializedScriptValue> injectKeyIntoKeyPath(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
{
IDB_TRACE("IDBObjectStoreBackendImpl::injectKeyIntoKeyPath");
return IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(key, value, keyPath);
return true;
}
-PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(const String& name, const String& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
+PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendImpl::createIndex(const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
if (name.isNull()) {
ec = IDBDatabaseException::NON_TRANSIENT_ERR;
{
Vector<int64_t> ids;
Vector<String> names;
- Vector<String> keyPaths;
+ Vector<IDBKeyPath> keyPaths;
Vector<bool> uniqueFlags;
Vector<bool> multiEntryFlags;
backingStore()->getIndexes(databaseId(), m_id, ids, names, keyPaths, uniqueFlags, multiEntryFlags);
#ifndef IDBObjectStoreBackendImpl_h
#define IDBObjectStoreBackendImpl_h
+#include "IDBKeyPath.h"
#include "IDBObjectStoreBackendInterface.h"
#include <wtf/HashMap.h>
#include <wtf/text/StringHash.h>
class IDBObjectStoreBackendImpl : public IDBObjectStoreBackendInterface {
public:
- static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, int64_t id, const String& name, const String& keyPath, bool autoIncrement)
+ static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, int64_t id, const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
{
return adoptRef(new IDBObjectStoreBackendImpl(backingStore, databaseId, id, name, keyPath, autoIncrement));
}
- static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement)
+ static PassRefPtr<IDBObjectStoreBackendImpl> create(IDBBackingStore* backingStore, int64_t databaseId, const String& name, const IDBKeyPath& keyPath, bool autoIncrement)
{
return adoptRef(new IDBObjectStoreBackendImpl(backingStore, databaseId, name, keyPath, autoIncrement));
}
void setId(int64_t id) { m_id = id; }
virtual String name() const { return m_name; }
- virtual String keyPath() const { return m_keyPath; }
+ virtual IDBKeyPath keyPath() const { return m_keyPath; }
virtual PassRefPtr<DOMStringList> indexNames() const;
virtual bool autoIncrement() const { return m_autoIncrement; }
virtual void deleteFunction(PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&);
- virtual PassRefPtr<IDBIndexBackendInterface> createIndex(const String& name, const String& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&);
+ virtual PassRefPtr<IDBIndexBackendInterface> createIndex(const String& name, const IDBKeyPath&, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&);
virtual PassRefPtr<IDBIndexBackendInterface> index(const String& name, ExceptionCode&);
virtual void deleteIndex(const String& name, IDBTransactionBackendInterface*, ExceptionCode&);
static bool populateIndex(IDBBackingStore&, int64_t databaseId, int64_t objectStoreId, PassRefPtr<IDBIndexBackendImpl>);
private:
- IDBObjectStoreBackendImpl(IDBBackingStore*, int64_t databaseId, int64_t id, const String& name, const String& keyPath, bool autoIncrement);
- IDBObjectStoreBackendImpl(IDBBackingStore*, int64_t databaseId, const String& name, const String& keyPath, bool autoIncrement);
+ IDBObjectStoreBackendImpl(IDBBackingStore*, int64_t databaseId, int64_t id, const String& name, const IDBKeyPath&, bool autoIncrement);
+ IDBObjectStoreBackendImpl(IDBBackingStore*, int64_t databaseId, const String& name, const IDBKeyPath&, bool autoIncrement);
void loadIndexes();
PassRefPtr<IDBKey> genAutoIncrementKey();
int64_t m_databaseId;
int64_t m_id;
String m_name;
- String m_keyPath;
+ IDBKeyPath m_keyPath;
bool m_autoIncrement;
typedef HashMap<String, RefPtr<IDBIndexBackendImpl> > IndexMap;
class IDBCallbacks;
class IDBIndexBackendInterface;
class IDBKey;
+class IDBKeyPath;
class IDBKeyRange;
class IDBTransactionBackendInterface;
class SerializedScriptValue;
virtual ~IDBObjectStoreBackendInterface() { }
virtual String name() const = 0;
- virtual String keyPath() const = 0;
+ virtual IDBKeyPath keyPath() const = 0;
virtual PassRefPtr<DOMStringList> indexNames() const = 0;
virtual bool autoIncrement() const = 0;
virtual void clear(PassRefPtr<IDBCallbacks>, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
- virtual PassRefPtr<IDBIndexBackendInterface> createIndex(const String& name, const String& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
+ virtual PassRefPtr<IDBIndexBackendInterface> createIndex(const String& name, const IDBKeyPath&, bool unique, bool multiEntry, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
virtual PassRefPtr<IDBIndexBackendInterface> index(const String& name, ExceptionCode&) = 0;
virtual void deleteIndex(const String& name, IDBTransactionBackendInterface*, ExceptionCode&) = 0;
return true;
}
+bool Dictionary::get(const String& key, Vector<String>& value) const
+{
+ v8::Local<v8::Value> v8Value;
+ if (!getKey(key, v8Value))
+ return false;
+
+ if (!v8Value->IsArray())
+ return false;
+
+ v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
+ for (size_t i = 0; i < v8Array->Length(); ++i) {
+ v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(i));
+ value.append(v8ValueToWebCoreString(indexedValue));
+ }
+
+ return true;
+}
bool Dictionary::getOwnPropertiesAsStringHashMap(WTF::HashMap<String, String>& hashMap) const
{
#include <v8.h>
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
+#include <wtf/Vector.h>
#include <wtf/text/AtomicString.h>
namespace WebCore {
-class DOMStringList;
class DOMWindow;
class IDBKeyRange;
class MediaKeyError;
#endif
bool get(const String&, HashSet<AtomicString>&) const;
bool get(const String&, Dictionary&) const;
+ bool get(const String&, Vector<String>&) const;
bool getOwnPropertiesAsStringHashMap(WTF::HashMap<String, String>&) const;
bool getWithUndefinedOrNullCheck(const String&, String&) const;
} // anonymous namespace
-PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const Vector<String>& keyPath)
+PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
{
IDB_TRACE("createIDBKeyFromSerializedValueAndKeyPath");
+ ASSERT(keyPath.type() == IDBKeyPath::StringType);
+ Vector<String> keyPathElements;
+ IDBKeyPathParseError error;
+ IDBParseKeyPath(keyPath.string(), keyPathElements, error);
+ ASSERT(error == IDBKeyPathParseErrorNone);
+
V8AuxiliaryContext context;
v8::Handle<v8::Value> v8Value(value->deserialize());
- v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPath, keyPath.size()));
+ v8::Handle<v8::Value> v8Key(getNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size()));
if (v8Key.IsEmpty())
return 0;
return createIDBKeyFromValue(v8Key);
}
-PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const Vector<String>& keyPath)
+PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
{
IDB_TRACE("injectIDBKeyIntoSerializedValue");
- V8AuxiliaryContext context;
- if (!keyPath.size())
+
+ ASSERT(keyPath.type() == IDBKeyPath::StringType);
+ Vector<String> keyPathElements;
+ IDBKeyPathParseError error;
+ IDBParseKeyPath(keyPath.string(), keyPathElements, error);
+ ASSERT(error == IDBKeyPathParseErrorNone);
+
+ if (!keyPathElements.size())
return 0;
+ V8AuxiliaryContext context;
v8::Handle<v8::Value> v8Value(value->deserialize());
- v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(v8Value, keyPath, keyPath.size() - 1));
+ v8::Handle<v8::Value> parent(ensureNthValueOnKeyPath(v8Value, keyPathElements, keyPathElements.size() - 1));
if (parent.IsEmpty())
return 0;
- if (!set(parent, keyPath.last(), toV8(key.get())))
+ if (!set(parent, keyPathElements.last(), toV8(key.get())))
return 0;
return SerializedScriptValue::create(v8Value);
namespace WebCore {
class IDBKey;
+class IDBKeyPath;
class SerializedScriptValue;
PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value>);
-PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue>, const Vector<String, 0>&);
-PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const Vector<String, 0>&);
+PassRefPtr<IDBKey> createIDBKeyFromSerializedValueAndKeyPath(PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
+PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
}
#include "V8IDBAny.h"
#include "SerializedScriptValue.h"
+#include "V8Binding.h"
#include "V8DOMStringList.h"
#include "V8IDBCursor.h"
#include "V8IDBCursorWithValue.h"
return toV8(impl->idbTransaction(), isolate);
case IDBAny::SerializedScriptValueType:
return impl->serializedScriptValue()->deserialize(0, isolate);
+ case IDBAny::StringType:
+ return v8String(impl->string());
}
ASSERT_NOT_REACHED();
String item(unsigned index) const;
bool contains(const String& str) const;
+ operator const Vector<String>&() const { return m_strings; }
+
private:
DOMStringList() { }
#include "IDBFactoryBackendInterface.h"
#include "IDBIndexBackendInterface.h"
#include "IDBKey.h"
+#include "IDBKeyPath.h"
#include "IDBKeyRange.h"
#include "IDBObjectStoreBackendInterface.h"
#include "IDBPendingTransactionMonitor.h"
return idbIndex;
}
+static String keyPathToString(const IDBKeyPath& keyPath)
+{
+ // FIXME: Replace with handlers for null/string/array types.
+ // https://bugs.webkit.org/show_bug.cgi?id=84303
+ switch (keyPath.type()) {
+ case IDBKeyPath::NullType:
+ return "(none)";
+ break;
+ case IDBKeyPath::StringType:
+ return keyPath.string();
+ break;
+ case IDBKeyPath::ArrayType:
+ return "[...]";
+ break;
+ }
+ ASSERT_NOT_REACHED();
+ return String();
+}
+
class DatabaseLoaderCallback : public ExecutableWithDatabase {
public:
static PassRefPtr<DatabaseLoaderCallback> create(InspectorIndexedDBAgent::FrontendProvider* frontendProvider, int requestId)
RefPtr<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create()
.setName(idbIndex->name())
- .setKeyPath(idbIndex->keyPath())
+ .setKeyPath(keyPathToString(idbIndex->keyPath()))
.setUnique(idbIndex->unique())
.setMultiEntry(idbIndex->multiEntry());
indexes->addItem(objectStoreIndex);
RefPtr<ObjectStore> objectStore = ObjectStore::create()
.setName(idbObjectStore->name())
- .setKeyPath(idbObjectStore->keyPath())
+ .setKeyPath(keyPathToString(idbObjectStore->keyPath()))
.setIndexes(indexes);
objectStores->addItem(objectStore);
}
class Image;
class IDBFactoryBackendInterface;
class IDBKey;
+class IDBKeyPath;
class IntRect;
class KURL;
class SerializedScriptValue;
// IndexedDB ----------------------------------------------------------
static PassRefPtr<IDBFactoryBackendInterface> idbFactory();
// Extracts keyPath from values and returns the corresponding keys.
- static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys);
+ static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const IDBKeyPath&, Vector<RefPtr<IDBKey> >& keys);
// Injects key via keyPath into value. Returns true on success.
- static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const String& keyPath);
+ static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const IDBKeyPath&);
// JavaScript ---------------------------------------------------------
static void notifyJSOutOfMemory(Frame*);
namespace WebCore {
-void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const String& keyPath, Vector<RefPtr<IDBKey>, 0>& keys)
+void IDBKeyPathBackendImpl::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue>, 0>& values, const IDBKeyPath& keyPath, Vector<RefPtr<IDBKey>, 0>& keys)
{
PlatformSupport::createIDBKeysFromSerializedValuesAndKeyPath(values, keyPath, keys);
}
-PassRefPtr<SerializedScriptValue> IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
+PassRefPtr<SerializedScriptValue> IDBKeyPathBackendImpl::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
{
return PlatformSupport::injectIDBKeyIntoSerializedValue(key, value, keyPath);
}
+2012-05-21 Joshua Bell <jsbell@chromium.org>
+
+ IndexedDB: Store key paths in IDBKeyPath type instead of String
+ https://bugs.webkit.org/show_bug.cgi?id=85298
+
+ Reviewed by Tony Chang, Kentaro Hara and James Robinson.
+
+ No functional changes, just finish migration from String to IDBKeyPath
+ for storing key paths, for eventual array support http://webkit.org/b/84207
+
+ * public/WebIDBDatabase.h: Remove temporary overload.
+ (WebKit):
+ (WebKit::WebIDBDatabase::objectStoreNames):
+ * public/WebIDBIndex.h: Remove temporary method.
+ (WebKit::WebIDBIndex::keyPath):
+ * public/WebIDBKeyPath.h: Remove obsolete methods, wrap WebCore::IDBKeyPath
+ (WebIDBKeyPath):
+ (WebKit::WebIDBKeyPath::WebIDBKeyPath):
+ * public/WebIDBObjectStore.h: Remove temporary method and overload.
+ (WebKit::WebIDBObjectStore::keyPath):
+ * public/platform/WebKitPlatformSupport.h: Remove temporary overloads.
+ (WebKit):
+ * src/AssertMatchingEnums.cpp: WebIDBKeyPath vs. IDBKeyPath enums.
+ * src/IDBDatabaseBackendProxy.cpp: Switch from String to IDBKeyPath.
+ (WebKit::IDBDatabaseBackendProxy::createObjectStore):
+ * src/IDBDatabaseBackendProxy.h: Switch from String to IDBKeyPath.
+ (IDBDatabaseBackendProxy):
+ * src/IDBIndexBackendProxy.cpp: Switch from String to IDBKeyPath.
+ (WebKit::IDBIndexBackendProxy::keyPath):
+ * src/IDBIndexBackendProxy.h: Switch from String to IDBKeyPath.
+ (IDBIndexBackendProxy):
+ * src/IDBObjectStoreBackendProxy.cpp: Switch from String to IDBKeyPath.
+ (WebKit::IDBObjectStoreBackendProxy::keyPath):
+ (WebKit::IDBObjectStoreBackendProxy::createIndex):
+ * src/IDBObjectStoreBackendProxy.h: Switch from String to IDBKeyPath.
+ (IDBObjectStoreBackendProxy):
+ * src/PlatformSupport.cpp: Switch from String to IDBKeyPath.
+ (WebCore::PlatformSupport::createIDBKeysFromSerializedValuesAndKeyPath):
+ (WebCore::PlatformSupport::injectIDBKeyIntoSerializedValue):
+ * src/WebIDBDatabaseImpl.cpp: Switch from String to IDBKeyPath.
+ (WebKit::WebIDBDatabaseImpl::createObjectStore):
+ * src/WebIDBDatabaseImpl.h: Remove temporary overload.
+ (WebIDBDatabaseImpl):
+ * src/WebIDBIndexImpl.cpp: Remove temporary method.
+ * src/WebIDBIndexImpl.h: Remove temporary method.
+ (WebIDBIndexImpl):
+ * src/WebIDBKeyPath.cpp: Remove most logic; just a wrapper for WebCore::IDBKeyPath.
+ (WebKit::WebIDBKeyPath::~WebIDBKeyPath):
+ (WebKit::WebIDBKeyPath::create):
+ (WebKit::WebIDBKeyPath::createNull):
+ (WebKit::WebIDBKeyPath::isValid):
+ (WebKit::WebIDBKeyPath::type):
+ (WebKit):
+ (WebKit::WebIDBKeyPath::array):
+ (WebKit::WebIDBKeyPath::string):
+ (WebKit::WebIDBKeyPath::WebIDBKeyPath):
+ (WebKit::WebIDBKeyPath::operator=):
+ (WebKit::WebIDBKeyPath::operator const WebCore::IDBKeyPath&):
+ * src/WebIDBObjectStoreImpl.cpp: Remove temporary method and overload.
+ (WebKit::WebIDBObjectStoreImpl::keyPath):
+ (WebKit::WebIDBObjectStoreImpl::createIndex):
+ * src/WebIDBObjectStoreImpl.h: Remove temporary method and overload.
+ (WebIDBObjectStoreImpl):
+ * tests/IDBBindingUtilitiesTest.cpp: Use IDBKeyPath.
+ (WebCore::checkKeyFromValueAndKeyPathInternal):
+ (WebCore::injectKey):
+ * tests/IDBLevelDBCodingTest.cpp: Added EncodeIDBKeyPath and DecodeIDBKeyPath tests.
+ (IDBLevelDBCoding::TEST):
+ (IDBLevelDBCoding):
+ * tests/IDBKeyPathTest.cpp:
+ (WebCore::checkKeyPath): Test IDBKeyPath validity.
+
2012-05-18 Michael Nordman <michaeln@google.com>
[chromium] DomStorage events handling needs TLC (2)
#include "WebDOMStringList.h"
#include "WebExceptionCode.h"
-#include "WebIDBKeyPath.h"
#include "platform/WebCommon.h"
namespace WebKit {
class WebFrame;
class WebIDBCallbacks;
class WebIDBDatabaseCallbacks;
+class WebIDBKeyPath;
class WebIDBObjectStore;
class WebIDBTransaction;
WEBKIT_ASSERT_NOT_REACHED();
return WebDOMStringList();
}
- // FIXME: Remove WebString keyPath overload once callers are updated.
- // http://webkit.org/b/84207
- virtual WebIDBObjectStore* createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, const WebIDBTransaction& transaction, WebExceptionCode& ec)
- {
- return createObjectStore(name, WebIDBKeyPath(keyPath), autoIncrement, transaction, ec);
- }
virtual WebIDBObjectStore* createObjectStore(const WebString&, const WebIDBKeyPath&, bool, const WebIDBTransaction&, WebExceptionCode&)
{
WEBKIT_ASSERT_NOT_REACHED();
}
virtual WebIDBKeyPath keyPath() const
{
- return WebIDBKeyPath(keyPathString());
- }
- // FIXME: Remove method once callers are updated.
- // http://webkit.org/b/84207
- virtual WebString keyPathString() const
- {
WEBKIT_ASSERT_NOT_REACHED();
- return WebString();
+ return WebIDBKeyPath::createNull();
}
virtual bool unique() const
{
class String;
}
+namespace WebCore { class IDBKeyPath; }
+
namespace WebKit {
class WebIDBKeyPath {
WEBKIT_EXPORT static WebIDBKeyPath create(const WebVector<WebString>&);
WEBKIT_EXPORT static WebIDBKeyPath createNull();
WEBKIT_EXPORT WebIDBKeyPath(const WebIDBKeyPath&);
- ~WebIDBKeyPath() { reset(); }
+ WEBKIT_EXPORT ~WebIDBKeyPath();
enum Type {
NullType = 0,
WEBKIT_EXPORT bool isValid() const;
WEBKIT_EXPORT Type type() const;
- // FIXME: Array-type key paths not yet supported. http://webkit.org/b/84207
- WebVector<WebString> array() const { WEBKIT_ASSERT_NOT_REACHED(); return WebVector<WebString>(); }
- WEBKIT_EXPORT WebString string() const;
-
- // FIXME: Remove these once callers are updated. http://webkit.org/b/84207
- WEBKIT_EXPORT WebIDBKeyPath(const WebString&);
- operator const WebString () const { return string(); }
- WEBKIT_EXPORT int parseError() const;
- WEBKIT_EXPORT void assign(const WebIDBKeyPath&);
- WEBKIT_EXPORT void reset();
+ WEBKIT_EXPORT WebVector<WebString> array() const; // Only valid for ArrayType.
+ WEBKIT_EXPORT WebString string() const; // Only valid for StringType.
#if WEBKIT_IMPLEMENTATION
- operator const WTF::Vector<WTF::String, 0>& () const;
+ WebIDBKeyPath(const WebCore::IDBKeyPath&);
+ WebIDBKeyPath& operator=(const WebCore::IDBKeyPath&);
+ operator const WebCore::IDBKeyPath&() const;
#endif
private:
- WebIDBKeyPath();
-
-#if WEBKIT_IMPLEMENTATION
- WebIDBKeyPath(const WTF::Vector<WTF::String, 0>&, int parseError);
-#endif
-
- WebPrivateOwnPtr<WTF::Vector<WTF::String, 0> > m_private;
- int m_parseError;
+ WebPrivateOwnPtr<WebCore::IDBKeyPath> m_private;
};
} // namespace WebKit
#include "WebDOMStringList.h"
#include "WebIDBCallbacks.h"
#include "WebIDBKeyPath.h"
-#include "WebIDBTransaction.h"
#include "platform/WebCommon.h"
#include "platform/WebString.h"
}
virtual WebIDBKeyPath keyPath() const
{
- return WebIDBKeyPath(keyPathString());
- }
- virtual WebString keyPathString() const
- {
WEBKIT_ASSERT_NOT_REACHED();
- return WebString();
+ return WebIDBKeyPath::createNull();
}
virtual WebDOMStringList indexNames() const
{
virtual void deleteFunction(const WebIDBKey&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
virtual void deleteFunction(const WebIDBKeyRange&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
virtual void clear(WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&) { WEBKIT_ASSERT_NOT_REACHED(); }
-
- // FIXME: Remove WebString keyPath overload once callers are updated.
- // http://webkit.org/b/84207
- virtual WebIDBIndex* createIndex(const WebString& name, const WebString& keyPath, bool unique, bool multiEntry, const WebIDBTransaction& transaction, WebExceptionCode& ec)
- {
- return createIndex(name, WebIDBKeyPath(keyPath), unique, multiEntry, transaction, ec);
- }
virtual WebIDBIndex* createIndex(const WebString&, const WebIDBKeyPath&, bool, bool, const WebIDBTransaction&, WebExceptionCode&)
{
WEBKIT_ASSERT_NOT_REACHED();
#ifndef WebKitPlatformSupport_h
#define WebKitPlatformSupport_h
-#include "../WebIDBKeyPath.h" // FIXME: Remove with: http://webkit.org/b/84207
#include "WebCommon.h"
#include "WebGraphicsContext3D.h"
#include "WebLocalizedString.h"
class WebCookieJar;
class WebIDBFactory; // FIXME: Does this belong in platform?
class WebIDBKey; // FIXME: Does this belong in platform?
+class WebIDBKeyPath; // FIXME: Does this belong in platform?
class WebMessagePortChannel; // FIXME: Does this belong in platform?
class WebPluginListBuilder; // FIXME: Does this belong in platform?
class WebSandboxSupport;
// Indexed Database ----------------------------------------------------
virtual WebIDBFactory* idbFactory() { return 0; }
- // FIXME: Remove WebString keyPath overload once callers are updated.
- // http://webkit.org/b/84207
- virtual void createIDBKeysFromSerializedValuesAndKeyPath(const WebVector<WebSerializedScriptValue>& values, const WebString& keyPath, WebVector<WebIDBKey>& keys) { createIDBKeysFromSerializedValuesAndKeyPath(values, WebIDBKeyPath(keyPath), keys); }
virtual void createIDBKeysFromSerializedValuesAndKeyPath(const WebVector<WebSerializedScriptValue>& values, const WebIDBKeyPath& keyPath, WebVector<WebIDBKey>& keys) { }
- // FIXME: Remove WebString keyPath overload once callers are updated.
- // http://webkit.org/b/84207
- virtual WebSerializedScriptValue injectIDBKeyIntoSerializedValue(const WebIDBKey& key, const WebSerializedScriptValue& value, const WebString& keyPath) { return injectIDBKeyIntoSerializedValue(key, value, WebIDBKeyPath(keyPath)); }
virtual WebSerializedScriptValue injectIDBKeyIntoSerializedValue(const WebIDBKey& key, const WebSerializedScriptValue& value, const WebIDBKeyPath& keyPath) { return WebSerializedScriptValue(); }
#include "IDBDatabaseException.h"
#include "IDBFactoryBackendInterface.h"
#include "IDBKey.h"
+#include "IDBKeyPath.h"
#include "IceOptions.h"
#include "IconURL.h"
#include "MediaPlayer.h"
#include "WebIDBDatabaseException.h"
#include "WebIDBFactory.h"
#include "WebIDBKey.h"
+#include "WebIDBKeyPath.h"
#include "WebIconURL.h"
#include "WebInputElement.h"
#include "WebMediaPlayer.h"
COMPILE_ASSERT_MATCHING_ENUM(WebIDBDatabaseExceptionDataError, IDBDatabaseException::DATA_ERR);
COMPILE_ASSERT_MATCHING_ENUM(WebIDBDatabaseExceptionQuotaError, IDBDatabaseException::QUOTA_ERR);
+#if ENABLE(INDEXED_DATABASE)
COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::InvalidType, IDBKey::InvalidType);
COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::ArrayType, IDBKey::ArrayType);
COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::StringType, IDBKey::StringType);
COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::DateType, IDBKey::DateType);
COMPILE_ASSERT_MATCHING_ENUM(WebIDBKey::NumberType, IDBKey::NumberType);
+COMPILE_ASSERT_MATCHING_ENUM(WebIDBKeyPath::NullType, IDBKeyPath::NullType);
+COMPILE_ASSERT_MATCHING_ENUM(WebIDBKeyPath::StringType, IDBKeyPath::StringType);
+COMPILE_ASSERT_MATCHING_ENUM(WebIDBKeyPath::ArrayType, IDBKeyPath::ArrayType);
+#endif
+
#if ENABLE(FILE_SYSTEM)
COMPILE_ASSERT_MATCHING_ENUM(WebFileSystem::TypeTemporary, FileSystemTypeTemporary);
COMPILE_ASSERT_MATCHING_ENUM(WebFileSystem::TypePersistent, FileSystemTypePersistent);
return m_webIDBDatabase->objectStoreNames();
}
-PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendProxy::createObjectStore(const String& name, const String& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
+PassRefPtr<IDBObjectStoreBackendInterface> IDBDatabaseBackendProxy::createObjectStore(const String& name, const IDBKeyPath& keyPath, bool autoIncrement, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
// The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer,
// all implementations of IDB interfaces are proxy objects.
virtual String version() const;
virtual PassRefPtr<WebCore::DOMStringList> objectStoreNames() const;
- virtual PassRefPtr<WebCore::IDBObjectStoreBackendInterface> createObjectStore(const String& name, const String& keyPath, bool autoIncrement, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
+ virtual PassRefPtr<WebCore::IDBObjectStoreBackendInterface> createObjectStore(const String& name, const WebCore::IDBKeyPath&, bool autoIncrement, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
virtual void deleteObjectStore(const String& name, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
virtual void setVersion(const String& version, PassRefPtr<WebCore::IDBCallbacks>, PassRefPtr<WebCore::IDBDatabaseCallbacks>, WebCore::ExceptionCode&);
virtual PassRefPtr<WebCore::IDBTransactionBackendInterface> transaction(WebCore::DOMStringList* storeNames, unsigned short mode, WebCore::ExceptionCode&);
#if ENABLE(INDEXED_DATABASE)
#include "IDBCallbacks.h"
+#include "IDBKeyPath.h"
#include "IDBKeyRange.h"
#include "IDBTransactionBackendProxy.h"
#include "WebIDBCallbacksImpl.h"
return m_webIDBIndex->name();
}
-String IDBIndexBackendProxy::keyPath()
+IDBKeyPath IDBIndexBackendProxy::keyPath()
{
- return m_webIDBIndex->keyPath().string();
+ return m_webIDBIndex->keyPath();
}
bool IDBIndexBackendProxy::unique()
#if ENABLE(INDEXED_DATABASE)
#include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
virtual ~IDBIndexBackendProxy();
virtual String name();
- virtual String keyPath();
+ virtual WebCore::IDBKeyPath keyPath();
virtual bool unique();
virtual bool multiEntry();
return m_webIDBObjectStore->name();
}
-String IDBObjectStoreBackendProxy::keyPath() const
+IDBKeyPath IDBObjectStoreBackendProxy::keyPath() const
{
- return m_webIDBObjectStore->keyPath().string();
+ return m_webIDBObjectStore->keyPath();
}
PassRefPtr<DOMStringList> IDBObjectStoreBackendProxy::indexNames() const
m_webIDBObjectStore->clear(new WebIDBCallbacksImpl(callbacks), *transactionProxy->getWebIDBTransaction(), ec);
}
-PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendProxy::createIndex(const String& name, const String& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
+PassRefPtr<IDBIndexBackendInterface> IDBObjectStoreBackendProxy::createIndex(const String& name, const IDBKeyPath& keyPath, bool unique, bool multiEntry, IDBTransactionBackendInterface* transaction, ExceptionCode& ec)
{
// The transaction pointer is guaranteed to be a pointer to a proxy object as, in the renderer,
// all implementations of IDB interfaces are proxy objects.
#if ENABLE(INDEXED_DATABASE)
+#include "IDBKeyPath.h"
#include "IDBObjectStoreBackendInterface.h"
#include <wtf/OwnPtr.h>
#include <wtf/PassOwnPtr.h>
virtual ~IDBObjectStoreBackendProxy();
virtual String name() const;
- virtual String keyPath() const;
+ virtual WebCore::IDBKeyPath keyPath() const;
virtual PassRefPtr<WebCore::DOMStringList> indexNames() const;
virtual bool autoIncrement() const;
virtual void deleteFunction(PassRefPtr<WebCore::IDBKeyRange>, PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
virtual void clear(PassRefPtr<WebCore::IDBCallbacks>, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
- PassRefPtr<WebCore::IDBIndexBackendInterface> createIndex(const String& name, const String& keyPath, bool unique, bool multiEntry, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
+ PassRefPtr<WebCore::IDBIndexBackendInterface> createIndex(const String& name, const WebCore::IDBKeyPath&, bool unique, bool multiEntry, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
PassRefPtr<WebCore::IDBIndexBackendInterface> index(const String& name, WebCore::ExceptionCode&);
void deleteIndex(const String& name, WebCore::IDBTransactionBackendInterface*, WebCore::ExceptionCode&);
#include "WebFrameClient.h"
#include "WebFrameImpl.h"
#include "WebIDBKey.h"
+#include "WebIDBKeyPath.h"
#include "WebKit.h"
#include "WebPluginContainerImpl.h"
#include "WebPluginListBuilderImpl.h"
return IDBFactoryBackendProxy::create();
}
-void PlatformSupport::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys)
+void PlatformSupport::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const IDBKeyPath& keyPath, Vector<RefPtr<IDBKey> >& keys)
{
WebVector<WebSerializedScriptValue> webValues = values;
WebVector<WebIDBKey> webKeys;
keys.append(PassRefPtr<IDBKey>(webKeys[i]));
}
-PassRefPtr<SerializedScriptValue> PlatformSupport::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
+PassRefPtr<SerializedScriptValue> PlatformSupport::injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const IDBKeyPath& keyPath)
{
return webKitPlatformSupport()->injectIDBKeyIntoSerializedValue(key, value, keyPath);
}
return m_databaseBackend->objectStoreNames();
}
-WebIDBObjectStore* WebIDBDatabaseImpl::createObjectStore(const WebString& name, const WebString& keyPath, bool autoIncrement, const WebIDBTransaction& transaction, WebExceptionCode& ec)
+WebIDBObjectStore* WebIDBDatabaseImpl::createObjectStore(const WebString& name, const WebIDBKeyPath& keyPath, bool autoIncrement, const WebIDBTransaction& transaction, WebExceptionCode& ec)
{
RefPtr<IDBObjectStoreBackendInterface> objectStore = m_databaseBackend->createObjectStore(name, keyPath, autoIncrement, transaction.getIDBTransactionBackendInterface(), ec);
if (!objectStore) {
virtual WebString version() const;
virtual WebDOMStringList objectStoreNames() const;
- // FIXME: Remove WebString keyPath overload once callers are updated.
- // http://webkit.org/b/84207
- virtual WebIDBObjectStore* createObjectStore(const WebString&, const WebString&, bool, const WebIDBTransaction&, WebExceptionCode&);
- virtual WebIDBObjectStore* createObjectStore(const WebString& name, const WebIDBKeyPath& keyPath, bool autoIncrement, const WebIDBTransaction& transaction, WebExceptionCode& ec) { return createObjectStore(name, keyPath.string(), autoIncrement, transaction, ec); }
+ virtual WebIDBObjectStore* createObjectStore(const WebString& name, const WebIDBKeyPath&, bool autoIncrement, const WebIDBTransaction&, WebExceptionCode&);
virtual void deleteObjectStore(const WebString& name, const WebIDBTransaction&, WebExceptionCode&);
virtual void setVersion(const WebString& version, WebIDBCallbacks*, WebExceptionCode&);
virtual WebIDBTransaction* transaction(const WebDOMStringList& names, unsigned short mode, WebExceptionCode&);
return WebIDBKeyPath(m_backend->keyPath());
}
-// FIXME: Remove this method once callers are updated.
-// http://webkit.org/b/84207
-WebString WebIDBIndexImpl::keyPathString() const
-{
- return m_backend->keyPath();
-}
-
bool WebIDBIndexImpl::unique() const
{
return m_backend->unique();
virtual WebString name() const;
virtual WebIDBKeyPath keyPath() const;
- // FIXME: Remove this method once callers are updated.
- // http://webkit.org/b/84207
- virtual WebString keyPathString() const;
virtual bool unique() const;
virtual bool multiEntry() const;
namespace WebKit {
-WebIDBKeyPath WebIDBKeyPath::create(const WebVector<WebString>&)
+WebIDBKeyPath::~WebIDBKeyPath()
{
- // FIXME: Array-type key paths not yet supported. http://webkit.org/b/84207
- WEBKIT_ASSERT_NOT_REACHED();
- return createNull();
+ m_private.reset(0);
}
WebIDBKeyPath WebIDBKeyPath::create(const WebString& keyPath)
{
- if (keyPath.isNull())
- return createNull();
-
- WTF::Vector<WTF::String> idbElements;
- IDBKeyPathParseError idbError;
- IDBParseKeyPath(keyPath, idbElements, idbError);
- return WebIDBKeyPath(idbElements, static_cast<int>(idbError));
-}
-
-WebIDBKeyPath WebIDBKeyPath::createNull()
-{
- return WebIDBKeyPath(WebString());
+ return WebIDBKeyPath(IDBKeyPath(keyPath));
}
-WebIDBKeyPath::WebIDBKeyPath(const WebIDBKeyPath& keyPath)
+WebIDBKeyPath WebIDBKeyPath::create(const WebVector<WebString>& keyPath)
{
- assign(keyPath);
+ Vector<String> strings;
+ for (size_t i = 0; i < keyPath.size(); ++i)
+ strings.append(keyPath[i]);
+ return WebIDBKeyPath(IDBKeyPath(strings));
}
-WebIDBKeyPath::WebIDBKeyPath(const WTF::Vector<WTF::String>& elements, int parseError)
- : m_private(new WTF::Vector<WTF::String>(elements))
- , m_parseError(parseError)
+WebIDBKeyPath WebIDBKeyPath::createNull()
{
+ return WebIDBKeyPath(IDBKeyPath());
}
bool WebIDBKeyPath::isValid() const
{
- return m_parseError == IDBKeyPathParseErrorNone;
+ ASSERT(m_private.get());
+ return m_private->isValid();
}
WebIDBKeyPath::Type WebIDBKeyPath::type() const
{
- return m_private.get() ? StringType : NullType;
+ ASSERT(m_private.get());
+ return Type(m_private->type());
}
-WebString WebIDBKeyPath::string() const
+
+WebVector<WebString> WebIDBKeyPath::array() const
{
- if (!m_private.get())
- return WebString();
-
- // FIXME: Store the complete string instead of rebuilding it.
- // http://webkit.org/b/84207
- WTF::String string("");
- WTF::Vector<WTF::String>& array = *m_private.get();
- for (size_t i = 0; i < array.size(); ++i) {
- if (i)
- string.append(".");
- string.append(array[i]);
- }
- return WebString(string);
+ ASSERT(m_private.get());
+ ASSERT(m_private->type() == IDBKeyPath::ArrayType);
+ return m_private->array();
}
-WebIDBKeyPath::WebIDBKeyPath(const WebString& keyPath)
- : m_parseError(IDBKeyPathParseErrorNone)
+WebString WebIDBKeyPath::string() const
{
- if (!keyPath.isNull()) {
- m_private.reset(new WTF::Vector<WTF::String>());
- IDBKeyPathParseError idbParseError;
- IDBParseKeyPath(keyPath, *m_private.get(), idbParseError);
- m_parseError = idbParseError;
- }
+ ASSERT(m_private.get());
+ ASSERT(m_private->type() == IDBKeyPath::StringType);
+ return m_private->string();
}
-int WebIDBKeyPath::parseError() const
+WebIDBKeyPath::WebIDBKeyPath(const WebIDBKeyPath& keyPath)
+ : m_private(new IDBKeyPath(keyPath))
{
- return m_parseError;
+ ASSERT(m_private.get());
}
-void WebIDBKeyPath::assign(const WebIDBKeyPath& keyPath)
+WebIDBKeyPath::WebIDBKeyPath(const WebCore::IDBKeyPath& value)
+ : m_private(new IDBKeyPath(value))
{
- m_parseError = keyPath.m_parseError;
- if (keyPath.m_private.get())
- m_private.reset(new WTF::Vector<WTF::String>(keyPath));
- else
- m_private.reset(0);
+ ASSERT(m_private.get());
}
-void WebIDBKeyPath::reset()
+WebIDBKeyPath& WebIDBKeyPath::operator=(const WebCore::IDBKeyPath& value)
{
- m_private.reset(0);
+ ASSERT(m_private.get());
+ m_private.reset(new IDBKeyPath(value));
+ return *this;
}
-WebIDBKeyPath::operator const WTF::Vector<WTF::String, 0>&() const
+WebIDBKeyPath::operator const WebCore::IDBKeyPath&() const
{
ASSERT(m_private.get());
- return *m_private.get();
+ return *(m_private.get());
}
} // namespace WebKit
#include "DOMStringList.h"
#include "IDBCallbacksProxy.h"
#include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
#include "IDBKeyRange.h"
#include "IDBObjectStoreBackendInterface.h"
#include "WebIDBIndexImpl.h"
WebIDBKeyPath WebIDBObjectStoreImpl::keyPath() const
{
- return WebIDBKeyPath(m_objectStore->keyPath());
-}
-
-// FIXME: Remove this method once callers are updated.
-// http://webkit.org/b/84207
-WebString WebIDBObjectStoreImpl::keyPathString() const
-{
return m_objectStore->keyPath();
}
m_objectStore->clear(IDBCallbacksProxy::create(adoptPtr(callbacks)), transaction.getIDBTransactionBackendInterface(), ec);
}
-WebIDBIndex* WebIDBObjectStoreImpl::createIndex(const WebString& name, const WebString& keyPath, bool unique, bool multiEntry, const WebIDBTransaction& transaction, WebExceptionCode& ec)
+WebIDBIndex* WebIDBObjectStoreImpl::createIndex(const WebString& name, const WebIDBKeyPath& keyPath, bool unique, bool multiEntry, const WebIDBTransaction& transaction, WebExceptionCode& ec)
{
RefPtr<IDBIndexBackendInterface> index = m_objectStore->createIndex(name, keyPath, unique, multiEntry, transaction.getIDBTransactionBackendInterface(), ec);
if (!index)
WebString name() const;
WebIDBKeyPath keyPath() const;
- // FIXME: Remove this method once callers are updated.
- // http://webkit.org/b/84207
- WebString keyPathString() const;
WebDOMStringList indexNames() const;
bool autoIncrement() const;
void deleteFunction(const WebIDBKeyRange&, WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&);
void clear(WebIDBCallbacks*, const WebIDBTransaction&, WebExceptionCode&);
- // FIXME: Remove WebString keyPath overload once callers are updated.
- // http://webkit.org/b/84207
- WebIDBIndex* createIndex(const WebString&, const WebString&, bool, bool, const WebIDBTransaction&, WebExceptionCode&);
- WebIDBIndex* createIndex(const WebString& name, const WebIDBKeyPath& keyPath, bool unique, bool multiEntry, const WebIDBTransaction& transaction, WebExceptionCode& ec) { return createIndex(name, keyPath.string(), unique, multiEntry, transaction, ec); }
+ WebIDBIndex* createIndex(const WebString& name, const WebIDBKeyPath&, bool unique, bool multiEntry, const WebIDBTransaction&, WebExceptionCode&);
WebIDBIndex* index(const WebString& name, WebExceptionCode&);
void deleteIndex(const WebString& name, const WebIDBTransaction&, WebExceptionCode&);
PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(SerializedScriptValue* value, const String& keyPath)
{
- Vector<String> idbKeyPath;
- IDBKeyPathParseError parseError;
- IDBParseKeyPath(keyPath, idbKeyPath, parseError);
- EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
+ IDBKeyPath idbKeyPath(keyPath);
+ EXPECT_TRUE(idbKeyPath.isValid());
return createIDBKeyFromSerializedValueAndKeyPath(value, idbKeyPath);
}
PassRefPtr<SerializedScriptValue> injectKey(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
- Vector<String> idbKeyPath;
- IDBKeyPathParseError parseError;
- IDBParseKeyPath(keyPath, idbKeyPath, parseError);
- EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
+ IDBKeyPath idbKeyPath(keyPath);
+ EXPECT_TRUE(idbKeyPath.isValid());
return injectIDBKeyIntoSerializedValue(key, value, idbKeyPath);
}
void checkKeyPath(const String& keyPath, const Vector<String>& expected, int parserError)
{
+ IDBKeyPath idbKeyPath(keyPath);
+ ASSERT_EQ(idbKeyPath.type(), IDBKeyPath::StringType);
+ ASSERT_EQ(idbKeyPath.isValid(), (parserError == IDBKeyPathParseErrorNone));
+
IDBKeyPathParseError error;
Vector<String> keyPathElements;
IDBParseKeyPath(keyPath, keyPathElements, error);
#if USE(LEVELDB)
#include "IDBKey.h"
+#include "IDBKeyPath.h"
#include "LevelDBSlice.h"
#include <gtest/gtest.h>
#include <wtf/Vector.h>
EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));
}
+TEST(IDBLevelDBCodingTest, EncodeIDBKeyPath)
+{
+ const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
+ const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
+ {
+ IDBKeyPath keyPath;
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::NullType);
+ Vector<char> v = encodeIDBKeyPath(keyPath);
+ EXPECT_EQ(v.size(), 3U);
+ EXPECT_EQ(v[0], kIDBKeyPathTypeCodedByte1);
+ EXPECT_EQ(v[1], kIDBKeyPathTypeCodedByte2);
+ EXPECT_EQ(v[2], IDBKeyPath::NullType);
+ }
+
+ {
+ Vector<String> testCases;
+ testCases.append("");
+ testCases.append("foo");
+ testCases.append("foo.bar");
+
+ for (size_t i = 0; i < testCases.size(); ++i) {
+ IDBKeyPath keyPath = IDBKeyPath(testCases[i]);
+ Vector<char> v = encodeIDBKeyPath(keyPath);
+ EXPECT_EQ(v.size(), encodeStringWithLength(testCases[i]).size() + 3);
+ const char* p = v.data();
+ const char* limit = v.data() + v.size();
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1);
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2);
+ EXPECT_EQ(*p++, IDBKeyPath::StringType);
+ String string;
+ p = decodeStringWithLength(p, limit, string);
+ EXPECT_EQ(string, testCases[i]);
+ EXPECT_EQ(p, limit);
+ }
+ }
+
+ {
+ Vector<String> testCase;
+ testCase.append("");
+ testCase.append("foo");
+ testCase.append("foo.bar");
+
+ IDBKeyPath keyPath(testCase);
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::ArrayType);
+ Vector<char> v = encodeIDBKeyPath(keyPath);
+ const char* p = v.data();
+ const char* limit = v.data() + v.size();
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1);
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2);
+ EXPECT_EQ(*p++, IDBKeyPath::ArrayType);
+ int64_t count;
+ p = decodeVarInt(p, limit, count);
+ EXPECT_EQ(count, static_cast<int64_t>(testCase.size()));
+ for (size_t i = 0; i < static_cast<size_t>(count); ++i) {
+ String string;
+ p = decodeStringWithLength(p, limit, string);
+ EXPECT_EQ(string, testCase[i]);
+ }
+ EXPECT_EQ(p, limit);
+ }
+}
+
+TEST(IDBLevelDBCodingTest, DecodeIDBKeyPath)
+{
+ const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
+ const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
+ {
+ // Legacy encoding of string key paths.
+ Vector<String> testCases;
+ testCases.append("");
+ testCases.append("foo");
+ testCases.append("foo.bar");
+
+ for (size_t i = 0; i < testCases.size(); ++i) {
+ Vector<char> v = encodeString(testCases[i]);
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::StringType);
+ EXPECT_EQ(testCases[i], keyPath.string());
+ }
+ }
+ {
+ Vector<char> v;
+ v.append(kIDBKeyPathTypeCodedByte1);
+ v.append(kIDBKeyPathTypeCodedByte2);
+ v.append(IDBKeyPath::NullType);
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::NullType);
+ EXPECT_TRUE(keyPath.isNull());
+ }
+ {
+ Vector<String> testCases;
+ testCases.append("");
+ testCases.append("foo");
+ testCases.append("foo.bar");
+
+ for (size_t i = 0; i < testCases.size(); ++i) {
+ Vector<char> v;
+ v.append(kIDBKeyPathTypeCodedByte1);
+ v.append(kIDBKeyPathTypeCodedByte2);
+ v.append(IDBKeyPath::StringType);
+ v.append(encodeStringWithLength(testCases[i]));
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::StringType);
+ EXPECT_EQ(testCases[i], keyPath.string());
+ }
+ }
+ {
+ Vector<String> testCase;
+ testCase.append("");
+ testCase.append("foo");
+ testCase.append("foo.bar");
+
+ Vector<char> v;
+ v.append(kIDBKeyPathTypeCodedByte1);
+ v.append(kIDBKeyPathTypeCodedByte2);
+ v.append(IDBKeyPath::ArrayType);
+ v.append(encodeVarInt(testCase.size()));
+ for (size_t i = 0; i < testCase.size(); ++i)
+ v.append(encodeStringWithLength(testCase[i]));
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::ArrayType);
+ EXPECT_EQ(keyPath.array().size(), testCase.size());
+ for (size_t i = 0; i < testCase.size(); ++i)
+ EXPECT_EQ(keyPath.array()[i], testCase[i]);
+ }
+}
+
TEST(IDBLevelDBCodingTest, ExtractAndCompareIDBKeys)
{
Vector<RefPtr<IDBKey> > keys;