IndexedDB: Need to distinguish key paths that don't yield value vs. yield invalid key
authorjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jan 2012 18:01:13 +0000 (18:01 +0000)
committerjsbell@chromium.org <jsbell@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jan 2012 18:01:13 +0000 (18:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76487

Source/WebCore:

Implement the precondition checks for IDBObjectStore.add/put operations: raise an error
if there is a key generator (autoIncrement) and the path yields a value and the value
is not a valid key; raise an error if any of the index key paths yield a value which
is not a valid key.

Reviewed by Tony Chang.

Tests: storage/indexeddb/keypath-edges.html
       storage/indexeddb/objectstore-basics.html

* storage/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::put):

Source/WebKit/chromium:

Added a NullType to represent a null IDBKey pointer. This is needed to distinguish the
cases in the spec where the key resolution algorithm returns no value (null) versus
returns a value but that value is not a valid key (invalid).

Reviewed by Tony Chang.

* public/WebIDBKey.h:
* src/WebIDBKey.cpp:
(WebKit::WebIDBKey::createNull): Added.
(WebKit::WebIDBKey::createFromValueAndKeyPath): Now returns null if value is null.
(WebKit::convertFromWebIDBKeyArray): Null keys should never exist within arrays.
(WebKit::WebIDBKey::assignInvalid):
(WebKit::WebIDBKey::assignNull):
(WebKit::WebIDBKey::type):

LayoutTests:

Reviewed by Tony Chang.

* storage/indexeddb/keypath-edges-expected.txt: Added.
* storage/indexeddb/keypath-edges.html: Added.
* storage/indexeddb/objectstore-basics-expected.txt:
* storage/indexeddb/objectstore-basics.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@105891 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/storage/indexeddb/keypath-edges-expected.txt [new file with mode: 0644]
LayoutTests/storage/indexeddb/keypath-edges.html [new file with mode: 0644]
LayoutTests/storage/indexeddb/objectstore-basics-expected.txt
LayoutTests/storage/indexeddb/objectstore-basics.html
Source/WebCore/ChangeLog
Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/public/WebIDBKey.h
Source/WebKit/chromium/src/WebIDBKey.cpp

index d7100f7..a5667cc 100644 (file)
@@ -1,3 +1,15 @@
+2012-01-25  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Need to distinguish key paths that don't yield value vs. yield invalid key
+        https://bugs.webkit.org/show_bug.cgi?id=76487
+
+        Reviewed by Tony Chang.
+
+        * storage/indexeddb/keypath-edges-expected.txt: Added.
+        * storage/indexeddb/keypath-edges.html: Added.
+        * storage/indexeddb/objectstore-basics-expected.txt:
+        * storage/indexeddb/objectstore-basics.html:
+
 2012-01-25  Tony Chang  <tony@chromium.org>
 
         Unreviewed, skip scrollbars/scroll-rtl-or-bt-layer.html on WebKit2
