<!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>[209829] tags/Safari-603.1.16</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/209829">209829</a></dd>
<dt>Author</dt> <dd>bshafiei@apple.com</dd>
<dt>Date</dt> <dd>2016-12-14 13:18:02 -0800 (Wed, 14 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/209824">r209824</a>.  rdar://problem/29666094</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#tagsSafari603116SourceWebCoreChangeLog">tags/Safari-603.1.16/Source/WebCore/ChangeLog</a></li>
<li><a href="#tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp">tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp</a></li>
<li><a href="#tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh">tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h</a></li>
<li><a href="#tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp">tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp</a></li>
<li><a href="#tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBCursorh">tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h</a></li>
<li><a href="#tagsSafari603116ToolsChangeLog">tags/Safari-603.1.16/Tools/ChangeLog</a></li>
<li><a href="#tagsSafari603116ToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj">tags/Safari-603.1.16/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIDBIndexUpgradeToV2html">tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.html</a></li>
<li><a href="#tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIDBIndexUpgradeToV2mm">tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.mm</a></li>
<li><a href="#tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIndexUpgradeblob">tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.blob</a></li>
<li><a href="#tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIndexUpgradesqlite3">tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.sqlite3</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="tagsSafari603116SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Source/WebCore/ChangeLog (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Source/WebCore/ChangeLog        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Source/WebCore/ChangeLog        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -1,3 +1,44 @@
</span><ins>+2016-12-14  Babak Shafiei  &lt;bshafiei@apple.com&gt;
+
+        Merge r209824.
+
+    2016-12-14  Brady Eidson  &lt;beidson@apple.com&gt;
+
+            IndexedDB 2.0: Massively speedup IDBIndex.get().
+            https://bugs.webkit.org/show_bug.cgi?id=165802
+
+            Reviewed by Alex Christensen.
+
+            No new tests (No behavior change to Javascript, table upgrade change covered by API test).
+
+            This change upgrades the IndexRecords schema to include the ObjectStore record ID for the referenced record.
+            It also adds a SQLite Index-by-key on IndexRecords.
+
+            This speeds up PerformanceTests/IndexedDB/index-get.html by 15-20x.
+
+            * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+            (WebCore::IDBServer::v3IndexRecordsTableSchema):
+            (WebCore::IDBServer::v3IndexRecordsTableSchemaAlternate):
+            (WebCore::IDBServer::v1IndexRecordsIndexSchema):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsTable):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidIndexRecordsIndex):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedPutIndexKey):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedPutIndexRecord):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::updateOneIndexForAddRecord):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::updateAllIndexesForAddRecord):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::getIndexRecord):
+            (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedGetIndexRecordForOneKey):
+            * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+
+            * Modules/indexeddb/server/SQLiteIDBCursor.cpp:
+            (WebCore::IDBServer::SQLiteIDBCursor::markAsErrored):
+            (WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
+            * Modules/indexeddb/server/SQLiteIDBCursor.h:
+            (WebCore::IDBServer::SQLiteIDBCursor::currentRecordRowID):
+
</ins><span class="cx"> 2016-12-14  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Make Style::Update const in RenderTreeUpdater
</span></span></pre></div>
<a id="tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -171,6 +171,29 @@
</span><span class="cx">     return v2IndexRecordsTableSchemaString;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static const String v3IndexRecordsTableSchema(const String&amp; tableName)
+{
+    return makeString(&quot;CREATE TABLE &quot;, tableName, &quot; (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, objectStoreRecordID INTEGER NOT NULL ON CONFLICT FAIL)&quot;);
+}
+
+static const String v3IndexRecordsTableSchema()
+{
+    static NeverDestroyed&lt;WTF::String&gt; indexRecordsTableSchemaString = v3IndexRecordsTableSchema(&quot;IndexRecords&quot;);
+    return indexRecordsTableSchemaString;
+}
+
+static const String v3IndexRecordsTableSchemaAlternate()
+{
+    static NeverDestroyed&lt;WTF::String&gt; indexRecordsTableSchemaString = v3IndexRecordsTableSchema(&quot;\&quot;IndexRecords\&quot;&quot;);
+    return indexRecordsTableSchemaString;
+}
+
+static const String&amp; v1IndexRecordsIndexSchema()
+{
+    static NeverDestroyed&lt;WTF::String&gt; indexRecordsIndexSchemaString(&quot;CREATE INDEX IndexRecordsIndex ON IndexRecords (key)&quot;);
+    return indexRecordsIndexSchemaString;
+}
+
</ins><span class="cx"> static const String blobRecordsTableSchema(const String&amp; tableName)
</span><span class="cx"> {
</span><span class="cx">     return makeString(&quot;CREATE TABLE &quot;, tableName, &quot; (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)&quot;);
</span><span class="lines">@@ -428,7 +451,7 @@
</span><span class="cx"> 
</span><span class="cx">         // If there is no IndexRecords table at all, create it and then bail.
</span><span class="cx">         if (sqliteResult == SQLITE_DONE) {
</span><del>-            if (!m_sqliteDB-&gt;executeCommand(v2IndexRecordsTableSchema())) {
</del><ins>+            if (!m_sqliteDB-&gt;executeCommand(v3IndexRecordsTableSchema())) {
</ins><span class="cx">                 LOG_ERROR(&quot;Could not create IndexRecords table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</span><span class="cx">                 return false;
</span><span class="cx">             }
</span><span class="lines">@@ -447,12 +470,13 @@
</span><span class="cx">     ASSERT(!currentSchema.isEmpty());
</span><span class="cx"> 
</span><span class="cx">     // If the schema in the backing store is the current schema, we're done.
</span><del>-    if (currentSchema == v2IndexRecordsTableSchema() || currentSchema == v2IndexRecordsTableSchemaAlternate())
</del><ins>+    if (currentSchema == v3IndexRecordsTableSchema() || currentSchema == v3IndexRecordsTableSchemaAlternate())
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><span class="cx">     // If the record table is not the current schema then it must be one of the previous schemas.
</span><span class="cx">     // If it is not then the database is in an unrecoverable state and this should be considered a fatal error.
</span><del>-    if (currentSchema != v1IndexRecordsTableSchema() &amp;&amp; currentSchema != v1IndexRecordsTableSchemaAlternate())
</del><ins>+    if (currentSchema != v1IndexRecordsTableSchema() &amp;&amp; currentSchema != v1IndexRecordsTableSchemaAlternate()
+        &amp;&amp; currentSchema != v2IndexRecordsTableSchema() &amp;&amp; currentSchema != v2IndexRecordsTableSchemaAlternate())
</ins><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> 
</span><span class="cx">     SQLiteTransaction transaction(*m_sqliteDB);
</span><span class="lines">@@ -459,12 +483,12 @@
</span><span class="cx">     transaction.begin();
</span><span class="cx"> 
</span><span class="cx">     // Create a temporary table with the correct schema and migrate all existing content over.
</span><del>-    if (!m_sqliteDB-&gt;executeCommand(v2IndexRecordsTableSchema(&quot;_Temp_IndexRecords&quot;))) {
</del><ins>+    if (!m_sqliteDB-&gt;executeCommand(v3IndexRecordsTableSchema(&quot;_Temp_IndexRecords&quot;))) {
</ins><span class="cx">         LOG_ERROR(&quot;Could not create temporary index records table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_sqliteDB-&gt;executeCommand(&quot;INSERT INTO _Temp_IndexRecords SELECT * FROM IndexRecords&quot;)) {
</del><ins>+    if (!m_sqliteDB-&gt;executeCommand(&quot;INSERT INTO _Temp_IndexRecords SELECT IndexRecords.indexID, IndexRecords.objectStoreID, IndexRecords.key, IndexRecords.value, Records.rowid FROM IndexRecords INNER JOIN Records ON Records.key = IndexRecords.value AND Records.objectStoreID = IndexRecords.objectStoreID&quot;)) {
</ins><span class="cx">         LOG_ERROR(&quot;Could not migrate existing IndexRecords content (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="lines">@@ -484,6 +508,50 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool SQLiteIDBBackingStore::ensureValidIndexRecordsIndex()
+{
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB-&gt;isOpen());
+
+    String currentSchema;
+    {
+        // Fetch the schema for an existing index record index.
+        SQLiteStatement statement(*m_sqliteDB, &quot;SELECT sql FROM sqlite_master WHERE name='IndexRecordsIndex'&quot;);
+        if (statement.prepare() != SQLITE_OK) {
+            LOG_ERROR(&quot;Unable to prepare statement to fetch schema for the IndexRecordsIndex index.&quot;);
+            return false;
+        }
+
+        int sqliteResult = statement.step();
+
+        // If there is no IndexRecordsIndex index at all, create it and then bail.
+        if (sqliteResult == SQLITE_DONE) {
+            if (!m_sqliteDB-&gt;executeCommand(v1IndexRecordsIndexSchema())) {
+                LOG_ERROR(&quot;Could not create IndexRecordsIndex index in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+                return false;
+            }
+
+            return true;
+        }
+
+        if (sqliteResult != SQLITE_ROW) {
+            LOG_ERROR(&quot;Error executing statement to fetch schema for the IndexRecordsIndex index.&quot;);
+            return false;
+        }
+
+        currentSchema = statement.getColumnText(0);
+    }
+
+    ASSERT(!currentSchema.isEmpty());
+
+    // If the schema in the backing store is the current schema, we're done.
+    if (currentSchema == v1IndexRecordsIndexSchema())
+        return true;
+
+    // There is currently no outdated schema for the IndexRecordsIndex, so any other existing schema means this database is invalid.
+    return false;
+}
+
</ins><span class="cx"> std::unique_ptr&lt;IDBDatabaseInfo&gt; SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_sqliteDB);
</span><span class="lines">@@ -744,6 +812,12 @@
</span><span class="cx">         return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error creating or migrating Index Records table in database&quot;) };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (!ensureValidIndexRecordsIndex()) {
+        LOG_ERROR(&quot;Error creating or migrating Index Records index in database&quot;);
+        closeSQLiteDB();
+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error creating or migrating Index Records index in database&quot;) };
+    }
+
</ins><span class="cx">     if (!ensureValidBlobTables()) {
</span><span class="cx">         LOG_ERROR(&quot;Error creating or confirming Blob Records tables in database&quot;);
</span><span class="cx">         closeSQLiteDB();
</span><span class="lines">@@ -1107,7 +1181,9 @@
</span><span class="cx">         auto* value = cursor-&gt;currentValue();
</span><span class="cx">         ThreadSafeDataBuffer valueBuffer = value ? value-&gt;data() : ThreadSafeDataBuffer();
</span><span class="cx"> 
</span><del>-        IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer);
</del><ins>+        ASSERT(cursor-&gt;currentRecordRowID());
+
+        IDBError error = updateOneIndexForAddRecord(info, key, valueBuffer, cursor-&gt;currentRecordRowID());
</ins><span class="cx">         if (!error.isNull()) {
</span><span class="cx">             auto* sql = cachedStatement(SQL::DeleteIndexInfo, ASCIILiteral(&quot;DELETE FROM IndexInfo WHERE id = ? AND objectStoreID = ?;&quot;));
</span><span class="cx">             if (!sql
</span><span class="lines">@@ -1167,7 +1243,7 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::uncheckedPutIndexKey(const IDBIndexInfo&amp; info, const IDBKeyData&amp; key, const IndexKey&amp; indexKey)
</del><ins>+IDBError SQLiteIDBBackingStore::uncheckedPutIndexKey(const IDBIndexInfo&amp; info, const IDBKeyData&amp; key, const IndexKey&amp; indexKey, int64_t recordID)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;SQLiteIDBBackingStore::uncheckedPutIndexKey - (%&quot; PRIu64 &quot;) %s, %s&quot;, info.identifier(), key.loggingString().utf8().data(), indexKey.asOneKey().loggingString().utf8().data());
</span><span class="cx"> 
</span><span class="lines">@@ -1194,7 +1270,7 @@
</span><span class="cx">     for (auto&amp; indexKey : indexKeys) {
</span><span class="cx">         if (!indexKey.isValid())
</span><span class="cx">             continue;
</span><del>-        auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey);
</del><ins>+        auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey, recordID);
</ins><span class="cx">         if (!error.isNull()) {
</span><span class="cx">             LOG_ERROR(&quot;Unable to put index record for newly created index&quot;);
</span><span class="cx">             return error;
</span><span class="lines">@@ -1204,7 +1280,7 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData&amp; keyValue, const WebCore::IDBKeyData&amp; indexKey)
</del><ins>+IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData&amp; keyValue, const WebCore::IDBKeyData&amp; indexKey, int64_t recordID)
</ins><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;SQLiteIDBBackingStore::uncheckedPutIndexRecord - %s, %s&quot;, keyValue.loggingString().utf8().data(), indexKey.loggingString().utf8().data());
</span><span class="cx"> 
</span><span class="lines">@@ -1221,12 +1297,13 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        auto* sql = cachedStatement(SQL::PutIndexRecord, ASCIILiteral(&quot;INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT));&quot;));
</del><ins>+        auto* sql = cachedStatement(SQL::PutIndexRecord, ASCIILiteral(&quot;INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT), ?);&quot;));
</ins><span class="cx">         if (!sql
</span><span class="cx">             || sql-&gt;bindInt64(1, indexID) != SQLITE_OK
</span><span class="cx">             || sql-&gt;bindInt64(2, objectStoreID) != SQLITE_OK
</span><span class="cx">             || sql-&gt;bindBlob(3, indexKeyBuffer-&gt;data(), indexKeyBuffer-&gt;size()) != SQLITE_OK
</span><span class="cx">             || sql-&gt;bindBlob(4, valueBuffer-&gt;data(), valueBuffer-&gt;size()) != SQLITE_OK
</span><ins>+            || sql-&gt;bindInt64(5, recordID) != SQLITE_OK
</ins><span class="cx">             || sql-&gt;step() != SQLITE_DONE) {
</span><span class="cx">             LOG_ERROR(&quot;Could not put index record for index %&quot; PRIi64 &quot; in object store %&quot; PRIi64 &quot; in Records table (%i) - %s&quot;, indexID, objectStoreID, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</span><span class="cx">             return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Error putting index record into database&quot;) };
</span><span class="lines">@@ -1563,7 +1640,7 @@
</span><span class="cx">     return error;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo&amp; info, const IDBKeyData&amp; key, const ThreadSafeDataBuffer&amp; value)
</del><ins>+IDBError SQLiteIDBBackingStore::updateOneIndexForAddRecord(const IDBIndexInfo&amp; info, const IDBKeyData&amp; key, const ThreadSafeDataBuffer&amp; value, int64_t recordID)
</ins><span class="cx"> {
</span><span class="cx">     JSLockHolder locker(vm());
</span><span class="cx"> 
</span><span class="lines">@@ -1577,10 +1654,10 @@
</span><span class="cx">     if (indexKey.isNull())
</span><span class="cx">         return { };
</span><span class="cx"> 
</span><del>-    return uncheckedPutIndexKey(info, key, indexKey);
</del><ins>+    return uncheckedPutIndexKey(info, key, indexKey, recordID);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStoreInfo&amp; info, const IDBKeyData&amp; key, const ThreadSafeDataBuffer&amp; value)
</del><ins>+IDBError SQLiteIDBBackingStore::updateAllIndexesForAddRecord(const IDBObjectStoreInfo&amp; info, const IDBKeyData&amp; key, const ThreadSafeDataBuffer&amp; value, int64_t recordID)
</ins><span class="cx"> {
</span><span class="cx">     JSLockHolder locker(vm());
</span><span class="cx"> 
</span><span class="lines">@@ -1597,7 +1674,7 @@
</span><span class="cx">         if (indexKey.isNull())
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        error = uncheckedPutIndexKey(index, key, indexKey);
</del><ins>+        error = uncheckedPutIndexKey(index, key, indexKey, recordID);
</ins><span class="cx">         if (!error.isNull())
</span><span class="cx">             break;
</span><span class="cx"> 
</span><span class="lines">@@ -1661,7 +1738,7 @@
</span><span class="cx">         recordID = m_sqliteDB-&gt;lastInsertRowID();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value.data());
</del><ins>+    auto error = updateAllIndexesForAddRecord(objectStoreInfo, keyData, value.data(), recordID);
</ins><span class="cx"> 
</span><span class="cx">     if (!error.isNull()) {
</span><span class="cx">         auto* sql = cachedStatement(SQL::DeleteObjectStoreRecord, ASCIILiteral(&quot;DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);&quot;));
</span><span class="lines">@@ -2112,6 +2189,9 @@
</span><span class="cx">         return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Attempt to get an index record from database without an in-progress transaction&quot;) };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (range.isExactlyOneKey())
+        return uncheckedGetIndexRecordForOneKey(indexID, objectStoreID, type, range.lowerKey, getResult);
+
</ins><span class="cx">     auto cursor = transaction-&gt;maybeOpenBackingStoreCursor(objectStoreID, indexID, range);
</span><span class="cx">     if (!cursor) {
</span><span class="cx">         LOG_ERROR(&quot;Cannot open cursor to perform index get in database&quot;);
</span><span class="lines">@@ -2135,6 +2215,65 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+IDBError SQLiteIDBBackingStore::uncheckedGetIndexRecordForOneKey(int64_t indexID, int64_t objectStoreID, IndexedDB::IndexRecordType type, const IDBKeyData&amp; key, IDBGetResult&amp; getResult)
+{
+    LOG(IndexedDB, &quot;SQLiteIDBBackingStore::uncheckedGetIndexRecordForOneKey&quot;);
+
+    ASSERT(key.isValid() &amp;&amp; key.type() != KeyType::Max &amp;&amp; key.type() != KeyType::Min);
+
+    RefPtr&lt;SharedBuffer&gt; buffer = serializeIDBKeyData(key);
+    if (!buffer) {
+        LOG_ERROR(&quot;Unable to serialize IDBKey to look up one index record&quot;);
+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to serialize IDBKey to look up one index record&quot;) };
+    }
+
+    auto* sql = cachedStatement(SQL::GetIndexRecordForOneKey, ASCIILiteral(&quot;SELECT IndexRecords.value, Records.value, Records.recordID FROM Records INNER JOIN IndexRecords ON Records.recordID = IndexRecords.objectStoreRecordID WHERE IndexRecords.indexID = ? AND IndexRecords.objectStoreID = ? AND IndexRecords.key = CAST(? AS TEXT) ORDER BY IndexRecords.key, IndexRecords.value&quot;));
+
+    if (!sql
+        || sql-&gt;bindInt64(1, indexID) != SQLITE_OK
+        || sql-&gt;bindInt64(2, objectStoreID) != SQLITE_OK
+        || sql-&gt;bindBlob(3, buffer-&gt;data(), buffer-&gt;size()) != SQLITE_OK) {
+        LOG_ERROR(&quot;Unable to lookup index record in database&quot;);
+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to lookup index record in database&quot;) };
+    }
+
+    int result = sql-&gt;step();
+    if (result != SQLITE_ROW &amp;&amp; result != SQLITE_DONE) {
+        LOG_ERROR(&quot;Unable to lookup index record in database&quot;);
+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to lookup index record in database&quot;) };
+    }
+
+    if (result == SQLITE_DONE)
+        return { };
+
+    IDBKeyData objectStoreKey;
+    Vector&lt;uint8_t&gt; keyVector;
+    sql-&gt;getColumnBlobAsVector(0, keyVector);
+
+    if (!deserializeIDBKeyData(keyVector.data(), keyVector.size(), objectStoreKey)) {
+        LOG_ERROR(&quot;Unable to deserialize key looking up index record in database&quot;);
+        return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Unable to deserialize key looking up index record in database&quot;) };
+    }
+
+    if (type == IndexedDB::IndexRecordType::Key) {
+        getResult = { objectStoreKey };
+        return { };
+    }
+
+    sql-&gt;getColumnBlobAsVector(1, keyVector);
+
+    int64_t recordID = sql-&gt;getColumnInt64(2);
+    Vector&lt;String&gt; blobURLs, blobFilePaths;
+    auto error = getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
+    ASSERT(blobURLs.size() == blobFilePaths.size());
+
+    if (!error.isNull())
+        return error;
+
+    getResult = { { ThreadSafeDataBuffer::adoptVector(keyVector), WTFMove(blobURLs), WTFMove(blobFilePaths) }, objectStoreKey };
+    return { };
+}
+
</ins><span class="cx"> IDBError SQLiteIDBBackingStore::getCount(const IDBResourceIdentifier&amp; transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const IDBKeyRangeData&amp; range, uint64_t&amp; outCount)
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;SQLiteIDBBackingStore::getCount - object store %&quot; PRIu64, objectStoreIdentifier);
</span></span></pre></div>
<a id="tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -98,6 +98,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool ensureValidRecordsTable();
</span><span class="cx">     bool ensureValidIndexRecordsTable();
</span><ins>+    bool ensureValidIndexRecordsIndex();
</ins><span class="cx">     bool ensureValidBlobTables();
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; createAndPopulateInitialDatabaseInfo();
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; extractExistingDatabaseInfo();
</span><span class="lines">@@ -106,11 +107,12 @@
</span><span class="cx">     IDBError uncheckedGetKeyGeneratorValue(int64_t objectStoreID, uint64_t&amp; outValue);
</span><span class="cx">     IDBError uncheckedSetKeyGeneratorValue(int64_t objectStoreID, uint64_t value);
</span><span class="cx"> 
</span><del>-    IDBError updateAllIndexesForAddRecord(const IDBObjectStoreInfo&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value);
-    IDBError updateOneIndexForAddRecord(const IDBIndexInfo&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value);
-    IDBError uncheckedPutIndexKey(const IDBIndexInfo&amp;, const IDBKeyData&amp; keyValue, const IndexKey&amp;);
-    IDBError uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const IDBKeyData&amp; keyValue, const IDBKeyData&amp; indexKey);
</del><ins>+    IDBError updateAllIndexesForAddRecord(const IDBObjectStoreInfo&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value, int64_t recordID);
+    IDBError updateOneIndexForAddRecord(const IDBIndexInfo&amp;, const IDBKeyData&amp;, const ThreadSafeDataBuffer&amp; value, int64_t recordID);
+    IDBError uncheckedPutIndexKey(const IDBIndexInfo&amp;, const IDBKeyData&amp; keyValue, const IndexKey&amp;, int64_t recordID);
+    IDBError uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const IDBKeyData&amp; keyValue, const IDBKeyData&amp; indexKey, int64_t recordID);
</ins><span class="cx">     IDBError uncheckedHasIndexRecord(const IDBIndexInfo&amp;, const IDBKeyData&amp;, bool&amp; hasRecord);
</span><ins>+    IDBError uncheckedGetIndexRecordForOneKey(int64_t indexeID, int64_t objectStoreID, IndexedDB::IndexRecordType, const IDBKeyData&amp;, IDBGetResult&amp;);
</ins><span class="cx"> 
</span><span class="cx">     IDBError deleteUnusedBlobFileRecords(SQLiteIDBTransaction&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -135,6 +137,7 @@
</span><span class="cx">         DeleteIndexInfo,
</span><span class="cx">         HasIndexRecord,
</span><span class="cx">         PutIndexRecord,
</span><ins>+        GetIndexRecordForOneKey,
</ins><span class="cx">         DeleteIndexRecords,
</span><span class="cx">         RenameIndex,
</span><span class="cx">         KeyExistsInObjectStore,
</span></span></pre></div>
<a id="tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -343,6 +343,13 @@
</span><span class="cx">     return result == AdvanceResult::Success;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SQLiteIDBCursor::markAsErrored()
+{
+    m_completed = true;
+    m_errored = true;
+    m_currentRecordRowID = 0;
+}
+
</ins><span class="cx"> SQLiteIDBCursor::AdvanceResult SQLiteIDBCursor::internalAdvanceOnce()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_transaction-&gt;sqliteTransaction());
</span><span class="lines">@@ -359,6 +366,7 @@
</span><span class="cx">         m_currentKey = IDBKeyData();
</span><span class="cx">         m_currentPrimaryKey = IDBKeyData();
</span><span class="cx">         m_currentValue = nullptr;
</span><ins>+        m_currentRecordRowID = 0;
</ins><span class="cx"> 
</span><span class="cx">         return AdvanceResult::Success;
</span><span class="cx">     }
</span><span class="lines">@@ -365,36 +373,33 @@
</span><span class="cx"> 
</span><span class="cx">     if (result != SQLITE_ROW) {
</span><span class="cx">         LOG_ERROR(&quot;Error advancing cursor - (%i) %s&quot;, result, m_transaction-&gt;sqliteTransaction()-&gt;database().lastErrorMsg());
</span><del>-        m_completed = true;
-        m_errored = true;
</del><ins>+        markAsErrored();
</ins><span class="cx">         return AdvanceResult::Failure;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    m_currentRecordRowID = m_statement-&gt;getColumnInt64(0);
+    ASSERT(m_currentRecordRowID);
+
</ins><span class="cx">     Vector&lt;uint8_t&gt; keyData;
</span><span class="cx">     m_statement-&gt;getColumnBlobAsVector(1, keyData);
</span><span class="cx"> 
</span><span class="cx">     if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentKey)) {
</span><span class="cx">         LOG_ERROR(&quot;Unable to deserialize key data from database while advancing cursor&quot;);
</span><del>-        m_completed = true;
-        m_errored = true;
</del><ins>+        markAsErrored();
</ins><span class="cx">         return AdvanceResult::Failure;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_statement-&gt;getColumnBlobAsVector(2, keyData);
</span><span class="cx"> 
</span><del>-    int64_t recordID = m_statement-&gt;getColumnInt64(0);
-    ASSERT(recordID);
-
</del><span class="cx">     // The primaryKey of an ObjectStore cursor is the same as its key.
</span><span class="cx">     if (m_indexID == IDBIndexInfo::InvalidId) {
</span><span class="cx">         m_currentPrimaryKey = m_currentKey;
</span><span class="cx"> 
</span><span class="cx">         Vector&lt;String&gt; blobURLs, blobFilePaths;
</span><del>-        auto error = m_transaction-&gt;backingStore().getBlobRecordsForObjectStoreRecord(recordID, blobURLs, blobFilePaths);
</del><ins>+        auto error = m_transaction-&gt;backingStore().getBlobRecordsForObjectStoreRecord(m_currentRecordRowID, blobURLs, blobFilePaths);
</ins><span class="cx">         if (!error.isNull()) {
</span><span class="cx">             LOG_ERROR(&quot;Unable to fetch blob records from database while advancing cursor&quot;);
</span><del>-            m_completed = true;
-            m_errored = true;
</del><ins>+            markAsErrored();
</ins><span class="cx">             return AdvanceResult::Failure;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -403,8 +408,7 @@
</span><span class="cx">     } else {
</span><span class="cx">         if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentPrimaryKey)) {
</span><span class="cx">             LOG_ERROR(&quot;Unable to deserialize value data from database while advancing index cursor&quot;);
</span><del>-            m_completed = true;
-            m_errored = true;
</del><ins>+            markAsErrored();
</ins><span class="cx">             return AdvanceResult::Failure;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -414,8 +418,7 @@
</span><span class="cx">             || objectStoreStatement.bindBlob(1, keyData.data(), keyData.size()) != SQLITE_OK
</span><span class="cx">             || objectStoreStatement.bindInt64(2, m_objectStoreID) != SQLITE_OK) {
</span><span class="cx">             LOG_ERROR(&quot;Could not create index cursor statement into object store records (%i) '%s'&quot;, m_statement-&gt;database().lastError(), m_statement-&gt;database().lastErrorMsg());
</span><del>-            m_completed = true;
-            m_errored = true;
</del><ins>+            markAsErrored();
</ins><span class="cx">             return AdvanceResult::Failure;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -430,8 +433,7 @@
</span><span class="cx">             return AdvanceResult::ShouldAdvanceAgain;
</span><span class="cx">         } else {
</span><span class="cx">             LOG_ERROR(&quot;Could not step index cursor statement into object store records (%i) '%s'&quot;, m_statement-&gt;database().lastError(), m_statement-&gt;database().lastErrorMsg());
</span><del>-            m_completed = true;
-            m_errored = true;
</del><ins>+            markAsErrored();
</ins><span class="cx">             return AdvanceResult::Failure;
</span><span class="cx"> 
</span><span class="cx">         }
</span></span></pre></div>
<a id="tagsSafari603116SourceWebCoreModulesindexeddbserverSQLiteIDBCursorh"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -59,6 +59,7 @@
</span><span class="cx">     SQLiteIDBTransaction* transaction() const { return m_transaction; }
</span><span class="cx"> 
</span><span class="cx">     int64_t objectStoreID() const { return m_objectStoreID; }
</span><ins>+    int64_t currentRecordRowID() const { return m_currentRecordRowID; }
</ins><span class="cx"> 
</span><span class="cx">     const IDBKeyData&amp; currentKey() const { return m_currentKey; }
</span><span class="cx">     const IDBKeyData&amp; currentPrimaryKey() const { return m_currentPrimaryKey; }
</span><span class="lines">@@ -81,6 +82,8 @@
</span><span class="cx"> 
</span><span class="cx">     void resetAndRebindStatement();
</span><span class="cx"> 
</span><ins>+    void markAsErrored();
+
</ins><span class="cx">     enum class AdvanceResult {
</span><span class="cx">         Success,
</span><span class="cx">         Failure,
</span><span class="lines">@@ -114,6 +117,7 @@
</span><span class="cx">     bool m_errored { false };
</span><span class="cx"> 
</span><span class="cx">     bool m_backingStoreCursor { false };
</span><ins>+    int64_t m_currentRecordRowID { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace IDBServer
</span></span></pre></div>
<a id="tagsSafari603116ToolsChangeLog"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Tools/ChangeLog (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Tools/ChangeLog        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Tools/ChangeLog        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-12-14  Babak Shafiei  &lt;bshafiei@apple.com&gt;
+
+        Merge r209824.
+
+    2016-12-14  Brady Eidson  &lt;beidson@apple.com&gt;
+
+            IndexedDB 2.0: Massively speedup IDBIndex.get().
+            https://bugs.webkit.org/show_bug.cgi?id=165802
+
+            Reviewed by Alex Christensen.
+
+            * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+            * TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.html: Added.
+            * TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.mm: Added.
+            * TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.blob: Added.
+            * TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.sqlite3: Added.
+
</ins><span class="cx"> 2016-12-14  Carlos Alberto Lopez Perez  &lt;clopez@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Yasm is needed for building the JHBuild after r208940
</span></span></pre></div>
<a id="tagsSafari603116ToolsTestWebKitAPITestWebKitAPIxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: tags/Safari-603.1.16/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (209828 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-12-14 21:14:25 UTC (rev 209828)
+++ tags/Safari-603.1.16/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -119,6 +119,10 @@
</span><span class="cx">                 510477741D298DDD009747EB /* IDBDeleteRecovery.sqlite3-wal in Copy Resources */ = {isa = PBXBuildFile; fileRef = 510477711D298D85009747EB /* IDBDeleteRecovery.sqlite3-wal */; };
</span><span class="cx">                 510477771D298E72009747EB /* IDBDeleteRecovery.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 510477761D298E57009747EB /* IDBDeleteRecovery.html */; };
</span><span class="cx">                 510477781D29923B009747EB /* IDBDeleteRecovery.mm in Sources */ = {isa = PBXBuildFile; fileRef = 510477751D298E03009747EB /* IDBDeleteRecovery.mm */; };
</span><ins>+                5110FCF11E01CD64006F8D0B /* IDBIndexUpgradeToV2.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5110FCF01E01CD53006F8D0B /* IDBIndexUpgradeToV2.html */; };
+                5110FCF61E01CD83006F8D0B /* IndexUpgrade.sqlite3 in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5110FCF31E01CD77006F8D0B /* IndexUpgrade.sqlite3 */; };
+                5110FCF91E01CD8A006F8D0B /* IndexUpgrade.blob in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5110FCF21E01CD77006F8D0B /* IndexUpgrade.blob */; };
+                5110FCFA1E01CDB8006F8D0B /* IDBIndexUpgradeToV2.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5110FCEF1E01CBAA006F8D0B /* IDBIndexUpgradeToV2.mm */; };
</ins><span class="cx">                 51393E221523952D005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 51393E1D1523944A005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp */; };
</span><span class="cx">                 5142B2731517C8C800C32B19 /* ContextMenuCanCopyURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 5142B2721517C89100C32B19 /* ContextMenuCanCopyURL.html */; };
</span><span class="cx">                 515BE16F1D428BB100DD7C68 /* StoreBlobToBeDeleted.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 515BE16E1D4288FF00DD7C68 /* StoreBlobToBeDeleted.html */; };
</span><span class="lines">@@ -588,6 +592,9 @@
</span><span class="cx">                         dstPath = TestWebKitAPI.resources;
</span><span class="cx">                         dstSubfolderSpec = 7;
</span><span class="cx">                         files = (
</span><ins>+                                5110FCF91E01CD8A006F8D0B /* IndexUpgrade.blob in Copy Resources */,
+                                5110FCF61E01CD83006F8D0B /* IndexUpgrade.sqlite3 in Copy Resources */,
+                                5110FCF11E01CD64006F8D0B /* IDBIndexUpgradeToV2.html in Copy Resources */,
</ins><span class="cx">                                 5C9E56871DF914AE00C9EE33 /* contentBlockerCheck.html in Copy Resources */,
</span><span class="cx">                                 07492B3C1DF8B86600633DE1 /* enumerateMediaDevices.html in Copy Resources */,
</span><span class="cx">                                 9B270FEE1DDC2C0B002D53F3 /* closed-shadow-tree-test.html in Copy Resources */,
</span><span class="lines">@@ -917,6 +924,10 @@
</span><span class="cx">                 510477711D298D85009747EB /* IDBDeleteRecovery.sqlite3-wal */ = {isa = PBXFileReference; lastKnownFileType = file; path = &quot;IDBDeleteRecovery.sqlite3-wal&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 510477751D298E03009747EB /* IDBDeleteRecovery.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IDBDeleteRecovery.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 510477761D298E57009747EB /* IDBDeleteRecovery.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IDBDeleteRecovery.html; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                5110FCEF1E01CBAA006F8D0B /* IDBIndexUpgradeToV2.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = IDBIndexUpgradeToV2.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5110FCF01E01CD53006F8D0B /* IDBIndexUpgradeToV2.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = IDBIndexUpgradeToV2.html; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5110FCF21E01CD77006F8D0B /* IndexUpgrade.blob */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = IndexUpgrade.blob; sourceTree = &quot;&lt;group&gt;&quot;; };
+                5110FCF31E01CD77006F8D0B /* IndexUpgrade.sqlite3 */ = {isa = PBXFileReference; lastKnownFileType = file; path = IndexUpgrade.sqlite3; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 51393E1D1523944A005F39C5 /* DOMWindowExtensionBasic_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMWindowExtensionBasic_Bundle.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 51393E1E1523944A005F39C5 /* DOMWindowExtensionBasic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMWindowExtensionBasic.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5142B2701517C88B00C32B19 /* ContextMenuCanCopyURL.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContextMenuCanCopyURL.mm; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1451,6 +1462,7 @@
</span><span class="cx">                                 3F1B52681D3D7129008D60C4 /* FullscreenLayoutConstraints.mm */,
</span><span class="cx">                                 CDE195B31CFE0ADE0053D256 /* FullscreenTopContentInset.mm */,
</span><span class="cx">                                 510477751D298E03009747EB /* IDBDeleteRecovery.mm */,
</span><ins>+                                5110FCEF1E01CBAA006F8D0B /* IDBIndexUpgradeToV2.mm */,
</ins><span class="cx">                                 51A587841D272EF3004BA9AF /* IndexedDBDatabaseProcessKill.mm */,
</span><span class="cx">                                 51BCEE491C84F4AF0042C82E /* IndexedDBMultiProcess.mm */,
</span><span class="cx">                                 51B1EE8D1C80F5880064FB98 /* IndexedDBPersistence.mm */,
</span><span class="lines">@@ -1618,6 +1630,9 @@
</span><span class="cx">                                 5104776F1D298D85009747EB /* IDBDeleteRecovery.sqlite3 */,
</span><span class="cx">                                 510477701D298D85009747EB /* IDBDeleteRecovery.sqlite3-shm */,
</span><span class="cx">                                 510477711D298D85009747EB /* IDBDeleteRecovery.sqlite3-wal */,
</span><ins>+                                5110FCF01E01CD53006F8D0B /* IDBIndexUpgradeToV2.html */,
+                                5110FCF21E01CD77006F8D0B /* IndexUpgrade.blob */,
+                                5110FCF31E01CD77006F8D0B /* IndexUpgrade.sqlite3 */,
</ins><span class="cx">                                 51A587821D272EB5004BA9AF /* IndexedDBDatabaseProcessKill-1.html */,
</span><span class="cx">                                 51BCEE4C1C84F52C0042C82E /* IndexedDBMultiProcess-1.html */,
</span><span class="cx">                                 51BCEE4D1C84F52C0042C82E /* IndexedDBMultiProcess-2.html */,
</span><span class="lines">@@ -2651,6 +2666,7 @@
</span><span class="cx">                                 7CCE7F211A411AE600447C4C /* WKPreferences.cpp in Sources */,
</span><span class="cx">                                 7C83E0B51D0A649300FEBCF3 /* WKRetainPtr.cpp in Sources */,
</span><span class="cx">                                 9C64DC321D76198A004B598E /* YouTubePluginReplacement.cpp in Sources */,
</span><ins>+                                5110FCFA1E01CDB8006F8D0B /* IDBIndexUpgradeToV2.mm in Sources */,
</ins><span class="cx">                                 5E4B1D2E1D404C6100053621 /* WKScrollViewDelegateCrash.mm in Sources */,
</span><span class="cx">                                 7CCE7F221A411AE600447C4C /* WKString.cpp in Sources */,
</span><span class="cx">                                 7CCE7F1E1A411AE600447C4C /* WKStringJSString.cpp in Sources */,
</span></span></pre></div>
<a id="tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIDBIndexUpgradeToV2htmlfromrev209824trunkToolsTestWebKitAPITestsWebKit2CocoaIDBIndexUpgradeToV2html"></a>
<div class="copfile"><h4>Copied: tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.html (from rev 209824, trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.html) (0 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.html                                (rev 0)
+++ tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.html        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+&lt;script&gt;
+
+var databaseName = &quot;index-upgrade-test&quot;;
+var openRequest = indexedDB.open(databaseName);
+var db;
+openRequest.onupgradeneeded = function(event) {
+    window.webkit.messageHandlers.testHandler.postMessage('Unexpected upgrade needed');
+}
+
+openRequest.onsuccess = function(event) {
+    var req = event.target.result.transaction('store').objectStore('store').index('index').get(&quot;indexkey!&quot;);
+    
+    req.onsuccess = function (event) {
+        window.webkit.messageHandlers.testHandler.postMessage(&quot;Object expected to be a blob: &quot; +  event.target.result.test);
+    }
+    req.onerror = function (event) {
+        window.webkit.messageHandlers.testHandler.postMessage(&quot;Unexpected get error&quot;);
+    }
+}
+
+&lt;/script&gt;
</ins></span></pre></div>
<a id="tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIDBIndexUpgradeToV2mmfromrev209824trunkToolsTestWebKitAPITestsWebKit2CocoaIDBIndexUpgradeToV2mm"></a>
<div class="copfile"><h4>Copied: tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.mm (from rev 209824, trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.mm) (0 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.mm                                (rev 0)
+++ tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IDBIndexUpgradeToV2.mm        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -0,0 +1,85 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#import &quot;config.h&quot;
+
+#import &quot;PlatformUtilities.h&quot;
+#import &quot;Test.h&quot;
+#import &lt;WebKit/WKProcessPoolPrivate.h&gt;
+#import &lt;WebKit/WKUserContentControllerPrivate.h&gt;
+#import &lt;WebKit/WKWebViewConfigurationPrivate.h&gt;
+#import &lt;WebKit/WebKit.h&gt;
+#import &lt;WebKit/_WKProcessPoolConfiguration.h&gt;
+#import &lt;WebKit/_WKUserStyleSheet.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+#if WK_API_ENABLED
+
+static bool receivedScriptMessage;
+static RetainPtr&lt;WKScriptMessage&gt; lastScriptMessage;
+
+@interface IDBIndexUpgradeToV2MessageHandler : NSObject &lt;WKScriptMessageHandler&gt;
+@end
+
+@implementation IDBIndexUpgradeToV2MessageHandler
+
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    receivedScriptMessage = true;
+    lastScriptMessage = message;
+}
+
+@end
+
+TEST(IndexedDB, IndexUpgradeToV2)
+{
+    RetainPtr&lt;IDBIndexUpgradeToV2MessageHandler&gt; handler = adoptNS([[IDBIndexUpgradeToV2MessageHandler alloc] init]);
+    RetainPtr&lt;WKWebViewConfiguration&gt; configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:handler.get() name:@&quot;testHandler&quot;];
+
+    [configuration.get().processPool _terminateDatabaseProcess];
+
+    // Copy the inconsistent database files to the database directory
+    NSURL *url1 = [[NSBundle mainBundle] URLForResource:@&quot;IndexUpgrade&quot; withExtension:@&quot;sqlite3&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;];
+    NSURL *url2 = [[NSBundle mainBundle] URLForResource:@&quot;IndexUpgrade&quot; withExtension:@&quot;blob&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;];
+
+    NSURL *targetURL = [NSURL fileURLWithPath:[@&quot;~/Library/WebKit/TestWebKitAPI/WebsiteData/IndexedDB/file__0/index-upgrade-test&quot; stringByExpandingTildeInPath]];
+    [[NSFileManager defaultManager] removeItemAtURL:targetURL error:nil];
+    [[NSFileManager defaultManager] createDirectoryAtURL:targetURL withIntermediateDirectories:YES attributes:nil error:nil];
+
+    [[NSFileManager defaultManager] copyItemAtURL:url1 toURL:[targetURL URLByAppendingPathComponent:@&quot;IndexedDB.sqlite3&quot;] error:nil];
+    [[NSFileManager defaultManager] copyItemAtURL:url2 toURL:[targetURL URLByAppendingPathComponent:@&quot;1.blob&quot;] error:nil];
+
+    RetainPtr&lt;WKWebView&gt; webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@&quot;IDBIndexUpgradeToV2&quot; withExtension:@&quot;html&quot; subdirectory:@&quot;TestWebKitAPI.resources&quot;]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&amp;receivedScriptMessage);
+
+    EXPECT_WK_STREQ(@&quot;Object expected to be a blob: [object Blob]&quot;, [lastScriptMessage body]);
+}
+
+#endif
</ins></span></pre></div>
<a id="tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIndexUpgradeblobfromrev209824trunkToolsTestWebKitAPITestsWebKit2CocoaIndexUpgradeblob"></a>
<div class="copfile"><h4>Copied: tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.blob (from rev 209824, trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.blob) (0 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.blob                                (rev 0)
+++ tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.blob        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -0,0 +1 @@
</span><ins>+fun times all around!
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="tagsSafari603116ToolsTestWebKitAPITestsWebKit2CocoaIndexUpgradesqlite3fromrev209824trunkToolsTestWebKitAPITestsWebKit2CocoaIndexUpgradesqlite3"></a>
<div class="copfile"><h4>Copied: tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.sqlite3 (from rev 209824, trunk/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.sqlite3) (0 => 209829)</h4>
<pre class="diff"><span>
<span class="info">--- tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.sqlite3                                (rev 0)
+++ tags/Safari-603.1.16/Tools/TestWebKitAPI/Tests/WebKit2Cocoa/IndexUpgrade.sqlite3        2016-12-14 21:18:02 UTC (rev 209829)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+SQLite format 3@          -\xFDp++!*\xC8+\xC2+)  \xEE \xBB  \xC2        A
+\xD3
+\x94
+\xCF
 \x81&lt;''\x827tableKeyGeneratorsKeyGeneratorsCREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL)9M'indexsqlite_autoindex_KeyGenerators_1KeyGenerators\x824+\x847tableIndexInfoIndexInfoC
 REATE TABLE IndexInfo (id INTEGER NOT NULL ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, isUnique INTEGER NOT NULL ON CONFLICT FAIL, multiEntry INTEGER NOT NULL ON CONFLICT FAIL)\x82P
