<!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>[163170] trunk/Source</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/163170">163170</a></dd>
<dt>Author</dt> <dd>beidson@apple.com</dd>
<dt>Date</dt> <dd>2014-01-31 07:55:28 -0800 (Fri, 31 Jan 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>IDB: Index writing
&lt;rdar://problem/15899973&gt; and https://bugs.webkit.org/show_bug.cgi?id=127868

Reviewed by Anders Carlsson.

Source/WebCore:

* Modules/indexeddb/IDBDatabaseBackend.cpp:
(WebCore::IDBDatabaseBackend::openConnectionInternal): Remove outdated comment and ASSERT.

* Modules/indexeddb/IDBObjectStore.cpp:
(WebCore::IDBObjectStore::createIndex): Conditionalize a block of code that is LevelDB-only.

Remove getColumnBlob().  Nobody used it, and it was dangerous because it reset the statement:
* platform/sql/SQLiteStatement.cpp:
* platform/sql/SQLiteStatement.h:
* WebCore.exp.in:

Source/WebKit2:

* DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
(WebKit::UniqueIDBDatabase::putRecordInBackingStore): Handle writing index records, as well.

* DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a table
  for index records
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::extractExistingMetadata): Extract IDBIndexMetadata
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex):
(WebKit::UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord): Store in the IndexRecords table.
* DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBDatabaseBackendcpp">trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbIDBObjectStorecpp">trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteStatementcpp">trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformsqlSQLiteStatementh">trunk/Source/WebCore/platform/sql/SQLiteStatement.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBUniqueIDBDatabasecpp">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBUniqueIDBDatabaseBackingStoreh">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBsqliteUniqueIDBDatabaseBackingStoreSQLitecpp">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp</a></li>
<li><a href="#trunkSourceWebKit2DatabaseProcessIndexedDBsqliteUniqueIDBDatabaseBackingStoreSQLiteh">trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/ChangeLog        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2014-01-31  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        IDB: Index writing
+        &lt;rdar://problem/15899973&gt; and https://bugs.webkit.org/show_bug.cgi?id=127868
+
+        Reviewed by Anders Carlsson.
+
+        * Modules/indexeddb/IDBDatabaseBackend.cpp:
+        (WebCore::IDBDatabaseBackend::openConnectionInternal): Remove outdated comment and ASSERT.
+
+        * Modules/indexeddb/IDBObjectStore.cpp:
+        (WebCore::IDBObjectStore::createIndex): Conditionalize a block of code that is LevelDB-only.
+
+        Remove getColumnBlob().  Nobody used it, and it was dangerous because it reset the statement:
+        * platform/sql/SQLiteStatement.cpp:
+        * platform/sql/SQLiteStatement.h:
+        * WebCore.exp.in:
+
</ins><span class="cx"> 2014-01-30  László Langó  &lt;lango@inf.u-szeged.hu&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Grid Layout] Do log(n) search in the named line vectors when positioning named line spans.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBDatabaseBackendcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBDatabaseBackend.cpp        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -467,9 +467,6 @@
</span><span class="cx">     bool isNewDatabase = m_metadata.version == IDBDatabaseMetadata::NoIntVersion;
</span><span class="cx"> 
</span><span class="cx">     if (version == IDBDatabaseMetadata::DefaultIntVersion) {
</span><del>-        // FIXME: this comments was related to Chromium code. It may be incorrect
-        // For unit tests only - skip upgrade steps. Calling from script with DefaultIntVersion throws exception.
-        ASSERT(isNewDatabase);
</del><span class="cx">         m_databaseCallbacksSet.add(databaseCallbacks);
</span><span class="cx">         callbacks-&gt;onSuccess(this, this-&gt;metadata());
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbIDBObjectStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStore.cpp        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -415,6 +415,7 @@
</span><span class="cx">     if (ec)
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><ins>+#if USE(LEVELDB)
</ins><span class="cx">     RefPtr&lt;IDBRequest&gt; indexRequest = openCursor(context, static_cast&lt;IDBKeyRange*&gt;(0), IDBCursor::directionNext(), IDBDatabaseBackend::PreemptiveTask, ec);
</span><span class="cx">     ASSERT(!ec);
</span><span class="cx">     if (ec)
</span><span class="lines">@@ -424,6 +425,9 @@
</span><span class="cx">     // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
</span><span class="cx">     RefPtr&lt;IndexPopulator&gt; indexPopulator = IndexPopulator::create(backendDB(), m_transaction-&gt;id(), id(), metadata);
</span><span class="cx">     indexRequest-&gt;setOnsuccess(indexPopulator);
</span><ins>+#else
+    ASSERT_UNUSED(context, context);
+#endif
</ins><span class="cx"> 
</span><span class="cx">     return index.release();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -82,7 +82,6 @@
</span><span class="cx"> __ZN7WebCore10Pasteboard14writePlainTextERKN3WTF6StringENS0_18SmartReplaceOptionE
</span><span class="cx"> __ZN7WebCore10RenderView10compositorEv
</span><span class="cx"> __ZN7WebCore10RenderView7hitTestERKNS_14HitTestRequestERNS_13HitTestResultE
</span><del>-__ZN7WebCore15SQLiteStatement13getColumnBlobEiRi
</del><span class="cx"> __ZN7WebCore15SQLiteStatement14getColumnInt64Ei
</span><span class="cx"> __ZN7WebCore15SQLiteStatement21getColumnBlobAsVectorEiRN3WTF6VectorIcLm0ENS1_15CrashOnOverflowEEE
</span><span class="cx"> __ZN7WebCore10ScrollView16setParentVisibleEb
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteStatementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/platform/sql/SQLiteStatement.cpp        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -428,34 +428,6 @@
</span><span class="cx">         result[i] = (static_cast&lt;const unsigned char*&gt;(blob))[i];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const void* SQLiteStatement::getColumnBlob(int col, int&amp; size)
-{
-    ASSERT(col &gt;= 0);
-
-    size = 0;
-
-    if (finalize() != SQLITE_OK)
-        LOG(SQLDatabase, &quot;Finalize failed&quot;);
-    if (prepare() != SQLITE_OK) {
-        LOG(SQLDatabase, &quot;Prepare failed&quot;);
-        return 0;
-    }
-    if (step() != SQLITE_ROW) {
-        LOG(SQLDatabase, &quot;Step wasn't a row&quot;);
-        return 0;
-    }
-
-    if (columnCount() &lt;= col)
-        return 0;
-        
-    const void* blob = sqlite3_column_blob(m_statement, col);
-    if (!blob)
-        return 0;
-
-    size = sqlite3_column_bytes(m_statement, col);
-    return blob;
-}
-
</del><span class="cx"> bool SQLiteStatement::returnTextResults(int col, Vector&lt;String&gt;&amp; v)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(col &gt;= 0);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsqlSQLiteStatementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/sql/SQLiteStatement.h (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/sql/SQLiteStatement.h        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebCore/platform/sql/SQLiteStatement.h        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -81,7 +81,6 @@
</span><span class="cx">     double getColumnDouble(int col);
</span><span class="cx">     int getColumnInt(int col);
</span><span class="cx">     int64_t getColumnInt64(int col);
</span><del>-    const void* getColumnBlob(int col, int&amp; size);
</del><span class="cx">     String getColumnBlobAsString(int col);
</span><span class="cx">     void getColumnBlobAsVector(int col, Vector&lt;char&gt;&amp;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/ChangeLog        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2014-01-31  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        IDB: Index writing
+        &lt;rdar://problem/15899973&gt; and https://bugs.webkit.org/show_bug.cgi?id=127868
+
+        Reviewed by Anders Carlsson.
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp:
+        (WebKit::UniqueIDBDatabase::putRecordInBackingStore): Handle writing index records, as well.
+
+        * DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h:
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp:
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::createAndPopulateInitialMetadata): Create a table
+          for index records
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::extractExistingMetadata): Extract IDBIndexMetadata
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteObjectStore):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::deleteIndex):
+        (WebKit::UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord): Store in the IndexRecords table.
+        * DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h:
+
</ins><span class="cx"> 2014-01-30  Jinwoo Song  &lt;jinwoo7.song@samsung.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [EFL][WK2] Unreviewed EFL WebKit2 build fix after r163116.
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBUniqueIDBDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabase.cpp        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -800,14 +800,20 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: The LevelDB port performs &quot;makeIndexWriters&quot; here. Necessary?
-
</del><span class="cx">     if (!m_backingStore-&gt;putRecord(transaction, objectStoreMetadata.id, *key, value.data(), value.size())) {
</span><span class="cx">         postMainThreadTask(createAsyncTask(*this, &amp;UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Internal backing store error putting a record&quot;)));
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: The LevelDB port updates index keys here. Necessary?
</del><ins>+    ASSERT(indexIDs.size() == indexKeys.size());
+    for (size_t i = 0; i &lt; indexIDs.size(); ++i) {
+        for (size_t j = 0; j &lt; indexKeys[i].size(); ++j) {
+            if (!m_backingStore-&gt;putIndexRecord(transaction, objectStoreMetadata.id, indexIDs[i], keyData, indexKeys[i][j])) {
+                postMainThreadTask(createAsyncTask(*this, &amp;UniqueIDBDatabase::didPutRecordInBackingStore, requestID, IDBKeyData(), IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Internal backing store error writing index key&quot;)));
+                return;
+            }
+        }
+    }
</ins><span class="cx"> 
</span><span class="cx">     if (putMode != IDBDatabaseBackend::CursorUpdate &amp;&amp; objectStoreMetadata.autoIncrement &amp;&amp; key-&gt;type() == IDBKey::NumberType) {
</span><span class="cx">         if (!m_backingStore-&gt;updateKeyGeneratorNumber(transaction, objectStoreMetadata.id, keyNumber, keyWasGenerated)) {
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBUniqueIDBDatabaseBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/UniqueIDBDatabaseBackingStore.h        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -68,6 +68,7 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool keyExistsInObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&amp;, bool&amp; keyExists) = 0;
</span><span class="cx">     virtual bool putRecord(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&amp;, const uint8_t* valueBuffer, size_t valueSize) = 0;
</span><ins>+    virtual bool putIndexRecord(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData&amp;, const WebCore::IDBKeyData&amp; indexKey) = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual bool getKeyRecordFromObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&amp;, RefPtr&lt;WebCore::SharedBuffer&gt;&amp; result) = 0;
</span><span class="cx">     virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&amp;, RefPtr&lt;WebCore::SharedBuffer&gt;&amp; result, RefPtr&lt;WebCore::IDBKey&gt;&amp; resultKey) = 0;
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBsqliteUniqueIDBDatabaseBackingStoreSQLitecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.cpp        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -99,6 +99,12 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (!m_sqliteDB-&gt;executeCommand(&quot;CREATE 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 UNIQUE ON CONFLICT REPLACE, value NOT NULL ON CONFLICT FAIL);&quot;)) {
+        LOG_ERROR(&quot;Could not create Records table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
</ins><span class="cx">     if (!m_sqliteDB-&gt;executeCommand(&quot;CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);&quot;)) {
</span><span class="cx">         LOG_ERROR(&quot;Could not create KeyGenerators table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</span><span class="cx">         m_sqliteDB = nullptr;
</span><span class="lines">@@ -202,11 +208,10 @@
</span><span class="cx">             osMetadata.id = sql.getColumnInt64(0);
</span><span class="cx">             osMetadata.name = sql.getColumnText(1);
</span><span class="cx"> 
</span><del>-            int keyPathSize;
-            const uint8_t* keyPathBuffer = static_cast&lt;const uint8_t*&gt;(sql.getColumnBlob(2, keyPathSize));
</del><ins>+            Vector&lt;char&gt; keyPathBuffer;
+            sql.getColumnBlobAsVector(2, keyPathBuffer);
</ins><span class="cx"> 
</span><del>-
-            if (!deserializeIDBKeyPath(keyPathBuffer, keyPathSize, osMetadata.keyPath)) {
</del><ins>+            if (!deserializeIDBKeyPath(reinterpret_cast&lt;const uint8_t*&gt;(keyPathBuffer.data()), keyPathBuffer.size(), osMetadata.keyPath)) {
</ins><span class="cx">                 LOG_ERROR(&quot;Unable to extract key path metadata from database&quot;);
</span><span class="cx">                 return nullptr;
</span><span class="cx">             }
</span><span class="lines">@@ -224,8 +229,47 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME: Once we save indexes we need to extract their metadata, also.
</del><ins>+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;&quot;));
+        if (sql.prepare() != SQLResultOk)
+            return nullptr;
</ins><span class="cx"> 
</span><ins>+        int result = sql.step();
+        while (result == SQLResultRow) {
+            IDBIndexMetadata indexMetadata;
+
+            indexMetadata.id = sql.getColumnInt64(0);
+            indexMetadata.name = sql.getColumnText(1);
+            int64_t objectStoreID = sql.getColumnInt64(2);
+
+            Vector&lt;char&gt; keyPathBuffer;
+            sql.getColumnBlobAsVector(3, keyPathBuffer);
+
+            if (!deserializeIDBKeyPath(reinterpret_cast&lt;const uint8_t*&gt;(keyPathBuffer.data()), keyPathBuffer.size(), indexMetadata.keyPath)) {
+                LOG_ERROR(&quot;Unable to extract key path metadata from database&quot;);
+                return nullptr;
+            }
+
+            indexMetadata.unique = sql.getColumnInt(4);
+            indexMetadata.multiEntry = sql.getColumnInt(5);
+
+            auto objectStoreMetadataIt = metadata-&gt;objectStores.find(objectStoreID);
+            if (objectStoreMetadataIt == metadata-&gt;objectStores.end()) {
+                LOG_ERROR(&quot;Found index referring to a non-existant object store&quot;);
+                return nullptr;
+            }
+
+            objectStoreMetadataIt-&gt;value.indexes.set(indexMetadata.id, indexMetadata);
+
+            result = sql.step();
+        }
+
+        if (result != SQLResultDone) {
+            LOG_ERROR(&quot;Error fetching index metadata from database on disk&quot;);
+            return nullptr;
+        }
+    }
+
</ins><span class="cx">     return metadata;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -452,33 +496,37 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Delete all associated Index records
</del><ins>+    // Delete all associated records
</ins><span class="cx">     {
</span><del>-        Vector&lt;int64_t&gt; indexIDs;
-        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT id FROM IndexInfo WHERE objectStoreID = ?;&quot;));
</del><ins>+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;DELETE FROM Records WHERE objectStoreID = ?;&quot;));
</ins><span class="cx">         if (sql.prepare() != SQLResultOk
</span><del>-            || sql.bindInt64(1, objectStoreID) != SQLResultOk) {
-            LOG_ERROR(&quot;Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s&quot;, objectStoreID, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</del><ins>+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR(&quot;Could not delete records for object store %lli (%i) - %s&quot;, objectStoreID, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</ins><span class="cx">             return false;
</span><span class="cx">         }
</span><ins>+    }
</ins><span class="cx"> 
</span><del>-        int resultCode;
-        while ((resultCode = sql.step()) == SQLResultRow)
-            indexIDs.append(sql.getColumnInt64(0));
-
-        if (resultCode != SQLResultDone) {
-            LOG_ERROR(&quot;Error fetching index ID records for object store id %lli from IndexInfo table (%i) - %s&quot;, objectStoreID, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</del><ins>+    // Delete all associated Indexes
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;DELETE FROM IndexInfo WHERE objectStoreID = ?;&quot;));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR(&quot;Could not delete index from IndexInfo table (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
</ins><span class="cx">             return false;
</span><span class="cx">         }
</span><del>-
-        for (auto indexID : indexIDs) {
-            if (!deleteIndex(transactionIdentifier, objectStoreID, indexID))
-                return false;
-        }
</del><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Delete all associated Index records
</ins><span class="cx">     {
</span><del>-        // FIXME: Execute SQL here to drop all records related to this object store.
</del><ins>+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;DELETE FROM IndexRecords WHERE objectStoreID = ?;&quot;));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR(&quot;Could not delete index records(%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return false;
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="lines">@@ -579,7 +627,17 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME (&lt;rdar://problem/15905293&gt;) - Once we store records against indexes, delete them here.
</del><ins>+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;DELETE FROM IndexRecords WHERE indexID = ? AND objectStoreID = ?;&quot;));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, indexID) != SQLResultOk
+            || sql.bindInt64(2, objectStoreID) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR(&quot;Could not delete index records for index id %lli from IndexRecords table (%i) - %s&quot;, indexID, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return false;
+        }
+    }
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -698,6 +756,49 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool UniqueIDBDatabaseBackingStoreSQLite::putIndexRecord(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, int64_t indexID, const IDBKeyData&amp; keyValue, const IDBKeyData&amp; indexKey)
+{
+    ASSERT(!isMainThread());
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB-&gt;isOpen());
+
+    SQLiteIDBTransaction* transaction = m_transactions.get(transactionIdentifier);
+    if (!transaction || !transaction-&gt;inProgress()) {
+        LOG_ERROR(&quot;Attempt to put index record into database without an established, in-progress transaction&quot;);
+        return false;
+    }
+    if (transaction-&gt;mode() == IndexedDB::TransactionMode::ReadOnly) {
+        LOG_ERROR(&quot;Attempt to put index record into database during read-only transaction&quot;);
+        return false;
+    }
+
+    RefPtr&lt;SharedBuffer&gt; indexKeyBuffer = serializeIDBKeyData(indexKey);
+    if (!indexKeyBuffer) {
+        LOG_ERROR(&quot;Unable to serialize index key to be stored in the database&quot;);
+        return false;
+    }
+
+    RefPtr&lt;SharedBuffer&gt; valueBuffer = serializeIDBKeyData(keyValue);
+    if (!valueBuffer) {
+        LOG_ERROR(&quot;Unable to serialize the value to be stored in the database&quot;);
+        return false;
+    }
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), ?);&quot;));
+        if (sql.prepare() != SQLResultOk
+            || sql.bindInt64(1, indexID) != SQLResultOk
+            || sql.bindInt64(2, objectStoreID) != SQLResultOk
+            || sql.bindBlob(3, indexKeyBuffer-&gt;data(), indexKeyBuffer-&gt;size()) != SQLResultOk
+            || sql.bindBlob(4, valueBuffer-&gt;data(), valueBuffer-&gt;size()) != SQLResultOk
+            || sql.step() != SQLResultDone) {
+            LOG_ERROR(&quot;Could not put index record for index %lli in object store %lli in Records table (%i) - %s&quot;, indexID, objectStoreID, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            return false;
+        }
+    }
+
+    return true;
+}
+
</ins><span class="cx"> bool UniqueIDBDatabaseBackingStoreSQLite::getKeyRecordFromObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const IDBKey&amp; key, RefPtr&lt;SharedBuffer&gt;&amp; result)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isMainThread());
</span></span></pre></div>
<a id="trunkSourceWebKit2DatabaseProcessIndexedDBsqliteUniqueIDBDatabaseBackingStoreSQLiteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h (163169 => 163170)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h        2014-01-31 15:11:05 UTC (rev 163169)
+++ trunk/Source/WebKit2/DatabaseProcess/IndexedDB/sqlite/UniqueIDBDatabaseBackingStoreSQLite.h        2014-01-31 15:55:28 UTC (rev 163170)
</span><span class="lines">@@ -73,7 +73,9 @@
</span><span class="cx"> 
</span><span class="cx">     virtual bool keyExistsInObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&amp;, bool&amp; keyExists) override;
</span><span class="cx">     virtual bool putRecord(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&amp;, const uint8_t* valueBuffer, size_t valueSize) override;
</span><ins>+    virtual bool putIndexRecord(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData&amp; keyValue, const WebCore::IDBKeyData&amp; indexKey) override;
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">     virtual bool getKeyRecordFromObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKey&amp;, RefPtr&lt;WebCore::SharedBuffer&gt;&amp; result) override;
</span><span class="cx">     virtual bool getKeyRangeRecordFromObjectStore(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, const WebCore::IDBKeyRange&amp;, RefPtr&lt;WebCore::SharedBuffer&gt;&amp; result, RefPtr&lt;WebCore::IDBKey&gt;&amp; resultKey) override;
</span><span class="cx">     virtual bool count(const IDBIdentifier&amp; transactionIdentifier, int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyRangeData&amp;, int64_t&amp; count) override;
</span></span></pre>
</div>
</div>

</body>
</html>