diff --git a/LayoutTests/storage/indexeddb/keypath-edges-expected.txt b/LayoutTests/storage/indexeddb/keypath-edges-expected.txt
new file mode 100644 (file)
index 0000000..e5fca32
--- /dev/null
@@ -0,0 +1,70 @@
+Test IndexedDB keyPath edge cases
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+indexedDB = window.indexedDB || window.webkitIndexedDB;
+PASS indexedDB == null is false
+IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException;
+PASS IDBDatabaseException == null is false
+IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
+PASS IDBTransaction == null is false
+indexedDB.deleteDatabase('keypath-edges')
+indexedDB.open('keypath-edges')
+
+openSuccess():
+db = event.target.result
+request = db.setVersion('1')
+db.createObjectStore('store-with-path', {keyPath: 'foo'})
+db.createObjectStore('store-with-path-and-generator', {keyPath: 'foo', autoIncrement: true})
+
+testKeyPaths():
+transaction = db.transaction(['store-with-path'], IDBTransaction.READ_WRITE)
+store = transaction.objectStore('store-with-path')
+
+Key path doesn't resolve to a value; should yield null, should throw DATA_ERR
+Expecting exception from store.put(null)
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.DATA_ERR
+
+Key path doesn't resolve to a value; should yield null, should throw DATA_ERR
+Expecting exception from store.put({})
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.DATA_ERR
+
+Key path resolves to a value that is invalid key; should yield 'invalid' key, should throw DATA_ERR
+Expecting exception from store.put({foo: null})
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.DATA_ERR
+
+Key path resolves to a value that is valid key; should yield 'string' key, should succeed
+store.put({foo: 'zoo'})
+PASS store.put succeeded
+
+testKeyPathsAndGenerator():
+transaction = db.transaction(['store-with-path-and-generator'], IDBTransaction.READ_WRITE)
+store = transaction.objectStore('store-with-path-and-generator')
+
+Key path doesn't resolve to a value; should yield null, put request should raise error event
+store.put(null)
+PASS Error event raised: The generated key could not be inserted into the object using the keyPath.
+PASS event.target.errorCode is IDBDatabaseException.DATA_ERR
+PASS event.cancelable is true
+event.preventDefault()
+
+Key path doesn't resolve to a value; should yield null, key should be generated, put request should succeed
+store.put({})
+PASS store.put succeeded
+
+Key path resolves to a value that is invalid key; should yield 'invalid' key, should throw DATA_ERR
+Expecting exception from store.put({foo: null})
+PASS Exception was thrown.
+PASS code is IDBDatabaseException.DATA_ERR
+
+Key path resolves to a value that is valid key; should yield 'string' key, should succeed
+store.put({foo: 'zoo'})
+PASS store.put succeeded
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/storage/indexeddb/keypath-edges.html b/LayoutTests/storage/indexeddb/keypath-edges.html
new file mode 100644 (file)
index 0000000..76808ca
--- /dev/null
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="resources/shared.js"></script>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+<script>
+
+description("Test IndexedDB keyPath edge cases");
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function test()
+{
+    evalAndLog("indexedDB = window.indexedDB || window.webkitIndexedDB;");
+    shouldBeFalse("indexedDB == null");
+    evalAndLog("IDBDatabaseException = window.IDBDatabaseException || window.webkitIDBDatabaseException;");
+    shouldBeFalse("IDBDatabaseException == null");
+    evalAndLog("IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;");
+    shouldBeFalse("IDBTransaction == null");
+
+    request = evalAndLog("indexedDB.deleteDatabase('keypath-edges')");
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function () {
+        request = evalAndLog("indexedDB.open('keypath-edges')");
+        request.onerror = unexpectedErrorCallback;
+        request.onsuccess = openSuccess;
+    };
+}
+
+function openSuccess()
+{
+    debug("");
+    debug("openSuccess():");
+    db = evalAndLog("db = event.target.result");
+    request = evalAndLog("request = db.setVersion('1')");
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function () {
+        transaction = request.result;
+        transaction.onabort = unexpectedAbortCallback;
+        evalAndLog("db.createObjectStore('store-with-path', {keyPath: 'foo'})");
+        evalAndLog("db.createObjectStore('store-with-path-and-generator', {keyPath: 'foo', autoIncrement: true})");
+        transaction.oncomplete = testKeyPaths;
+    };
+}
+
+function testKeyPaths()
+{
+    debug("");
+    debug("testKeyPaths():");
+
+    transaction = evalAndLog("transaction = db.transaction(['store-with-path'], IDBTransaction.READ_WRITE)");
+    store = evalAndLog("store = transaction.objectStore('store-with-path')");
+
+    debug("");
+    debug("Key path doesn't resolve to a value; should yield null, should throw DATA_ERR");
+    evalAndExpectException("store.put(null)", "IDBDatabaseException.DATA_ERR");
+
+    debug("");
+    debug("Key path doesn't resolve to a value; should yield null, should throw DATA_ERR");
+    evalAndExpectException("store.put({})", "IDBDatabaseException.DATA_ERR");
+
+    debug("");
+    debug("Key path resolves to a value that is invalid key; should yield 'invalid' key, should throw DATA_ERR");
+    evalAndExpectException("store.put({foo: null})", "IDBDatabaseException.DATA_ERR");
+
+    debug("");
+    debug("Key path resolves to a value that is valid key; should yield 'string' key, should succeed");
+    request = evalAndLog("store.put({foo: 'zoo'})");
+    request.onerror = unexpectedErrorCallback;
+    request.onsuccess = function () {
+        testPassed("store.put succeeded");
+    };
+
+    transaction.onabort = unexpectedAbortCallback;
+    transaction.oncomplete = testKeyPathsAndGenerator;
+}
+
+function testKeyPathsAndGenerator()
+{
+    debug("");
+    debug("testKeyPathsAndGenerator():");
+
+    transaction = evalAndLog("transaction = db.transaction(['store-with-path-and-generator'], IDBTransaction.READ_WRITE)");
+    store = evalAndLog("store = transaction.objectStore('store-with-path-and-generator')");
+
+    debug("");
+    debug("Key path doesn't resolve to a value; should yield null, put request should raise error event");
+    request = evalAndLog("store.put(null)");
+    request.onerror = function (e) {
+        testPassed("Error event raised: " + e.target.webkitErrorMessage);
+        shouldBe("event.target.errorCode", "IDBDatabaseException.DATA_ERR");
+        shouldBeTrue("event.cancelable");
+        evalAndLog("event.preventDefault()");
+
+        debug("");
+        debug("Key path doesn't resolve to a value; should yield null, key should be generated, put request should succeed");
+        request = evalAndLog("store.put({})");
+        request.onerror = unexpectedErrorCallback;
+        request.onsuccess = function () {
+            testPassed("store.put succeeded");
+
+            debug("");
+            debug("Key path resolves to a value that is invalid key; should yield 'invalid' key, should throw DATA_ERR");
+            evalAndExpectException("store.put({foo: null})", "IDBDatabaseException.DATA_ERR");
+
+            debug("");
+            debug("Key path resolves to a value that is valid key; should yield 'string' key, should succeed");
+            request = evalAndLog("store.put({foo: 'zoo'})");
+            request.onerror = unexpectedErrorCallback;
+            request.onsuccess = function () {
+                testPassed("store.put succeeded");
+            };
+        };
+    };
+
+    transaction.onabort = unexpectedAbortCallback;
+    transaction.oncomplete = done;
+}
+
+test();
+
+</script>
+</body>
+</html>
index ec04692..6a940de 100644 (file)
@@ -98,11 +98,9 @@ PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.DATA_ERR
 db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 store = transaction.objectStore('storeName')
