IndexedDB: Store key paths in IDBKeyPath type instead of String
authorjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 May 2012 21:34:39 +0000 (21:34 +0000)
committerjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 May 2012 21:34:39 +0000 (21:34 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@117817 268f45cc-cd09-0410-ab3c-d52691b4dbfc

63 files changed:
LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/keypath-basics-expected.txt
LayoutTests/storage/indexeddb/resources/keypath-basics.js
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBAny.cpp
Source/WebCore/Modules/indexeddb/IDBAny.h
Source/WebCore/Modules/indexeddb/IDBBackingStore.h
Source/WebCore/Modules/indexeddb/IDBDatabase.cpp
Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.cpp
Source/WebCore/Modules/indexeddb/IDBDatabaseBackendImpl.h
Source/WebCore/Modules/indexeddb/IDBDatabaseBackendInterface.h
Source/WebCore/Modules/indexeddb/IDBIndex.h
Source/WebCore/Modules/indexeddb/IDBIndex.idl
Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp
Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.h
Source/WebCore/Modules/indexeddb/IDBIndexBackendInterface.h
Source/WebCore/Modules/indexeddb/IDBKeyPath.cpp
Source/WebCore/Modules/indexeddb/IDBKeyPath.h
Source/WebCore/Modules/indexeddb/IDBKeyPathBackendImpl.cpp
Source/WebCore/Modules/indexeddb/IDBKeyPathBackendImpl.h
Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/IDBLevelDBBackingStore.h
Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.cpp
Source/WebCore/Modules/indexeddb/IDBLevelDBCoding.h
Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp
Source/WebCore/Modules/indexeddb/IDBObjectStore.h
Source/WebCore/Modules/indexeddb/IDBObjectStore.idl
Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp
Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h
Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendInterface.h
Source/WebCore/bindings/v8/Dictionary.cpp
Source/WebCore/bindings/v8/Dictionary.h
Source/WebCore/bindings/v8/IDBBindingUtilities.cpp
Source/WebCore/bindings/v8/IDBBindingUtilities.h
Source/WebCore/bindings/v8/custom/V8IDBAnyCustom.cpp
Source/WebCore/dom/DOMStringList.h
Source/WebCore/inspector/InspectorIndexedDBAgent.cpp
Source/WebCore/platform/chromium/PlatformSupport.h
Source/WebCore/storage/chromium/IDBKeyPathBackendImpl.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebIDBDatabase.h
Source/WebKit/chromium/public/WebIDBIndex.h
Source/WebKit/chromium/public/WebIDBKeyPath.h
Source/WebKit/chromium/public/WebIDBObjectStore.h
Source/WebKit/chromium/public/platform/WebKitPlatformSupport.h
Source/WebKit/chromium/src/AssertMatchingEnums.cpp
Source/WebKit/chromium/src/IDBDatabaseBackendProxy.cpp
Source/WebKit/chromium/src/IDBDatabaseBackendProxy.h
Source/WebKit/chromium/src/IDBIndexBackendProxy.cpp
Source/WebKit/chromium/src/IDBIndexBackendProxy.h
Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.cpp
Source/WebKit/chromium/src/IDBObjectStoreBackendProxy.h
Source/WebKit/chromium/src/PlatformSupport.cpp
Source/WebKit/chromium/src/WebIDBDatabaseImpl.cpp
Source/WebKit/chromium/src/WebIDBDatabaseImpl.h
Source/WebKit/chromium/src/WebIDBIndexImpl.cpp
Source/WebKit/chromium/src/WebIDBIndexImpl.h
Source/WebKit/chromium/src/WebIDBKeyPath.cpp
Source/WebKit/chromium/src/WebIDBObjectStoreImpl.cpp
Source/WebKit/chromium/src/WebIDBObjectStoreImpl.h
Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp
Source/WebKit/chromium/tests/IDBKeyPathTest.cpp
Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp

index e4c8ee4..f3f79f2 100644 (file)
@@ -1,5 +1,15 @@
 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
 
index b3081d2..8629463 100644 (file)
@@ -9,40 +9,33 @@ indexedDB.open(name)
 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 = '[]'
index b25c731..e6b2606 100644 (file)
@@ -27,28 +27,23 @@ function testValidKeyPaths()
 {
     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);
     });
 