+++\x84WtableObjectStoreInfoObjectStoreInfo CREATE TABLE ObjectStoreInfo (id INTEGER PRIMARY KEY NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, name TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, keyPath BLOB NOT NULL ON CONFLICT FAIL, autoInc INTEGER NOT NULL ON CONFLICT FAIL, maxIndexID INTEGER NOT NULL ON CONFLICT FAIL)= Q+indexsqlite_autoindex_ObjectStoreInfo_2ObjectStoreInfo+= Q+indexsqlite_autoindex_ObjectStoreInfo_1ObjectStoreInfo \x81-++\x82tableIDBDatabaseInfoIDBDatabaseInfo        CREATE TABLE IDBDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL)=        Q+indexsqlite_autoindex_IDBDatabaseInfo_1IDBDatabaseInfo
+\x817\x82=tableBlobFilesBlobFilesCREATE TABLE BlobFiles (blobURL TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL, fileName TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT FAIL)1Eindexsqlite_autoindex_BlobFiles_2BlobFiles1Eindexsqlite_autoindex_BlobFiles_1BlobFiles\x81##\x81stableBlobRecordsBlobRecordsCREATE TABLE BlobRecords (objectStoreRow INTEGER NOT NULL ON CONFLICT FAIL, blobURL TEXT NOT NULL ON CONFLICT FAIL)\x82%%\x83ItableIndexRecordsIndexRecordsCREATE TABLE IndexRecords (indexID INTEGER NOT NULL ON CONFLICT FAIL, objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL)`%\x81+indexRecordsIndexRecordsCREATE UNIQUE INDEX RecordsIndex ON Records (objectStoreID, key)\x81S\x82}tableRecordsRecordsCREATE TABLE Records (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, 
 value NOT NULL ON CONFLICT FAIL, recordID INTEGER PRIMARY KEY)+nn
 
 
 
 \x81        !\x82