-store.add({x: null}, 'validkey')
-PASS event.cancelable is true
-addWithNullIndexFailure():
-PASS event.target.errorCode is webkitIDBDatabaseException.DATA_ERR
-event.preventDefault()
+Expecting exception from store.add({x: null}, 'validkey')
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.DATA_ERR
 db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)
 store = transaction.objectStore('storeName')
 store.get('key')
@@ -164,6 +162,10 @@ The key parameter was provided but does not contain a valid key.
 Expecting exception from storeWithOutOfLineKeys.put({}, null)
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.DATA_ERR
+If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.
+Expecting exception from storeWithIndex.put({indexKey: null}, 'key')
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.DATA_ERR
 
 IDBObjectStore.add()
 The object store uses in-line keys and the key parameter was provided.
@@ -186,6 +188,10 @@ The key parameter was provided but does not contain a valid key.
 Expecting exception from storeWithOutOfLineKeys.add({}, null)
 PASS Exception was thrown.
 PASS code is webkitIDBDatabaseException.DATA_ERR
+If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.
+Expecting exception from storeWithIndex.add({indexKey: null}, 'key')
+PASS Exception was thrown.
+PASS code is webkitIDBDatabaseException.DATA_ERR
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 120aa60..6d8b5fd 100644 (file)
@@ -215,18 +215,7 @@ function addAgainFailure()
     transaction.onabort = unexpectedErrorCallback;
     var store = evalAndLog("store = transaction.objectStore('storeName')");
 