@@ -87,4 +82,4 @@ function testInvalidKeyPaths()
     finishJSTest();
 }
 
-test();
\ No newline at end of file
+test();
index a94d5db..6aedc34 100644 (file)
@@ -1,3 +1,128 @@
+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()
index 57a406e..30028cc 100644 (file)
@@ -49,6 +49,13 @@ PassRefPtr<IDBAny> IDBAny::createNull()
     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)
 {
@@ -118,6 +125,12 @@ PassRefPtr<SerializedScriptValue> IDBAny::serializedScriptValue()
     return m_serializedScriptValue;
 }
 
+const String& IDBAny::string()
+{
+    ASSERT(m_type == StringType);
+    return m_string;
+}
+
 void IDBAny::setNull()
 {
     ASSERT(m_type == UndefinedType);
@@ -194,6 +207,13 @@ void IDBAny::set(PassRefPtr<SerializedScriptValue> value)
     m_serializedScriptValue = value;
 }
 
+void IDBAny::set(const String& value)
+{
+    ASSERT(m_type == UndefinedType);
+    m_type = StringType;
+    m_string = value;
+}
+
 } // namespace WebCore
 
 #endif
index 6beda58..93eb240 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "PlatformString.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
@@ -49,6 +50,7 @@ class IDBAny : public RefCounted<IDBAny> {
 public:
     static PassRefPtr<IDBAny> createInvalid();
     static PassRefPtr<IDBAny> createNull();
+    static PassRefPtr<IDBAny> createString(const String&);
     template<typename T>
     static PassRefPtr<IDBAny> create(T* idbObject)
     {
@@ -77,7 +79,8 @@ public:
         IDBKeyType,
         IDBObjectStoreType,
         IDBTransactionType,
-        SerializedScriptValueType
+        SerializedScriptValueType,
+        StringType,
     };
 
     Type type() const { return m_type; }
@@ -92,6 +95,7 @@ public:
     PassRefPtr<IDBObjectStore> idbObjectStore();
     PassRefPtr<IDBTransaction> idbTransaction();
     PassRefPtr<SerializedScriptValue> serializedScriptValue();
+    const String& string();
 
     // Set can only be called once.
     void setNull();
@@ -105,6 +109,7 @@ public:
     void set(PassRefPtr<IDBObjectStore>);
     void set(PassRefPtr<IDBTransaction>);
     void set(PassRefPtr<SerializedScriptValue>);
+    void set(const String&);
 
 private:
     IDBAny();
@@ -122,6 +127,7 @@ private:
     RefPtr<IDBObjectStore> m_idbObjectStore;
     RefPtr<IDBTransaction> m_idbTransaction;
     RefPtr<SerializedScriptValue> m_serializedScriptValue;
+    String m_string;
 };
 
 } // namespace WebCore
index e7b2222..f784062 100644 (file)
@@ -52,8 +52,8 @@ public:
     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> {
@@ -77,8 +77,8 @@ public:
     };
     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;
index 3060cdb..eb8d863 100644 (file)
@@ -92,9 +92,14 @@ PassRefPtr<IDBObjectStore> IDBDatabase::createObjectStore(const String& name, co
         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;
     }
index b05b328..59199fc 100644 (file)
@@ -137,7 +137,7 @@ PassRefPtr<DOMStringList> IDBDatabaseBackendImpl::objectStoreNames() const
     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);
 
@@ -376,7 +376,7 @@ void IDBDatabaseBackendImpl::loadObjectStores()
 {
     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);
 
index 1086eb1..3318e2b 100644 (file)
@@ -65,7 +65,7 @@ public:
     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&);
index 56e8f2d..e072a0f 100644 (file)
@@ -38,6 +38,7 @@ class DOMStringList;
 class Frame;
 class IDBCallbacks;
 class IDBDatabaseCallbacks;
+class IDBKeyPath;
 class IDBObjectStoreBackendInterface;
 class IDBTransactionBackendInterface;
 
@@ -55,7 +56,7 @@ public:
     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;