+ \xF0?\x80test9\x80blob:blobinternal:///07a0a444-9673-4fbd-9175-b8d6630fd053
+\x80text/plain\x80indexKey        \x80indexkey!\xFF\xFF\xFF\xFF
+\xF1\xF1
 
 
 
         !         \xF0?+\xD7\xD7
 
 
 
 '                =!`        indexkey! \xF0?+\xC2\xC2
 
 
 
 &lt;        blob:blobinternal:///07a0a444-9673-4fbd-9175-b8d6630fd053+\xBC\xBC
 
 
 
 Bblob:blobinternal:///07a0a444-9673-4fbd-9175-b8d6630fd0531.blob
+\xC3\xC3
 
 
 
 &lt;        blob:blobinternal:///07a0a444-9673-4fbd-9175-b8d6630fd053
+\xF6\xF6
 
 
 
                 1.blob+\x9D\xEB\xC8\xB3\x9D
 
 
 
 -MaxObjectStoreID1+DatabaseVersion1!%1DatabaseNameindex-upgrade-test+MetadataVersion1
+\xB3\xDC\xC8\xB3\xED
 
 
 
 -MaxObjectStoreID+DatabaseVersion%DatabaseName+        MetadataVersion+\xBE\xBE
 
 
 
 @vstorebplist00\xD1Ttype 
+\xFC\xFC
 
 
 
                 
+\xF7\xF7
 
 
 
         store+\xA8\xA8
 
 
 
 V                \x81indexbplist00\xD2TtypeVstringXindexKey+$+\xFB\xFB
 
 
 
         
+\xFC\xFC
 
 
 
                 
</ins><span class="cx">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>