-    request = evalAndLog("store.add({x: null}, 'validkey')");
-    request.onsuccess = unexpectedSuccessCallback;
-    request.onerror = addWithNullIndexFailure;
-}
-
-function addWithNullIndexFailure()
-{
-    shouldBeTrue("event.cancelable");
-    debug("addWithNullIndexFailure():");
-    shouldBe("event.target.errorCode", "webkitIDBDatabaseException.DATA_ERR");
-
-    evalAndLog("event.preventDefault()");
+    evalAndExpectException("store.add({x: null}, 'validkey')", "webkitIDBDatabaseException.DATA_ERR");
 
     transaction = evalAndLog("db.transaction(['storeName'], webkitIDBTransaction.READ_WRITE)");
     transaction.onabort = unexpectedErrorCallback;
@@ -318,8 +307,8 @@ function testPreConditions()
         debug("The key parameter was provided but does not contain a valid key.");
         evalAndExpectException("storeWithOutOfLineKeys.put({}, null)", "webkitIDBDatabaseException.DATA_ERR");
 
-        // FIXME: Add precondition checks for put() with index key paths that yield invalid keys.
-        // https://bugs.webkit.org/show_bug.cgi?id=76487
+        debug("If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.");
+        evalAndExpectException("storeWithIndex.put({indexKey: null}, 'key')", "webkitIDBDatabaseException.DATA_ERR");
 
         debug("");
         debug("IDBObjectStore.add()");
@@ -338,8 +327,8 @@ function testPreConditions()
         debug("The key parameter was provided but does not contain a valid key.");
         evalAndExpectException("storeWithOutOfLineKeys.add({}, null)", "webkitIDBDatabaseException.DATA_ERR");
 
-        // FIXME: Add precondition checks for add() with index key paths that yield invalid keys.
-        // https://bugs.webkit.org/show_bug.cgi?id=76487
+        debug("If there are any indexes referencing this object store whose key path is a string, evaluating their key path on the value parameter yields a value, and that value is not a valid key.");
+        evalAndExpectException("storeWithIndex.add({indexKey: null}, 'key')", "webkitIDBDatabaseException.DATA_ERR");
 
         done();
     };
index aa423ad..dfbc59d 100644 (file)
@@ -1,3 +1,21 @@
+2012-01-25  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Need to distinguish key paths that don't yield value vs. yield invalid key
+        https://bugs.webkit.org/show_bug.cgi?id=76487
+
+        Implement the precondition checks for IDBObjectStore.add/put operations: raise an error
+        if there is a key generator (autoIncrement) and the path yields a value and the value
+        is not a valid key; raise an error if any of the index key paths yield a value which
+        is not a valid key.
+
+        Reviewed by Tony Chang.
+
+        Tests: storage/indexeddb/keypath-edges.html
+               storage/indexeddb/objectstore-basics.html
+
+        * storage/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::put):
+
 2012-01-25  Yong Li  <yoli@rim.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=65377
index 1d6cd41..51a90d0 100644 (file)
@@ -131,35 +131,43 @@ void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> prpValue,
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
     RefPtr<IDBTransactionBackendInterface> transaction = transactionPtr;
 