index caa10e9..a90ace0 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "IDBCursor.h"
 #include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
 #include "IDBKeyRange.h"
 #include "IDBRequest.h"
 #include "PlatformString.h"
@@ -50,7 +51,7 @@ public:
     // 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(); }
 
index f18f6b7..ab6ceb7 100644 (file)
@@ -30,7 +30,7 @@ module storage {
     ] 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;
 
index 5f54e6a..0e0e52f 100644 (file)
@@ -41,7 +41,7 @@
 
 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)
@@ -53,7 +53,7 @@ IDBIndexBackendImpl::IDBIndexBackendImpl(IDBBackingStore* backingStore, int64_t
 {
 }
 
-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)
index 95e0f1e..c7bce0e 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "IDBCursorBackendInterface.h"
 #include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
 
 namespace WebCore {
 
@@ -40,11 +41,11 @@ class ScriptExecutionContext;
 
 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));
     }
@@ -62,7 +63,7 @@ public:
 
     // 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; }
 
@@ -75,8 +76,8 @@ public:
     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>);
@@ -96,7 +97,7 @@ private:
     IDBObjectStoreBackendImpl* m_objectStoreBackend;
     int64_t m_id;
     String m_name;
-    String m_keyPath;
+    IDBKeyPath m_keyPath;
     bool m_unique;
     bool m_multiEntry;
 };
index 15ac386..d35d117 100644 (file)
@@ -36,6 +36,7 @@ namespace WebCore {
 
 class IDBCallbacks;
 class IDBKey;
+class IDBKeyPath;
 class IDBKeyRange;
 class IDBTransactionBackendInterface;
 
@@ -46,7 +47,7 @@ public:
     virtual ~IDBIndexBackendInterface() { }
 
     virtual String name() = 0;
-    virtual String keyPath() = 0;
+    virtual IDBKeyPath keyPath() = 0;
     virtual bool unique() = 0;
     virtual bool multiEntry() = 0;
 
index cd5e966..47a70ae 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "DOMStringList.h"
 #include <wtf/ASCIICType.h>
 #include <wtf/dtoa.h>
 
@@ -179,6 +180,61 @@ void IDBParseKeyPath(const String& keyPath, Vector<String>& elements, IDBKeyPath
     }
 }
 
+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)
index c52a63b..f5236c1 100644 (file)
 
 #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 {
 
@@ -42,9 +41,44 @@ enum IDBKeyPathParseError {
     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
index 94c7f27..64a1fbc 100644 (file)
 
 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>();
index 1c76232..0f057eb 100644 (file)
 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&);
 };
 
 }
index c7ef752..49777c6 100644 (file)
@@ -32,6 +32,7 @@
 #include <wtf/Assertions.h>
 #include "FileSystem.h"
 #include "IDBFactoryBackendImpl.h"
+#include "IDBKeyPath.h"
 #include "IDBKeyRange.h"
 #include "IDBLevelDBCoding.h"
 #include "LevelDBComparator.h"
@@ -98,6 +99,14 @@ static bool putString(DBOrTransaction* db, const Vector<char> key, const String&
     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);
@@ -327,7 +336,7 @@ static bool checkObjectStoreAndMetaDataType(const LevelDBIterator* it, const Vec
     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);
@@ -363,8 +372,7 @@ void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>
             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)) {
@@ -393,17 +401,23 @@ void IDBLevelDBBackingStore::getObjectStores(int64_t databaseId, Vector<int64_t>
 
         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);
     }
 }
@@ -424,7 +438,7 @@ static int64_t getNewObjectStoreId(LevelDBTransaction* transaction, int64_t data
     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);
@@ -446,7 +460,7 @@ bool IDBLevelDBBackingStore::createObjectStore(int64_t databaseId, const String&
         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;
@@ -717,7 +731,7 @@ static bool checkIndexAndMetaDataKey(const LevelDBIterator* it, const Vector<cha
 }
 
 
-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);
@@ -760,7 +774,7 @@ void IDBLevelDBBackingStore::getIndexes(int64_t databaseId, int64_t objectStoreI
             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;
@@ -793,7 +807,7 @@ static int64_t getNewIndexId(LevelDBTransaction* transaction, int64_t databaseId
     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);
@@ -817,7 +831,7 @@ bool IDBLevelDBBackingStore::createIndex(int64_t databaseId, int64_t objectStore
         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;
index e17a6f1..cc870fe 100644 (file)
@@ -50,8 +50,8 @@ public:
     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&);
@@ -63,8 +63,8 @@ public:
 
     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*);
