<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[207931] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/207931">207931</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2016-10-26 20:13:21 -0700 (Wed, 26 Oct 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Replace IDBKeyPath with a WTF::Variant
https://bugs.webkit.org/show_bug.cgi?id=163909

Reviewed by Darin Adler.

Source/WebCore:

Replace IDBKeyPath class with the IDBKeyPathVariant type entirely
and rename IDBKeyPathVariant to IDBKeyPath.

Unfortunately, IDBKeyPath still needs some special handling when
returned to the JavaScript because we do not have a toJS() accepting
a WTF::Variant as input yet.

There should be no significant behavior change except that
IDBIndex.keyPath / IDBObjectStore.keyPath now returns an array of
Strings instead of a DOMStringList object when the IDBKeyPath
contains a vector. This is a progression and matches the
specification:
- https://www.w3.org/TR/IndexedDB/#widl-IDBIndex-keyPath
- https://www.w3.org/TR/IndexedDB/#widl-IDBObjectStore-keyPath

No new tests, rebaselined existing tests.

* Modules/indexeddb/IDBCursor.cpp:
(WebCore::IDBCursor::update):
* Modules/indexeddb/IDBDatabase.h:
* Modules/indexeddb/IDBGetResult.cpp:
(WebCore::IDBGetResult::isolatedCopy):
* Modules/indexeddb/IDBKeyPath.cpp:
(WebCore::isIDBKeyPathValid):
(WebCore::IDBKeyPathIsolatedCopy):
* Modules/indexeddb/IDBKeyPath.h:
(WebCore::IDBKeyPathIsolatedCopy):
* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::keyPath):
(WebCore::IDBObjectStore::putOrAdd):
(WebCore::IDBObjectStore::createIndex):
* Modules/indexeddb/IDBObjectStore.h:
* Modules/indexeddb/server/IDBSerialization.cpp:
(WebCore::serializeIDBKeyPath):
(WebCore::deserializeIDBKeyPath):
* Modules/indexeddb/server/IDBSerialization.h:
* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::SQLiteIDBBackingStore::extractExistingDatabaseInfo):
* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
* Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
(WebCore::IDBDatabaseInfo::createNewObjectStore):
* Modules/indexeddb/shared/IDBDatabaseInfo.h:
* Modules/indexeddb/shared/IDBIndexInfo.cpp:
(WebCore::IDBIndexInfo::IDBIndexInfo):
(WebCore::IDBIndexInfo::isolatedCopy):
* Modules/indexeddb/shared/IDBIndexInfo.h:
* Modules/indexeddb/shared/IDBObjectStoreInfo.cpp:
(WebCore::IDBObjectStoreInfo::IDBObjectStoreInfo):
(WebCore::IDBObjectStoreInfo::createNewIndex):
(WebCore::IDBObjectStoreInfo::isolatedCopy):
* Modules/indexeddb/shared/IDBObjectStoreInfo.h:
(WebCore::IDBObjectStoreInfo::keyPath):
* bindings/js/IDBBindingUtilities.cpp:
(WebCore::injectIDBKeyIntoScriptValue):
(WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
(WebCore::canInjectIDBKeyIntoScriptValue):
(WebCore::createKeyPathArray):
(WebCore::toJS):
* bindings/js/IDBBindingUtilities.h:
* inspector/InspectorIndexedDBAgent.cpp:

Source/WebKit2:

Add coders to encode / decode IDBKeyPath type for IPC.

* Shared/Databases/IndexedDB/WebIDBResult.cpp:
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder&lt;IDBKeyPath&gt;::encode):
(IPC::ArgumentCoder&lt;IDBKeyPath&gt;::decode):
* Shared/WebCoreArgumentCoders.h:
* WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:

LayoutTests:

Rebaseline a few tests now that IDBIndex.keyPath / IDBObjectStore.keyPath
no longer incorrectly return DOMStringList objects and return regular
arrays instead.

