<!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>[192068] 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/192068">192068</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2015-11-05 12:23:02 -0800 (Thu, 05 Nov 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Modern IDB: Implement IDBIndex get/getKey/count requests.
https://bugs.webkit.org/show_bug.cgi?id=150910

Reviewed by Alex Christensen.

Source/WebCore:

Tests: storage/indexeddb/modern/index-get-count-basic.html
       storage/indexeddb/modern/index-get-count-failures.html

* Modules/indexeddb/IndexedDB.h:

* Modules/indexeddb/client/IDBAnyImpl.cpp:
(WebCore::IDBClient::IDBAny::IDBAny):
(WebCore::IDBClient::IDBAny::modernIDBIndex):
* Modules/indexeddb/client/IDBAnyImpl.h:
(WebCore::IDBClient::IDBAny::create):
(WebCore::IDBClient::IDBAny::createUndefined):

* Modules/indexeddb/client/IDBIndexImpl.cpp:
(WebCore::IDBClient::IDBIndex::count):
(WebCore::IDBClient::IDBIndex::doCount):
(WebCore::IDBClient::IDBIndex::get):
(WebCore::IDBClient::IDBIndex::doGet):
(WebCore::IDBClient::IDBIndex::getKey):
(WebCore::IDBClient::IDBIndex::doGetKey):
* Modules/indexeddb/client/IDBIndexImpl.h:
(WebCore::IDBClient::IDBIndex::info):

* Modules/indexeddb/client/IDBObjectStoreImpl.h:
(WebCore::IDBClient::IDBObjectStore::isDeleted):
(WebCore::IDBClient::IDBObjectStore::modernTransaction):

* Modules/indexeddb/client/IDBRequestImpl.cpp:
(WebCore::IDBClient::IDBRequest::createCount):
(WebCore::IDBClient::IDBRequest::createGet):
(WebCore::IDBClient::IDBRequest::IDBRequest):
(WebCore::IDBClient::IDBRequest::sourceObjectStoreIdentifier):
(WebCore::IDBClient::IDBRequest::sourceIndexIdentifier):
(WebCore::IDBClient::IDBRequest::requestedIndexRecordType):
(WebCore::IDBClient::IDBRequest::setResultToUndefined):
* Modules/indexeddb/client/IDBRequestImpl.h:

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::requestGetValue):
(WebCore::IDBClient::IDBTransaction::requestGetKey):
(WebCore::IDBClient::IDBTransaction::didGetRecordOnServer):
(WebCore::IDBClient::IDBTransaction::requestCount):
* Modules/indexeddb/client/IDBTransactionImpl.h:

* Modules/indexeddb/client/TransactionOperation.cpp:
(WebCore::IDBClient::TransactionOperation::TransactionOperation):
* Modules/indexeddb/client/TransactionOperation.h:
(WebCore::IDBClient::TransactionOperation::indexIdentifier):
(WebCore::IDBClient::TransactionOperation::indexRecordType):

* Modules/indexeddb/server/IDBBackingStore.h:

* Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
(WebCore::IDBServer::MemoryIDBBackingStore::getRecord):
(WebCore::IDBServer::MemoryIDBBackingStore::getIndexRecord):
(WebCore::IDBServer::MemoryIDBBackingStore::getCount):
* Modules/indexeddb/server/MemoryIDBBackingStore.h:

* Modules/indexeddb/server/MemoryIndex.cpp:
(WebCore::IDBServer::MemoryIndex::valueForKeyRange):
(WebCore::IDBServer::MemoryIndex::countForKeyRange):
* Modules/indexeddb/server/MemoryIndex.h:

* Modules/indexeddb/server/MemoryObjectStore.cpp:
(WebCore::IDBServer::MemoryObjectStore::createIndex):
(WebCore::IDBServer::MemoryObjectStore::countForKeyRange):
(WebCore::IDBServer::MemoryObjectStore::indexValueForKeyRange):
* Modules/indexeddb/server/MemoryObjectStore.h:

* Modules/indexeddb/server/UniqueIDBDatabase.cpp:
(WebCore::IDBServer::UniqueIDBDatabase::getRecord):
(WebCore::IDBServer::UniqueIDBDatabase::performGetIndexRecord):
(WebCore::IDBServer::UniqueIDBDatabase::getCount):
(WebCore::IDBServer::UniqueIDBDatabase::performGetCount):
(WebCore::IDBServer::UniqueIDBDatabase::performGetRecord): Deleted.
* Modules/indexeddb/server/UniqueIDBDatabase.h:

* Modules/indexeddb/shared/IDBRequestData.cpp:
(WebCore::IDBRequestData::IDBRequestData):
(WebCore::IDBRequestData::objectStoreIdentifier):
(WebCore::IDBRequestData::indexIdentifier):
(WebCore::IDBRequestData::indexRecordType):
* Modules/indexeddb/shared/IDBRequestData.h:

LayoutTests:

* storage/indexeddb/modern/index-get-count-basic-expected.txt: Added.
* storage/indexeddb/modern/index-get-count-basic.html: Added.
* storage/indexeddb/modern/index-get-count-failures-expected.txt: Added.
* storage/indexeddb/modern/index-get-count-failures.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIndexedDBh">trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBAnyImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBAnyImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBIndexImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBIndexImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBRequestImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBRequestImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplh">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientTransactionOperationcpp">trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientTransactionOperationh">trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBBackingStoreh">trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStoreh">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIndexcpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryIndexh">trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryObjectStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverMemoryObjectStoreh">trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabasecpp">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh">trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatacpp">trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatah">trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernindexgetcountbasicexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernindexgetcountbasichtml">trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic.html</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernindexgetcountfailuresexpectedtxt">trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures-expected.txt</a></li>
<li><a href="#trunkLayoutTestsstorageindexeddbmodernindexgetcountfailureshtml">trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/LayoutTests/ChangeLog        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-11-05  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Implement IDBIndex get/getKey/count requests.
+        https://bugs.webkit.org/show_bug.cgi?id=150910
+
+        Reviewed by Alex Christensen.
+
+        * storage/indexeddb/modern/index-get-count-basic-expected.txt: Added.
+        * storage/indexeddb/modern/index-get-count-basic.html: Added.
+        * storage/indexeddb/modern/index-get-count-failures-expected.txt: Added.
+        * storage/indexeddb/modern/index-get-count-failures.html: Added.
+
</ins><span class="cx"> 2015-11-05  Ryan Haddad  &lt;ryanhaddad@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rebaselining fast/text/tatechuyoko.html on win
</span></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernindexgetcountbasicexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic-expected.txt (0 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic-expected.txt                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic-expected.txt        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+ALERT: Initial upgrade needed: Old version - 0 New version - 1
+ALERT: get result is: undefined
+ALERT: getKey result is: undefined
+ALERT: count result is: 0
+ALERT: Initial upgrade versionchange transaction complete
+ALERT: Done
+This tests the most basic operation of the IDBIndex methods get(), getKey(), and count().
+It doesn't actually do anything other than exercise the requests themselves because we don't actually index yet.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernindexgetcountbasichtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic.html (0 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic.html                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/index-get-count-basic.html        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+This tests the most basic operation of the IDBIndex methods get(), getKey(), and count().&lt;br&gt;
+It doesn't actually do anything other than exercise the requests themselves because we don't actually index yet.&lt;br&gt;
+&lt;div id=&quot;logger&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    alert(&quot;Done&quot;);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function gol(message)
+{
+    document.getElementById(&quot;logger&quot;).innerHTML += message + &quot;&lt;br&gt;&quot;;
+}
+
+var createRequest = window.indexedDB.open(&quot;IndexGetCountBasicDatabase&quot;, 1);
+
+createRequest.onupgradeneeded = function(event) {
+    alert(&quot;Initial upgrade needed: Old version - &quot; + event.oldVersion + &quot; New version - &quot; + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    var database = event.target.result;
+    var objectStore = database.createObjectStore(&quot;TestObjectStore&quot;);
+    var index = objectStore.createIndex(&quot;TestIndex&quot;, &quot;foo&quot;);
+
+    objectStore.put(&quot;bar&quot;, &quot;foo&quot;);
+    
+    var request1 = index.get(&quot;bar&quot;);
+    request1.onsuccess = function() {
+        alert(&quot;get result is: &quot; + request1.result);
+    }
+
+    request2 = index.getKey(&quot;bar&quot;);
+    request2.onsuccess = function() {
+        alert(&quot;getKey result is: &quot; + request2.result);
+    }
+    
+    var request3 = index.count();
+    request3.onsuccess = function() {
+        alert(&quot;count result is: &quot; + request3.result);
+    }
+        
+    versionTransaction.onabort = function(event) {
+        alert(&quot;Initial upgrade versionchange transaction unexpected aborted&quot;);
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        alert(&quot;Initial upgrade versionchange transaction complete&quot;);
+        done();
+    }
+
+    versionTransaction.onerror = function(event) {
+        alert(&quot;Initial upgrade versionchange transaction unexpected error&quot; + event);
+        done();
+    }
+}
+
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernindexgetcountfailuresexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures-expected.txt (0 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures-expected.txt                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures-expected.txt        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -0,0 +1,15 @@
</span><ins>+This tests some obvious failures that can happen while calling the IDBIndex methods get(), getKey(), and count().
+Initial upgrade needed: Old version - 0 New version - 1
+Failed to get with a null key
+Failed to getKey with a null key
+Failed to count with a null range
+Failed to get with deleted IDBObjectStore
+Failed to getKey with deleted IDBObjectStore
+Failed to count with deleted IDBObjectStore
+Initial upgrade versionchange transaction complete
+Failed to get while transaction inactive
+Failed to getKey while transaction inactive
+Failed to count while transaction inactive
+readonly transaction complete
+Done
+
</ins></span></pre></div>
<a id="trunkLayoutTestsstorageindexeddbmodernindexgetcountfailureshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures.html (0 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures.html                                (rev 0)
+++ trunk/LayoutTests/storage/indexeddb/modern/index-get-count-failures.html        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -0,0 +1,167 @@
</span><ins>+This tests some obvious failures that can happen while calling the IDBIndex methods get(), getKey(), and count().&lt;br&gt;
+&lt;div id=&quot;logger&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+
+if (window.testRunner) {
+    testRunner.waitUntilDone();
+    testRunner.dumpAsText();
+}
+
+function done()
+{
+    log(&quot;Done&quot;);
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+function log(message)
+{
+    document.getElementById(&quot;logger&quot;).innerHTML += message + &quot;&lt;br&gt;&quot;;
+}
+
+var createRequest = window.indexedDB.open(&quot;IndexGetCountFailuresDatabase&quot;, 1);
+var database;
+var index;
+
+createRequest.onupgradeneeded = function(event) {
+    log(&quot;Initial upgrade needed: Old version - &quot; + event.oldVersion + &quot; New version - &quot; + event.newVersion);
+
+    var versionTransaction = createRequest.transaction;
+    database = event.target.result;
+    var objectStore = database.createObjectStore(&quot;TestObjectStore&quot;);
+    index = objectStore.createIndex(&quot;TestIndex&quot;, &quot;foo&quot;);
+    
+    try {
+        index.get(null);
+    } catch(e) {
+        log(&quot;Failed to get with a null key&quot;);
+    }
+
+    try {
+        index.getKey(null);
+    } catch(e) {
+        log(&quot;Failed to getKey with a null key&quot;);
+    }
+
+    try {
+        index.count(null);
+    } catch(e) {
+        log(&quot;Failed to count with a null range&quot;);
+    }
+    
+    // FIXME: once IDBObjectStore.deleteIndex() is implemented, try these
+    // https://bugs.webkit.org/show_bug.cgi?id=150911
+    // objectStore.deleteIndex(&quot;TestIndex&quot;);
+    // 
+    // try {
+    //     index.get(&quot;test&quot;);
+    // } catch(e) {
+    //     log(&quot;Failed to get with deleted IDBIndex&quot;);
+    // }
+    // 
+    // try {
+    //     index.getKey(&quot;test&quot;);
+    // } catch(e) {
+    //     log(&quot;Failed to getKey with deleted IDBIndex&quot;);
+    // }
+    // 
+    // try {
+    //     index.count();
+    // } catch(e) {
+    //     log(&quot;Failed to count with deleted IDBIndex&quot;);
+    // }
+
+    database.deleteObjectStore(&quot;TestObjectStore&quot;);
+    try {
+        index.get(null);
+    } catch(e) {
+         log(&quot;Failed to get with deleted IDBObjectStore&quot;);
+    }
+
+    try {
+        index.getKey(null);
+    } catch(e) {
+         log(&quot;Failed to getKey with deleted IDBObjectStore&quot;);
+    }
+
+    try {
+        index.count(null);
+    } catch(e) {
+         log(&quot;Failed to count with deleted IDBObjectStore&quot;);
+    }
+
+    var objectStore = database.createObjectStore(&quot;TestObjectStore2&quot;);
+    objectStore.createIndex(&quot;TestIndex&quot;, &quot;foo&quot;);
+        
+    versionTransaction.onabort = function(event) {
+        log(&quot;Initial upgrade versionchange transaction unexpected aborted&quot;);
+        done();
+    }
+
+    versionTransaction.oncomplete = function(event) {
+        log(&quot;Initial upgrade versionchange transaction complete&quot;);
+        continueTest1();
+    }
+
+    versionTransaction.onerror = function(event) {
+        log(&quot;Initial upgrade versionchange transaction unexpected error&quot; + event);
+        done();
+    }
+}
+
+function continueTest1()
+{
+    var transaction = database.transaction(&quot;TestObjectStore2&quot;, &quot;readonly&quot;);
+    var objectStore = transaction.objectStore(&quot;TestObjectStore2&quot;);
+    index = objectStore.index(&quot;TestIndex&quot;);
+
+    // Spin the transaction with get requests to keep it alive long enough for the setTimeout to fire.
+    var canFinish = false;
+    var spinGet = function() { 
+        objectStore.get(&quot;foo&quot;).onsuccess = function() {
+            if (!canFinish)
+                spinGet();
+        }
+    }
+    spinGet();
+
+    var testWhileInactive = function() {
+        try {
+            index.get(null);
+        } catch(e) {
+             log(&quot;Failed to get while transaction inactive&quot;);
+        }
+
+        try {
+            index.getKey(null);
+        } catch(e) {
+             log(&quot;Failed to getKey while transaction inactive&quot;);
+        }
+
+        try {
+            index.count(null);
+        } catch(e) {
+             log(&quot;Failed to count while transaction inactive&quot;);
+        }
+        canFinish = true;
+    }
+    
+    setTimeout(testWhileInactive, 0);
+    
+    transaction.onabort = function(event) {
+        log(&quot;readonly transaction unexpected abort&quot; + event);
+        done();
+    }
+
+    transaction.oncomplete = function(event) {
+        log(&quot;readonly transaction complete&quot;);
+        done();
+    }
+
+    transaction.onerror = function(event) {
+        log(&quot;readonly transaction unexpected error&quot; + event);
+        done();
+    }
+}
+
+&lt;/script&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/ChangeLog        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -1,3 +1,93 @@
</span><ins>+2015-11-05  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Implement IDBIndex get/getKey/count requests.
+        https://bugs.webkit.org/show_bug.cgi?id=150910
+
+        Reviewed by Alex Christensen.
+
+        Tests: storage/indexeddb/modern/index-get-count-basic.html
+               storage/indexeddb/modern/index-get-count-failures.html
+
+        * Modules/indexeddb/IndexedDB.h:
+
+        * Modules/indexeddb/client/IDBAnyImpl.cpp:
+        (WebCore::IDBClient::IDBAny::IDBAny):
+        (WebCore::IDBClient::IDBAny::modernIDBIndex):
+        * Modules/indexeddb/client/IDBAnyImpl.h:
+        (WebCore::IDBClient::IDBAny::create):
+        (WebCore::IDBClient::IDBAny::createUndefined):
+
+        * Modules/indexeddb/client/IDBIndexImpl.cpp:
+        (WebCore::IDBClient::IDBIndex::count):
+        (WebCore::IDBClient::IDBIndex::doCount):
+        (WebCore::IDBClient::IDBIndex::get):
+        (WebCore::IDBClient::IDBIndex::doGet):
+        (WebCore::IDBClient::IDBIndex::getKey):
+        (WebCore::IDBClient::IDBIndex::doGetKey):
+        * Modules/indexeddb/client/IDBIndexImpl.h:
+        (WebCore::IDBClient::IDBIndex::info):
+        
+        * Modules/indexeddb/client/IDBObjectStoreImpl.h:
+        (WebCore::IDBClient::IDBObjectStore::isDeleted):
+        (WebCore::IDBClient::IDBObjectStore::modernTransaction):
+        
+        * Modules/indexeddb/client/IDBRequestImpl.cpp:
+        (WebCore::IDBClient::IDBRequest::createCount):
+        (WebCore::IDBClient::IDBRequest::createGet):
+        (WebCore::IDBClient::IDBRequest::IDBRequest):
+        (WebCore::IDBClient::IDBRequest::sourceObjectStoreIdentifier):
+        (WebCore::IDBClient::IDBRequest::sourceIndexIdentifier):
+        (WebCore::IDBClient::IDBRequest::requestedIndexRecordType):
+        (WebCore::IDBClient::IDBRequest::setResultToUndefined):
+        * Modules/indexeddb/client/IDBRequestImpl.h:
+        
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::requestGetValue):
+        (WebCore::IDBClient::IDBTransaction::requestGetKey):
+        (WebCore::IDBClient::IDBTransaction::didGetRecordOnServer):
+        (WebCore::IDBClient::IDBTransaction::requestCount):
+        * Modules/indexeddb/client/IDBTransactionImpl.h:
+        
+        * Modules/indexeddb/client/TransactionOperation.cpp:
+        (WebCore::IDBClient::TransactionOperation::TransactionOperation):
+        * Modules/indexeddb/client/TransactionOperation.h:
+        (WebCore::IDBClient::TransactionOperation::indexIdentifier):
+        (WebCore::IDBClient::TransactionOperation::indexRecordType):
+        
+        * Modules/indexeddb/server/IDBBackingStore.h:
+        
+        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
+        (WebCore::IDBServer::MemoryIDBBackingStore::getRecord):
+        (WebCore::IDBServer::MemoryIDBBackingStore::getIndexRecord):
+        (WebCore::IDBServer::MemoryIDBBackingStore::getCount):
+        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
+        
+        * Modules/indexeddb/server/MemoryIndex.cpp:
+        (WebCore::IDBServer::MemoryIndex::valueForKeyRange):
+        (WebCore::IDBServer::MemoryIndex::countForKeyRange):
+        * Modules/indexeddb/server/MemoryIndex.h:
+        
+        * Modules/indexeddb/server/MemoryObjectStore.cpp:
+        (WebCore::IDBServer::MemoryObjectStore::createIndex):
+        (WebCore::IDBServer::MemoryObjectStore::countForKeyRange):
+        (WebCore::IDBServer::MemoryObjectStore::indexValueForKeyRange):
+        * Modules/indexeddb/server/MemoryObjectStore.h:
+        
+        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
+        (WebCore::IDBServer::UniqueIDBDatabase::getRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::performGetIndexRecord):
+        (WebCore::IDBServer::UniqueIDBDatabase::getCount):
+        (WebCore::IDBServer::UniqueIDBDatabase::performGetCount):
+        (WebCore::IDBServer::UniqueIDBDatabase::performGetRecord): Deleted.
+        * Modules/indexeddb/server/UniqueIDBDatabase.h:
+        
+        * Modules/indexeddb/shared/IDBRequestData.cpp:
+        (WebCore::IDBRequestData::IDBRequestData):
+        (WebCore::IDBRequestData::objectStoreIdentifier):
+        (WebCore::IDBRequestData::indexIdentifier):
+        (WebCore::IDBRequestData::indexRecordType):
+        * Modules/indexeddb/shared/IDBRequestData.h:
+
</ins><span class="cx"> 2015-11-05  Zhuo Li  &lt;zachli@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Rename the variable to avoid conflict between the variable and the parameter.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIndexedDBh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/IndexedDB.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -77,6 +77,11 @@
</span><span class="cx">     NoOverwrite,
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+enum class IndexRecordType {
+    Key,
+    Value,
+};
+
</ins><span class="cx"> // In order of the least to the highest precedent in terms of sort order.
</span><span class="cx"> enum KeyType {
</span><span class="cx">     Max = -1,
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBAnyImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -36,6 +36,11 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><ins>+IDBAny::IDBAny(IDBAny::Type type)
+    : m_type(type)
+{
+}
+
</ins><span class="cx"> IDBAny::IDBAny(Ref&lt;IDBDatabase&gt;&amp;&amp; database)
</span><span class="cx">     : m_type(IDBAny::Type::IDBDatabase)
</span><span class="cx">     , m_database(adoptRef(&amp;database.leakRef()))
</span><span class="lines">@@ -44,10 +49,16 @@
</span><span class="cx"> 
</span><span class="cx"> IDBAny::IDBAny(Ref&lt;IDBObjectStore&gt;&amp;&amp; objectStore)
</span><span class="cx">     : m_type(IDBAny::Type::IDBObjectStore)
</span><del>-    , m_objectStore(adoptRef(&amp;objectStore.leakRef()))
</del><ins>+    , m_objectStore(WTF::move(objectStore))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBAny::IDBAny(Ref&lt;IDBIndex&gt;&amp;&amp; index)
+    : m_type(IDBAny::Type::IDBIndex)
+    , m_index(WTF::move(index))
+{
+}
+
</ins><span class="cx"> IDBAny::IDBAny(const IDBKeyPath&amp; keyPath)
</span><span class="cx">     : m_type(IDBAny::Type::KeyPath)
</span><span class="cx">     , m_idbKeyPath(keyPath)
</span><span class="lines">@@ -106,6 +117,12 @@
</span><span class="cx">     return m_objectStore.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBIndex* IDBAny::modernIDBIndex()
+{
+    ASSERT(m_type == IDBAny::Type::IDBIndex);
+    return m_index.get();
+}
+
</ins><span class="cx"> RefPtr&lt;WebCore::IDBTransaction&gt; IDBAny::idbTransaction()
</span><span class="cx"> {
</span><span class="cx">     return nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBAnyImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBAnyImpl.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IDBAny.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseImpl.h&quot;
</span><ins>+#include &quot;IDBIndexImpl.h&quot;
</ins><span class="cx"> #include &quot;IDBObjectStoreImpl.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -47,6 +48,11 @@
</span><span class="cx">         return adoptRef(new IDBAny(WTF::move(objectStore)));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static RefPtr&lt;IDBAny&gt; create(Ref&lt;IDBIndex&gt;&amp;&amp; index)
+    {
+        return adoptRef(new IDBAny(WTF::move(index)));
+    }
+
</ins><span class="cx">     static RefPtr&lt;IDBAny&gt; create(const IDBKeyPath&amp; keyPath)
</span><span class="cx">     {
</span><span class="cx">         return adoptRef(new IDBAny(keyPath));
</span><span class="lines">@@ -57,6 +63,11 @@
</span><span class="cx">         return adoptRef(new IDBAny(value));
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static RefPtr&lt;IDBAny&gt; createUndefined()
+    {
+        return adoptRef(new IDBAny(IDBAny::Type::Undefined));
+    }
+
</ins><span class="cx">     virtual ~IDBAny();
</span><span class="cx"> 
</span><span class="cx">     virtual Type type() const override final { return m_type; }
</span><span class="lines">@@ -74,16 +85,20 @@
</span><span class="cx">     virtual const IDBKeyPath&amp; keyPath() override final;
</span><span class="cx"> 
</span><span class="cx">     IDBObjectStore* modernIDBObjectStore();
</span><ins>+    IDBIndex* modernIDBIndex();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><ins>+    explicit IDBAny(IDBAny::Type);
</ins><span class="cx">     explicit IDBAny(Ref&lt;IDBDatabase&gt;&amp;&amp;);
</span><span class="cx">     explicit IDBAny(Ref&lt;IDBObjectStore&gt;&amp;&amp;);
</span><ins>+    explicit IDBAny(Ref&lt;IDBIndex&gt;&amp;&amp;);
</ins><span class="cx">     explicit IDBAny(const IDBKeyPath&amp;);
</span><span class="cx">     explicit IDBAny(const Deprecated::ScriptValue&amp;);
</span><span class="cx"> 
</span><span class="cx">     IDBAny::Type m_type { IDBAny::Type::Undefined };
</span><span class="cx">     RefPtr&lt;IDBDatabase&gt; m_database;
</span><span class="cx">     RefPtr&lt;IDBObjectStore&gt; m_objectStore;
</span><ins>+    RefPtr&lt;IDBIndex&gt; m_index;
</ins><span class="cx"> 
</span><span class="cx">     const IDBKeyPath m_idbKeyPath;
</span><span class="cx">     const Deprecated::ScriptValue m_scriptValue;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBIndexImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -28,8 +28,13 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;DOMRequestState.h&quot;
</ins><span class="cx"> #include &quot;IDBAnyImpl.h&quot;
</span><ins>+#include &quot;IDBBindingUtilities.h&quot;
+#include &quot;IDBKeyRangeData.h&quot;
</ins><span class="cx"> #include &quot;IDBObjectStoreImpl.h&quot;
</span><ins>+#include &quot;IDBTransactionImpl.h&quot;
+#include &quot;Logging.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBClient {
</span><span class="lines">@@ -89,19 +94,69 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::count(ScriptExecutionContext*, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::count(ScriptExecutionContext* context, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    LOG(IndexedDB, &quot;IDBIndex::count&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    IDBKeyRangeData range;
+    range.isNull = false;
+    return doCount(*context, range, ec);}
+
+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::count(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode&amp; ec)
+{
+    LOG(IndexedDB, &quot;IDBIndex::count&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    return doCount(*context, IDBKeyRangeData(range), ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::count(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::count(ScriptExecutionContext* context, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    LOG(IndexedDB, &quot;IDBIndex::count&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    DOMRequestState requestState(context);
+    RefPtr&lt;IDBKey&gt; idbKey = scriptValueToIDBKey(&amp;requestState, key);
+    if (!idbKey || idbKey-&gt;type() == KeyType::Invalid) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    return doCount(*context, IDBKeyRangeData(idbKey.get()), ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::count(ScriptExecutionContext*, const Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::doCount(ScriptExecutionContext&amp; context, const IDBKeyRangeData&amp; range, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    if (m_deleted || m_objectStore-&gt;isDeleted()) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    if (range.isNull) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    auto&amp; transaction = m_objectStore-&gt;modernTransaction();
+    if (!transaction.isActive()) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::TransactionInactiveError);
+        return nullptr;
+    }
+
+    return transaction.requestCount(context, *this, range);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::openKeyCursor(ScriptExecutionContext*, IDBKeyRange*, const String&amp;, ExceptionCode&amp;)
</span><span class="lines">@@ -114,26 +169,110 @@
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::get(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::get(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    LOG(IndexedDB, &quot;IDBIndex::get&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    return doGet(*context, IDBKeyRangeData(range), ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::get(ScriptExecutionContext*, const Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::get(ScriptExecutionContext* context, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    LOG(IndexedDB, &quot;IDBIndex::get&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    DOMRequestState requestState(context);
+    RefPtr&lt;IDBKey&gt; idbKey = scriptValueToIDBKey(&amp;requestState, key);
+    if (!idbKey || idbKey-&gt;type() == KeyType::Invalid) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    return doGet(*context, IDBKeyRangeData(idbKey.get()), ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::doGet(ScriptExecutionContext&amp; context, const IDBKeyRangeData&amp; range, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    if (m_deleted || m_objectStore-&gt;isDeleted()) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    if (range.isNull) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    auto&amp; transaction = m_objectStore-&gt;modernTransaction();
+    if (!transaction.isActive()) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::TransactionInactiveError);
+        return nullptr;
+    }
+
+    return transaction.requestGetValue(context, *this, range);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::getKey(ScriptExecutionContext*, const Deprecated::ScriptValue&amp;, ExceptionCode&amp;)
</del><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::getKey(ScriptExecutionContext* context, IDBKeyRange* range, ExceptionCode&amp; ec)
</ins><span class="cx"> {
</span><del>-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    LOG(IndexedDB, &quot;IDBIndex::getKey&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    return doGetKey(*context, IDBKeyRangeData(range), ec);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::getKey(ScriptExecutionContext* context, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp; ec)
+{
+    LOG(IndexedDB, &quot;IDBIndex::getKey&quot;);
+
+    if (!context) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    DOMRequestState requestState(context);
+    RefPtr&lt;IDBKey&gt; idbKey = scriptValueToIDBKey(&amp;requestState, key);
+    if (!idbKey || idbKey-&gt;type() == KeyType::Invalid) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    return doGetKey(*context, IDBKeyRangeData(idbKey.get()), ec);
+}
+
+RefPtr&lt;WebCore::IDBRequest&gt; IDBIndex::doGetKey(ScriptExecutionContext&amp; context, const IDBKeyRangeData&amp; range, ExceptionCode&amp; ec)
+{
+    if (m_deleted || m_objectStore-&gt;isDeleted()) {
+        ec = INVALID_STATE_ERR;
+        return nullptr;
+    }
+
+    if (range.isNull) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::DataError);
+        return nullptr;
+    }
+
+    auto&amp; transaction = m_objectStore-&gt;modernTransaction();
+    if (!transaction.isActive()) {
+        ec = static_cast&lt;ExceptionCode&gt;(IDBExceptionCode::TransactionInactiveError);
+        return nullptr;
+    }
+
+    return transaction.requestGetKey(context, *this, range);
+}
+
</ins><span class="cx"> } // namespace IDBClient
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBIndexImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBIndexImpl.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -33,6 +33,9 @@
</span><span class="cx"> #include &quot;IDBIndexInfo.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+
+struct IDBKeyRangeData;
+
</ins><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="cx"> class IDBObjectStore;
</span><span class="lines">@@ -72,11 +75,19 @@
</span><span class="cx">     virtual RefPtr&lt;WebCore::IDBRequest&gt; getKey(ScriptExecutionContext*, IDBKeyRange*, ExceptionCode&amp;) override final;
</span><span class="cx">     virtual RefPtr&lt;WebCore::IDBRequest&gt; getKey(ScriptExecutionContext*, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp;) override final;
</span><span class="cx"> 
</span><ins>+    const IDBIndexInfo&amp; info() const { return m_info; }
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBIndex(const IDBIndexInfo&amp;, IDBObjectStore&amp;);
</span><span class="cx"> 
</span><ins>+    RefPtr&lt;WebCore::IDBRequest&gt; doCount(ScriptExecutionContext&amp;, const IDBKeyRangeData&amp;, ExceptionCode&amp;);
+    RefPtr&lt;WebCore::IDBRequest&gt; doGet(ScriptExecutionContext&amp;, const IDBKeyRangeData&amp;, ExceptionCode&amp;);
+    RefPtr&lt;WebCore::IDBRequest&gt; doGetKey(ScriptExecutionContext&amp;, const IDBKeyRangeData&amp;, ExceptionCode&amp;);
+
</ins><span class="cx">     IDBIndexInfo m_info;
</span><span class="cx">     Ref&lt;IDBObjectStore&gt; m_objectStore;
</span><ins>+
+    bool m_deleted { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBObjectStoreImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBObjectStoreImpl.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -79,9 +79,14 @@
</span><span class="cx">     virtual RefPtr&lt;WebCore::IDBRequest&gt; count(ScriptExecutionContext*, const Deprecated::ScriptValue&amp; key, ExceptionCode&amp;) override final;
</span><span class="cx"> 
</span><span class="cx">     void markAsDeleted();
</span><ins>+    bool isDeleted() const { return m_deleted; }
</ins><span class="cx"> 
</span><span class="cx">     const IDBObjectStoreInfo&amp; info() const { return m_info; }
</span><span class="cx"> 
</span><ins>+    // FIXME: After removing LegacyIDB and folding abstract/implementation classes together,
+    // this will no longer be necessary.
+    IDBTransaction&amp; modernTransaction() { return m_transaction.get(); }
+
</ins><span class="cx"> private:
</span><span class="cx">     IDBObjectStore(const IDBObjectStoreInfo&amp;, IDBTransaction&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBRequestImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -47,6 +47,16 @@
</span><span class="cx">     return adoptRef(*new IDBRequest(context, objectStore, transaction));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;IDBRequest&gt; IDBRequest::createCount(ScriptExecutionContext&amp; context, IDBIndex&amp; index, IDBTransaction&amp; transaction)
+{
+    return adoptRef(*new IDBRequest(context, index, transaction));
+}
+
+Ref&lt;IDBRequest&gt; IDBRequest::createGet(ScriptExecutionContext&amp; context, IDBIndex&amp; index, IndexedDB::IndexRecordType requestedRecordType, IDBTransaction&amp; transaction)
+{
+    return adoptRef(*new IDBRequest(context, index, requestedRecordType, transaction));
+}
+
</ins><span class="cx"> IDBRequest::IDBRequest(IDBConnectionToServer&amp; connection, ScriptExecutionContext* context)
</span><span class="cx">     : IDBOpenDBRequest(context)
</span><span class="cx">     , m_connection(connection)
</span><span class="lines">@@ -60,11 +70,27 @@
</span><span class="cx">     , m_transaction(&amp;transaction)
</span><span class="cx">     , m_connection(transaction.serverConnection())
</span><span class="cx">     , m_resourceIdentifier(transaction.serverConnection())
</span><del>-    , m_source(adoptRef(*IDBAny::create(objectStore).leakRef()))
</del><ins>+    , m_source(IDBAny::create(objectStore))
</ins><span class="cx"> {
</span><span class="cx">     suspendIfNeeded();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBRequest::IDBRequest(ScriptExecutionContext&amp; context, IDBIndex&amp; index, IDBTransaction&amp; transaction)
+    : IDBOpenDBRequest(&amp;context)
+    , m_transaction(&amp;transaction)
+    , m_connection(transaction.serverConnection())
+    , m_resourceIdentifier(transaction.serverConnection())
+    , m_source(IDBAny::create(index))
+{
+    suspendIfNeeded();
+}
+
+IDBRequest::IDBRequest(ScriptExecutionContext&amp; context, IDBIndex&amp; index, IndexedDB::IndexRecordType requestedRecordType, IDBTransaction&amp; transaction)
+    : IDBRequest(context, index, transaction)
+{
+    m_requestedIndexRecordType = requestedRecordType;
+}
+
</ins><span class="cx"> IDBRequest::~IDBRequest()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -104,14 +130,44 @@
</span><span class="cx"> {
</span><span class="cx">     if (!m_source)
</span><span class="cx">         return 0;
</span><del>-    if (m_source-&gt;type() != IDBAny::Type::IDBObjectStore)
</del><ins>+
+    if (m_source-&gt;type() == IDBAny::Type::IDBObjectStore) {
+        auto* objectStore = m_source-&gt;modernIDBObjectStore();
+        if (!objectStore)
+            return 0;
+        return objectStore-&gt;info().identifier();
+    }
+
+    if (m_source-&gt;type() == IDBAny::Type::IDBIndex) {
+        auto* index = m_source-&gt;modernIDBIndex();
+        if (!index)
+            return 0;
+        return index-&gt;info().objectStoreIdentifier();
+    }
+
+    return 0;
+}
+
+uint64_t IDBRequest::sourceIndexIdentifier() const
+{
+    if (!m_source)
</ins><span class="cx">         return 0;
</span><del>-    if (!m_source-&gt;modernIDBObjectStore())
</del><ins>+    if (m_source-&gt;type() != IDBAny::Type::IDBIndex)
</ins><span class="cx">         return 0;
</span><ins>+    if (!m_source-&gt;modernIDBIndex())
+        return 0;
</ins><span class="cx"> 
</span><del>-    return m_source-&gt;modernIDBObjectStore()-&gt;info().identifier();
</del><ins>+    return m_source-&gt;modernIDBIndex()-&gt;info().identifier();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IndexedDB::IndexRecordType IDBRequest::requestedIndexRecordType() const
+{
+    ASSERT(m_source);
+    ASSERT(m_source-&gt;type() == IDBAny::Type::IDBIndex);
+
+    return m_requestedIndexRecordType;
+}
+
</ins><span class="cx"> EventTargetInterface IDBRequest::eventTargetInterface() const
</span><span class="cx"> {
</span><span class="cx">     return IDBRequestEventTargetInterfaceType;
</span><span class="lines">@@ -204,13 +260,7 @@
</span><span class="cx"> 
</span><span class="cx"> void IDBRequest::setResultToUndefined()
</span><span class="cx"> {
</span><del>-    auto context = scriptExecutionContext();
-    if (!context)
-        return;
-
-    DOMRequestState state(context);
-    if (auto* execState = state.exec())
-        m_result = IDBAny::create(Deprecated::ScriptValue(execState-&gt;vm(), JSC::jsUndefined()));
</del><ins>+    m_result = IDBAny::createUndefined();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void IDBRequest::requestCompleted(const IDBResultData&amp; resultData)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBRequestImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBRequestImpl.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -41,6 +41,9 @@
</span><span class="cx"> class IDBResultData;
</span><span class="cx"> class ThreadSafeDataBuffer;
</span><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class IndexRecordType;
+}
</ins><span class="cx"> 
</span><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="lines">@@ -49,6 +52,8 @@
</span><span class="cx"> class IDBRequest : public WebCore::IDBOpenDBRequest, public RefCounted&lt;IDBRequest&gt; {
</span><span class="cx"> public:
</span><span class="cx">     static Ref&lt;IDBRequest&gt; create(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBTransaction&amp;);
</span><ins>+    static Ref&lt;IDBRequest&gt; createCount(ScriptExecutionContext&amp;, IDBIndex&amp;, IDBTransaction&amp;);
+    static Ref&lt;IDBRequest&gt; createGet(ScriptExecutionContext&amp;, IDBIndex&amp;, IndexedDB::IndexRecordType, IDBTransaction&amp;);
</ins><span class="cx"> 
</span><span class="cx">     const IDBResourceIdentifier&amp; resourceIdentifier() const { return m_resourceIdentifier; }
</span><span class="cx"> 
</span><span class="lines">@@ -62,6 +67,8 @@
</span><span class="cx">     virtual const String&amp; readyState() const override;
</span><span class="cx"> 
</span><span class="cx">     uint64_t sourceObjectStoreIdentifier() const;
</span><ins>+    uint64_t sourceIndexIdentifier() const;
+    IndexedDB::IndexRecordType requestedIndexRecordType() const;
</ins><span class="cx"> 
</span><span class="cx">     // EventTarget
</span><span class="cx">     virtual EventTargetInterface eventTargetInterface() const override;
</span><span class="lines">@@ -85,6 +92,8 @@
</span><span class="cx"> protected:
</span><span class="cx">     IDBRequest(IDBConnectionToServer&amp;, ScriptExecutionContext*);
</span><span class="cx">     IDBRequest(ScriptExecutionContext&amp;, IDBObjectStore&amp;, IDBTransaction&amp;);
</span><ins>+    IDBRequest(ScriptExecutionContext&amp;, IDBIndex&amp;, IDBTransaction&amp;);
+    IDBRequest(ScriptExecutionContext&amp;, IDBIndex&amp;, IndexedDB::IndexRecordType, IDBTransaction&amp;);
</ins><span class="cx"> 
</span><span class="cx">     // ActiveDOMObject.
</span><span class="cx">     virtual const char* activeDOMObjectName() const override final;
</span><span class="lines">@@ -109,6 +118,7 @@
</span><span class="cx">     IDBResourceIdentifier m_resourceIdentifier;
</span><span class="cx">     RefPtr&lt;IDBAny&gt; m_source;
</span><span class="cx">     bool m_hasPendingActivity { true };
</span><ins>+    IndexedDB::IndexRecordType m_requestedIndexRecordType;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -446,6 +446,33 @@
</span><span class="cx">     return WTF::move(request);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;IDBRequest&gt; IDBTransaction::requestGetValue(ScriptExecutionContext&amp; context, IDBIndex&amp; index, const IDBKeyRangeData&amp; range)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::requestGetValue&quot;);
+    return requestIndexRecord(context, index, IndexedDB::IndexRecordType::Value, range);
+}
+
+Ref&lt;IDBRequest&gt; IDBTransaction::requestGetKey(ScriptExecutionContext&amp; context, IDBIndex&amp; index, const IDBKeyRangeData&amp; range)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::requestGetValue&quot;);
+    return requestIndexRecord(context, index, IndexedDB::IndexRecordType::Key, range);
+}
+
+Ref&lt;IDBRequest&gt; IDBTransaction::requestIndexRecord(ScriptExecutionContext&amp; context, IDBIndex&amp; index, IndexedDB::IndexRecordType type, const IDBKeyRangeData&amp;range)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::requestGetValue&quot;);
+    ASSERT(isActive());
+    ASSERT(!range.isNull);
+
+    Ref&lt;IDBRequest&gt; request = IDBRequest::createGet(context, index, type, *this);
+    addRequest(request.get());
+
+    auto operation = createTransactionOperation(*this, request.get(), &amp;IDBTransaction::didGetRecordOnServer, &amp;IDBTransaction::getRecordOnServer, range);
+    scheduleOperation(WTF::move(operation));
+
+    return WTF::move(request);
+}
+
</ins><span class="cx"> void IDBTransaction::getRecordOnServer(TransactionOperation&amp; operation, const IDBKeyRangeData&amp; keyRange)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::getRecordOnServer&quot;);
</span><span class="lines">@@ -457,13 +484,24 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::didGetRecordOnServer&quot;);
</span><span class="cx"> 
</span><del>-    request.setResultToStructuredClone(resultData.resultData());
</del><ins>+    if (request.sourceIndexIdentifier() &amp;&amp; request.requestedIndexRecordType() == IndexedDB::IndexRecordType::Key) {
+        if (resultData.resultKey())
+            request.setResult(resultData.resultKey());
+        else
+            request.setResultToUndefined();
+    } else {
+        if (resultData.resultData().data())
+            request.setResultToStructuredClone(resultData.resultData());
+        else
+            request.setResultToUndefined();
+    }
+
</ins><span class="cx">     request.requestCompleted(resultData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;IDBRequest&gt; IDBTransaction::requestCount(ScriptExecutionContext&amp; context, IDBObjectStore&amp; objectStore, const IDBKeyRangeData&amp; range)
</span><span class="cx"> {
</span><del>-    LOG(IndexedDB, &quot;IDBTransaction::requestCount&quot;);
</del><ins>+    LOG(IndexedDB, &quot;IDBTransaction::requestCount (IDBObjectStore)&quot;);
</ins><span class="cx">     ASSERT(isActive());
</span><span class="cx">     ASSERT(!range.isNull);
</span><span class="cx"> 
</span><span class="lines">@@ -475,6 +513,20 @@
</span><span class="cx">     return request;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Ref&lt;IDBRequest&gt; IDBTransaction::requestCount(ScriptExecutionContext&amp; context, IDBIndex&amp; index, const IDBKeyRangeData&amp; range)
+{
+    LOG(IndexedDB, &quot;IDBTransaction::requestCount (IDBIndex)&quot;);
+    ASSERT(isActive());
+    ASSERT(!range.isNull);
+
+    Ref&lt;IDBRequest&gt; request = IDBRequest::createCount(context, index, *this);
+    addRequest(request.get());
+
+    scheduleOperation(createTransactionOperation(*this, request.get(), &amp;IDBTransaction::didGetCountOnServer, &amp;IDBTransaction::getCountOnServer, range));
+
+    return request;
+}
+
</ins><span class="cx"> void IDBTransaction::getCountOnServer(TransactionOperation&amp; operation, const IDBKeyRangeData&amp; keyRange)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;IDBTransaction::getCountOnServer&quot;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="cx"> class IDBDatabase;
</span><ins>+class IDBIndex;
</ins><span class="cx"> class TransactionOperation;
</span><span class="cx"> 
</span><span class="cx"> class IDBTransaction : public WebCore::IDBTransaction {
</span><span class="lines">@@ -97,6 +98,9 @@
</span><span class="cx">     Ref&lt;IDBRequest&gt; requestDeleteRecord(ScriptExecutionContext&amp;, IDBObjectStore&amp;, const IDBKeyRangeData&amp;);
</span><span class="cx">     Ref&lt;IDBRequest&gt; requestClearObjectStore(ScriptExecutionContext&amp;, IDBObjectStore&amp;);
</span><span class="cx">     Ref&lt;IDBRequest&gt; requestCount(ScriptExecutionContext&amp;, IDBObjectStore&amp;, const IDBKeyRangeData&amp;);
</span><ins>+    Ref&lt;IDBRequest&gt; requestCount(ScriptExecutionContext&amp;, IDBIndex&amp;, const IDBKeyRangeData&amp;);
+    Ref&lt;IDBRequest&gt; requestGetValue(ScriptExecutionContext&amp;, IDBIndex&amp;, const IDBKeyRangeData&amp;);
+    Ref&lt;IDBRequest&gt; requestGetKey(ScriptExecutionContext&amp;, IDBIndex&amp;, const IDBKeyRangeData&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void deleteObjectStore(const String&amp; objectStoreName);
</span><span class="cx"> 
</span><span class="lines">@@ -126,6 +130,8 @@
</span><span class="cx">     void fireOnAbort();
</span><span class="cx">     void enqueueEvent(Ref&lt;Event&gt;);
</span><span class="cx"> 
</span><ins>+    Ref&lt;IDBRequest&gt; requestIndexRecord(ScriptExecutionContext&amp;, IDBIndex&amp;, IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;);
+
</ins><span class="cx">     void commitOnServer(TransactionOperation&amp;);
</span><span class="cx">     void abortOnServer(TransactionOperation&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientTransactionOperationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -35,6 +35,9 @@
</span><span class="cx">     : TransactionOperation(transaction)
</span><span class="cx"> {
</span><span class="cx">     m_objectStoreIdentifier = request.sourceObjectStoreIdentifier();
</span><ins>+    m_indexIdentifier = request.sourceIndexIdentifier();
+    if (m_indexIdentifier)
+        m_indexRecordType = request.requestedIndexRecordType();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBClient
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientTransactionOperationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/client/TransactionOperation.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -36,6 +36,10 @@
</span><span class="cx"> 
</span><span class="cx"> class IDBResultData;
</span><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class IndexRecordType;
+}
+
</ins><span class="cx"> namespace IDBClient {
</span><span class="cx"> 
</span><span class="cx"> class TransactionOperation : public RefCounted&lt;TransactionOperation&gt; {
</span><span class="lines">@@ -54,7 +58,9 @@
</span><span class="cx">     const IDBResourceIdentifier&amp; identifier() const { return m_identifier; }
</span><span class="cx">     IDBResourceIdentifier transactionIdentifier() const { return m_transaction-&gt;info().identifier(); }
</span><span class="cx">     uint64_t objectStoreIdentifier() const { return m_objectStoreIdentifier; }
</span><ins>+    uint64_t indexIdentifier() const { return m_indexIdentifier; }
</ins><span class="cx">     IDBTransaction&amp; transaction() { return m_transaction.get(); }
</span><ins>+    IndexedDB::IndexRecordType indexRecordType() const { return m_indexRecordType; }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     TransactionOperation(IDBTransaction&amp; transaction)
</span><span class="lines">@@ -68,6 +74,8 @@
</span><span class="cx">     Ref&lt;IDBTransaction&gt; m_transaction;
</span><span class="cx">     IDBResourceIdentifier m_identifier;
</span><span class="cx">     uint64_t m_objectStoreIdentifier { 0 };
</span><ins>+    uint64_t m_indexIdentifier { 0 };
+    IndexedDB::IndexRecordType m_indexRecordType;
</ins><span class="cx">     std::function&lt;void ()&gt; m_performFunction;
</span><span class="cx">     std::function&lt;void (const IDBResultData&amp;)&gt; m_completeFunction;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -42,6 +42,10 @@
</span><span class="cx"> 
</span><span class="cx"> struct IDBKeyRangeData;
</span><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class IndexRecordType;
+}
+
</ins><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="cx"> class IDBBackingStore {
</span><span class="lines">@@ -62,7 +66,8 @@
</span><span class="cx">     virtual IDBError deleteRange(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;) = 0;
</span><span class="cx">     virtual IDBError putRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value) = 0;
</span><span class="cx">     virtual IDBError getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;, ThreadSafeDataBuffer&amp; outValue) = 0;
</span><del>-    virtual IDBError getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;, uint64_t&amp; outCount) = 0;
</del><ins>+    virtual IDBError getIndexRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;, ThreadSafeDataBuffer&amp; outValue) = 0;
+    virtual IDBError getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&amp;, uint64_t&amp; outCount) = 0;
</ins><span class="cx">     virtual IDBError generateKeyNumber(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t&amp; keyNumber) = 0;
</span><span class="cx"> 
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -262,7 +262,7 @@
</span><span class="cx">     return IDBError();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError MemoryIDBBackingStore::getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp; keyRangeData, ThreadSafeDataBuffer&amp; outValue)
</del><ins>+IDBError MemoryIDBBackingStore::getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp; range, ThreadSafeDataBuffer&amp; outValue)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;MemoryIDBBackingStore::getRecord&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -275,12 +275,29 @@
</span><span class="cx">     if (!objectStore)
</span><span class="cx">         return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store object store found&quot;));
</span><span class="cx"> 
</span><del>-    outValue = objectStore-&gt;valueForKeyRange(keyRangeData);
</del><ins>+    outValue = objectStore-&gt;valueForKeyRange(range);
</ins><span class="cx">     return IDBError();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError MemoryIDBBackingStore::getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp; range, uint64_t&amp; outCount)
</del><ins>+IDBError MemoryIDBBackingStore::getIndexRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData&amp; range, ThreadSafeDataBuffer&amp; outValue)
</ins><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;MemoryIDBBackingStore::getIndexRecord&quot;);
+
+    ASSERT(objectStoreIdentifier);
+
+    if (!m_transactions.contains(transactionIdentifier))
+        return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store transaction found to get record&quot;));
+
+    MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
+    if (!objectStore)
+        return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store object store found&quot;));
+
+    outValue = objectStore-&gt;indexValueForKeyRange(indexIdentifier, recordType, range);
+    return IDBError();
+}
+
+IDBError MemoryIDBBackingStore::getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&amp; range, uint64_t&amp; outCount)
+{
</ins><span class="cx">     LOG(IndexedDB, &quot;MemoryIDBBackingStore::getCount&quot;);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(objectStoreIdentifier);
</span><span class="lines">@@ -292,7 +309,8 @@
</span><span class="cx">     if (!objectStore)
</span><span class="cx">         return IDBError(IDBExceptionCode::Unknown, WTF::ASCIILiteral(&quot;No backing store object store found&quot;));
</span><span class="cx"> 
</span><del>-    outCount = objectStore-&gt;countForKeyRange(range);
</del><ins>+    outCount = objectStore-&gt;countForKeyRange(indexIdentifier, range);
+
</ins><span class="cx">     return IDBError();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -60,7 +60,8 @@
</span><span class="cx">     virtual IDBError deleteRange(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;) override final;
</span><span class="cx">     virtual IDBError putRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value) override final;
</span><span class="cx">     virtual IDBError getRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;, ThreadSafeDataBuffer&amp; outValue) override final;
</span><del>-    virtual IDBError getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;, uint64_t&amp; outCount) override final;
</del><ins>+    virtual IDBError getIndexRecord(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;, ThreadSafeDataBuffer&amp; outValue) override final;
+    virtual IDBError getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&amp;, uint64_t&amp; outCount) override final;
</ins><span class="cx">     virtual IDBError generateKeyNumber(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t&amp; keyNumber) override final;
</span><span class="cx"> 
</span><span class="cx">     void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&amp;);
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIndexcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -28,6 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> 
</span><ins>+#include &quot;ThreadSafeDataBuffer.h&quot;
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="lines">@@ -45,6 +47,20 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ThreadSafeDataBuffer MemoryIndex::valueForKeyRange(IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;) const
+{
+    // FIXME: Once indexes actually index, we'll return something real.
+    // https://bugs.webkit.org/show_bug.cgi?id=150939
+    return { };
+}
+
+uint64_t MemoryIndex::countForKeyRange(const IDBKeyRangeData&amp;)
+{
+    // FIXME: Once indexes actually index, we'll return something real.
+    // https://bugs.webkit.org/show_bug.cgi?id=150939
+    return 0;
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryIndexh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryIndex.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -31,6 +31,15 @@
</span><span class="cx"> #include &quot;IDBIndexInfo.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><ins>+
+class ThreadSafeDataBuffer;
+
+struct IDBKeyRangeData;
+
+namespace IndexedDB {
+enum class IndexRecordType;
+}
+
</ins><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="cx"> class MemoryIndex {
</span><span class="lines">@@ -42,6 +51,9 @@
</span><span class="cx"> 
</span><span class="cx">     const IDBIndexInfo&amp; info() const { return m_info; }
</span><span class="cx"> 
</span><ins>+    ThreadSafeDataBuffer valueForKeyRange(IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;) const;
+    uint64_t countForKeyRange(const IDBKeyRangeData&amp;);
+    
</ins><span class="cx"> private:
</span><span class="cx">     MemoryIndex(const IDBIndexInfo&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryObjectStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;MemoryObjectStore::createIndex&quot;);
</span><span class="cx"> 
</span><del>-    if (!m_writeTransaction || m_writeTransaction-&gt;isVersionChange() || m_writeTransaction != &amp;transaction)
</del><ins>+    if (!m_writeTransaction || !m_writeTransaction-&gt;isVersionChange() || m_writeTransaction != &amp;transaction)
</ins><span class="cx">         return IDBError(IDBExceptionCode::ConstraintError);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!m_indexesByIdentifier.contains(info.identifier()));
</span><span class="lines">@@ -175,10 +175,16 @@
</span><span class="cx">         m_orderedKeys-&gt;insert(keyData);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-uint64_t MemoryObjectStore::countForKeyRange(const IDBKeyRangeData&amp; inRange) const
</del><ins>+uint64_t MemoryObjectStore::countForKeyRange(uint64_t indexIdentifier, const IDBKeyRangeData&amp; inRange) const
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;MemoryObjectStore::countForKeyRange&quot;);
</span><span class="cx"> 
</span><ins>+    if (indexIdentifier) {
+        auto* index = m_indexesByIdentifier.get(indexIdentifier);
+        ASSERT(index);
+        return index-&gt;countForKeyRange(inRange);
+    }
+
</ins><span class="cx">     if (!m_keyValueStore)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><span class="lines">@@ -209,6 +215,15 @@
</span><span class="cx">     return m_keyValueStore-&gt;get(key);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ThreadSafeDataBuffer MemoryObjectStore::indexValueForKeyRange(uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData&amp; range) const
+{
+    LOG(IndexedDB, &quot;MemoryObjectStore::indexValueForKeyRange&quot;);
+
+    auto* index = m_indexesByIdentifier.get(indexIdentifier);
+    ASSERT(index);
+    return index-&gt;valueForKeyRange(recordType, range);
+}
+
</ins><span class="cx"> IDBKeyData MemoryObjectStore::lowestKeyWithRecordInRange(const IDBKeyRangeData&amp; keyRangeData) const
</span><span class="cx"> {
</span><span class="cx">     if (!m_keyValueStore)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverMemoryObjectStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/MemoryObjectStore.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -42,6 +42,10 @@
</span><span class="cx"> 
</span><span class="cx"> struct IDBKeyRangeData;
</span><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class IndexRecordType;
+}
+
</ins><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="cx"> class MemoryBackingStoreTransaction;
</span><span class="lines">@@ -74,7 +78,8 @@
</span><span class="cx">     void replaceKeyValueStore(std::unique_ptr&lt;KeyValueMap&gt;&amp;&amp;);
</span><span class="cx"> 
</span><span class="cx">     ThreadSafeDataBuffer valueForKeyRange(const IDBKeyRangeData&amp;) const;
</span><del>-    uint64_t countForKeyRange(const IDBKeyRangeData&amp;) const;
</del><ins>+    ThreadSafeDataBuffer indexValueForKeyRange(uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;) const;
+    uint64_t countForKeyRange(uint64_t indexIdentifier, const IDBKeyRangeData&amp;) const;
</ins><span class="cx"> 
</span><span class="cx">     const IDBObjectStoreInfo&amp; info() const { return m_info; }
</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 (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -447,13 +447,17 @@
</span><span class="cx">     performKeyDataCallback(callbackIdentifier, error, resultKey);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UniqueIDBDatabase::getRecord(const IDBRequestData&amp; requestData, const IDBKeyRangeData&amp; keyRangeData, ValueDataCallback callback)
</del><ins>+void UniqueIDBDatabase::getRecord(const IDBRequestData&amp; requestData, const IDBKeyRangeData&amp; range, ValueDataCallback callback)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::getRecord&quot;);
</span><span class="cx"> 
</span><span class="cx">     uint64_t callbackID = storeCallback(callback);
</span><del>-    m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performGetRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyRangeData));
</del><ins>+
+    if (uint64_t indexIdentifier = requestData.indexIdentifier())
+        m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performGetIndexRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), indexIdentifier, requestData.indexRecordType(), range));
+    else
+        m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performGetRecord, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), range));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void UniqueIDBDatabase::performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp; keyRangeData)
</span><span class="lines">@@ -462,7 +466,6 @@
</span><span class="cx">     LOG(IndexedDB, &quot;(db) UniqueIDBDatabase::performGetRecord&quot;);
</span><span class="cx"> 
</span><span class="cx">     ASSERT(m_backingStore);
</span><del>-    ASSERT(objectStoreIdentifier);
</del><span class="cx"> 
</span><span class="cx">     ThreadSafeDataBuffer valueData;
</span><span class="cx">     IDBError error = m_backingStore-&gt;getRecord(transactionIdentifier, objectStoreIdentifier, keyRangeData, valueData);
</span><span class="lines">@@ -470,6 +473,19 @@
</span><span class="cx">     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformGetRecord, callbackIdentifier, error, valueData));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void UniqueIDBDatabase::performGetIndexRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData&amp; range)
+{
+    ASSERT(!isMainThread());
+    LOG(IndexedDB, &quot;(db) UniqueIDBDatabase::performGetIndexRecord&quot;);
+
+    ASSERT(m_backingStore);
+
+    ThreadSafeDataBuffer valueData;
+    IDBError error = m_backingStore-&gt;getIndexRecord(transactionIdentifier, objectStoreIdentifier, indexIdentifier, recordType, range, valueData);
+
+    m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformGetRecord, callbackIdentifier, error, valueData));
+}
+
</ins><span class="cx"> void UniqueIDBDatabase::didPerformGetRecord(uint64_t callbackIdentifier, const IDBError&amp; error, const ThreadSafeDataBuffer&amp; resultData)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="lines">@@ -484,10 +500,10 @@
</span><span class="cx">     LOG(IndexedDB, &quot;(main) UniqueIDBDatabase::getCount&quot;);
</span><span class="cx"> 
</span><span class="cx">     uint64_t callbackID = storeCallback(callback);
</span><del>-    m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performGetCount, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), range));
</del><ins>+    m_server.postDatabaseTask(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::performGetCount, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), requestData.indexIdentifier(), range));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void UniqueIDBDatabase::performGetCount(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp; keyRangeData)
</del><ins>+void UniqueIDBDatabase::performGetCount(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&amp; keyRangeData)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!isMainThread());
</span><span class="cx">     LOG(IndexedDB, &quot;(db) UniqueIDBDatabase::performGetCount&quot;);
</span><span class="lines">@@ -496,7 +512,7 @@
</span><span class="cx">     ASSERT(objectStoreIdentifier);
</span><span class="cx"> 
</span><span class="cx">     uint64_t count;
</span><del>-    IDBError error = m_backingStore-&gt;getCount(transactionIdentifier, objectStoreIdentifier, keyRangeData, count);
</del><ins>+    IDBError error = m_backingStore-&gt;getCount(transactionIdentifier, objectStoreIdentifier, indexIdentifier, keyRangeData, count);
</ins><span class="cx"> 
</span><span class="cx">     m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &amp;UniqueIDBDatabase::didPerformGetCount, callbackIdentifier, error, count));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverUniqueIDBDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -48,6 +48,10 @@
</span><span class="cx"> class IDBRequestData;
</span><span class="cx"> class IDBTransactionInfo;
</span><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class IndexRecordType;
+}
+
</ins><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><span class="cx"> class IDBConnectionToClient;
</span><span class="lines">@@ -109,7 +113,8 @@
</span><span class="cx">     void performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, const IDBIndexInfo&amp;);
</span><span class="cx">     void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; valueData, IndexedDB::ObjectStoreOverwriteMode);
</span><span class="cx">     void performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;);
</span><del>-    void performGetCount(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;);
</del><ins>+    void performGetIndexRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&amp;);
+    void performGetCount(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&amp;);
</ins><span class="cx">     void performDeleteRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&amp;);
</span><span class="cx">     void performActivateTransactionInBackingStore(uint64_t callbackIdentifier, const IDBTransactionInfo&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.cpp        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -46,12 +46,17 @@
</span><span class="cx">     , m_requestIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(operation.identifier()))
</span><span class="cx">     , m_transactionIdentifier(std::make_unique&lt;IDBResourceIdentifier&gt;(operation.transactionIdentifier()))
</span><span class="cx">     , m_objectStoreIdentifier(operation.objectStoreIdentifier())
</span><ins>+    , m_indexIdentifier(operation.indexIdentifier())
</ins><span class="cx"> {
</span><ins>+    if (m_indexIdentifier)
+        m_indexRecordType = operation.indexRecordType();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBRequestData::IDBRequestData(const IDBRequestData&amp; other)
</span><span class="cx">     : m_serverConnectionIdentifier(other.m_serverConnectionIdentifier)
</span><span class="cx">     , m_objectStoreIdentifier(other.m_objectStoreIdentifier)
</span><ins>+    , m_indexIdentifier(other.m_indexIdentifier)
+    , m_indexRecordType(other.m_indexRecordType)
</ins><span class="cx">     , m_databaseIdentifier(other.m_databaseIdentifier)
</span><span class="cx">     , m_requestedVersion(other.m_requestedVersion)
</span><span class="cx"> {
</span><span class="lines">@@ -81,10 +86,22 @@
</span><span class="cx"> 
</span><span class="cx"> uint64_t IDBRequestData::objectStoreIdentifier() const
</span><span class="cx"> {
</span><del>-    RELEASE_ASSERT(m_objectStoreIdentifier);
</del><ins>+    ASSERT(m_objectStoreIdentifier);
</ins><span class="cx">     return m_objectStoreIdentifier;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+uint64_t IDBRequestData::indexIdentifier() const
+{
+    ASSERT(m_objectStoreIdentifier || m_indexIdentifier);
+    return m_indexIdentifier;
+}
+
+IndexedDB::IndexRecordType IDBRequestData::indexRecordType() const
+{
+    ASSERT(m_indexIdentifier);
+    return m_indexRecordType;
+}
+
</ins><span class="cx"> uint64_t IDBRequestData::requestedVersion() const
</span><span class="cx"> {
</span><span class="cx">     return m_requestedVersion;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbsharedIDBRequestDatah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h (192067 => 192068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h        2015-11-05 19:55:27 UTC (rev 192067)
+++ trunk/Source/WebCore/Modules/indexeddb/shared/IDBRequestData.h        2015-11-05 20:23:02 UTC (rev 192068)
</span><span class="lines">@@ -33,6 +33,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+namespace IndexedDB {
+enum class IndexRecordType;
+}
+
</ins><span class="cx"> namespace IDBClient {
</span><span class="cx"> class IDBConnectionToServer;
</span><span class="cx"> class IDBOpenDBRequest;
</span><span class="lines">@@ -50,6 +54,8 @@
</span><span class="cx">     IDBResourceIdentifier requestIdentifier() const;
</span><span class="cx">     IDBResourceIdentifier transactionIdentifier() const;
</span><span class="cx">     uint64_t objectStoreIdentifier() const;
</span><ins>+    uint64_t indexIdentifier() const;
+    IndexedDB::IndexRecordType indexRecordType() const;
</ins><span class="cx"> 
</span><span class="cx">     const IDBDatabaseIdentifier&amp; databaseIdentifier() const { return m_databaseIdentifier; }
</span><span class="cx">     uint64_t requestedVersion() const;
</span><span class="lines">@@ -61,6 +67,8 @@
</span><span class="cx">     std::unique_ptr&lt;IDBResourceIdentifier&gt; m_requestIdentifier;
</span><span class="cx">     std::unique_ptr&lt;IDBResourceIdentifier&gt; m_transactionIdentifier;
</span><span class="cx">     uint64_t m_objectStoreIdentifier { 0 };
</span><ins>+    uint64_t m_indexIdentifier { 0 };
+    IndexedDB::IndexRecordType m_indexRecordType;
</ins><span class="cx"> 
</span><span class="cx">     IDBDatabaseIdentifier m_databaseIdentifier;
</span><span class="cx">     uint64_t m_requestedVersion { 0 };
</span></span></pre>
</div>
</div>

</body>
</html>