index 50de12f..1ea7f68 100644 (file)
@@ -30,6 +30,7 @@
 #if USE(LEVELDB)
 
 #include "IDBKey.h"
+#include "IDBKeyPath.h"
 #include "LevelDBSlice.h"
 #include <wtf/text/StringBuilder.h>
 
@@ -142,6 +143,9 @@ static const unsigned char kIDBKeyNumberTypeByte = 3;
 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;
 
@@ -626,6 +630,74 @@ int compareEncodedIDBKeys(const Vector<char>& keyA, const Vector<char>& keyB)
     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)
index c801df7..cc1f727 100644 (file)
@@ -36,6 +36,7 @@
 namespace WebCore {
 
 class IDBKey;
+class IDBKeyPath;
 class LevelDBSlice;
 
 namespace IDBLevelDBCoding {
@@ -63,6 +64,8 @@ Vector<char> encodeIDBKey(const IDBKey&);
 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);
 
index c35fb48..5ae2646 100644 (file)
@@ -60,7 +60,7 @@ String IDBObjectStore::name() const
     return m_backend->name();
 }
 
-String IDBObjectStore::keyPath() const
+PassRefPtr<IDBAny> IDBObjectStore::keyPath() const
 {
     IDB_TRACE("IDBObjectStore::keyPath");
     return m_backend->keyPath();
@@ -211,8 +211,13 @@ PassRefPtr<IDBRequest> IDBObjectStore::clear(ScriptExecutionContext* context, Ex
 
 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;
     }
index c5aaf38..9b28a74 100644 (file)
@@ -57,7 +57,7 @@ public:
 
     // Implement the IDBObjectStore IDL
     String name() const;
-    String keyPath() const;
+    PassRefPtr<IDBAny> keyPath() const;
     PassRefPtr<DOMStringList> indexNames() const;
     IDBTransaction* transaction() const;
     bool autoIncrement() const;
@@ -79,6 +79,8 @@ public:
     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&);
 
index 4cc3345..e59cbbc 100644 (file)
@@ -29,7 +29,7 @@ module storage {
         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;
index e4d29dd..5caf797 100644 (file)
@@ -51,7 +51,7 @@ IDBObjectStoreBackendImpl::~IDBObjectStoreBackendImpl()
 {
 }
 
-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)
@@ -63,7 +63,7 @@ IDBObjectStoreBackendImpl::IDBObjectStoreBackendImpl(IDBBackingStore* backingSto
     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)
@@ -137,9 +137,11 @@ void IDBObjectStoreBackendImpl::getInternal(ScriptExecutionContext*, PassRefPtr<
     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;
@@ -150,7 +152,7 @@ static PassRefPtr<IDBKey> fetchKeyFromKeyPath(SerializedScriptValue* value, cons
     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);
@@ -497,7 +499,7 @@ bool IDBObjectStoreBackendImpl::populateIndex(IDBBackingStore& backingStore, int
     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;
@@ -648,7 +650,7 @@ void IDBObjectStoreBackendImpl::loadIndexes()
 {
     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);
index 3ebc77c..06ecac8 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef IDBObjectStoreBackendImpl_h
 #define IDBObjectStoreBackendImpl_h
 
+#include "IDBKeyPath.h"
 #include "IDBObjectStoreBackendInterface.h"
 #include <wtf/HashMap.h>
 #include <wtf/text/StringHash.h>
@@ -42,11 +43,11 @@ class ScriptExecutionContext;
 
 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));
     }
@@ -61,7 +62,7 @@ public:
     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; }
 
@@ -72,7 +73,7 @@ public:
     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&);
 
@@ -82,8 +83,8 @@ public:
     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();
@@ -112,7 +113,7 @@ private:
     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;