-    if (key && (key->type() == IDBKey::InvalidType)) {
-        ec = IDBDatabaseException::DATA_ERR;
-        return;
-    }
-
-    const bool autoIncrement = objectStore->autoIncrement();
-    const bool hasKeyPath = !objectStore->m_keyPath.isNull();
-
     if (putMode != CursorUpdate) {
+        if (key && !key->valid()) {
+            ec = IDBDatabaseException::DATA_ERR;
+            return;
+        }
+        const bool autoIncrement = objectStore->autoIncrement();
+        const bool hasKeyPath = !objectStore->m_keyPath.isNull();
         if (!key && !autoIncrement && !hasKeyPath) {
             ec = IDBDatabaseException::DATA_ERR;
             return;
         }
         if (hasKeyPath) {
-            if (key && key->valid()) {
+            if (key) {
                 ec = IDBDatabaseException::DATA_ERR;
                 return;
             }
+
+            RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
             if (!autoIncrement) {
-                RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
                 if (!keyPathKey || !keyPathKey->valid()) {
                     ec = IDBDatabaseException::DATA_ERR;
                     return;
                 }
+            } else if (keyPathKey && !keyPathKey->valid()) {
+                ec = IDBDatabaseException::DATA_ERR;
+                return;
             }
         }
-        // FIXME: Add precondition checks for index key paths that yield invalid keys.
-        // https://bugs.webkit.org/show_bug.cgi?id=76487
-     }
+        for (IndexMap::iterator it = m_indexes.begin(); it != m_indexes.end(); ++it) {
+            const RefPtr<IDBIndexBackendImpl>& index = it->second;
+            RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
+            if (indexKey && !indexKey->valid()) {
+                ec = IDBDatabaseException::DATA_ERR;
+                return;
+            }
+        }
+    }
 
     if (!transaction->scheduleTask(createCallbackTask(&IDBObjectStoreBackendImpl::putInternal, objectStore, value, key, putMode, callbacks, transaction)))
         ec = IDBDatabaseException::TRANSACTION_INACTIVE_ERR;
@@ -173,11 +181,6 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBack
     const bool autoIncrement = objectStore->autoIncrement();
     const bool hasKeyPath = !objectStore->m_keyPath.isNull();
 