* storage/indexeddb/modern/idbindex-properties-basic-expected.txt:
* storage/indexeddb/modern/idbindex-properties-basic-private-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernidbindexpropertiesbasicexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernidbindexpropertiesbasicprivateexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-private-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBCursorcpp">trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBDatabaseh">trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBGetResultcpp">trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBKeyPathcpp">trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBKeyPathh">trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStorecpp">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStoreh">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBSerializationcpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBSerializationh">trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfocpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfoh">trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBIndexInfocpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBIndexInfoh">trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBObjectStoreInfocpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBObjectStoreInfoh">trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp</a></li>
<li><a href="#trunkSourceWebCorebindingsjsIDBBindingUtilitiesh">trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorIndexedDBAgentcpp">trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedDatabasesIndexedDBWebIDBResultcpp">trunk/Source/WebKit2/Shared/Databases/IndexedDB/WebIDBResult.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCoderscpp">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCodersh">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServercpp">trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/LayoutTests/ChangeLog        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-10-26  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Replace IDBKeyPath with a WTF::Variant
+        https://bugs.webkit.org/show_bug.cgi?id=163909
+
+        Reviewed by Darin Adler.
+
+        Rebaseline a few tests now that IDBIndex.keyPath / IDBObjectStore.keyPath
+        no longer incorrectly return DOMStringList objects and return regular
+        arrays instead.
+
+        * storage/indexeddb/modern/idbindex-properties-basic-expected.txt:
+        * storage/indexeddb/modern/idbindex-properties-basic-private-expected.txt:
+
</ins><span class="cx"> 2016-10-26  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Ignore out-of-flow siblings when searching for a spanner candidate.
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernidbindexpropertiesbasicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-expected.txt (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-expected.txt        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-expected.txt        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -41,13 +41,13 @@
</span><span class="cx"> TestIndex6
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> TestIndex7
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo,bar
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> Initial upgrade versionchange transaction complete
</span><span class="lines">@@ -84,13 +84,13 @@
</span><span class="cx"> TestIndex6
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> TestIndex7
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo,bar
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> readonly transaction complete
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernidbindexpropertiesbasicprivateexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-private-expected.txt (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-private-expected.txt        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/LayoutTests/storage/indexeddb/modern/idbindex-properties-basic-private-expected.txt        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -41,13 +41,13 @@
</span><span class="cx"> TestIndex6
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> TestIndex7
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo,bar
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> Initial upgrade versionchange transaction complete
</span><span class="lines">@@ -84,13 +84,13 @@
</span><span class="cx"> TestIndex6
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> TestIndex7
</span><span class="cx"> [object IDBObjectStore]
</span><span class="cx"> TestObjectStore
</span><del>-[object DOMStringList]
</del><ins>+foo,bar
</ins><span class="cx"> false
</span><span class="cx"> false
</span><span class="cx"> readonly transaction complete
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/ChangeLog        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -1,3 +1,72 @@
</span><ins>+2016-10-26  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Replace IDBKeyPath with a WTF::Variant
+        https://bugs.webkit.org/show_bug.cgi?id=163909
+
+        Reviewed by Darin Adler.
+
+        Replace IDBKeyPath class with the IDBKeyPathVariant type entirely
+        and rename IDBKeyPathVariant to IDBKeyPath.
+
+        Unfortunately, IDBKeyPath still needs some special handling when
+        returned to the JavaScript because we do not have a toJS() accepting
+        a WTF::Variant as input yet.
+
+        There should be no significant behavior change except that
+        IDBIndex.keyPath / IDBObjectStore.keyPath now returns an array of
+        Strings instead of a DOMStringList object when the IDBKeyPath
+        contains a vector. This is a progression and matches the
+        specification:
+        - https://www.w3.org/TR/IndexedDB/#widl-IDBIndex-keyPath
+        - https://www.w3.org/TR/IndexedDB/#widl-IDBObjectStore-keyPath
+
+        No new tests, rebaselined existing tests.
+
+        * Modules/indexeddb/IDBCursor.cpp:
+        (WebCore::IDBCursor::update):
+        * Modules/indexeddb/IDBDatabase.h:
+        * Modules/indexeddb/IDBGetResult.cpp:
+        (WebCore::IDBGetResult::isolatedCopy):
+        * Modules/indexeddb/IDBKeyPath.cpp:
+        (WebCore::isIDBKeyPathValid):
+        (WebCore::IDBKeyPathIsolatedCopy):
+        * Modules/indexeddb/IDBKeyPath.h:
+        (WebCore::IDBKeyPathIsolatedCopy):
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::keyPath):
+        (WebCore::IDBObjectStore::putOrAdd):
+        (WebCore::IDBObjectStore::createIndex):
+        * Modules/indexeddb/IDBObjectStore.h:
+        * Modules/indexeddb/server/IDBSerialization.cpp:
+        (WebCore::serializeIDBKeyPath):
+        (WebCore::deserializeIDBKeyPath):
+        * Modules/indexeddb/server/IDBSerialization.h:
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::SQLiteIDBBackingStore::extractExistingDatabaseInfo):
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
+        * Modules/indexeddb/shared/IDBDatabaseInfo.cpp:
+        (WebCore::IDBDatabaseInfo::createNewObjectStore):
+        * Modules/indexeddb/shared/IDBDatabaseInfo.h:
+        * Modules/indexeddb/shared/IDBIndexInfo.cpp:
+        (WebCore::IDBIndexInfo::IDBIndexInfo):
+        (WebCore::IDBIndexInfo::isolatedCopy):
+        * Modules/indexeddb/shared/IDBIndexInfo.h:
+        * Modules/indexeddb/shared/IDBObjectStoreInfo.cpp:
+        (WebCore::IDBObjectStoreInfo::IDBObjectStoreInfo):
+        (WebCore::IDBObjectStoreInfo::createNewIndex):
+        (WebCore::IDBObjectStoreInfo::isolatedCopy):
+        * Modules/indexeddb/shared/IDBObjectStoreInfo.h:
+        (WebCore::IDBObjectStoreInfo::keyPath):
+        * bindings/js/IDBBindingUtilities.cpp:
+        (WebCore::injectIDBKeyIntoScriptValue):
+        (WebCore::maybeCreateIDBKeyFromScriptValueAndKeyPath):
+        (WebCore::canInjectIDBKeyIntoScriptValue):
+        (WebCore::createKeyPathArray):
+        (WebCore::toJS):
+        * bindings/js/IDBBindingUtilities.h:
+        * inspector/InspectorIndexedDBAgent.cpp:
+
</ins><span class="cx"> 2016-10-26  Zalan Bujtas  &lt;zalan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Ignore out-of-flow siblings when searching for a spanner candidate.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBCursorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursor.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -194,10 +194,10 @@
</span><span class="cx">         return Exception { IDBDatabaseException::InvalidStateError, ASCIILiteral(&quot;Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor.&quot;) };
</span><span class="cx"> 
</span><span class="cx">     auto&amp; objectStore = effectiveObjectStore();
</span><del>-    auto&amp; keyPath = objectStore.info().keyPath();
-    const bool usesInLineKeys = !keyPath.isNull();
</del><ins>+    auto&amp; optionalKeyPath = objectStore.info().keyPath();
+    const bool usesInLineKeys = !!optionalKeyPath;
</ins><span class="cx">     if (usesInLineKeys) {
</span><del>-        RefPtr&lt;IDBKey&gt; keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, keyPath);
</del><ins>+        RefPtr&lt;IDBKey&gt; keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, optionalKeyPath.value());
</ins><span class="cx">         IDBKeyData keyPathKeyData(keyPathKey.get());
</span><span class="cx">         if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData)
</span><span class="cx">             return Exception { IDBDatabaseException::DataError, ASCIILiteral(&quot;Failed to execute 'update' on 'IDBCursor': The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key.&quot;) };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabase.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx">     RefPtr&lt;DOMStringList&gt; objectStoreNames() const;
</span><span class="cx"> 
</span><span class="cx">     struct ObjectStoreParameters {
</span><del>-        Optional&lt;IDBKeyPathVariant&gt; keyPath;
</del><ins>+        Optional&lt;IDBKeyPath&gt; keyPath;
</ins><span class="cx">         bool autoIncrement;
</span><span class="cx">     };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBGetResultcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBGetResult.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">     destination.m_value = source.m_value.isolatedCopy();
</span><span class="cx">     destination.m_keyData = source.m_keyData.isolatedCopy();
</span><span class="cx">     destination.m_primaryKeyData = source.m_primaryKeyData.isolatedCopy();
</span><del>-    destination.m_keyPath = source.m_keyPath.isolatedCopy();
</del><ins>+    destination.m_keyPath = WebCore::isolatedCopy(source.m_keyPath);
</ins><span class="cx">     destination.m_isDefined = source.m_isDefined;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBKeyPathcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -24,11 +24,10 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> #include &quot;config.h&quot;
</span><del>-#include &quot;IDBKeyPath.h&quot;
</del><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><ins>+#include &quot;IDBKeyPath.h&quot;
</ins><span class="cx"> 
</span><del>-#include &quot;KeyedCoding.h&quot;
</del><span class="cx"> #include &lt;wtf/ASCIICType.h&gt;
</span><span class="cx"> #include &lt;wtf/dtoa.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -191,39 +190,8 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBKeyPath::IDBKeyPath(const String&amp; string)
-    : m_type(Type::String)
-    , m_string(string)
</del><ins>+bool isIDBKeyPathValid(const IDBKeyPath&amp; keyPath)
</ins><span class="cx"> {
</span><del>-    ASSERT(!m_string.isNull());
-}
-
-IDBKeyPath::IDBKeyPath(const Vector&lt;String&gt;&amp; array)
-    : m_type(Type::Array)
-    , m_array(array)
-{
-#if !LOG_DISABLED
-    for (auto&amp; key : array)
-        ASSERT(!key.isNull());
-#endif
-}
-
-IDBKeyPath::IDBKeyPath(Optional&lt;IDBKeyPathVariant&gt;&amp;&amp; variant)
-{
-    if (!variant)
-        return;
-
-    if (WTF::holds_alternative&lt;String&gt;(*variant)) {
-        m_type = Type::String;
-        m_string = WTFMove(WTF::get&lt;String&gt;(*variant));
-    } else {
-        m_type = Type::Array;
-        m_array = WTFMove(WTF::get&lt;Vector&lt;String&gt;&gt;(*variant));
-    }
-}
-
-bool isIDBKeyPathValid(const IDBKeyPathVariant&amp; keyPath)
-{
</del><span class="cx">     auto visitor = WTF::makeVisitor([](const String&amp; string) {
</span><span class="cx">         return IDBIsValidKeyPath(string);
</span><span class="cx">     }, [](const Vector&lt;String&gt;&amp; vector) {
</span><span class="lines">@@ -238,73 +206,19 @@
</span><span class="cx">     return WTF::visit(visitor, keyPath);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool IDBKeyPath::operator==(const IDBKeyPath&amp; other) const
</del><ins>+IDBKeyPath isolatedCopy(const IDBKeyPath&amp; keyPath)
</ins><span class="cx"> {
</span><del>-    if (m_type != other.m_type)
-        return false;
-
-    switch (m_type) {
-    case Type::Null:
-        return true;
-    case Type::String:
-        return m_string == other.m_string;
-    case Type::Array:
-        return m_array == other.m_array;
-    }
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-IDBKeyPath IDBKeyPath::isolatedCopy() const
-{
-    IDBKeyPath result;
-    result.m_type = m_type;
-    result.m_string = m_string.isolatedCopy();
-    result.m_array.reserveInitialCapacity(m_array.size());
-    for (auto&amp; key : m_array)
-        result.m_array.uncheckedAppend(key.isolatedCopy());
-    return result;
-}
-
-void IDBKeyPath::encode(KeyedEncoder&amp; encoder) const
-{
-    encoder.encodeEnum(&quot;type&quot;, m_type);
-    switch (m_type) {
-    case Type::Null:
-        return;
-    case Type::String:
-        encoder.encodeString(&quot;string&quot;, m_string);
-        return;
-    case Type::Array:
-        encoder.encodeObjects(&quot;array&quot;, m_array.begin(), m_array.end(), [](WebCore::KeyedEncoder&amp; encoder, const String&amp; string) {
-            encoder.encodeString(&quot;string&quot;, string);
-        });
-        return;
-    };
-    ASSERT_NOT_REACHED();
-}
-
-bool IDBKeyPath::decode(KeyedDecoder&amp; decoder, IDBKeyPath&amp; result)
-{
-    bool succeeded = decoder.decodeEnum(&quot;type&quot;, result.m_type, [](Type value) {
-        return value == Type::Null || value == Type::String || value == Type::Array;
</del><ins>+    auto visitor = WTF::makeVisitor([](const String&amp; string) -&gt; IDBKeyPath {
+        return string.isolatedCopy();
+    }, [](const Vector&lt;String&gt;&amp; vector) -&gt; IDBKeyPath {
+        Vector&lt;String&gt; vectorCopy;
+        vectorCopy.reserveInitialCapacity(vector.size());
+        for (auto&amp; string : vector)
+            vectorCopy.uncheckedAppend(string.isolatedCopy());
+        return vectorCopy;
</ins><span class="cx">     });
</span><del>-    if (!succeeded)
-        return false;
</del><span class="cx"> 
</span><del>-    switch (result.m_type) {
-    case Type::Null:
-        return true;
-    case Type::String:
-        return decoder.decodeString(&quot;string&quot;, result.m_string);
-    case Type::Array:
-        result.m_array.clear();
-        return decoder.decodeObjects(&quot;array&quot;, result.m_array, [](KeyedDecoder&amp; decoder, String&amp; result) {
-            return decoder.decodeString(&quot;string&quot;, result);
-        });
-    }
-    ASSERT_NOT_REACHED();
-    return false;
</del><ins>+    return WTF::visit(visitor, keyPath);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBKeyPathh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBKeyPath.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -33,12 +33,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-using IDBKeyPathVariant = WTF::Variant&lt;String, Vector&lt;String&gt;&gt;;
-bool isIDBKeyPathValid(const IDBKeyPathVariant&amp;);
</del><ins>+using IDBKeyPath = WTF::Variant&lt;String, Vector&lt;String&gt;&gt;;
+bool isIDBKeyPathValid(const IDBKeyPath&amp;);
</ins><span class="cx"> 
</span><del>-class KeyedDecoder;
-class KeyedEncoder;
-
</del><span class="cx"> enum class IDBKeyPathParseError {
</span><span class="cx">     None,
</span><span class="cx">     Start,
</span><span class="lines">@@ -47,97 +44,14 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> void IDBParseKeyPath(const String&amp;, Vector&lt;String&gt;&amp;, IDBKeyPathParseError&amp;);
</span><del>-
-// FIXME: We should be able to replace IDBKeyPath with IDBKeyPathVariant.
-class IDBKeyPath {
-public:
-    IDBKeyPath() { }
-    WEBCORE_EXPORT IDBKeyPath(const String&amp;);
-    WEBCORE_EXPORT IDBKeyPath(const Vector&lt;String&gt;&amp; array);
-    WEBCORE_EXPORT IDBKeyPath(Optional&lt;IDBKeyPathVariant&gt;&amp;&amp;);
-
-    enum class Type { Null, String, Array };
-    Type type() const { return m_type; }
-
-    const Vector&lt;String&gt;&amp; array() const
-    {
-        ASSERT(m_type == Type::Array);
-        return m_array;
-    }
-
-    const String&amp; string() const
-    {
-        ASSERT(m_type == Type::String);
-        return m_string;
-    }
-
-    bool isNull() const { return m_type == Type::Null; }
-    bool operator==(const IDBKeyPath&amp; other) const;
-
-    IDBKeyPath isolatedCopy() const;
-
-    template&lt;class Encoder&gt; void encode(Encoder&amp;) const;
-    template&lt;class Decoder&gt; static bool decode(Decoder&amp;, IDBKeyPath&amp;);
-    
-    WEBCORE_EXPORT void encode(KeyedEncoder&amp;) const;
-    WEBCORE_EXPORT static bool decode(KeyedDecoder&amp;, IDBKeyPath&amp;);
-
-private:
-    Type m_type { Type::Null };
-    String m_string;
-    Vector&lt;String&gt; m_array;
-};
-
-template&lt;class Encoder&gt; void IDBKeyPath::encode(Encoder&amp; encoder) const
</del><ins>+IDBKeyPath isolatedCopy(const IDBKeyPath&amp;);
+inline Optional&lt;IDBKeyPath&gt; isolatedCopy(const Optional&lt;IDBKeyPath&gt;&amp; variant)
</ins><span class="cx"> {
</span><del>-    encoder.encodeEnum(m_type);
-
-    switch (m_type) {
-    case Type::Null:
-        break;
-    case Type::String:
-        encoder &lt;&lt; m_string;
-        break;
-    case Type::Array:
-        encoder &lt;&lt; m_array;
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
</del><ins>+    if (!variant)
+        return { };
+    return isolatedCopy(variant.value());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;class Decoder&gt; bool IDBKeyPath::decode(Decoder&amp; decoder, IDBKeyPath&amp; keyPath)
-{
-    Type type;
-    if (!decoder.decodeEnum(type))
-        return false;
-
-    switch (type) {
-    case Type::Null:
-        keyPath = IDBKeyPath();
-        return true;
-
-    case Type::String: {
-        String string;
-        if (!decoder.decode(string))
-            return false;
-
-        keyPath = IDBKeyPath(string);
-        return true;
-    }
-    case Type::Array: {
-        Vector&lt;String&gt; array;
-        if (!decoder.decode(array))
-            return false;
-
-        keyPath = IDBKeyPath(array);
-        return true;
-    }
-    default:
-        return true;
-    }
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -120,7 +120,7 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const IDBKeyPath&amp; IDBObjectStore::keyPath() const
</del><ins>+const Optional&lt;IDBKeyPath&gt;&amp; IDBObjectStore::keyPath() const
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(currentThread() == m_transaction-&gt;database().originThreadID());
</span><span class="cx">     return m_info.keyPath();
</span><span class="lines">@@ -311,13 +311,13 @@
</span><span class="cx">     if (key &amp;&amp; !key-&gt;isValid())
</span><span class="cx">         return Exception { IDBDatabaseException::DataError, ASCIILiteral(&quot;Failed to store record in an IDBObjectStore: The parameter is not a valid key.&quot;) };
</span><span class="cx"> 
</span><del>-    bool usesInlineKeys = !m_info.keyPath().isNull();
</del><ins>+    bool usesInlineKeys = !!m_info.keyPath();
</ins><span class="cx">     bool usesKeyGenerator = autoIncrement();
</span><span class="cx">     if (usesInlineKeys &amp;&amp; inlineKeyCheck == InlineKeyCheck::Perform) {
</span><span class="cx">         if (key)
</span><span class="cx">             return Exception { IDBDatabaseException::DataError, ASCIILiteral(&quot;Failed to store record in an IDBObjectStore: The object store uses in-line keys and the key parameter was provided.&quot;) };
</span><span class="cx"> 
</span><del>-        RefPtr&lt;IDBKey&gt; keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath());
</del><ins>+        RefPtr&lt;IDBKey&gt; keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(state, value, m_info.keyPath().value());
</ins><span class="cx">         if (keyPathKey &amp;&amp; !keyPathKey-&gt;isValid())
</span><span class="cx">             return Exception { IDBDatabaseException::DataError, ASCIILiteral(&quot;Failed to store record in an IDBObjectStore: Evaluating the object store's key path yielded a value that is not a valid key.&quot;) };
</span><span class="cx"> 
</span><span class="lines">@@ -324,7 +324,7 @@
</span><span class="cx">         if (!keyPathKey) {
</span><span class="cx">             if (!usesKeyGenerator)
</span><span class="cx">                 return Exception { IDBDatabaseException::DataError, ASCIILiteral(&quot;Failed to store record in an IDBObjectStore: Evaluating the object store's key path did not yield a value.&quot;) };
</span><del>-            if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath()))
</del><ins>+            if (!canInjectIDBKeyIntoScriptValue(state, value, m_info.keyPath().value()))
</ins><span class="cx">                 return Exception { IDBDatabaseException::DataError };
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -399,7 +399,7 @@
</span><span class="cx">     return m_transaction-&gt;requestClearObjectStore(execState, *this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ExceptionOr&lt;Ref&lt;IDBIndex&gt;&gt; IDBObjectStore::createIndex(ExecState&amp;, const String&amp; name, IDBKeyPathVariant&amp;&amp; keyPath, const IndexParameters&amp; parameters)
</del><ins>+ExceptionOr&lt;Ref&lt;IDBIndex&gt;&gt; IDBObjectStore::createIndex(ExecState&amp;, const String&amp; name, IDBKeyPath&amp;&amp; keyPath, const IndexParameters&amp; parameters)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBObjectStore::createIndex %s&quot;, name.utf8().data());
</span><span class="cx">     ASSERT(currentThread() == m_transaction-&gt;database().originThreadID());
</span><span class="lines">@@ -426,7 +426,7 @@
</span><span class="cx">         return Exception { IDBDatabaseException::InvalidAccessError, ASCIILiteral(&quot;Failed to execute 'createIndex' on 'IDBObjectStore': The keyPath argument was an array and the multiEntry option is true.&quot;) };
</span><span class="cx"> 
</span><span class="cx">     // Install the new Index into the ObjectStore's info.
</span><del>-    IDBIndexInfo info = m_info.createNewIndex(name, Optional&lt;IDBKeyPathVariant&gt;(WTFMove(keyPath)), parameters.unique, parameters.multiEntry);
</del><ins>+    IDBIndexInfo info = m_info.createNewIndex(name, WTFMove(keyPath), parameters.unique, parameters.multiEntry);
</ins><span class="cx">     m_transaction-&gt;database().didCreateIndexInfo(info);
</span><span class="cx"> 
</span><span class="cx">     // Create the actual IDBObjectStore from the transaction, which also schedules the operation server side.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx"> 
</span><span class="cx">     const String&amp; name() const;
</span><span class="cx">     ExceptionOr&lt;void&gt; setName(const String&amp;);
</span><del>-    const IDBKeyPath&amp; keyPath() const;
</del><ins>+    const Optional&lt;IDBKeyPath&gt;&amp; keyPath() const;
</ins><span class="cx">     RefPtr&lt;DOMStringList&gt; indexNames() const;
</span><span class="cx">     IDBTransaction&amp; transaction();
</span><span class="cx">     bool autoIncrement() const;
</span><span class="lines">@@ -83,7 +83,7 @@
</span><span class="cx">     ExceptionOr&lt;Ref&lt;IDBRequest&gt;&gt; deleteFunction(JSC::ExecState&amp;, IDBKeyRange*);
</span><span class="cx">     ExceptionOr&lt;Ref&lt;IDBRequest&gt;&gt; deleteFunction(JSC::ExecState&amp;, JSC::JSValue key);
</span><span class="cx">     ExceptionOr&lt;Ref&lt;IDBRequest&gt;&gt; clear(JSC::ExecState&amp;);
</span><del>-    ExceptionOr&lt;Ref&lt;IDBIndex&gt;&gt; createIndex(JSC::ExecState&amp;, const String&amp; name, IDBKeyPathVariant&amp;&amp;, const IndexParameters&amp;);
</del><ins>+    ExceptionOr&lt;Ref&lt;IDBIndex&gt;&gt; createIndex(JSC::ExecState&amp;, const String&amp; name, IDBKeyPath&amp;&amp;, const IndexParameters&amp;);
</ins><span class="cx">     ExceptionOr&lt;Ref&lt;IDBIndex&gt;&gt; index(const String&amp; name);
</span><span class="cx">     ExceptionOr&lt;void&gt; deleteIndex(const String&amp; name);
</span><span class="cx">     ExceptionOr&lt;Ref&lt;IDBRequest&gt;&gt; count(JSC::ExecState&amp;, IDBKeyRange*);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBSerializationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -33,20 +33,65 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-RefPtr&lt;SharedBuffer&gt; serializeIDBKeyPath(const IDBKeyPath&amp; keyPath)
</del><ins>+enum class KeyPathType { Null, String, Array };
+
+RefPtr&lt;SharedBuffer&gt; serializeIDBKeyPath(const Optional&lt;IDBKeyPath&gt;&amp; keyPath)
</ins><span class="cx"> {
</span><span class="cx">     auto encoder = KeyedEncoder::encoder();
</span><del>-    keyPath.encode(*encoder);
</del><ins>+
+    if (keyPath) {
+        auto visitor = WTF::makeVisitor([&amp;](const String&amp; string) {
+            encoder-&gt;encodeEnum(&quot;type&quot;, KeyPathType::String);
+            encoder-&gt;encodeString(&quot;string&quot;, string);
+        }, [&amp;](const Vector&lt;String&gt;&amp; vector) {
+            encoder-&gt;encodeEnum(&quot;type&quot;, KeyPathType::Array);
+            encoder-&gt;encodeObjects(&quot;array&quot;, vector.begin(), vector.end(), [](WebCore::KeyedEncoder&amp; encoder, const String&amp; string) {
+                encoder.encodeString(&quot;string&quot;, string);
+            });
+        });
+        WTF::visit(visitor, keyPath.value());
+    } else
+        encoder-&gt;encodeEnum(&quot;type&quot;, KeyPathType::Null);
+
</ins><span class="cx">     return encoder-&gt;finishEncoding();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool deserializeIDBKeyPath(const uint8_t* data, size_t size, IDBKeyPath&amp; result)
</del><ins>+bool deserializeIDBKeyPath(const uint8_t* data, size_t size, Optional&lt;IDBKeyPath&gt;&amp; result)
</ins><span class="cx"> {
</span><span class="cx">     if (!data || !size)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     auto decoder = KeyedDecoder::decoder(data, size);
</span><del>-    return IDBKeyPath::decode(*decoder, result);
</del><ins>+
+    KeyPathType type;
+    bool succeeded = decoder-&gt;decodeEnum(&quot;type&quot;, type, [](KeyPathType value) {
+        return value == KeyPathType::Null || value == KeyPathType::String || value == KeyPathType::Array;
+    });
+    if (!succeeded)
+        return false;
+
+    switch (type) {
+    case KeyPathType::Null:
+        break;
+    case KeyPathType::String: {
+        String string;
+        if (!decoder-&gt;decodeString(&quot;string&quot;, string))
+            return false;
+        result = IDBKeyPath(WTFMove(string));
+        break;
+    }
+    case KeyPathType::Array: {
+        Vector&lt;String&gt; vector;
+        succeeded = decoder-&gt;decodeObjects(&quot;array&quot;, vector, [](KeyedDecoder&amp; decoder, String&amp; result) {
+            return decoder.decodeString(&quot;string&quot;, result);
+        });
+        if (!succeeded)
+            return false;
+        result = IDBKeyPath(WTFMove(vector));
+        break;
+    }
+    }
+    return true;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;SharedBuffer&gt; serializeIDBKeyData(const IDBKeyData&amp; key)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBSerializationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -28,15 +28,15 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;IDBKeyPath.h&quot;
</ins><span class="cx"> #include &quot;SharedBuffer.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class IDBKeyData;
</span><del>-class IDBKeyPath;
</del><span class="cx"> 
</span><del>-RefPtr&lt;SharedBuffer&gt; serializeIDBKeyPath(const IDBKeyPath&amp;);
-bool deserializeIDBKeyPath(const uint8_t* buffer, size_t bufferSize, IDBKeyPath&amp;);
</del><ins>+RefPtr&lt;SharedBuffer&gt; serializeIDBKeyPath(const Optional&lt;IDBKeyPath&gt;&amp;);
+bool deserializeIDBKeyPath(const uint8_t* buffer, size_t bufferSize, Optional&lt;IDBKeyPath&gt;&amp;);
</ins><span class="cx"> 
</span><span class="cx"> RefPtr&lt;SharedBuffer&gt; serializeIDBKeyData(const IDBKeyData&amp;);
</span><span class="cx"> bool deserializeIDBKeyData(const uint8_t* buffer, size_t bufferSize, IDBKeyData&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -599,7 +599,7 @@
</span><span class="cx">             Vector&lt;char&gt; keyPathBuffer;
</span><span class="cx">             sql.getColumnBlobAsVector(2, keyPathBuffer);
</span><span class="cx"> 
</span><del>-            IDBKeyPath objectStoreKeyPath;
</del><ins>+            Optional&lt;IDBKeyPath&gt; objectStoreKeyPath;
</ins><span class="cx">             if (!deserializeIDBKeyPath(reinterpret_cast&lt;const uint8_t*&gt;(keyPathBuffer.data()), keyPathBuffer.size(), objectStoreKeyPath)) {
</span><span class="cx">                 LOG_ERROR(&quot;Unable to extract key path from database&quot;);
</span><span class="cx">                 return nullptr;
</span><span class="lines">@@ -607,7 +607,7 @@
</span><span class="cx"> 
</span><span class="cx">             bool autoIncrement = sql.getColumnInt(3);
</span><span class="cx"> 
</span><del>-            databaseInfo-&gt;addExistingObjectStore({ objectStoreID, objectStoreName, objectStoreKeyPath, autoIncrement });
</del><ins>+            databaseInfo-&gt;addExistingObjectStore({ objectStoreID, objectStoreName, WTFMove(objectStoreKeyPath), autoIncrement });
</ins><span class="cx"> 
</span><span class="cx">             result = sql.step();
</span><span class="cx">         }
</span><span class="lines">@@ -632,11 +632,15 @@
</span><span class="cx">             Vector&lt;char&gt; keyPathBuffer;
</span><span class="cx">             sql.getColumnBlobAsVector(3, keyPathBuffer);
</span><span class="cx"> 
</span><del>-            IDBKeyPath indexKeyPath;
</del><ins>+            Optional&lt;IDBKeyPath&gt; indexKeyPath;
</ins><span class="cx">             if (!deserializeIDBKeyPath(reinterpret_cast&lt;const uint8_t*&gt;(keyPathBuffer.data()), keyPathBuffer.size(), indexKeyPath)) {
</span><span class="cx">                 LOG_ERROR(&quot;Unable to extract key path from database&quot;);
</span><span class="cx">                 return nullptr;
</span><span class="cx">             }
</span><ins>+            if (!indexKeyPath) {
+                LOG_ERROR(&quot;Unable to extract key path from database&quot;);
+                return nullptr;
+            }
</ins><span class="cx"> 
</span><span class="cx">             bool unique = sql.getColumnInt(4);
</span><span class="cx">             bool multiEntry = sql.getColumnInt(5);
</span><span class="lines">@@ -647,7 +651,7 @@
</span><span class="cx">                 return nullptr;
</span><span class="cx">             }
</span><span class="cx"> 
</span><del>-            objectStore-&gt;addExistingIndex({ indexID, objectStoreID, indexName, indexKeyPath, unique, multiEntry });
</del><ins>+            objectStore-&gt;addExistingIndex({ indexID, objectStoreID, indexName, WTFMove(indexKeyPath.value()), unique, multiEntry });
</ins><span class="cx"> 
</span><span class="cx">             result = sql.step();
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -953,7 +953,7 @@
</span><span class="cx">     // If ObjectStore has a key path and the key is autogenerated, then inject the key into the value
</span><span class="cx">     // using steps to assign a key to a value using a key path.
</span><span class="cx">     ThreadSafeDataBuffer injectedRecordValue;
</span><del>-    if (usedKeyIsGenerated &amp;&amp; !objectStoreInfo-&gt;keyPath().isNull()) {
</del><ins>+    if (usedKeyIsGenerated &amp;&amp; objectStoreInfo-&gt;keyPath()) {
</ins><span class="cx">         VM&amp; vm = databaseThreadVM();
</span><span class="cx">         JSLockHolder locker(vm);
</span><span class="cx">         auto scope = DECLARE_THROW_SCOPE(vm);
</span><span class="lines">@@ -964,7 +964,7 @@
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (!injectIDBKeyIntoScriptValue(databaseThreadExecState(), usedKey, value, objectStoreInfo-&gt;keyPath())) {
</del><ins>+        if (!injectIDBKeyIntoScriptValue(databaseThreadExecState(), usedKey, value, objectStoreInfo-&gt;keyPath().value())) {
</ins><span class="cx">             postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(IDBDatabaseException::ConstraintError, ASCIILiteral(&quot;Unable to inject record key into record value&quot;)), usedKey));
</span><span class="cx">             return;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -66,9 +66,9 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBObjectStoreInfo IDBDatabaseInfo::createNewObjectStore(const String&amp; name, const IDBKeyPath&amp; keyPath, bool autoIncrement)
</del><ins>+IDBObjectStoreInfo IDBDatabaseInfo::createNewObjectStore(const String&amp; name, Optional&lt;IDBKeyPath&gt;&amp;&amp; keyPath, bool autoIncrement)
</ins><span class="cx"> {
</span><del>-    IDBObjectStoreInfo info(++m_maxObjectStoreID, name, keyPath, autoIncrement);
</del><ins>+    IDBObjectStoreInfo info(++m_maxObjectStoreID, name, WTFMove(keyPath), autoIncrement);
</ins><span class="cx">     m_objectStoreMap.set(info.identifier(), info);
</span><span class="cx">     return info;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBDatabaseInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBDatabaseInfo.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -33,8 +33,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class IDBKeyPath;
-
</del><span class="cx"> class IDBDatabaseInfo {
</span><span class="cx"> public:
</span><span class="cx">     IDBDatabaseInfo(const String&amp; name, uint64_t version);
</span><span class="lines">@@ -50,7 +48,7 @@
</span><span class="cx">     uint64_t version() const { return m_version; }
</span><span class="cx"> 
</span><span class="cx">     bool hasObjectStore(const String&amp; name) const;
</span><del>-    IDBObjectStoreInfo createNewObjectStore(const String&amp; name, const IDBKeyPath&amp;, bool autoIncrement);
</del><ins>+    IDBObjectStoreInfo createNewObjectStore(const String&amp; name, Optional&lt;IDBKeyPath&gt;&amp;&amp;, bool autoIncrement);
</ins><span class="cx">     void addExistingObjectStore(const IDBObjectStoreInfo&amp;);
</span><span class="cx">     IDBObjectStoreInfo* infoForExistingObjectStore(uint64_t objectStoreIdentifier);
</span><span class="cx">     IDBObjectStoreInfo* infoForExistingObjectStore(const String&amp; objectStoreName);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBIndexInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -34,11 +34,11 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBIndexInfo::IDBIndexInfo(uint64_t identifier, uint64_t objectStoreIdentifier, const String&amp; name, const IDBKeyPath&amp; keyPath, bool unique, bool multiEntry)
</del><ins>+IDBIndexInfo::IDBIndexInfo(uint64_t identifier, uint64_t objectStoreIdentifier, const String&amp; name, IDBKeyPath&amp;&amp; keyPath, bool unique, bool multiEntry)
</ins><span class="cx">     : m_identifier(identifier)
</span><span class="cx">     , m_objectStoreIdentifier(objectStoreIdentifier)
</span><span class="cx">     , m_name(name)
</span><del>-    , m_keyPath(keyPath)
</del><ins>+    , m_keyPath(WTFMove(keyPath))
</ins><span class="cx">     , m_unique(unique)
</span><span class="cx">     , m_multiEntry(multiEntry)
</span><span class="cx"> {
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx"> 
</span><span class="cx"> IDBIndexInfo IDBIndexInfo::isolatedCopy() const
</span><span class="cx"> {
</span><del>-    return { m_identifier, m_objectStoreIdentifier, m_name.isolatedCopy(), m_keyPath.isolatedCopy(), m_unique, m_multiEntry };
</del><ins>+    return { m_identifier, m_objectStoreIdentifier, m_name.isolatedCopy(), WebCore::isolatedCopy(m_keyPath), m_unique, m_multiEntry };
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if !LOG_DISABLED
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBIndexInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBIndexInfo.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> class IDBIndexInfo {
</span><span class="cx"> public:
</span><span class="cx">     WEBCORE_EXPORT IDBIndexInfo();
</span><del>-    IDBIndexInfo(uint64_t identifier, uint64_t objectStoreIdentifier, const String&amp; name, const IDBKeyPath&amp;, bool unique, bool multiEntry);
</del><ins>+    IDBIndexInfo(uint64_t identifier, uint64_t objectStoreIdentifier, const String&amp; name, IDBKeyPath&amp;&amp;, bool unique, bool multiEntry);
</ins><span class="cx"> 
</span><span class="cx">     IDBIndexInfo isolatedCopy() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBObjectStoreInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -35,17 +35,17 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBObjectStoreInfo::IDBObjectStoreInfo(uint64_t identifier, const String&amp; name, const IDBKeyPath&amp; keyPath, bool autoIncrement)
</del><ins>+IDBObjectStoreInfo::IDBObjectStoreInfo(uint64_t identifier, const String&amp; name, Optional&lt;IDBKeyPath&gt;&amp;&amp; keyPath, bool autoIncrement)
</ins><span class="cx">     : m_identifier(identifier)
</span><span class="cx">     , m_name(name)
</span><del>-    , m_keyPath(keyPath)
</del><ins>+    , m_keyPath(WTFMove(keyPath))
</ins><span class="cx">     , m_autoIncrement(autoIncrement)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBIndexInfo IDBObjectStoreInfo::createNewIndex(const String&amp; name, const IDBKeyPath&amp; keyPath, bool unique, bool multiEntry)
</del><ins>+IDBIndexInfo IDBObjectStoreInfo::createNewIndex(const String&amp; name, IDBKeyPath&amp;&amp; keyPath, bool unique, bool multiEntry)
</ins><span class="cx"> {
</span><del>-    IDBIndexInfo info(++m_maxIndexID, m_identifier, name, keyPath, unique, multiEntry);
</del><ins>+    IDBIndexInfo info(++m_maxIndexID, m_identifier, name, WTFMove(keyPath), unique, multiEntry);
</ins><span class="cx">     m_indexMap.set(info.identifier(), info);
</span><span class="cx">     return info;
</span><span class="cx"> }
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx"> 
</span><span class="cx"> IDBObjectStoreInfo IDBObjectStoreInfo::isolatedCopy() const
</span><span class="cx"> {
</span><del>-    IDBObjectStoreInfo result = { m_identifier, m_name.isolatedCopy(), m_keyPath.isolatedCopy(), m_autoIncrement };
</del><ins>+    IDBObjectStoreInfo result = { m_identifier, m_name.isolatedCopy(), WebCore::isolatedCopy(m_keyPath), m_autoIncrement };
</ins><span class="cx"> 
</span><span class="cx">     for (auto&amp; iterator : m_indexMap) {
</span><span class="cx">         result.m_indexMap.set(iterator.key, iterator.value.isolatedCopy());
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBObjectStoreInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -35,16 +35,14 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-class IDBKeyPath;
-
</del><span class="cx"> class IDBObjectStoreInfo {
</span><span class="cx"> public:
</span><span class="cx">     WEBCORE_EXPORT IDBObjectStoreInfo();
</span><del>-    IDBObjectStoreInfo(uint64_t identifier, const String&amp; name, const IDBKeyPath&amp;, bool autoIncrement);
</del><ins>+    IDBObjectStoreInfo(uint64_t identifier, const String&amp; name, Optional&lt;IDBKeyPath&gt;&amp;&amp;, bool autoIncrement);
</ins><span class="cx"> 
</span><span class="cx">     uint64_t identifier() const { return m_identifier; }
</span><span class="cx">     const String&amp; name() const { return m_name; }
</span><del>-    const IDBKeyPath&amp; keyPath() const { return m_keyPath; }
</del><ins>+    const Optional&lt;IDBKeyPath&gt;&amp; keyPath() const { return m_keyPath; }
</ins><span class="cx">     bool autoIncrement() const { return m_autoIncrement; }
</span><span class="cx">     uint64_t maxIndexID() const { return m_maxIndexID; }
</span><span class="cx"> 
</span><span class="lines">@@ -52,7 +50,7 @@
</span><span class="cx"> 
</span><span class="cx">     IDBObjectStoreInfo isolatedCopy() const;
</span><span class="cx"> 
</span><del>-    IDBIndexInfo createNewIndex(const String&amp; name, const IDBKeyPath&amp;, bool unique, bool multiEntry);
</del><ins>+    IDBIndexInfo createNewIndex(const String&amp; name, IDBKeyPath&amp;&amp;, bool unique, bool multiEntry);
</ins><span class="cx">     void addExistingIndex(const IDBIndexInfo&amp;);
</span><span class="cx">     bool hasIndex(const String&amp; name) const;
</span><span class="cx">     bool hasIndex(uint64_t indexIdentifier) const;
</span><span class="lines">@@ -75,7 +73,7 @@
</span><span class="cx"> private:
</span><span class="cx">     uint64_t m_identifier { 0 };
</span><span class="cx">     String m_name;
</span><del>-    IDBKeyPath m_keyPath;
</del><ins>+    Optional&lt;IDBKeyPath&gt; m_keyPath;
</ins><span class="cx">     bool m_autoIncrement { false };
</span><span class="cx">     uint64_t m_maxIndexID { 0 };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -242,11 +242,11 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;injectIDBKeyIntoScriptValue&quot;);
</span><span class="cx"> 
</span><del>-    ASSERT(keyPath.type() == IDBKeyPath::Type::String);
</del><ins>+    ASSERT(WTF::holds_alternative&lt;String&gt;(keyPath));
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;String&gt; keyPathElements;
</span><span class="cx">     IDBKeyPathParseError error;
</span><del>-    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
</del><ins>+    IDBParseKeyPath(WTF::get&lt;String&gt;(keyPath), keyPathElements, error);
</ins><span class="cx">     ASSERT(error == IDBKeyPathParseError::None);
</span><span class="cx"> 
</span><span class="cx">     if (keyPathElements.isEmpty())
</span><span class="lines">@@ -269,10 +269,8 @@
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;IDBKey&gt; maybeCreateIDBKeyFromScriptValueAndKeyPath(ExecState&amp; exec, const JSValue&amp; value, const IDBKeyPath&amp; keyPath)
</span><span class="cx"> {
</span><del>-    ASSERT(!keyPath.isNull());
-
-    if (keyPath.type() == IDBKeyPath::Type::Array) {
-        const Vector&lt;String&gt;&amp; array = keyPath.array();
</del><ins>+    if (WTF::holds_alternative&lt;Vector&lt;String&gt;&gt;(keyPath)) {
+        auto&amp; array = WTF::get&lt;Vector&lt;String&gt;&gt;(keyPath);
</ins><span class="cx">         Vector&lt;RefPtr&lt;IDBKey&gt;&gt; result;
</span><span class="cx">         result.reserveInitialCapacity(array.size());
</span><span class="cx">         for (auto&amp; string : array) {
</span><span class="lines">@@ -284,8 +282,7 @@
</span><span class="cx">         return IDBKey::createArray(WTFMove(result));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT(keyPath.type() == IDBKeyPath::Type::String);
-    return internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath.string());
</del><ins>+    return internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, WTF::get&lt;String&gt;(keyPath));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool canInjectIDBKeyIntoScriptValue(ExecState&amp; exec, const JSValue&amp; scriptValue, const IDBKeyPath&amp; keyPath)
</span><span class="lines">@@ -292,10 +289,10 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(StorageAPI, &quot;canInjectIDBKeyIntoScriptValue&quot;);
</span><span class="cx"> 
</span><del>-    ASSERT(keyPath.type() == IDBKeyPath::Type::String);
</del><ins>+    ASSERT(WTF::holds_alternative&lt;String&gt;(keyPath));
</ins><span class="cx">     Vector&lt;String&gt; keyPathElements;
</span><span class="cx">     IDBKeyPathParseError error;
</span><del>-    IDBParseKeyPath(keyPath.string(), keyPathElements, error);
</del><ins>+    IDBParseKeyPath(WTF::get&lt;String&gt;(keyPath), keyPathElements, error);
</ins><span class="cx">     ASSERT(error == IDBKeyPathParseError::None);
</span><span class="cx"> 
</span><span class="cx">     if (!keyPathElements.size())
</span><span class="lines">@@ -339,35 +336,30 @@
</span><span class="cx"> 
</span><span class="cx"> static Vector&lt;IDBKeyData&gt; createKeyPathArray(ExecState&amp; exec, JSValue value, const IDBIndexInfo&amp; info)
</span><span class="cx"> {
</span><del>-    Vector&lt;IDBKeyData&gt; keys;
-
-    switch (info.keyPath().type()) {
-    case IDBKeyPath::Type::Array:
-        for (auto&amp; entry : info.keyPath().array()) {
-            auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry);
-            if (!key)
-                return { };
-            keys.append(key.get());
-        }
-        break;
-    case IDBKeyPath::Type::String: {
-        auto idbKey = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, info.keyPath().string());
</del><ins>+    auto visitor = WTF::makeVisitor([&amp;](const String&amp; string) -&gt; Vector&lt;IDBKeyData&gt; {
+        auto idbKey = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, string);
</ins><span class="cx">         if (!idbKey)
</span><span class="cx">             return { };
</span><span class="cx"> 
</span><ins>+        Vector&lt;IDBKeyData&gt; keys;
</ins><span class="cx">         if (info.multiEntry() &amp;&amp; idbKey-&gt;type() == IndexedDB::Array) {
</span><span class="cx">             for (auto&amp; key : idbKey-&gt;array())
</span><span class="cx">                 keys.append(key.get());
</span><span class="cx">         } else
</span><span class="cx">             keys.append(idbKey.get());
</span><ins>+        return keys;
+    }, [&amp;](const Vector&lt;String&gt;&amp; vector) -&gt; Vector&lt;IDBKeyData&gt; {
+        Vector&lt;IDBKeyData&gt; keys;
+        for (auto&amp; entry : vector) {
+            auto key = internalCreateIDBKeyFromScriptValueAndKeyPath(exec, value, entry);
+            if (!key)
+                return { };
+            keys.append(key.get());
+        }
+        return keys;
+    });
</ins><span class="cx"> 
</span><del>-        break;
-    }
-    case IDBKeyPath::Type::Null:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-
-    return keys;
</del><ins>+    return WTF::visit(visitor, info.keyPath());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void generateIndexKeyForValue(ExecState&amp; exec, const IDBIndexInfo&amp; info, JSValue value, IndexKey&amp; outKey)
</span><span class="lines">@@ -380,22 +372,17 @@
</span><span class="cx">     outKey = IndexKey(WTFMove(keyDatas));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSValue toJS(ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, const IDBKeyPath&amp; value)
</del><ins>+JSValue toJS(ExecState&amp; state, JSDOMGlobalObject&amp; globalObject, const Optional&lt;IDBKeyPath&gt;&amp; keyPath)
</ins><span class="cx"> {
</span><del>-    switch (value.type()) {
-    case IDBKeyPath::Type::Null:
</del><ins>+    if (!keyPath)
</ins><span class="cx">         return jsNull();
</span><del>-    case IDBKeyPath::Type::String:
-        return jsStringWithCache(&amp;state, value.string());
-    case IDBKeyPath::Type::Array:
-        auto keyPaths = DOMStringList::create();
-        for (auto&amp; path : value.array())
-            keyPaths-&gt;append(path);
-        return toJS(&amp;state, &amp;globalObject, keyPaths);
-    }
</del><span class="cx"> 
</span><del>-    ASSERT_NOT_REACHED();
-    return jsNull();
</del><ins>+    auto visitor = WTF::makeVisitor([&amp;](const String&amp; string) -&gt; JSValue {
+        return toJS&lt;IDLDOMString&gt;(state, globalObject, string);
+    }, [&amp;](const Vector&lt;String&gt;&amp; vector) -&gt; JSValue {
+        return toJS&lt;IDLSequence&lt;IDLDOMString&gt;&gt;(state, globalObject, vector);
+    });
+    return WTF::visit(visitor, keyPath.value());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsIDBBindingUtilitiesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/bindings/js/IDBBindingUtilities.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;IDBKeyPath.h&quot;
</ins><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -41,13 +42,13 @@
</span><span class="cx"> class IDBIndexInfo;
</span><span class="cx"> class IDBKey;
</span><span class="cx"> class IDBKeyData;
</span><del>-class IDBKeyPath;
</del><span class="cx"> class IDBValue;
</span><span class="cx"> class IndexKey;
</span><span class="cx"> class JSDOMGlobalObject;
</span><span class="cx"> class ThreadSafeDataBuffer;
</span><span class="cx"> 
</span><del>-JSC::JSValue toJS(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, const IDBKeyPath&amp;);
</del><ins>+// FIXME: Remove this once we support returning union types.
+JSC::JSValue toJS(JSC::ExecState&amp;, JSDOMGlobalObject&amp;, const Optional&lt;IDBKeyPath&gt;&amp;);
</ins><span class="cx"> 
</span><span class="cx"> RefPtr&lt;IDBKey&gt; maybeCreateIDBKeyFromScriptValueAndKeyPath(JSC::ExecState&amp;, const JSC::JSValue&amp;, const IDBKeyPath&amp;);
</span><span class="cx"> bool canInjectIDBKeyIntoScriptValue(JSC::ExecState&amp;, const JSC::JSValue&amp;, const IDBKeyPath&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorIndexedDBAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebCore/inspector/InspectorIndexedDBAgent.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -162,39 +162,24 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-static RefPtr&lt;KeyPath&gt; keyPathFromIDBKeyPath(const IDBKeyPath&amp; idbKeyPath)
</del><ins>+static RefPtr&lt;KeyPath&gt; keyPathFromIDBKeyPath(const Optional&lt;IDBKeyPath&gt;&amp; idbKeyPath)
</ins><span class="cx"> {
</span><del>-    RefPtr&lt;KeyPath&gt; keyPath;
-    switch (idbKeyPath.type()) {
-    case IDBKeyPath::Type::Null:
-        keyPath = KeyPath::create()
-            .setType(KeyPath::Type::Null)
-            .release();
-        break;
</del><ins>+    if (!idbKeyPath)
+        return KeyPath::create().setType(KeyPath::Type::Null).release();
</ins><span class="cx"> 
</span><del>-    case IDBKeyPath::Type::String:
-        keyPath = KeyPath::create()
-            .setType(KeyPath::Type::String)
-            .release();
-        keyPath-&gt;setString(idbKeyPath.string());
-        break;
-
-    case IDBKeyPath::Type::Array: {
</del><ins>+    auto visitor = WTF::makeVisitor([](const String&amp; string) {
+        RefPtr&lt;KeyPath&gt; keyPath = KeyPath::create().setType(KeyPath::Type::String).release();
+        keyPath-&gt;setString(string);
+        return keyPath;
+    }, [](const Vector&lt;String&gt;&amp; vector) {
</ins><span class="cx">         auto array = Inspector::Protocol::Array&lt;String&gt;::create();
</span><del>-        for (auto&amp; string : idbKeyPath.array())
</del><ins>+        for (auto&amp; string : vector)
</ins><span class="cx">             array-&gt;addItem(string);
</span><del>-        keyPath = KeyPath::create()
-            .setType(KeyPath::Type::Array)
-            .release();
</del><ins>+        RefPtr&lt;KeyPath&gt; keyPath = KeyPath::create().setType(KeyPath::Type::Array).release();
</ins><span class="cx">         keyPath-&gt;setArray(WTFMove(array));
</span><del>-        break;
-    }
-
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
-    return keyPath;
</del><ins>+        return keyPath;
+    });
+    return WTF::visit(visitor, idbKeyPath.value());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static RefPtr&lt;IDBTransaction&gt; transactionForDatabase(IDBDatabase* idbDatabase, const String&amp; objectStoreName, const String&amp; mode = IDBTransaction::modeReadOnly())
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebKit2/ChangeLog        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-10-26  Chris Dumez  &lt;cdumez@apple.com&gt;
+
+        Replace IDBKeyPath with a WTF::Variant
+        https://bugs.webkit.org/show_bug.cgi?id=163909
+
+        Reviewed by Darin Adler.
+
+        Add coders to encode / decode IDBKeyPath type for IPC.
+
+        * Shared/Databases/IndexedDB/WebIDBResult.cpp:
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder&lt;IDBKeyPath&gt;::encode):
+        (IPC::ArgumentCoder&lt;IDBKeyPath&gt;::decode):
+        * Shared/WebCoreArgumentCoders.h:
+        * WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp:
+
</ins><span class="cx"> 2016-10-26  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: remove unused bool return value from FrontendChannel::sendMessageToFrontend
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedDatabasesIndexedDBWebIDBResultcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/Databases/IndexedDB/WebIDBResult.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Databases/IndexedDB/WebIDBResult.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebKit2/Shared/Databases/IndexedDB/WebIDBResult.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><del>-#include &quot;ArgumentCoders.h&quot;
</del><ins>+#include &quot;WebCoreArgumentCoders.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebKit {
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCoderscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -2303,5 +2303,35 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(INDEXED_DATABASE)
+void ArgumentCoder&lt;IDBKeyPath&gt;::encode(Encoder&amp; encoder, const IDBKeyPath&amp; keyPath)
+{
+    bool isString = WTF::holds_alternative&lt;String&gt;(keyPath);
+    encoder &lt;&lt; isString;
+    if (isString)
+        encoder &lt;&lt; WTF::get&lt;String&gt;(keyPath);
+    else
+        encoder &lt;&lt; WTF::get&lt;Vector&lt;String&gt;&gt;(keyPath);
+}
</ins><span class="cx"> 
</span><ins>+bool ArgumentCoder&lt;IDBKeyPath&gt;::decode(Decoder&amp; decoder, IDBKeyPath&amp; keyPath)
+{
+    bool isString;
+    if (!decoder.decode(isString))
+        return false;
+    if (isString) {
+        String string;
+        if (!decoder.decode(string))
+            return false;
+        keyPath = string;
+    } else {
+        Vector&lt;String&gt; vector;
+        if (!decoder.decode(vector))
+            return false;
+        keyPath = vector;
+    }
+    return true;
+}
+#endif
+
</ins><span class="cx"> } // namespace IPC
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCodersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -134,6 +134,12 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(INDEXED_DATABASE)
+namespace WebCore {
+using IDBKeyPath = Variant&lt;String, Vector&lt;String&gt;&gt;;
+}
+#endif
+
</ins><span class="cx"> namespace IPC {
</span><span class="cx"> 
</span><span class="cx"> template&lt;&gt; struct ArgumentCoder&lt;WebCore::AffineTransform&gt; {
</span><span class="lines">@@ -547,6 +553,15 @@
</span><span class="cx"> };
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(INDEXED_DATABASE)
+
+template&lt;&gt; struct ArgumentCoder&lt;WebCore::IDBKeyPath&gt; {
+    static void encode(Encoder&amp;, const WebCore::IDBKeyPath&amp;);
+    static bool decode(Decoder&amp;, WebCore::IDBKeyPath&amp;);
+};
+
+#endif
+
</ins><span class="cx"> } // namespace IPC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessDatabasesIndexedDBWebIDBConnectionToServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp (207930 => 207931)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp        2016-10-27 02:49:54 UTC (rev 207930)
+++ trunk/Source/WebKit2/WebProcess/Databases/IndexedDB/WebIDBConnectionToServer.cpp        2016-10-27 03:13:21 UTC (rev 207931)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;DatabaseToWebProcessConnectionMessages.h&quot;
</span><span class="cx"> #include &quot;NetworkConnectionToWebProcessMessages.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessConnection.h&quot;
</span><ins>+#include &quot;WebCoreArgumentCoders.h&quot;
</ins><span class="cx"> #include &quot;WebIDBConnectionToClientMessages.h&quot;
</span><span class="cx"> #include &quot;WebIDBResult.h&quot;
</span><span class="cx"> #include &quot;WebProcess.h&quot;
</span></span></pre>
</div>
</div>

</body>
</html>