index bd09fc2..5e5d98e 100644 (file)
@@ -37,6 +37,7 @@ class DOMStringList;
 class IDBCallbacks;
 class IDBIndexBackendInterface;
 class IDBKey;
+class IDBKeyPath;
 class IDBKeyRange;
 class IDBTransactionBackendInterface;
 class SerializedScriptValue;
@@ -48,7 +49,7 @@ public:
     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;
 
@@ -65,7 +66,7 @@ public:
 
     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;
 
index 10aafe8..dc724fa 100644 (file)
@@ -424,6 +424,23 @@ bool Dictionary::get(const String& key, Dictionary& value) const
     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
 {
index c4c33b1..f153ea9 100644 (file)
 #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;
@@ -85,6 +85,7 @@ public:
 #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;
index df67780..15b43e9 100644 (file)
@@ -153,30 +153,43 @@ v8::Handle<v8::Value> ensureNthValueOnKeyPath(v8::Handle<v8::Value>& rootValue,
 
 } // 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);
index 47286a5..30eed42 100644 (file)
 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&);
 
 }
 
index 1434054..1e37cdf 100644 (file)
@@ -32,6 +32,7 @@
 #include "V8IDBAny.h"
 
 #include "SerializedScriptValue.h"
+#include "V8Binding.h"
 #include "V8DOMStringList.h"
 #include "V8IDBCursor.h"
 #include "V8IDBCursorWithValue.h"
@@ -74,6 +75,8 @@ v8::Handle<v8::Value> toV8(IDBAny* impl, v8::Isolate* isolate)
         return toV8(impl->idbTransaction(), isolate);
     case IDBAny::SerializedScriptValueType:
         return impl->serializedScriptValue()->deserialize(0, isolate);
+    case IDBAny::StringType:
+        return v8String(impl->string());
     }
 
     ASSERT_NOT_REACHED();
index 057dac4..464fa22 100644 (file)
@@ -52,6 +52,8 @@ public:
     String item(unsigned index) const;
     bool contains(const String& str) const;
 
+    operator const Vector<String>&() const { return m_strings; }
+
 private:
     DOMStringList() { }
 
index d9ea4b3..cbd92cf 100644 (file)
@@ -46,6 +46,7 @@
 #include "IDBFactoryBackendInterface.h"
 #include "IDBIndexBackendInterface.h"
 #include "IDBKey.h"
+#include "IDBKeyPath.h"
 #include "IDBKeyRange.h"
 #include "IDBObjectStoreBackendInterface.h"
 #include "IDBPendingTransactionMonitor.h"
@@ -225,6 +226,25 @@ static PassRefPtr<IDBIndexBackendInterface> indexForObjectStore(IDBObjectStoreBa
     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)
@@ -260,7 +280,7 @@ public:
 
                 RefPtr<ObjectStoreIndex> objectStoreIndex = ObjectStoreIndex::create()
                     .setName(idbIndex->name())
-                    .setKeyPath(idbIndex->keyPath())
+                    .setKeyPath(keyPathToString(idbIndex->keyPath()))
                     .setUnique(idbIndex->unique())
                     .setMultiEntry(idbIndex->multiEntry());
                 indexes->addItem(objectStoreIndex);
@@ -268,7 +288,7 @@ public:
 
             RefPtr<ObjectStore> objectStore = ObjectStore::create()
                 .setName(idbObjectStore->name())
-                .setKeyPath(idbObjectStore->keyPath())
+                .setKeyPath(keyPathToString(idbObjectStore->keyPath()))
                 .setIndexes(indexes);
             objectStores->addItem(objectStore);
         }
index f8b5b7e..50c0a0b 100644 (file)
@@ -78,6 +78,7 @@ class GraphicsContext;
 class Image;
 class IDBFactoryBackendInterface;
 class IDBKey;
+class IDBKeyPath;
 class IntRect;
 class KURL;
 class SerializedScriptValue;
@@ -178,9 +179,9 @@ public:
     // 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*);
index b804a0f..c86c77d 100644 (file)
 
 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);
 }
index 949b4e5..5159d98 100644 (file)
@@ -1,3 +1,75 @@
+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)
index f53b02e..b398534 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "WebDOMStringList.h"
 #include "WebExceptionCode.h"