-    if (hasKeyPath && key && putMode != CursorUpdate) {
-        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "A key was supplied for an objectStore that has a keyPath."));
-        return 0;
-    }
-
     if (autoIncrement && key) {
         objectStore->resetAutoIncrementKeyCache();
         return key;
@@ -207,11 +210,7 @@ PassRefPtr<IDBKey> IDBObjectStoreBackendImpl::selectKeyForPut(IDBObjectStoreBack
     if (hasKeyPath) {
         RefPtr<IDBKey> keyPathKey = fetchKeyFromKeyPath(value.get(), objectStore->m_keyPath);
 
-        if (!keyPathKey) {
-            callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The key could not be fetched from the keyPath."));
-            return 0;
-        }
-
+        // FIXME: This check should be moved to put() and raise an exception. WK76952
         if (putMode == CursorUpdate && !keyPathKey->isEqual(key)) {
             callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "The key fetched from the keyPath does not match the key of the cursor."));
             return 0;
@@ -234,11 +233,7 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<
     RefPtr<IDBKey> key = selectKeyForPut(objectStore.get(), prpKey.get(), putMode, callbacks.get(), value);
     if (!key)
         return;
-
-    if (key->type() == IDBKey::InvalidType) {
-        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "Not a valid key."));
-        return;
-    }
+    ASSERT(key->valid());
 
     Vector<RefPtr<IDBKey> > indexKeys;
     for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) {
@@ -249,10 +244,7 @@ void IDBObjectStoreBackendImpl::putInternal(ScriptExecutionContext*, PassRefPtr<
             indexKeys.append(indexKey.release());
             continue;
         }
-        if (indexKey->type() == IDBKey::InvalidType) {
-            callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "One of the derived (from a keyPath) keys for an index is not valid."));
-            return;
-        }
+        ASSERT(indexKey->valid());
 
         if ((!index->multiEntry() || indexKey->type() != IDBKey::ArrayType) && !index->addingKeyAllowed(indexKey.get(), key.get())) {
             callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements."));
@@ -339,7 +331,7 @@ void IDBObjectStoreBackendImpl::deleteFunction(PassRefPtr<IDBKey> prpKey, PassRe
     RefPtr<IDBObjectStoreBackendImpl> objectStore = this;
     RefPtr<IDBKey> key = prpKey;
     RefPtr<IDBCallbacks> callbacks = prpCallbacks;
-    if (key->type() == IDBKey::InvalidType) {
+    if (!key || !key->valid()) {
         ec = IDBDatabaseException::DATA_ERR;
         return;
     }
index 6dc00cd..e6c6659 100644 (file)
@@ -1,3 +1,23 @@
+2012-01-25  Joshua Bell  <jsbell@chromium.org>
+
+        IndexedDB: Need to distinguish key paths that don't yield value vs. yield invalid key
+        https://bugs.webkit.org/show_bug.cgi?id=76487
+
+        Added a NullType to represent a null IDBKey pointer. This is needed to distinguish the
+        cases in the spec where the key resolution algorithm returns no value (null) versus
+        returns a value but that value is not a valid key (invalid).
+
+        Reviewed by Tony Chang.
+
+        * public/WebIDBKey.h:
+        * src/WebIDBKey.cpp:
+        (WebKit::WebIDBKey::createNull): Added.
+        (WebKit::WebIDBKey::createFromValueAndKeyPath): Now returns null if value is null.
+        (WebKit::convertFromWebIDBKeyArray): Null keys should never exist within arrays.
+        (WebKit::WebIDBKey::assignInvalid):
+        (WebKit::WebIDBKey::assignNull):
+        (WebKit::WebIDBKey::type):
+
 2012-01-24  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Unreviewed chromium test fix.
index e479717..a781423 100644 (file)
@@ -49,6 +49,7 @@ public:
     WEBKIT_EXPORT static WebIDBKey createDate(double);
     WEBKIT_EXPORT static WebIDBKey createNumber(double);
     WEBKIT_EXPORT static WebIDBKey createInvalid();
+    WEBKIT_EXPORT static WebIDBKey createNull();
     WEBKIT_EXPORT static WebIDBKey createFromValueAndKeyPath(const WebSerializedScriptValue&, const WebIDBKeyPath&);
     WEBKIT_EXPORT static WebSerializedScriptValue injectIDBKeyIntoSerializedValue(const WebIDBKey&, const WebSerializedScriptValue&, const WebIDBKeyPath&);
 
@@ -65,6 +66,7 @@ public:
     WEBKIT_EXPORT void assignDate(double);
     WEBKIT_EXPORT void assignNumber(double);
     WEBKIT_EXPORT void assignInvalid();
+    WEBKIT_EXPORT void assignNull();
     WEBKIT_EXPORT void reset();
 
     enum Type {
@@ -72,7 +74,8 @@ public:
         ArrayType,
         StringType,
         DateType,
-        NumberType
+        NumberType,
+        NullType,
     };
 
     WEBKIT_EXPORT Type type() const;
index 35be9f3..25be6c5 100644 (file)
@@ -76,10 +76,18 @@ WebIDBKey WebIDBKey::createInvalid()
     return key;
 }
 
+WebIDBKey WebIDBKey::createNull()
+{
+    WebIDBKey key;
+    key.assignNull();
+    return key;
+}
+
 WebIDBKey WebIDBKey::createFromValueAndKeyPath(const WebSerializedScriptValue& serializedScriptValue, const WebIDBKeyPath& idbKeyPath)
 {
+    // FIXME: If key path is empty string, this should return invalid key instead
     if (serializedScriptValue.isNull())
-        return WebIDBKey::createInvalid();
+        return WebIDBKey::createNull();
     return createIDBKeyFromSerializedValueAndKeyPath(serializedScriptValue, idbKeyPath);
 }
 
@@ -112,6 +120,7 @@ static PassRefPtr<IDBKey> convertFromWebIDBKeyArray(const WebVector<WebIDBKey>&
             keys.append(IDBKey::createNumber(array[i].number()));
             break;
         case WebIDBKey::InvalidType:
+        case WebIDBKey::NullType:
             ASSERT_NOT_REACHED();
             break;
         }
@@ -170,6 +179,11 @@ void WebIDBKey::assignNumber(double number)
 
 void WebIDBKey::assignInvalid()
 {
+    m_private = IDBKey::createInvalid();
+}
+
+void WebIDBKey::assignNull()
+{
     m_private = 0;
 }
 
@@ -181,7 +195,7 @@ void WebIDBKey::reset()
 WebIDBKey::Type WebIDBKey::type() const
 {
     if (!m_private.get())
-        return InvalidType;
+        return NullType;
     return Type(m_private->type());
 }