-#include "WebIDBKeyPath.h"
 #include "platform/WebCommon.h"
 
 namespace WebKit {
@@ -36,6 +35,7 @@ namespace WebKit {
 class WebFrame;
 class WebIDBCallbacks;
 class WebIDBDatabaseCallbacks;
+class WebIDBKeyPath;
 class WebIDBObjectStore;
 class WebIDBTransaction;
 
@@ -59,12 +59,6 @@ public:
         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();
index 2b1f9b4..b100808 100644 (file)
@@ -49,14 +49,8 @@ public:
     }
     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
     {
index 97bac06..beb1fa2 100644 (file)
@@ -36,6 +36,8 @@ template<typename T, size_t inlineCapacity> class Vector;
 class String;
 }
 
+namespace WebCore { class IDBKeyPath; }
+
 namespace WebKit {
 
 class WebIDBKeyPath {
@@ -44,7 +46,7 @@ public:
     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,
@@ -54,30 +56,17 @@ public:
 
     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
index 4008e1d..0af426e 100644 (file)
@@ -30,7 +30,6 @@
 #include "WebDOMStringList.h"
 #include "WebIDBCallbacks.h"
 #include "WebIDBKeyPath.h"
-#include "WebIDBTransaction.h"
 #include "platform/WebCommon.h"
 #include "platform/WebString.h"
 
@@ -51,12 +50,8 @@ public:
     }
     virtual WebIDBKeyPath keyPath() const
     {
-        return WebIDBKeyPath(keyPathString());
-    }
-    virtual WebString keyPathString() const
-    {
         WEBKIT_ASSERT_NOT_REACHED();
-        return WebString();
+        return WebIDBKeyPath::createNull();
     }
     virtual WebDOMStringList indexNames() const
     {
@@ -81,13 +76,6 @@ public:
     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();
index fe436f3..a756b53 100644 (file)
@@ -31,7 +31,6 @@
 #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"
@@ -53,6 +52,7 @@ class WebApplicationCacheHostClient; // FIXME: Does this belong in platform?
 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;
@@ -106,13 +106,7 @@ public:
     // 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(); }
 
 
index cd0f07f..5bc960a 100644 (file)
@@ -52,6 +52,7 @@
 #include "IDBDatabaseException.h"
 #include "IDBFactoryBackendInterface.h"
 #include "IDBKey.h"
+#include "IDBKeyPath.h"
 #include "IceOptions.h"
 #include "IconURL.h"
 #include "MediaPlayer.h"
@@ -86,6 +87,7 @@
 #include "WebIDBDatabaseException.h"
 #include "WebIDBFactory.h"
 #include "WebIDBKey.h"
+#include "WebIDBKeyPath.h"
 #include "WebIconURL.h"
 #include "WebInputElement.h"
 #include "WebMediaPlayer.h"
@@ -467,12 +469,18 @@ COMPILE_ASSERT_MATCHING_ENUM(WebView::UserStyleInjectInSubsequentDocuments, Inje
 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);
index 1797992..6e53549 100644 (file)
@@ -75,7 +75,7 @@ PassRefPtr<DOMStringList> IDBDatabaseBackendProxy::objectStoreNames() const
     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.
index 5a5baf2..b78ac69 100644 (file)
@@ -46,7 +46,7 @@ public:
     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&);
index fc746aa..280db88 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(INDEXED_DATABASE)
 
 #include "IDBCallbacks.h"
+#include "IDBKeyPath.h"
 #include "IDBKeyRange.h"
 #include "IDBTransactionBackendProxy.h"
 #include "WebIDBCallbacksImpl.h"
@@ -60,9 +61,9 @@ String IDBIndexBackendProxy::name()
     return m_webIDBIndex->name();
 }
 
-String IDBIndexBackendProxy::keyPath()
+IDBKeyPath IDBIndexBackendProxy::keyPath()
 {
-    return m_webIDBIndex->keyPath().string();
+    return m_webIDBIndex->keyPath();
 }
 
 bool IDBIndexBackendProxy::unique()
index d5cc8bb..2734056 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(INDEXED_DATABASE)
 
 #include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
 
@@ -42,7 +43,7 @@ public:
     virtual ~IDBIndexBackendProxy();
 
     virtual String name();
-    virtual String keyPath();
+    virtual WebCore::IDBKeyPath keyPath();
     virtual bool unique();
     virtual bool multiEntry();
 
index 24f23a5..c03b2f1 100755 (executable)
@@ -64,9 +64,9 @@ String IDBObjectStoreBackendProxy::name() const
     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
@@ -119,7 +119,7 @@ void IDBObjectStoreBackendProxy::clear(PassRefPtr<IDBCallbacks> callbacks, IDBTr
     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.
index fb7781d..5d6796c 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(INDEXED_DATABASE)
 
+#include "IDBKeyPath.h"
 #include "IDBObjectStoreBackendInterface.h"
 #include <wtf/OwnPtr.h>
 #include <wtf/PassOwnPtr.h>
@@ -43,7 +44,7 @@ public:
     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;
 
@@ -53,7 +54,7 @@ public:
     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&);
 
index eeab786..3303d45 100644 (file)
@@ -40,6 +40,7 @@
 #include "WebFrameClient.h"
 #include "WebFrameImpl.h"
 #include "WebIDBKey.h"
+#include "WebIDBKeyPath.h"
 #include "WebKit.h"
 #include "WebPluginContainerImpl.h"
 #include "WebPluginListBuilderImpl.h"
@@ -495,7 +496,7 @@ PassRefPtr<IDBFactoryBackendInterface> PlatformSupport::idbFactory()
     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;
@@ -507,7 +508,7 @@ void PlatformSupport::createIDBKeysFromSerializedValuesAndKeyPath(const Vector<R
         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);
 }
index 447b993..4be43dc 100644 (file)
@@ -66,7 +66,7 @@ WebDOMStringList WebIDBDatabaseImpl::objectStoreNames() const
     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) {
index f73be57..96571bb 100644 (file)
@@ -53,10 +53,7 @@ public:
     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&);
index 752a862..7f74e5a 100644 (file)
@@ -58,13 +58,6 @@ WebIDBKeyPath WebIDBIndexImpl::keyPath() const
     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();
index 90d8366..04fea58 100644 (file)
@@ -45,9 +45,6 @@ public:
 
     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;
 
index bcf5dbd..17c158f 100644 (file)
@@ -37,101 +37,79 @@ using namespace WebCore;
 
 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
index 5ec35df..ebd7ae9 100755 (executable)
@@ -31,6 +31,7 @@
 #include "DOMStringList.h"
 #include "IDBCallbacksProxy.h"
 #include "IDBIndexBackendInterface.h"
+#include "IDBKeyPath.h"
 #include "IDBKeyRange.h"
 #include "IDBObjectStoreBackendInterface.h"
 #include "WebIDBIndexImpl.h"
@@ -59,13 +60,6 @@ WebString WebIDBObjectStoreImpl::name() const
 
 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();
 }
 
@@ -104,7 +98,7 @@ void WebIDBObjectStoreImpl::clear(WebIDBCallbacks* callbacks, const WebIDBTransa
     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)
index 96ff6ee..91aee78 100644 (file)
@@ -47,9 +47,6 @@ public:
 
     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;
 
@@ -59,10 +56,7 @@ public:
     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&);
 
index d60295a..c135185 100644 (file)
@@ -41,10 +41,8 @@ namespace {
 
 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);
 }
 
@@ -56,10 +54,8 @@ void checkKeyPathNullValue(SerializedScriptValue* value, const String& keyPath)
 
 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);
 }
 
index e2fdaeb..7d662c0 100644 (file)
@@ -37,6 +37,10 @@ namespace {
 
 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);
index eb9962d..8f5b8ef 100644 (file)
@@ -30,6 +30,7 @@
 #if USE(LEVELDB)
 
 #include "IDBKey.h"
+#include "IDBKeyPath.h"
 #include "LevelDBSlice.h"
 #include <gtest/gtest.h>
 #include <wtf/Vector.h>
@@ -418,6 +419,133 @@ TEST(IDBLevelDBCodingTest, EncodeDecodeIDBKey)
     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;