<!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>[195443] trunk</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>Modern IDB: Support populating/extracting database metadata with SQLite backend.
Source/WebCore:

Nhttps://bugs.webkit.org/show_bug.cgi?id=153318

Reviewed by Alex Christensen.

No new tests (Covered by current tests).

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* Modules/indexeddb/client/IDBDatabaseImpl.cpp:
(WebCore::IDBClient::IDBDatabase::willAbortTransaction): Committing transactions can abort if the commit
  ends in error.

* Modules/indexeddb/client/IDBTransactionImpl.cpp:
(WebCore::IDBClient::IDBTransaction::didCommit): Before a committing transaction is aborted, notify the
  IDBDatabase that it aborted.

Copied over from WK2:
* Modules/indexeddb/server/IDBSerialization.cpp: Added.
(WebCore::serializeIDBKeyPath):
(WebCore::deserializeIDBKeyPath):
(WebCore::serializeIDBKeyData):
(WebCore::deserializeIDBKeyData):
* Modules/indexeddb/server/IDBSerialization.h: Added.

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::createBackingStore): Optionally create a SQLite backing store.

Mostly copied over verbatim from WebKit2's UniqueIDBDatabaseBackingStoreSQLite.cpp:
* Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
(WebCore::IDBServer::idbKeyCollate):
(WebCore::IDBServer::v1RecordsTableSchema):
(WebCore::IDBServer::v1RecordsTableSchemaAlternate):
(WebCore::IDBServer::v2RecordsTableSchema):
(WebCore::IDBServer::v2RecordsTableSchemaAlternate):
(WebCore::IDBServer::createOrMigrateRecordsTableIfNecessary):
(WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidRecordsTable):
(WebCore::IDBServer::SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo):
(WebCore::IDBServer::SQLiteIDBBackingStore::extractExistingDatabaseInfo):
(WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo):
(WebCore::IDBServer::SQLiteIDBBackingStore::beginTransaction):
(WebCore::IDBServer::SQLiteIDBBackingStore::abortTransaction):
(WebCore::IDBServer::SQLiteIDBBackingStore::commitTransaction):
(WebCore::IDBServer::SQLiteIDBBackingStore::createObjectStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::unregisterCursor):
* Modules/indexeddb/server/SQLiteIDBBackingStore.h:

Copied over from WK2:
* Modules/indexeddb/server/SQLiteIDBCursor.cpp: Added.
(WebCore::IDBServer::SQLiteIDBCursor::maybeCreate):
(WebCore::IDBServer::SQLiteIDBCursor::SQLiteIDBCursor):
(WebCore::IDBServer::buildIndexStatement):
(WebCore::IDBServer::buildObjectStoreStatement):
(WebCore::IDBServer::SQLiteIDBCursor::establishStatement):
(WebCore::IDBServer::SQLiteIDBCursor::createSQLiteStatement):
(WebCore::IDBServer::SQLiteIDBCursor::objectStoreRecordsChanged):
(WebCore::IDBServer::SQLiteIDBCursor::resetAndRebindStatement):
(WebCore::IDBServer::SQLiteIDBCursor::bindArguments):
(WebCore::IDBServer::SQLiteIDBCursor::advance):
(WebCore::IDBServer::SQLiteIDBCursor::advanceUnique):
(WebCore::IDBServer::SQLiteIDBCursor::advanceOnce):
(WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
(WebCore::IDBServer::SQLiteIDBCursor::iterate):
* Modules/indexeddb/server/SQLiteIDBCursor.h: Added.
(WebCore::IDBServer::SQLiteIDBCursor::identifier):
(WebCore::IDBServer::SQLiteIDBCursor::transaction):
(WebCore::IDBServer::SQLiteIDBCursor::objectStoreID):
(WebCore::IDBServer::SQLiteIDBCursor::currentKey):
(WebCore::IDBServer::SQLiteIDBCursor::currentPrimaryKey):
(WebCore::IDBServer::SQLiteIDBCursor::currentValueBuffer):
(WebCore::IDBServer::SQLiteIDBCursor::didError):

Copied over from WK2:
* Modules/indexeddb/server/SQLiteIDBTransaction.cpp: Added.
(WebCore::IDBServer::SQLiteIDBTransaction::SQLiteIDBTransaction):
(WebCore::IDBServer::SQLiteIDBTransaction::~SQLiteIDBTransaction):
(WebCore::IDBServer::SQLiteIDBTransaction::begin):
(WebCore::IDBServer::SQLiteIDBTransaction::commit):
(WebCore::IDBServer::SQLiteIDBTransaction::reset):
(WebCore::IDBServer::SQLiteIDBTransaction::rollback):
(WebCore::IDBServer::SQLiteIDBTransaction::maybeOpenCursor):
(WebCore::IDBServer::SQLiteIDBTransaction::closeCursor):
(WebCore::IDBServer::SQLiteIDBTransaction::notifyCursorsOfChanges):
(WebCore::IDBServer::SQLiteIDBTransaction::clearCursors):
(WebCore::IDBServer::SQLiteIDBTransaction::inProgress):
* Modules/indexeddb/server/SQLiteIDBTransaction.h: Added.
(WebCore::IDBServer::SQLiteIDBTransaction::transactionIdentifier):
(WebCore::IDBServer::SQLiteIDBTransaction::mode):
(WebCore::IDBServer::SQLiteIDBTransaction::sqliteTransaction):

* page/Page.cpp:
(WebCore::Page::setSessionID): If the new SessionID is different from the last one,
  clear the IDBConnectionToServer.
(WebCore::Page::idbConnection): Always ask the DatabaseProvider; It handles whether or not
  the session is ephemeral.

LayoutTests:

https://bugs.webkit.org/show_bug.cgi?id=153318

Reviewed by Alex Christensen.

* platform/mac-wk1/TestExpectations: Skip all of the tests that run against the
  SQLite backend and currently fail (which is most of them!)</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmacwk1TestExpectations">trunk/LayoutTests/platform/mac-wk1/TestExpectations</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBDatabaseImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp">trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCorepagePagecpp">trunk/Source/WebCore/page/Page.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBSerializationcpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBSerializationh">trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorh">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBTransactioncpp">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverSQLiteIDBTransactionh">trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/LayoutTests/ChangeLog        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2016-01-21  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Support populating/extracting database metadata with SQLite backend.
+        https://bugs.webkit.org/show_bug.cgi?id=153318
+
+        Reviewed by Alex Christensen.
+
+        * platform/mac-wk1/TestExpectations: Skip all of the tests that run against the
+          SQLite backend and currently fail (which is most of them!)
+
</ins><span class="cx"> 2016-01-21  Nikita Vasilyev  &lt;nvasilyev@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r195305): Web Inspector: WebInspector.Object can dispatch constructor-level events multiple times
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacwk1TestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac-wk1/TestExpectations        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -243,3 +243,451 @@
</span><span class="cx"> 
</span><span class="cx"> # Lacking WK1 TestRunner API that evaluates JavaScript through JSC APIs and not WebCore APIs
</span><span class="cx"> inspector/script-profiler/event-type-API.html
</span><ins>+
+########################################
+### START OF (3) IndexedDB failures with SQLite
+
+# SQLite backend tests with text failures
+crypto/subtle/rsa-indexeddb-non-exportable.html [ Failure ]
+fast/history/page-cache-indexed-opened-db.html [ Failure ]
+imported/w3c/indexeddb/close-in-upgradeneeded.html [ Failure ]
+imported/w3c/indexeddb/cursor-overloads.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-direction-index-keyrange.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-direction-index.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-direction-objectstore-keyrange.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-direction-objectstore.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-direction.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-key.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-primarykey.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor-reused.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index6.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index7.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index8.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_index9.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_objectstore.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_objectstore2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_objectstore3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_objectstore4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_advance_objectstore5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index6.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index7.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_index8.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_invalid.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_objectstore.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_objectstore2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_objectstore3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_objectstore4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_objectstore5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_continue_objectstore6.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_index.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_index2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_index3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_index4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_index5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_objectstore.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_objectstore2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_objectstore3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_objectstore4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_delete_objectstore5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_iterating.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_iterating_index.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_iterating_index2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_iterating_objectstore.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_iterating_objectstore2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index6.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_index7.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore2.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore3.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore4.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore5.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore6.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore7.htm [ Failure ]
+imported/w3c/indexeddb/idbcursor_update_objectstore8.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_close.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_close2.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore-createIndex-emptyname.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore10-1000ends.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore10-emptyname.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore2.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore3.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_createObjectStore5.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_deleteObjectStore2.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_deleteObjectStore4-not_reused.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_transaction.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_transaction2.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_transaction3.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_transaction4.htm [ Failure ]
+imported/w3c/indexeddb/idbdatabase_transaction5.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_deleteDatabase.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_deleteDatabase2.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_deleteDatabase3.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_deleteDatabase4.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open10.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open11.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open2.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open3.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open4.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open5.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open6.htm [ Failure ]
+imported/w3c/indexeddb/idbfactory_open7.htm [ Failure ]
+imported/w3c/indexeddb/idbindex-multientry.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_count.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_count2.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_count3.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_count4.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_get.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_get2.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_get3.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_get4.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_getKey.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_getKey2.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_getKey3.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_getKey4.htm [ Failure ]
+imported/w3c/indexeddb/idbindex_indexNames.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add14.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add15.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add16.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add3.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add4.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add5.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add6.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add7.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_add8.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_clear.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_clear2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_clear3.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_clear4.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_count.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_count2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_count3.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_count4.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex12.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex13.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex3-usable-right-away.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex4-deleteIndex-event_order.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex5-emptykeypath.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex6-event_order.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex7-event_order.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex8-valid_keys.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_createIndex9-emptyname.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete3.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete4.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete5.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete6.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_delete7.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_deleteIndex.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_deleted.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get3.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get4.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get5.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get6.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_get7.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_index.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_openCursor.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put14.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put15.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put16.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put2.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put3.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put4.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put5.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put6.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put7.htm [ Failure ]
+imported/w3c/indexeddb/idbobjectstore_put8.htm [ Failure ]
+imported/w3c/indexeddb/idbtransaction-oncomplete.htm [ Failure ]
+imported/w3c/indexeddb/idbtransaction_abort.htm [ Failure ]
+imported/w3c/indexeddb/idbversionchangeevent.htm [ Failure ]
+imported/w3c/indexeddb/index_sort_order.htm [ Failure ]
+imported/w3c/indexeddb/key_valid.html [ Failure ]
+imported/w3c/indexeddb/keygenerator-constrainterror.htm [ Failure ]
+imported/w3c/indexeddb/keygenerator-overflow.htm [ Failure ]
+imported/w3c/indexeddb/keygenerator.htm [ Failure ]
+imported/w3c/indexeddb/keyorder.htm [ Failure ]
+imported/w3c/indexeddb/keypath_maxsize.htm [ Failure ]
+imported/w3c/indexeddb/list_ordering.htm [ Failure ]
+imported/w3c/indexeddb/objectstore_keyorder.htm [ Failure ]
+imported/w3c/indexeddb/request_bubble-and-capture.htm [ Failure ]
+imported/w3c/indexeddb/string-list-ordering.htm [ Failure ]
+imported/w3c/indexeddb/transaction-create_in_versionchange.htm [ Failure ]
+imported/w3c/indexeddb/transaction-lifetime-blocked.htm [ Failure ]
+imported/w3c/indexeddb/transaction-lifetime.htm [ Failure ]
+imported/w3c/indexeddb/transaction-requestqueue.htm [ Failure ]
+imported/w3c/indexeddb/transaction_bubble-and-capture.htm [ Failure ]
+imported/w3c/indexeddb/value.htm [ Failure ]
+imported/w3c/indexeddb/value_recursive.htm [ Failure ]
+imported/w3c/indexeddb/writer-starvation.htm [ Failure ]
+storage/indexeddb/aborted-versionchange-closes.html [ Failure ]
+storage/indexeddb/basics.html [ Failure ]
+storage/indexeddb/closed-cursor.html [ Failure ]
+storage/indexeddb/create-and-remove-object-store.html [ Failure ]
+storage/indexeddb/create-object-store-options.html [ Failure ]
+storage/indexeddb/createIndex-after-failure.html [ Failure ]
+storage/indexeddb/cursor-added-bug.html [ Failure ]
+storage/indexeddb/cursor-advance.html [ Failure ]
+storage/indexeddb/cursor-basics.html [ Failure ]
+storage/indexeddb/cursor-cast.html [ Failure ]
+storage/indexeddb/cursor-continue-dir.html [ Failure ]
+storage/indexeddb/cursor-continue-validity.html [ Failure ]
+storage/indexeddb/cursor-continue.html [ Failure ]
+storage/indexeddb/cursor-delete.html [ Failure ]
+storage/indexeddb/cursor-finished.html [ Failure ]
+storage/indexeddb/cursor-inconsistency.html [ Failure ]
+storage/indexeddb/cursor-index-delete.html [ Failure ]
+storage/indexeddb/cursor-key-order.html [ Failure ]
+storage/indexeddb/cursor-overloads.html [ Failure ]
+storage/indexeddb/cursor-prev-no-duplicate.html [ Failure ]
+storage/indexeddb/cursor-primary-key-order.html [ Failure ]
+storage/indexeddb/cursor-properties.html [ Failure ]
+storage/indexeddb/cursor-reverse-bug.html [ Failure ]
+storage/indexeddb/cursor-skip-deleted.html [ Failure ]
+storage/indexeddb/cursor-update-value-argument-required.html [ Failure ]
+storage/indexeddb/cursor-update.html [ Failure ]
+storage/indexeddb/cursor-value.html [ Failure ]
+storage/indexeddb/database-basics.html [ Failure ]
+storage/indexeddb/database-close.html [ Failure ]
+storage/indexeddb/database-closepending-flag.html [ Failure ]
+storage/indexeddb/database-deletepending-flag.html [ Failure ]
+storage/indexeddb/database-odd-names.html [ Failure ]
+storage/indexeddb/database-wrapper.html [ Failure ]
+storage/indexeddb/delete-in-upgradeneeded-close-in-open-success.html [ Failure ]
+storage/indexeddb/delete-range.html [ Failure ]
+storage/indexeddb/deleteIndex.html [ Failure ]
+storage/indexeddb/deleted-objects.html [ Failure ]
+storage/indexeddb/deletedatabase-blocked.html [ Failure ]
+storage/indexeddb/deletedatabase-delayed-by-open-and-versionchange.html [ Failure ]
+storage/indexeddb/deletedatabase-not-blocked.html [ Failure ]
+storage/indexeddb/deletedatabase-transaction.html [ Failure ]
+storage/indexeddb/dont-wedge.html [ Failure ]
+storage/indexeddb/duplicates.html [ Failure ]
+storage/indexeddb/error-causes-abort-by-default.html [ Failure ]
+storage/indexeddb/exception-in-event-aborts.html [ Failure ]
+storage/indexeddb/exceptions.html [ Failure ]
+storage/indexeddb/factory-deletedatabase.html [ Failure ]
+storage/indexeddb/get-keyrange.html [ Failure ]
+storage/indexeddb/index-basics.html [ Failure ]
+storage/indexeddb/index-count.html [ Failure ]
+storage/indexeddb/index-cursor.html [ Failure ]
+storage/indexeddb/index-duplicate-keypaths.html [ Failure ]
+storage/indexeddb/index-multientry.html [ Failure ]
+storage/indexeddb/index-population.html [ Failure ]
+storage/indexeddb/index-unique.html [ Failure ]
+storage/indexeddb/intversion-blocked.html [ Failure ]
+storage/indexeddb/intversion-close-between-events.html [ Failure ]
+storage/indexeddb/intversion-close-in-oncomplete.html [ Failure ]
+storage/indexeddb/intversion-close-in-upgradeneeded.html [ Failure ]
+storage/indexeddb/intversion-encoding.html [ Failure ]
+storage/indexeddb/intversion-gated-on-delete.html [ Failure ]
+storage/indexeddb/intversion-long-queue.html [ Failure ]
+storage/indexeddb/intversion-omit-parameter.html [ Failure ]
+storage/indexeddb/intversion-open-in-upgradeneeded.html [ Failure ]
+storage/indexeddb/intversion-open-with-version.html [ Failure ]
+storage/indexeddb/intversion-pending-version-changes-ascending.html [ Failure ]
+storage/indexeddb/intversion-pending-version-changes-descending.html [ Failure ]
+storage/indexeddb/intversion-pending-version-changes-same.html [ Failure ]
+storage/indexeddb/intversion-persistence.html [ Failure ]
+storage/indexeddb/intversion-revert-on-abort.html [ Failure ]
+storage/indexeddb/intversion-two-opens-no-versions.html [ Failure ]
+storage/indexeddb/intversion-upgrades.html [ Failure ]
+storage/indexeddb/key-generator.html [ Failure ]
+storage/indexeddb/key-sort-order-across-types.html [ Failure ]
+storage/indexeddb/key-sort-order-date.html [ Failure ]
+storage/indexeddb/key-type-array.html [ Failure ]
+storage/indexeddb/key-type-binary.html [ Failure ]
+storage/indexeddb/key-type-infinity.html [ Failure ]
+storage/indexeddb/keypath-arrays.html [ Failure ]
+storage/indexeddb/keypath-edges.html [ Failure ]
+storage/indexeddb/keypath-fetch-key.html [ Failure ]
+storage/indexeddb/keypath-intrinsic-properties.html [ Failure ]
+storage/indexeddb/lazy-index-population.html [ Failure ]
+storage/indexeddb/lazy-index-types.html [ Failure ]
+storage/indexeddb/list-ordering.html [ Failure ]
+storage/indexeddb/metadata-race.html [ Failure ]
+storage/indexeddb/metadata.html [ Failure ]
+storage/indexeddb/modern/abort-objectstore-info.html [ Failure ]
+storage/indexeddb/modern/abort-requests-cancelled.html [ Failure ]
+storage/indexeddb/modern/aborted-put.html [ Failure ]
+storage/indexeddb/modern/autoincrement-abort.html [ Failure ]
+storage/indexeddb/modern/basic-add.html [ Failure ]
+storage/indexeddb/modern/basic-put.html [ Failure ]
+storage/indexeddb/modern/blocked-open-db-requests.html [ Failure ]
+storage/indexeddb/modern/create-index-failures.html [ Failure ]
+storage/indexeddb/modern/createobjectstore-basic.html [ Failure ]
+storage/indexeddb/modern/createobjectstore-failures.html [ Failure ]
+storage/indexeddb/modern/cursor-1.html [ Failure ]
+storage/indexeddb/modern/cursor-2.html [ Failure ]
+storage/indexeddb/modern/cursor-3.html [ Failure ]
+storage/indexeddb/modern/cursor-4.html [ Failure ]
+storage/indexeddb/modern/cursor-5.html [ Failure ]
+storage/indexeddb/modern/cursor-6.html [ Failure ]
+storage/indexeddb/modern/cursor-7.html [ Failure ]
+storage/indexeddb/modern/cursor-8.html [ Failure ]
+storage/indexeddb/modern/date-basic.html [ Failure ]
+storage/indexeddb/modern/deletedatabase-1.html [ Failure ]
+storage/indexeddb/modern/deletedatabase-2.html [ Failure ]
+storage/indexeddb/modern/deleteindex-1.html [ Failure ]
+storage/indexeddb/modern/deleteindex-2.html [ Failure ]
+storage/indexeddb/modern/deleteobjectstore-1.html [ Failure ]
+storage/indexeddb/modern/double-open.html [ Failure ]
+storage/indexeddb/modern/get-index-failures.html [ Failure ]
+storage/indexeddb/modern/get-keyrange.html [ Failure ]
+storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html [ Failure ]
+storage/indexeddb/modern/idbdatabase-transaction-failures.html [ Failure ]
+storage/indexeddb/modern/idbindex-properties-basic.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-clear-1.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-clear-2.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-count-1.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-count-failures.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-delete-1.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-delete-2.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-delete-failures.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-get-failures.html [ Failure ]
+storage/indexeddb/modern/idbobjectstore-put-and-clear-failures.html [ Failure ]
+storage/indexeddb/modern/index-1.html [ Failure ]
+storage/indexeddb/modern/index-2.html [ Failure ]
+storage/indexeddb/modern/index-3.html [ Failure ]
+storage/indexeddb/modern/index-4.html [ Failure ]
+storage/indexeddb/modern/index-5.html [ Failure ]
+storage/indexeddb/modern/index-cursor-1.html [ Failure ]
+storage/indexeddb/modern/index-cursor-2.html [ Failure ]
+storage/indexeddb/modern/index-cursor-3.html [ Failure ]
+storage/indexeddb/modern/index-get-count-basic.html [ Failure ]
+storage/indexeddb/modern/index-get-count-failures.html [ Failure ]
+storage/indexeddb/modern/keypath-basic.html [ Failure ]
+storage/indexeddb/modern/memory-index-not-deleted-with-objectstore.html [ Failure ]
+storage/indexeddb/modern/objectstore-attributes.html [ Failure ]
+storage/indexeddb/modern/objectstore-cursor-advance-failures.html [ Failure ]
+storage/indexeddb/modern/objectstore-cursor-continue-failures.html [ Failure ]
+storage/indexeddb/modern/opencursor-failures.html [ Failure ]
+storage/indexeddb/modern/opendatabase-success-after-versionchange.html [ Failure ]
+storage/indexeddb/modern/opendatabase-versions.html [ Failure ]
+storage/indexeddb/modern/request-readystate.html [ Failure ]
+storage/indexeddb/modern/transaction-scheduler-1.html [ Failure ]
+storage/indexeddb/modern/transaction-scheduler-2.html [ Failure ]
+storage/indexeddb/modern/transaction-scheduler-3.html [ Failure ]
+storage/indexeddb/modern/transaction-scheduler-4.html [ Failure ]
+storage/indexeddb/modern/transaction-scheduler-5.html [ Failure ]
+storage/indexeddb/modern/transaction-scheduler-6.html [ Failure ]
+storage/indexeddb/modern/transactions-stop-on-navigation.html [ Failure ]
+storage/indexeddb/modern/versionchange-abort-then-reopen.html [ Failure ]
+storage/indexeddb/modern/versionchange-event.html [ Failure ]
+storage/indexeddb/mozilla/add-twice-failure.html [ Failure ]
+storage/indexeddb/mozilla/autoincrement-indexes.html [ Failure ]
+storage/indexeddb/mozilla/bad-keypath.html [ Failure ]
+storage/indexeddb/mozilla/clear.html [ Failure ]
+storage/indexeddb/mozilla/create-index-with-integer-keys.html [ Failure ]
+storage/indexeddb/mozilla/cursor-mutation-objectstore-only.html [ Failure ]
+storage/indexeddb/mozilla/cursor-mutation.html [ Failure ]
+storage/indexeddb/mozilla/cursor-update-updates-indexes.html [ Failure ]
+storage/indexeddb/mozilla/cursors.html [ Failure ]
+storage/indexeddb/mozilla/delete-result.html [ Failure ]
+storage/indexeddb/mozilla/event-source.html [ Failure ]
+storage/indexeddb/mozilla/global-data.html [ Failure ]
+storage/indexeddb/mozilla/index-prev-no-duplicate.html [ Failure ]
+storage/indexeddb/mozilla/indexes.html [ Failure ]
+storage/indexeddb/mozilla/key-requirements.html [ Failure ]
+storage/indexeddb/mozilla/object-cursors.html [ Failure ]
+storage/indexeddb/mozilla/object-identity.html [ Failure ]
+storage/indexeddb/mozilla/object-store-inline-autoincrement-key-added-on-put.html [ Failure ]
+storage/indexeddb/mozilla/object-store-remove-values.html [ Failure ]
+storage/indexeddb/mozilla/odd-result-order.html [ Failure ]
+storage/indexeddb/mozilla/open-database-null-name.html [ Failure ]
+storage/indexeddb/mozilla/put-get-values.html [ Failure ]
+storage/indexeddb/mozilla/readonly-transactions.html [ Failure ]
+storage/indexeddb/mozilla/readwrite-transactions.html [ Failure ]
+storage/indexeddb/mozilla/readyState.html [ Failure ]
+storage/indexeddb/mozilla/remove-objectstore.html [ Failure ]
+storage/indexeddb/mutating-cursor.html [ Failure ]
+storage/indexeddb/noblobs.html [ Failure ]
+storage/indexeddb/object-lookups-in-versionchange.html [ Failure ]
+storage/indexeddb/objectstore-autoincrement.html [ Failure ]
+storage/indexeddb/objectstore-basics.html [ Failure ]
+storage/indexeddb/objectstore-clear.html [ Failure ]
+storage/indexeddb/objectstore-count.html [ Failure ]
+storage/indexeddb/objectstore-cursor.html [ Failure ]
+storage/indexeddb/objectstore-removeobjectstore.html [ Failure ]
+storage/indexeddb/odd-strings.html [ Failure ]
+storage/indexeddb/open-cursor.html [ Failure ]
+storage/indexeddb/open-during-transaction.html [ Failure ]
+storage/indexeddb/open-ordering.html [ Failure ]
+storage/indexeddb/opencursor-key.html [ Failure ]
+storage/indexeddb/optional-arguments.html [ Failure ]
+storage/indexeddb/pending-activity.html [ Failure ]
+storage/indexeddb/persistence.html [ Failure ]
+storage/indexeddb/prefetch-bugfix-108071.html [ Failure ]
+storage/indexeddb/prefetch-invalidation.html [ Failure ]
+storage/indexeddb/prefetch-race.html [ Failure ]
+storage/indexeddb/queued-commands.html [ Failure ]
+storage/indexeddb/readonly.html [ Failure ]
+storage/indexeddb/request-continue-abort.html [ Failure ]
+storage/indexeddb/request-event-propagation.html [ Failure ]
+storage/indexeddb/request-result-cache.html [ Failure ]
+storage/indexeddb/set_version_blocked.html [ Failure ]
+storage/indexeddb/setversion-blocked-by-versionchange-close.html [ Failure ]
+storage/indexeddb/setversion-not-blocked.html [ Failure ]
+storage/indexeddb/structured-clone.html [ Failure ]
+storage/indexeddb/transaction-abort.html [ Failure ]
+storage/indexeddb/transaction-active-flag.html [ Failure ]
+storage/indexeddb/transaction-after-close.html [ Failure ]
+storage/indexeddb/transaction-and-objectstore-calls.html [ Failure ]
+storage/indexeddb/transaction-basics.html [ Failure ]
+storage/indexeddb/transaction-complete-with-js-recursion-cross-frame.html [ Failure ]
+storage/indexeddb/transaction-complete-with-js-recursion.html [ Failure ]
+storage/indexeddb/transaction-coordination-across-databases.html [ Failure ]
+storage/indexeddb/transaction-coordination-within-database.html [ Failure ]
+storage/indexeddb/transaction-crash-on-abort.html [ Failure ]
+storage/indexeddb/transaction-error.html [ Failure ]
+storage/indexeddb/transaction-event-propagation.html [ Failure ]
+storage/indexeddb/transaction-ordering.html [ Failure ]
+storage/indexeddb/transaction-overlapping.html [ Failure ]
+storage/indexeddb/transaction-read-only.html [ Failure ]
+storage/indexeddb/transaction-readwrite-exclusive.html [ Failure ]
+storage/indexeddb/transaction-rollback.html [ Failure ]
+storage/indexeddb/transaction-scope-sequencing.html [ Failure ]
+storage/indexeddb/unblocked-version-changes.html [ Failure ]
+storage/indexeddb/value-undefined.html [ Failure ]
+storage/indexeddb/values-odd-types.html [ Failure ]
+storage/indexeddb/version-change-abort.html [ Failure ]
+storage/indexeddb/version-change-event.html [ Failure ]
+storage/indexeddb/version-change-exclusive.html [ Failure ]
+storage/indexeddb/versionchangerequest-activedomobject.html [ Failure ]
+
+#SQLite backend tests that timeout
+crypto/subtle/rsa-indexeddb.html [ Skip ]
+imported/w3c/indexeddb/idbcursor-advance-continue-async.htm [ Skip ]
+imported/w3c/indexeddb/idbcursor-advance-invalid.htm [ Skip ]
+imported/w3c/indexeddb/idbcursor-advance.htm [ Skip ]
+imported/w3c/indexeddb/idbcursor-continue.htm [ Skip ]
+imported/w3c/indexeddb/idbcursor-source.htm [ Skip ]
+imported/w3c/indexeddb/idbfactory_open12.htm [ Skip ]
+imported/w3c/indexeddb/idbindex-multientry-big.htm [ Skip ]
+imported/w3c/indexeddb/idbobjectstore_openCursor_invalid.htm [ Skip ]
+imported/w3c/indexeddb/keypath.htm [ Skip ]
+storage/indexeddb/primary-key-unique-to-objectstore.html [ Skip ]
+
+### END OF (3) IndexedDB failures with SQLite
+########################################
</ins></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -874,6 +874,7 @@
</span><span class="cx">     Modules/indexeddb/legacy/LegacyVersionChangeEvent.cpp
</span><span class="cx"> 
</span><span class="cx">     Modules/indexeddb/server/IDBConnectionToClient.cpp
</span><ins>+    Modules/indexeddb/server/IDBSerialization.cpp
</ins><span class="cx">     Modules/indexeddb/server/IDBServer.cpp
</span><span class="cx">     Modules/indexeddb/server/IndexValueEntry.cpp
</span><span class="cx">     Modules/indexeddb/server/IndexValueStore.cpp
</span><span class="lines">@@ -885,6 +886,8 @@
</span><span class="cx">     Modules/indexeddb/server/MemoryObjectStore.cpp
</span><span class="cx">     Modules/indexeddb/server/MemoryObjectStoreCursor.cpp
</span><span class="cx">     Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
</span><ins>+    Modules/indexeddb/server/SQLiteIDBCursor.cpp
+    Modules/indexeddb/server/SQLiteIDBTransaction.cpp
</ins><span class="cx">     Modules/indexeddb/server/ServerOpenDBRequest.cpp
</span><span class="cx">     Modules/indexeddb/server/UniqueIDBDatabase.cpp
</span><span class="cx">     Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/ChangeLog        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -1,3 +1,102 @@
</span><ins>+2016-01-21  Brady Eidson  &lt;beidson@apple.com&gt;
+
+        Modern IDB: Support populating/extracting database metadata with SQLite backend.
+        Nhttps://bugs.webkit.org/show_bug.cgi?id=153318
+
+        Reviewed by Alex Christensen.
+
+        No new tests (Covered by current tests).
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * Modules/indexeddb/client/IDBDatabaseImpl.cpp:
+        (WebCore::IDBClient::IDBDatabase::willAbortTransaction): Committing transactions can abort if the commit
+          ends in error.
+
+        * Modules/indexeddb/client/IDBTransactionImpl.cpp:
+        (WebCore::IDBClient::IDBTransaction::didCommit): Before a committing transaction is aborted, notify the
+          IDBDatabase that it aborted.
+
+        Copied over from WK2:
+        * Modules/indexeddb/server/IDBSerialization.cpp: Added.
+        (WebCore::serializeIDBKeyPath):
+        (WebCore::deserializeIDBKeyPath):
+        (WebCore::serializeIDBKeyData):
+        (WebCore::deserializeIDBKeyData):
+        * Modules/indexeddb/server/IDBSerialization.h: Added.
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::createBackingStore): Optionally create a SQLite backing store.
+        
+        Mostly copied over verbatim from WebKit2's UniqueIDBDatabaseBackingStoreSQLite.cpp: 
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
+        (WebCore::IDBServer::idbKeyCollate):
+        (WebCore::IDBServer::v1RecordsTableSchema):
+        (WebCore::IDBServer::v1RecordsTableSchemaAlternate):
+        (WebCore::IDBServer::v2RecordsTableSchema):
+        (WebCore::IDBServer::v2RecordsTableSchemaAlternate):
+        (WebCore::IDBServer::createOrMigrateRecordsTableIfNecessary):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::ensureValidRecordsTable):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::extractExistingDatabaseInfo):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::beginTransaction):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::abortTransaction):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::commitTransaction):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::createObjectStore):
+        (WebCore::IDBServer::SQLiteIDBBackingStore::unregisterCursor):
+        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
+        
+        Copied over from WK2:
+        * Modules/indexeddb/server/SQLiteIDBCursor.cpp: Added.
+        (WebCore::IDBServer::SQLiteIDBCursor::maybeCreate):
+        (WebCore::IDBServer::SQLiteIDBCursor::SQLiteIDBCursor):
+        (WebCore::IDBServer::buildIndexStatement):
+        (WebCore::IDBServer::buildObjectStoreStatement):
+        (WebCore::IDBServer::SQLiteIDBCursor::establishStatement):
+        (WebCore::IDBServer::SQLiteIDBCursor::createSQLiteStatement):
+        (WebCore::IDBServer::SQLiteIDBCursor::objectStoreRecordsChanged):
+        (WebCore::IDBServer::SQLiteIDBCursor::resetAndRebindStatement):
+        (WebCore::IDBServer::SQLiteIDBCursor::bindArguments):
+        (WebCore::IDBServer::SQLiteIDBCursor::advance):
+        (WebCore::IDBServer::SQLiteIDBCursor::advanceUnique):
+        (WebCore::IDBServer::SQLiteIDBCursor::advanceOnce):
+        (WebCore::IDBServer::SQLiteIDBCursor::internalAdvanceOnce):
+        (WebCore::IDBServer::SQLiteIDBCursor::iterate):
+        * Modules/indexeddb/server/SQLiteIDBCursor.h: Added.
+        (WebCore::IDBServer::SQLiteIDBCursor::identifier):
+        (WebCore::IDBServer::SQLiteIDBCursor::transaction):
+        (WebCore::IDBServer::SQLiteIDBCursor::objectStoreID):
+        (WebCore::IDBServer::SQLiteIDBCursor::currentKey):
+        (WebCore::IDBServer::SQLiteIDBCursor::currentPrimaryKey):
+        (WebCore::IDBServer::SQLiteIDBCursor::currentValueBuffer):
+        (WebCore::IDBServer::SQLiteIDBCursor::didError):
+
+        Copied over from WK2:
+        * Modules/indexeddb/server/SQLiteIDBTransaction.cpp: Added.
+        (WebCore::IDBServer::SQLiteIDBTransaction::SQLiteIDBTransaction):
+        (WebCore::IDBServer::SQLiteIDBTransaction::~SQLiteIDBTransaction):
+        (WebCore::IDBServer::SQLiteIDBTransaction::begin):
+        (WebCore::IDBServer::SQLiteIDBTransaction::commit):
+        (WebCore::IDBServer::SQLiteIDBTransaction::reset):
+        (WebCore::IDBServer::SQLiteIDBTransaction::rollback):
+        (WebCore::IDBServer::SQLiteIDBTransaction::maybeOpenCursor):
+        (WebCore::IDBServer::SQLiteIDBTransaction::closeCursor):
+        (WebCore::IDBServer::SQLiteIDBTransaction::notifyCursorsOfChanges):
+        (WebCore::IDBServer::SQLiteIDBTransaction::clearCursors):
+        (WebCore::IDBServer::SQLiteIDBTransaction::inProgress):
+        * Modules/indexeddb/server/SQLiteIDBTransaction.h: Added.
+        (WebCore::IDBServer::SQLiteIDBTransaction::transactionIdentifier):
+        (WebCore::IDBServer::SQLiteIDBTransaction::mode):
+        (WebCore::IDBServer::SQLiteIDBTransaction::sqliteTransaction):
+
+        * page/Page.cpp:
+        (WebCore::Page::setSessionID): If the new SessionID is different from the last one,
+          clear the IDBConnectionToServer.
+        (WebCore::Page::idbConnection): Always ask the DatabaseProvider; It handles whether or not 
+          the session is ephemeral.
+
</ins><span class="cx"> 2016-01-21  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         CMake build fix after r195302.
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBDatabaseImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -330,6 +330,9 @@
</span><span class="cx">     LOG(IndexedDB, &quot;IDBDatabase::willAbortTransaction %s&quot;, transaction.info().identifier().loggingString().utf8().data());
</span><span class="cx"> 
</span><span class="cx">     auto refTransaction = m_activeTransactions.take(transaction.info().identifier());
</span><ins>+    if (!refTransaction)
+        refTransaction = m_committingTransactions.take(transaction.info().identifier());
+
</ins><span class="cx">     ASSERT(refTransaction);
</span><span class="cx">     m_abortingTransactions.set(transaction.info().identifier(), WTFMove(refTransaction));
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbclientIDBTransactionImplcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -386,8 +386,10 @@
</span><span class="cx">     if (error.isNull()) {
</span><span class="cx">         m_database-&gt;didCommitTransaction(*this);
</span><span class="cx">         fireOnComplete();
</span><del>-    } else
</del><ins>+    } else {
+        m_database-&gt;willAbortTransaction(*this);
</ins><span class="cx">         notifyDidAbort(error);
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     finishAbortOrCommit();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBSerializationcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp (0 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+/*
+ * Copyright (C) 2014, 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.
+ */
+#include &quot;config.h&quot;
+#include &quot;IDBSerialization.h&quot;
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;IDBKeyData.h&quot;
+#include &quot;IDBKeyPath.h&quot;
+#include &quot;KeyedCoding.h&quot;
+
+namespace WebCore {
+
+RefPtr&lt;SharedBuffer&gt; serializeIDBKeyPath(const IDBKeyPath&amp; keyPath)
+{
+    auto encoder = KeyedEncoder::encoder();
+    keyPath.encode(*encoder);
+    return encoder-&gt;finishEncoding();
+}
+
+bool deserializeIDBKeyPath(const uint8_t* data, size_t size, IDBKeyPath&amp; result)
+{
+    if (!data || !size)
+        return false;
+
+    auto decoder = KeyedDecoder::decoder(data, size);
+    return IDBKeyPath::decode(*decoder, result);
+}
+
+RefPtr&lt;SharedBuffer&gt; serializeIDBKeyData(const IDBKeyData&amp; key)
+{
+    auto encoder = KeyedEncoder::encoder();
+    key.encode(*encoder);
+    return encoder-&gt;finishEncoding();
+}
+
+bool deserializeIDBKeyData(const uint8_t* data, size_t size, IDBKeyData&amp; result)
+{
+    if (!data || !size)
+        return false;
+
+    auto decoder = KeyedDecoder::decoder(data, size);
+    return IDBKeyData::decode(*decoder, result);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBSerializationh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h (0 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+/*
+ * Copyright (C) 2014, 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.
+ */
+
+#ifndef IDBSerialization_h
+#define IDBSerialization_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;SharedBuffer.h&quot;
+#include &lt;wtf/Vector.h&gt;
+
+namespace WebCore {
+
+class IDBKeyData;
+class IDBKeyPath;
+
+RefPtr&lt;SharedBuffer&gt; serializeIDBKeyPath(const IDBKeyPath&amp;);
+bool deserializeIDBKeyPath(const uint8_t* buffer, size_t bufferSize, IDBKeyPath&amp;);
+
+RefPtr&lt;SharedBuffer&gt; serializeIDBKeyData(const IDBKeyData&amp;);
+bool deserializeIDBKeyData(const uint8_t* buffer, size_t bufferSize, IDBKeyData&amp;);
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+#endif // IDBSerialization_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -117,9 +117,10 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!isMainThread());
</span><span class="cx"> 
</span><del>-    // FIXME: Once the SQLite backing store is functional, conditionally make either a Memory or SQLite backing store.
</del><ins>+    if (m_databaseDirectoryPath.isEmpty())
+        return MemoryIDBBackingStore::create(identifier);
</ins><span class="cx"> 
</span><del>-    return MemoryIDBBackingStore::create(identifier);
</del><ins>+    return std::make_unique&lt;SQLiteIDBBackingStore&gt;(identifier, m_databaseDirectoryPath);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void IDBServer::openDatabase(const IDBRequestData&amp; requestData)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -31,14 +31,77 @@
</span><span class="cx"> #include &quot;FileSystem.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseException.h&quot;
</span><span class="cx"> #include &quot;IDBKeyData.h&quot;
</span><ins>+#include &quot;IDBSerialization.h&quot;
+#include &quot;IDBTransactionInfo.h&quot;
</ins><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;SQLiteDatabase.h&quot;
</span><span class="cx"> #include &quot;SQLiteFileSystem.h&quot;
</span><ins>+#include &quot;SQLiteIDBCursor.h&quot;
+#include &quot;SQLiteStatement.h&quot;
+#include &quot;SQLiteTransaction.h&quot;
</ins><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><ins>+// Current version of the metadata schema being used in the metadata database.
+static const int currentMetadataVersion = 1;
+
+static int idbKeyCollate(int aLength, const void* aBuffer, int bLength, const void* bBuffer)
+{
+    IDBKeyData a, b;
+    if (!deserializeIDBKeyData(static_cast&lt;const uint8_t*&gt;(aBuffer), aLength, a)) {
+        LOG_ERROR(&quot;Unable to deserialize key A in collation function.&quot;);
+
+        // There's no way to indicate an error to SQLite - we have to return a sorting decision.
+        // We arbitrarily choose &quot;A &gt; B&quot;
+        return 1;
+    }
+    if (!deserializeIDBKeyData(static_cast&lt;const uint8_t*&gt;(bBuffer), bLength, b)) {
+        LOG_ERROR(&quot;Unable to deserialize key B in collation function.&quot;);
+
+        // There's no way to indicate an error to SQLite - we have to return a sorting decision.
+        // We arbitrarily choose &quot;A &gt; B&quot;
+        return 1;
+    }
+
+    return a.compare(b);
+}
+
+static const String v1RecordsTableSchema(const String&amp; tableName)
+{
+    return makeString(&quot;CREATE TABLE &quot;, tableName, &quot; (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;);
+}
+
+static const String&amp; v1RecordsTableSchema()
+{
+    static NeverDestroyed&lt;WTF::String&gt; v1RecordsTableSchemaString(v1RecordsTableSchema(&quot;Records&quot;));
+    return v1RecordsTableSchemaString;
+}
+
+static const String&amp; v1RecordsTableSchemaAlternate()
+{
+    static NeverDestroyed&lt;WTF::String&gt; v1RecordsTableSchemaString(v1RecordsTableSchema(&quot;\&quot;Records\&quot;&quot;));
+    return v1RecordsTableSchemaString;
+}
+
+static const String v2RecordsTableSchema(const String&amp; tableName)
+{
+    return makeString(&quot;CREATE TABLE &quot;, tableName, &quot; (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value NOT NULL ON CONFLICT FAIL)&quot;);
+}
+
+static const String&amp; v2RecordsTableSchema()
+{
+    static NeverDestroyed&lt;WTF::String&gt; v2RecordsTableSchemaString(v2RecordsTableSchema(&quot;Records&quot;));
+    return v2RecordsTableSchemaString;
+}
+
+static const String&amp; v2RecordsTableSchemaAlternate()
+{
+    static NeverDestroyed&lt;WTF::String&gt; v2RecordsTableSchemaString(v2RecordsTableSchema(&quot;\&quot;Records\&quot;&quot;));
+    return v2RecordsTableSchemaString;
+}
+
</ins><span class="cx"> SQLiteIDBBackingStore::SQLiteIDBBackingStore(const IDBDatabaseIdentifier&amp; identifier, const String&amp; databaseRootDirectory)
</span><span class="cx">     : m_identifier(identifier)
</span><span class="cx"> {
</span><span class="lines">@@ -51,6 +114,282 @@
</span><span class="cx">         m_sqliteDB-&gt;close();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase&amp; database)
+{
+    String currentSchema;
+    {
+        // Fetch the schema for an existing records table.
+        SQLiteStatement statement(database, &quot;SELECT type, sql FROM sqlite_master WHERE tbl_name='Records'&quot;);
+        if (statement.prepare() != SQLITE_OK) {
+            LOG_ERROR(&quot;Unable to prepare statement to fetch schema for the Records table.&quot;);
+            return false;
+        }
+
+        int sqliteResult = statement.step();
+
+        // If there is no Records table at all, create it and then bail.
+        if (sqliteResult == SQLITE_DONE) {
+            if (!database.executeCommand(v2RecordsTableSchema())) {
+                LOG_ERROR(&quot;Could not create Records table in database (%i) - %s&quot;, database.lastError(), database.lastErrorMsg());
+                return false;
+            }
+
+            return true;
+        }
+
+        if (sqliteResult != SQLITE_ROW) {
+            LOG_ERROR(&quot;Error executing statement to fetch schema for the Records table.&quot;);
+            return false;
+        }
+
+        currentSchema = statement.getColumnText(1);
+    }
+
+    ASSERT(!currentSchema.isEmpty());
+
+    // If the schema in the backing store is the current schema, we're done.
+    if (currentSchema == v2RecordsTableSchema() || currentSchema == v2RecordsTableSchemaAlternate())
+        return true;
+
+    // If the record table is not the current schema then it must be one of the previous schemas.
+    // If it is not then the database is in an unrecoverable state and this should be considered a fatal error.
+    if (currentSchema != v1RecordsTableSchema() &amp;&amp; currentSchema != v1RecordsTableSchemaAlternate())
+        RELEASE_ASSERT_NOT_REACHED();
+
+    SQLiteTransaction transaction(database);
+    transaction.begin();
+
+    // Create a temporary table with the correct schema and migrate all existing content over.
+    if (!database.executeCommand(v2RecordsTableSchema(&quot;_Temp_Records&quot;))) {
+        LOG_ERROR(&quot;Could not create temporary records table in database (%i) - %s&quot;, database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    if (!database.executeCommand(&quot;INSERT INTO _Temp_Records SELECT * FROM Records&quot;)) {
+        LOG_ERROR(&quot;Could not migrate existing Records content (%i) - %s&quot;, database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    if (!database.executeCommand(&quot;DROP TABLE Records&quot;)) {
+        LOG_ERROR(&quot;Could not drop existing Records table (%i) - %s&quot;, database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    if (!database.executeCommand(&quot;ALTER TABLE _Temp_Records RENAME TO Records&quot;)) {
+        LOG_ERROR(&quot;Could not rename temporary Records table (%i) - %s&quot;, database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    transaction.commit();
+
+    return true;
+}
+
+bool SQLiteIDBBackingStore::ensureValidRecordsTable()
+{
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB-&gt;isOpen());
+
+    if (!createOrMigrateRecordsTableIfNecessary(*m_sqliteDB))
+        return false;
+
+    // Whether the updated records table already existed or if it was just created and the data migrated over,
+    // make sure the uniqueness index exists.
+    if (!m_sqliteDB-&gt;executeCommand(&quot;CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);&quot;)) {
+        LOG_ERROR(&quot;Could not create RecordsIndex on Records table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        return false;
+    }
+
+    return true;
+}
+
+std::unique_ptr&lt;IDBDatabaseInfo&gt; SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo()
+{
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB-&gt;isOpen());
+
+    if (!m_sqliteDB-&gt;executeCommand(&quot;CREATE TABLE IDBDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL);&quot;)) {
+        LOG_ERROR(&quot;Could not create IDBDatabaseInfo table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    if (!m_sqliteDB-&gt;executeCommand(&quot;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);&quot;)) {
+        LOG_ERROR(&quot;Could not create ObjectStoreInfo table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    if (!m_sqliteDB-&gt;executeCommand(&quot;CREATE 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);&quot;)) {
+        LOG_ERROR(&quot;Could not create IndexInfo table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    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, value NOT NULL ON CONFLICT FAIL);&quot;)) {
+        LOG_ERROR(&quot;Could not create IndexRecords table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    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;)) {
+        LOG_ERROR(&quot;Could not create KeyGenerators table in database (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;INSERT INTO IDBDatabaseInfo VALUES ('MetadataVersion', ?);&quot;));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindInt(1, currentMetadataVersion) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR(&quot;Could not insert database metadata version into IDBDatabaseInfo table (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            m_sqliteDB = nullptr;
+            return nullptr;
+        }
+    }
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;INSERT INTO IDBDatabaseInfo VALUES ('DatabaseName', ?);&quot;));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindText(1, m_identifier.databaseName()) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR(&quot;Could not insert database name into IDBDatabaseInfo table (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            m_sqliteDB = nullptr;
+            return nullptr;
+        }
+    }
+    {
+        // Database versions are defined to be a uin64_t in the spec but sqlite3 doesn't support native binding of unsigned integers.
+        // Therefore we'll store the version as a String.
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;INSERT INTO IDBDatabaseInfo VALUES ('DatabaseVersion', ?);&quot;));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindText(1, String::number(0)) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR(&quot;Could not insert default version into IDBDatabaseInfo table (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+            m_sqliteDB = nullptr;
+            return nullptr;
+        }
+    }
+
+    if (!m_sqliteDB-&gt;executeCommand(ASCIILiteral(&quot;INSERT INTO IDBDatabaseInfo VALUES ('MaxObjectStoreID', 1);&quot;))) {
+        LOG_ERROR(&quot;Could not insert default version into IDBDatabaseInfo table (%i) - %s&quot;, m_sqliteDB-&gt;lastError(), m_sqliteDB-&gt;lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    // This initial database info matches the default values we just put into the metadata database.
+    return std::make_unique&lt;IDBDatabaseInfo&gt;(m_identifier.databaseName(), 0);
+}
+
+std::unique_ptr&lt;IDBDatabaseInfo&gt; SQLiteIDBBackingStore::extractExistingDatabaseInfo()
+{
+    ASSERT(m_sqliteDB);
+
+    if (!m_sqliteDB-&gt;tableExists(ASCIILiteral(&quot;IDBDatabaseInfo&quot;)))
+        return nullptr;
+
+    String databaseName;
+    {
+        SQLiteStatement sql(*m_sqliteDB, &quot;SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseName';&quot;);
+        if (sql.isColumnNull(0))
+            return nullptr;
+        databaseName = sql.getColumnText(0);
+        if (databaseName != m_identifier.databaseName()) {
+            LOG_ERROR(&quot;Database name in the info database ('%s') does not match the expected name ('%s')&quot;, databaseName.utf8().data(), m_identifier.databaseName().utf8().data());
+            return nullptr;
+        }
+    }
+    uint64_t databaseVersion;
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseVersion';&quot;));
+        if (sql.isColumnNull(0))
+            return nullptr;
+        String stringVersion = sql.getColumnText(0);
+        bool ok;
+        databaseVersion = stringVersion.toUInt64Strict(&amp;ok);
+        if (!ok) {
+            LOG_ERROR(&quot;Database version on disk ('%s') does not cleanly convert to an unsigned 64-bit integer version&quot;, stringVersion.utf8().data());
+            return nullptr;
+        }
+    }
+
+    auto databaseInfo = std::make_unique&lt;IDBDatabaseInfo&gt;(databaseName, databaseVersion);
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT id, name, keyPath, autoInc, maxIndexID FROM ObjectStoreInfo;&quot;));
+        if (sql.prepare() != SQLITE_OK)
+            return nullptr;
+
+        int result = sql.step();
+        while (result == SQLITE_ROW) {
+            uint64_t objectStoreID = sql.getColumnInt64(0);
+            String objectStoreName = sql.getColumnText(1);
+
+            Vector&lt;char&gt; keyPathBuffer;
+            sql.getColumnBlobAsVector(2, keyPathBuffer);
+
+            IDBKeyPath objectStoreKeyPath;
+            if (!deserializeIDBKeyPath(reinterpret_cast&lt;const uint8_t*&gt;(keyPathBuffer.data()), keyPathBuffer.size(), objectStoreKeyPath)) {
+                LOG_ERROR(&quot;Unable to extract key path from database&quot;);
+                return nullptr;
+            }
+
+            bool autoIncrement = sql.getColumnInt(3);
+
+            databaseInfo-&gt;addExistingObjectStore({ objectStoreID, objectStoreName, objectStoreKeyPath, autoIncrement });
+
+            result = sql.step();
+        }
+
+        if (result != SQLITE_DONE) {
+            LOG_ERROR(&quot;Error fetching object store info from database on disk&quot;);
+            return nullptr;
+        }
+    }
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral(&quot;SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;&quot;));
+        if (sql.prepare() != SQLITE_OK)
+            return nullptr;
+
+        int result = sql.step();
+        while (result == SQLITE_ROW) {
+            uint64_t indexID = sql.getColumnInt64(0);
+            String indexName = sql.getColumnText(1);
+            uint64_t objectStoreID = sql.getColumnInt64(2);
+
+            Vector&lt;char&gt; keyPathBuffer;
+            sql.getColumnBlobAsVector(3, keyPathBuffer);
+
+            IDBKeyPath indexKeyPath;
+            if (!deserializeIDBKeyPath(reinterpret_cast&lt;const uint8_t*&gt;(keyPathBuffer.data()), keyPathBuffer.size(), indexKeyPath)) {
+                LOG_ERROR(&quot;Unable to extract key path from database&quot;);
+                return nullptr;
+            }
+
+            bool unique = sql.getColumnInt(4);
+            bool multiEntry = sql.getColumnInt(5);
+
+            auto objectStore = databaseInfo-&gt;infoForExistingObjectStore(objectStoreID);
+            if (!objectStore) {
+                LOG_ERROR(&quot;Found index referring to a non-existant object store&quot;);
+                return nullptr;
+            }
+
+            objectStore-&gt;addExistingIndex({ indexID, objectStoreID, indexName, indexKeyPath, unique, multiEntry });
+
+            result = sql.step();
+        }
+
+        if (result != SQLITE_DONE) {
+            LOG_ERROR(&quot;Error fetching index info from database on disk&quot;);
+            return nullptr;
+        }
+    }
+
+    return databaseInfo;
+}
+
</ins><span class="cx"> const IDBDatabaseInfo&amp; SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()
</span><span class="cx"> {
</span><span class="cx">     LOG(IndexedDB, &quot;SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s&quot;, m_identifier.databaseName().utf8().data());
</span><span class="lines">@@ -73,29 +412,57 @@
</span><span class="cx">     if (!m_sqliteDB)
</span><span class="cx">         return *m_databaseInfo;
</span><span class="cx"> 
</span><del>-    // FIXME: Support populating new SQLite files and pulling DatabaseInfo from existing SQLite files.
-    // Doing so will make a new m_databaseInfo which overrides the default one we created up above.
</del><ins>+    m_sqliteDB-&gt;setCollationFunction(&quot;IDBKEY&quot;, [this](int aLength, const void* a, int bLength, const void* b) {
+        return idbKeyCollate(aLength, a, bLength, b);
+    });
</ins><span class="cx"> 
</span><ins>+    if (!ensureValidRecordsTable()) {
+        LOG_ERROR(&quot;Error creating or migrating Records table in database&quot;);
+        m_sqliteDB = nullptr;
+        return *m_databaseInfo;
+    }
+
+    auto databaseInfo = extractExistingDatabaseInfo();
+    if (!databaseInfo)
+        databaseInfo = createAndPopulateInitialDatabaseInfo();
+
+    if (!databaseInfo)
+        LOG_ERROR(&quot;Unable to establish IDB database at path '%s'&quot;, dbFilename.utf8().data());
+    else
+        m_databaseInfo = WTFMove(databaseInfo);
+
</ins><span class="cx">     return *m_databaseInfo;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo&amp;)
</del><ins>+IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo&amp; info)
</ins><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;SQLiteIDBBackingStore::beginTransaction - %s&quot;, info.identifier().loggingString().utf8().data());
+    UNUSED_PARAM(info);
+
</ins><span class="cx">     return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Not implemented&quot;) };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier&amp;)
</del><ins>+IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier&amp; identifier)
</ins><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;SQLiteIDBBackingStore::abortTransaction - %s&quot;, identifier.loggingString().utf8().data());
+    UNUSED_PARAM(identifier);
+
</ins><span class="cx">     return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Not implemented&quot;) };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier&amp;)
</del><ins>+IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier&amp; identifier)
</ins><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;SQLiteIDBBackingStore::commitTransaction - %s&quot;, identifier.loggingString().utf8().data());
+    UNUSED_PARAM(identifier);
+
</ins><span class="cx">     return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Not implemented&quot;) };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier&amp;, const IDBObjectStoreInfo&amp;)
</del><ins>+IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier&amp;, const IDBObjectStoreInfo&amp; info)
</ins><span class="cx"> {
</span><ins>+    LOG(IndexedDB, &quot;SQLiteIDBBackingStore::createObjectStore - adding OS %s with ID %&quot; PRIu64, info.name().utf8().data(), info.identifier());
+    UNUSED_PARAM(info);
+
</ins><span class="cx">     return { IDBDatabaseException::UnknownError, ASCIILiteral(&quot;Not implemented&quot;) };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -189,6 +556,12 @@
</span><span class="cx">     SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_absoluteDatabaseDirectory);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void SQLiteIDBBackingStore::unregisterCursor(SQLiteIDBCursor&amp; cursor)
+{
+    ASSERT(m_cursors.contains(cursor.identifier()));
+    m_cursors.remove(cursor.identifier());
+}
+
</ins><span class="cx"> } // namespace IDBServer
</span><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBBackingStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -31,6 +31,9 @@
</span><span class="cx"> #include &quot;IDBBackingStore.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseIdentifier.h&quot;
</span><span class="cx"> #include &quot;IDBDatabaseInfo.h&quot;
</span><ins>+#include &quot;IDBResourceIdentifier.h&quot;
+#include &quot;SQLiteIDBTransaction.h&quot;
+#include &lt;wtf/HashMap.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -38,6 +41,8 @@
</span><span class="cx"> 
</span><span class="cx"> namespace IDBServer {
</span><span class="cx"> 
</span><ins>+class SQLiteIDBCursor;
+
</ins><span class="cx"> class SQLiteIDBBackingStore : public IDBBackingStore {
</span><span class="cx"> public:
</span><span class="cx">     SQLiteIDBBackingStore(const IDBDatabaseIdentifier&amp;, const String&amp; databaseRootDirectory);
</span><span class="lines">@@ -68,12 +73,21 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void deleteBackingStore() override final;
</span><span class="cx"> 
</span><ins>+    void unregisterCursor(SQLiteIDBCursor&amp;);
+
</ins><span class="cx"> private:
</span><ins>+    bool ensureValidRecordsTable();
+    std::unique_ptr&lt;IDBDatabaseInfo&gt; createAndPopulateInitialDatabaseInfo();
+    std::unique_ptr&lt;IDBDatabaseInfo&gt; extractExistingDatabaseInfo();
+
</ins><span class="cx">     IDBDatabaseIdentifier m_identifier;
</span><span class="cx">     std::unique_ptr&lt;IDBDatabaseInfo&gt; m_databaseInfo;
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;SQLiteDatabase&gt; m_sqliteDB;
</span><span class="cx"> 
</span><ins>+    HashMap&lt;IDBResourceIdentifier, std::unique_ptr&lt;SQLiteIDBTransaction&gt;&gt; m_transactions;
+    HashMap&lt;IDBResourceIdentifier, SQLiteIDBCursor*&gt; m_cursors;
+
</ins><span class="cx">     String m_absoluteDatabaseDirectory;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp (0 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -0,0 +1,394 @@
</span><ins>+/*
+ * Copyright (C) 2014, 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.
+ */
+#include &quot;config.h&quot;
+#include &quot;SQLiteIDBCursor.h&quot;
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;IDBCursorInfo.h&quot;
+#include &quot;IDBSerialization.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;SQLiteIDBTransaction.h&quot;
+#include &quot;SQLiteStatement.h&quot;
+#include &quot;SQLiteTransaction.h&quot;
+#include &lt;sqlite3.h&gt;
+
+namespace WebCore {
+namespace IDBServer {
+
+std::unique_ptr&lt;SQLiteIDBCursor&gt; SQLiteIDBCursor::maybeCreate(SQLiteIDBTransaction&amp; transaction, const IDBCursorInfo&amp; info)
+{
+    auto cursor = std::unique_ptr&lt;SQLiteIDBCursor&gt;(new SQLiteIDBCursor(transaction, info));
+
+    if (!cursor-&gt;establishStatement())
+        return nullptr;
+
+    if (!cursor-&gt;advance(1))
+        return nullptr;
+
+    return cursor;
+}
+
+SQLiteIDBCursor::SQLiteIDBCursor(SQLiteIDBTransaction&amp; transaction, const IDBCursorInfo&amp; info)
+    : m_transaction(&amp;transaction)
+    , m_cursorIdentifier(info.identifier())
+    , m_objectStoreID(info.objectStoreIdentifier())
+    , m_indexID(info.sourceIdentifier())
+    , m_cursorDirection(info.cursorDirection())
+    , m_keyRange(info.range())
+    , m_currentRecordID(-1)
+    , m_statementNeedsReset(false)
+    , m_boundID(0)
+    , m_completed(false)
+    , m_errored(false)
+{
+    ASSERT(m_objectStoreID);
+}
+
+static String buildIndexStatement(const IDBKeyRangeData&amp; keyRange, IndexedDB::CursorDirection cursorDirection)
+{
+    StringBuilder builder;
+
+    builder.appendLiteral(&quot;SELECT rowid, key, value FROM IndexRecords WHERE indexID = ? AND key &quot;);
+    if (!keyRange.lowerKey.isNull() &amp;&amp; !keyRange.lowerOpen)
+        builder.appendLiteral(&quot;&gt;=&quot;);
+    else
+        builder.append('&gt;');
+
+    builder.appendLiteral(&quot; CAST(? AS TEXT) AND key &quot;);
+    if (!keyRange.upperKey.isNull() &amp;&amp; !keyRange.upperOpen)
+        builder.appendLiteral(&quot;&lt;=&quot;);
+    else
+        builder.append('&lt;');
+
+    builder.appendLiteral(&quot; CAST(? AS TEXT) ORDER BY key&quot;);
+    if (cursorDirection == IndexedDB::CursorDirection::Prev || cursorDirection == IndexedDB::CursorDirection::PrevNoDuplicate)
+        builder.appendLiteral(&quot; DESC&quot;);
+
+    builder.appendLiteral(&quot;, value&quot;);
+    if (cursorDirection == IndexedDB::CursorDirection::Prev)
+        builder.appendLiteral(&quot; DESC&quot;);
+
+    builder.append(';');
+
+    return builder.toString();
+}
+
+static String buildObjectStoreStatement(const IDBKeyRangeData&amp; keyRange, IndexedDB::CursorDirection cursorDirection)
+{
+    StringBuilder builder;
+
+    builder.appendLiteral(&quot;SELECT rowid, key, value FROM Records WHERE objectStoreID = ? AND key &quot;);
+
+    if (!keyRange.lowerKey.isNull() &amp;&amp; !keyRange.lowerOpen)
+        builder.appendLiteral(&quot;&gt;=&quot;);
+    else
+        builder.append('&gt;');
+
+    builder.appendLiteral(&quot; CAST(? AS TEXT) AND key &quot;);
+
+    if (!keyRange.upperKey.isNull() &amp;&amp; !keyRange.upperOpen)
+        builder.appendLiteral(&quot;&lt;=&quot;);
+    else
+        builder.append('&lt;');
+
+    builder.appendLiteral(&quot; CAST(? AS TEXT) ORDER BY key&quot;);
+
+    if (cursorDirection == IndexedDB::CursorDirection::Prev || cursorDirection == IndexedDB::CursorDirection::PrevNoDuplicate)
+        builder.appendLiteral(&quot; DESC&quot;);
+
+    builder.append(';');
+
+    return builder.toString();
+}
+
+bool SQLiteIDBCursor::establishStatement()
+{
+    ASSERT(!m_statement);
+    String sql;
+
+    if (m_indexID != IDBIndexMetadata::InvalidId) {
+        sql = buildIndexStatement(m_keyRange, m_cursorDirection);
+        m_boundID = m_indexID;
+    } else {
+        sql = buildObjectStoreStatement(m_keyRange, m_cursorDirection);
+        m_boundID = m_objectStoreID;
+    }
+
+    m_currentLowerKey = m_keyRange.lowerKey.isNull() ? IDBKeyData::minimum() : m_keyRange.lowerKey;
+    m_currentUpperKey = m_keyRange.upperKey.isNull() ? IDBKeyData::maximum() : m_keyRange.upperKey;
+
+    return createSQLiteStatement(sql);
+}
+
+bool SQLiteIDBCursor::createSQLiteStatement(const String&amp; sql)
+{
+    LOG(IndexedDB, &quot;Creating cursor with SQL query: \&quot;%s\&quot;&quot;, sql.utf8().data());
+
+    ASSERT(!m_currentLowerKey.isNull());
+    ASSERT(!m_currentUpperKey.isNull());
+    ASSERT(m_transaction-&gt;sqliteTransaction());
+
+    m_statement = std::make_unique&lt;SQLiteStatement&gt;(m_transaction-&gt;sqliteTransaction()-&gt;database(), sql);
+
+    if (m_statement-&gt;prepare() != SQLITE_OK) {
+        LOG_ERROR(&quot;Could not create cursor statement (prepare/id) - '%s'&quot;, m_transaction-&gt;sqliteTransaction()-&gt;database().lastErrorMsg());
+        return false;
+    }
+
+    return bindArguments();
+}
+
+void SQLiteIDBCursor::objectStoreRecordsChanged()
+{
+    // If ObjectStore or Index contents changed, we need to reset the statement and bind new parameters to it.
+    // This is to pick up any changes that might exist.
+
+    m_statementNeedsReset = true;
+}
+
+void SQLiteIDBCursor::resetAndRebindStatement()
+{
+    ASSERT(!m_currentLowerKey.isNull());
+    ASSERT(!m_currentUpperKey.isNull());
+    ASSERT(m_transaction-&gt;sqliteTransaction());
+    ASSERT(m_statement);
+    ASSERT(m_statementNeedsReset);
+
+    m_statementNeedsReset = false;
+
+    // If this cursor never fetched any records, we don't need to reset the statement.
+    if (m_currentKey.isNull())
+        return;
+
+    // Otherwise update the lower key or upper key used for the cursor range.
+    // This is so the cursor can pick up where we left off.
+    if (m_cursorDirection == IndexedDB::CursorDirection::Next || m_cursorDirection == IndexedDB::CursorDirection::NextNoDuplicate)
+        m_currentLowerKey = m_currentKey;
+    else
+        m_currentUpperKey = m_currentKey;
+
+    if (m_statement-&gt;reset() != SQLITE_OK) {
+        LOG_ERROR(&quot;Could not reset cursor statement to respond to object store changes&quot;);
+        return;
+    }
+
+    bindArguments();
+}
+
+bool SQLiteIDBCursor::bindArguments()
+{
+    if (m_statement-&gt;bindInt64(1, m_boundID) != SQLITE_OK) {
+        LOG_ERROR(&quot;Could not bind id argument (bound ID)&quot;);
+        return false;
+    }
+
+    RefPtr&lt;SharedBuffer&gt; buffer = serializeIDBKeyData(m_currentLowerKey);
+    if (m_statement-&gt;bindBlob(2, buffer-&gt;data(), buffer-&gt;size()) != SQLITE_OK) {
+        LOG_ERROR(&quot;Could not create cursor statement (lower key)&quot;);
+        return false;
+    }
+
+    buffer = serializeIDBKeyData(m_currentUpperKey);
+    if (m_statement-&gt;bindBlob(3, buffer-&gt;data(), buffer-&gt;size()) != SQLITE_OK) {
+        LOG_ERROR(&quot;Could not create cursor statement (upper key)&quot;);
+        return false;
+    }
+
+    return true;
+}
+
+bool SQLiteIDBCursor::advance(uint64_t count)
+{
+    bool isUnique = m_cursorDirection == IndexedDB::CursorDirection::NextNoDuplicate || m_cursorDirection == IndexedDB::CursorDirection::PrevNoDuplicate;
+
+    for (uint64_t i = 0; i &lt; count; ++i) {
+        if (!isUnique) {
+            if (!advanceOnce())
+                return false;
+        } else {
+            if (!advanceUnique())
+                return false;
+        }
+    }
+
+    return true;
+}
+
+bool SQLiteIDBCursor::advanceUnique()
+{
+    IDBKeyData currentKey = m_currentKey;
+
+    while (!m_completed) {
+        if (!advanceOnce())
+            return false;
+
+        // If the new current key is different from the old current key, we're done.
+        if (currentKey.compare(m_currentKey))
+            return true;
+    }
+
+    return false;
+}
+
+bool SQLiteIDBCursor::advanceOnce()
+{
+    if (m_statementNeedsReset)
+        resetAndRebindStatement();
+
+    AdvanceResult result;
+    do {
+        result = internalAdvanceOnce();
+    } while (result == AdvanceResult::ShouldAdvanceAgain);
+
+    return result == AdvanceResult::Success;
+}
+
+SQLiteIDBCursor::AdvanceResult SQLiteIDBCursor::internalAdvanceOnce()
+{
+    ASSERT(m_transaction-&gt;sqliteTransaction());
+    ASSERT(m_statement);
+
+    if (m_completed) {
+        LOG_ERROR(&quot;Attempt to advance a completed cursor&quot;);
+        return AdvanceResult::Failure;
+    }
+
+    int result = m_statement-&gt;step();
+    if (result == SQLITE_DONE) {
+        m_completed = true;
+
+        // When a cursor reaches its end, that is indicated by having undefined keys/values
+        m_currentKey = IDBKeyData();
+        m_currentPrimaryKey = IDBKeyData();
+        m_currentValueBuffer.clear();
+
+        return AdvanceResult::Success;
+    }
+
+    if (result != SQLITE_ROW) {
+        LOG_ERROR(&quot;Error advancing cursor - (%i) %s&quot;, result, m_transaction-&gt;sqliteTransaction()-&gt;database().lastErrorMsg());
+        m_completed = true;
+        m_errored = true;
+        return AdvanceResult::Failure;
+    }
+
+    int64_t recordID = m_statement-&gt;getColumnInt64(0);
+
+    // If the recordID of the record just fetched is the same as the current record ID
+    // then this statement must have been re-prepared in response to an object store change.
+    // We don't want to re-use the current record so we'll move on to the next one.
+    if (recordID == m_currentRecordID)
+        return AdvanceResult::ShouldAdvanceAgain;
+
+    m_currentRecordID = recordID;
+
+    Vector&lt;uint8_t&gt; keyData;
+    m_statement-&gt;getColumnBlobAsVector(1, keyData);
+
+    if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentKey)) {
+        LOG_ERROR(&quot;Unable to deserialize key data from database while advancing cursor&quot;);
+        m_completed = true;
+        m_errored = true;
+        return AdvanceResult::Failure;
+    }
+
+    m_statement-&gt;getColumnBlobAsVector(2, keyData);
+    m_currentValueBuffer = keyData;
+
+    // The primaryKey of an ObjectStore cursor is the same as its key.
+    if (m_indexID == IDBIndexMetadata::InvalidId)
+        m_currentPrimaryKey = m_currentKey;
+    else {
+        if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentPrimaryKey)) {
+            LOG_ERROR(&quot;Unable to deserialize value data from database while advancing index cursor&quot;);
+            m_completed = true;
+            m_errored = true;
+            return AdvanceResult::Failure;
+        }
+
+        SQLiteStatement objectStoreStatement(m_statement-&gt;database(), &quot;SELECT value FROM Records WHERE key = CAST(? AS TEXT) and objectStoreID = ?;&quot;);
+
+        if (objectStoreStatement.prepare() != SQLITE_OK
+            || objectStoreStatement.bindBlob(1, m_currentValueBuffer.data(), m_currentValueBuffer.size()) != SQLITE_OK
+            || objectStoreStatement.bindInt64(2, m_objectStoreID) != SQLITE_OK) {
+            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());
+            m_completed = true;
+            m_errored = true;
+            return AdvanceResult::Failure;
+        }
+
+        int result = objectStoreStatement.step();
+
+        if (result == SQLITE_ROW)
+            objectStoreStatement.getColumnBlobAsVector(0, m_currentValueBuffer);
+        else if (result == SQLITE_DONE) {
+            // This indicates that the record we're trying to retrieve has been removed from the object store.
+            // Skip over it.
+            return AdvanceResult::ShouldAdvanceAgain;
+        } else {
+            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());
+            m_completed = true;
+            m_errored = true;
+            return AdvanceResult::Failure;
+
+        }
+    }
+
+    return AdvanceResult::Success;
+}
+
+bool SQLiteIDBCursor::iterate(const WebCore::IDBKeyData&amp; targetKey)
+{
+    ASSERT(m_transaction-&gt;sqliteTransaction());
+    ASSERT(m_statement);
+
+    bool result = advance(1);
+
+    // Iterating with no key is equivalent to advancing 1 step.
+    if (targetKey.isNull() || !result)
+        return result;
+
+    while (!m_completed) {
+        if (!result)
+            return false;
+
+        // Search for the next key &gt;= the target if the cursor is a Next cursor, or the next key &lt;= if the cursor is a Previous cursor.
+        if (m_cursorDirection == IndexedDB::CursorDirection::Next || m_cursorDirection == IndexedDB::CursorDirection::NextNoDuplicate) {
+            if (m_currentKey.compare(targetKey) &gt;= 0)
+                break;
+        } else if (m_currentKey.compare(targetKey) &lt;= 0)
+            break;
+
+        result = advance(1);
+    }
+
+    return result;
+}
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBCursorh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h (0 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -0,0 +1,113 @@
</span><ins>+/*
+ * Copyright (C) 2014, 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.
+ */
+#ifndef SQLiteIDBCursor_h
+#define SQLiteIDBCursor_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;IDBDatabaseBackend.h&quot;
+#include &quot;IDBKeyData.h&quot;
+#include &quot;IDBKeyRangeData.h&quot;
+#include &quot;IDBResourceIdentifier.h&quot;
+#include &quot;SQLiteStatement.h&quot;
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace WebCore {
+
+class IDBCursorInfo;
+
+namespace IDBServer {
+
+class SQLiteIDBTransaction;
+
+class SQLiteIDBCursor {
+    WTF_MAKE_NONCOPYABLE(SQLiteIDBCursor);
+public:
+    static std::unique_ptr&lt;SQLiteIDBCursor&gt; maybeCreate(SQLiteIDBTransaction&amp;, const IDBCursorInfo&amp;);
+
+    const IDBResourceIdentifier&amp; identifier() const { return m_cursorIdentifier; }
+    SQLiteIDBTransaction* transaction() const { return m_transaction; }
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+
+    const IDBKeyData&amp; currentKey() const { return m_currentKey; }
+    const IDBKeyData&amp; currentPrimaryKey() const { return m_currentPrimaryKey; }
+    const Vector&lt;uint8_t&gt;&amp; currentValueBuffer() const { return m_currentValueBuffer; }
+
+    bool advance(uint64_t count);
+    bool iterate(const IDBKeyData&amp; targetKey);
+
+    bool didError() const { return m_errored; }
+
+    void objectStoreRecordsChanged();
+
+private:
+    SQLiteIDBCursor(SQLiteIDBTransaction&amp;, const IDBCursorInfo&amp;);
+
+    bool establishStatement();
+    bool createSQLiteStatement(const String&amp; sql);
+    bool bindArguments();
+
+    void resetAndRebindStatement();
+
+    enum class AdvanceResult {
+        Success,
+        Failure,
+        ShouldAdvanceAgain
+    };
+
+    AdvanceResult internalAdvanceOnce();
+    bool advanceOnce();
+    bool advanceUnique();
+
+    SQLiteIDBTransaction* m_transaction;
+    IDBResourceIdentifier m_cursorIdentifier;
+    int64_t m_objectStoreID;
+    int64_t m_indexID;
+    IndexedDB::CursorDirection m_cursorDirection;
+    IDBKeyRangeData m_keyRange;
+
+    IDBKeyData m_currentLowerKey;
+    IDBKeyData m_currentUpperKey;
+
+    int64_t m_currentRecordID;
+    IDBKeyData m_currentKey;
+    IDBKeyData m_currentPrimaryKey;
+    Vector&lt;uint8_t&gt; m_currentValueBuffer;
+
+    std::unique_ptr&lt;SQLiteStatement&gt; m_statement;
+    bool m_statementNeedsReset;
+    int64_t m_boundID;
+
+    bool m_completed;
+    bool m_errored;
+};
+
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+#endif // SQLiteIDBCursor_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBTransactioncpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp (0 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+/*
+ * Copyright (C) 2013, 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.
+ */
+#include &quot;config.h&quot;
+#include &quot;SQLiteIDBTransaction.h&quot;
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;IDBCursorInfo.h&quot;
+#include &quot;IndexedDB.h&quot;
+#include &quot;SQLiteIDBBackingStore.h&quot;
+#include &quot;SQLiteIDBCursor.h&quot;
+#include &quot;SQLiteTransaction.h&quot;
+
+namespace WebCore {
+namespace IDBServer {
+
+SQLiteIDBTransaction::SQLiteIDBTransaction(SQLiteIDBBackingStore&amp; backingStore, const IDBResourceIdentifier&amp; transactionIdentifier, IndexedDB::TransactionMode mode)
+    : m_identifier(transactionIdentifier)
+    , m_mode(mode)
+    , m_backingStore(backingStore)
+{
+}
+
+SQLiteIDBTransaction::~SQLiteIDBTransaction()
+{
+    if (inProgress())
+        m_sqliteTransaction-&gt;rollback();
+
+    // Explicitly clear cursors, as that also unregisters them from the backing store.
+    clearCursors();
+}
+
+
+bool SQLiteIDBTransaction::begin(SQLiteDatabase&amp; database)
+{
+    ASSERT(!m_sqliteTransaction);
+    m_sqliteTransaction = std::make_unique&lt;SQLiteTransaction&gt;(database, m_mode == IndexedDB::TransactionMode::ReadOnly);
+
+    m_sqliteTransaction-&gt;begin();
+
+    return m_sqliteTransaction-&gt;inProgress();
+}
+
+bool SQLiteIDBTransaction::commit()
+{
+    // It's okay to not have a SQLite transaction or not have started it yet because it's okay for a WebProcess
+    // to request the commit of a transaction immediately after creating it before it has even been used.
+    if (!m_sqliteTransaction || !m_sqliteTransaction-&gt;inProgress())
+        return false;
+
+    m_sqliteTransaction-&gt;commit();
+
+    return !m_sqliteTransaction-&gt;inProgress();
+}
+
+bool SQLiteIDBTransaction::reset()
+{
+    m_sqliteTransaction = nullptr;
+    clearCursors();
+
+    return true;
+}
+
+bool SQLiteIDBTransaction::rollback()
+{
+    ASSERT(m_sqliteTransaction);
+    if (m_sqliteTransaction-&gt;inProgress())
+        m_sqliteTransaction-&gt;rollback();
+
+    return true;
+}
+
+SQLiteIDBCursor* SQLiteIDBTransaction::maybeOpenCursor(const IDBCursorInfo&amp; info)
+{
+    ASSERT(m_sqliteTransaction);
+    if (!m_sqliteTransaction-&gt;inProgress())
+        return nullptr;
+
+    auto addResult = m_cursors.add(info.identifier(), SQLiteIDBCursor::maybeCreate(*this, info));
+
+    ASSERT(addResult.isNewEntry);
+
+    // It is possible the cursor failed to create and we just stored a null value.
+    if (!addResult.iterator-&gt;value) {
+        m_cursors.remove(addResult.iterator);
+        return nullptr;
+    }
+
+    return addResult.iterator-&gt;value.get();
+}
+
+void SQLiteIDBTransaction::closeCursor(SQLiteIDBCursor&amp; cursor)
+{
+    ASSERT(m_cursors.contains(cursor.identifier()));
+
+    m_backingStore.unregisterCursor(cursor);
+    m_cursors.remove(cursor.identifier());
+}
+
+void SQLiteIDBTransaction::notifyCursorsOfChanges(int64_t objectStoreID)
+{
+    for (auto&amp; i : m_cursors) {
+        if (i.value-&gt;objectStoreID() == objectStoreID)
+            i.value-&gt;objectStoreRecordsChanged();
+    }
+}
+
+void SQLiteIDBTransaction::clearCursors()
+{
+    for (auto&amp; cursor : m_cursors.values())
+        m_backingStore.unregisterCursor(*cursor);
+
+    m_cursors.clear();
+}
+
+bool SQLiteIDBTransaction::inProgress() const
+{
+    return m_sqliteTransaction &amp;&amp; m_sqliteTransaction-&gt;inProgress();
+}
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
</ins></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverSQLiteIDBTransactionh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h (0 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h                                (rev 0)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -0,0 +1,86 @@
</span><ins>+/*
+ * Copyright (C) 2013, 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.
+ */
+
+#ifndef SQLiteIDBTransaction_h
+#define SQLiteIDBTransaction_h
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include &quot;IDBResourceIdentifier.h&quot;
+#include &quot;IndexedDB.h&quot;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+
+namespace WebCore {
+
+class IDBCursorInfo;
+class SQLiteDatabase;
+class SQLiteTransaction;
+struct IDBKeyRangeData;
+
+namespace IDBServer {
+
+class SQLiteIDBBackingStore;
+class SQLiteIDBCursor;
+
+class SQLiteIDBTransaction {
+    WTF_MAKE_NONCOPYABLE(SQLiteIDBTransaction);
+public:
+    SQLiteIDBTransaction(SQLiteIDBBackingStore&amp;, const IDBResourceIdentifier&amp; transactionIdentifier, IndexedDB::TransactionMode);
+    ~SQLiteIDBTransaction();
+
+    const IDBResourceIdentifier&amp; transactionIdentifier() const { return m_identifier; }
+
+    bool begin(SQLiteDatabase&amp;);
+    bool commit();
+    bool reset();
+    bool rollback();
+
+    SQLiteIDBCursor* maybeOpenCursor(const IDBCursorInfo&amp;);
+
+    void closeCursor(SQLiteIDBCursor&amp;);
+    void notifyCursorsOfChanges(int64_t objectStoreID);
+
+    IndexedDB::TransactionMode mode() const { return m_mode; }
+    bool inProgress() const;
+
+    SQLiteTransaction* sqliteTransaction() const { return m_sqliteTransaction.get(); }
+
+private:
+    void clearCursors();
+
+    IDBResourceIdentifier m_identifier;
+    IndexedDB::TransactionMode m_mode;
+
+    SQLiteIDBBackingStore&amp; m_backingStore;
+    std::unique_ptr&lt;SQLiteTransaction&gt; m_sqliteTransaction;
+    HashMap&lt;IDBResourceIdentifier, std::unique_ptr&lt;SQLiteIDBCursor&gt;&gt; m_cursors;
+};
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+#endif // SQLiteIDBTransaction_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -1932,6 +1932,12 @@
</span><span class="cx">                 510D4A36103165EE0049EA54 /* SocketStreamHandleBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510D4A30103165EE0049EA54 /* SocketStreamHandleBase.cpp */; };
</span><span class="cx">                 510D4A37103165EE0049EA54 /* SocketStreamHandleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A31103165EE0049EA54 /* SocketStreamHandleBase.h */; };
</span><span class="cx">                 510D4A38103165EE0049EA54 /* SocketStreamHandleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */; };
</span><ins>+                511EC1271C50AACA0032F983 /* IDBSerialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EC1251C50AA570032F983 /* IDBSerialization.cpp */; };
+                511EC1281C50AACA0032F983 /* IDBSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = 511EC1261C50AA570032F983 /* IDBSerialization.h */; };
+                511EC12B1C50ABBF0032F983 /* SQLiteIDBTransaction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EC1291C50ABBA0032F983 /* SQLiteIDBTransaction.cpp */; };
+                511EC12C1C50ABBF0032F983 /* SQLiteIDBTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 511EC12A1C50ABBA0032F983 /* SQLiteIDBTransaction.h */; };
+                511EC12F1C50ABF50032F983 /* SQLiteIDBCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EC12D1C50ABEC0032F983 /* SQLiteIDBCursor.cpp */; };
+                511EC1301C50ABF50032F983 /* SQLiteIDBCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 511EC12E1C50ABEC0032F983 /* SQLiteIDBCursor.h */; };
</ins><span class="cx">                 511EF2C017F0FD3500E4FA16 /* JSIDBAny.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2A817F0FC4800E4FA16 /* JSIDBAny.cpp */; };
</span><span class="cx">                 511EF2C117F0FD3500E4FA16 /* JSIDBCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2A917F0FC4800E4FA16 /* JSIDBCursor.cpp */; };
</span><span class="cx">                 511EF2C217F0FD3500E4FA16 /* JSIDBCursorWithValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2AA17F0FC4800E4FA16 /* JSIDBCursorWithValue.cpp */; };
</span><span class="lines">@@ -9369,6 +9375,12 @@
</span><span class="cx">                 510D4A30103165EE0049EA54 /* SocketStreamHandleBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketStreamHandleBase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 510D4A31103165EE0049EA54 /* SocketStreamHandleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamHandleBase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamHandleClient.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                511EC1251C50AA570032F983 /* IDBSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBSerialization.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                511EC1261C50AA570032F983 /* IDBSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBSerialization.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                511EC1291C50ABBA0032F983 /* SQLiteIDBTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteIDBTransaction.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                511EC12A1C50ABBA0032F983 /* SQLiteIDBTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteIDBTransaction.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                511EC12D1C50ABEC0032F983 /* SQLiteIDBCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteIDBCursor.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                511EC12E1C50ABEC0032F983 /* SQLiteIDBCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteIDBCursor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 511EC1A5188DACA400BA3EB6 /* IDBKeyData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBKeyData.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 511EC1A7188DAE7B00BA3EB6 /* IDBKeyData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBKeyData.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 511EF2A817F0FC4800E4FA16 /* JSIDBAny.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBAny.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -16969,6 +16981,8 @@
</span><span class="cx">                                 516D7D6D1BB5F06500AF7C77 /* IDBConnectionToClient.cpp */,
</span><span class="cx">                                 510A58FE1BB07AA500C19282 /* IDBConnectionToClient.h */,
</span><span class="cx">                                 516D7D6E1BB5F06500AF7C77 /* IDBConnectionToClientDelegate.h */,
</span><ins>+                                511EC1251C50AA570032F983 /* IDBSerialization.cpp */,
+                                511EC1261C50AA570032F983 /* IDBSerialization.h */,
</ins><span class="cx">                                 510A58EF1BAB720F00C19282 /* IDBServer.cpp */,
</span><span class="cx">                                 510A58F01BAB720F00C19282 /* IDBServer.h */,
</span><span class="cx">                                 51EEAA711BEFFA7900218008 /* IndexValueEntry.cpp */,
</span><span class="lines">@@ -16991,6 +17005,10 @@
</span><span class="cx">                                 517139041BF64DE3000D5F01 /* MemoryObjectStoreCursor.h */,
</span><span class="cx">                                 512BDB481C456FAB006494DF /* SQLiteIDBBackingStore.cpp */,
</span><span class="cx">                                 512BDB491C456FAB006494DF /* SQLiteIDBBackingStore.h */,
</span><ins>+                                511EC12D1C50ABEC0032F983 /* SQLiteIDBCursor.cpp */,
+                                511EC12E1C50ABEC0032F983 /* SQLiteIDBCursor.h */,
+                                511EC1291C50ABBA0032F983 /* SQLiteIDBTransaction.cpp */,
+                                511EC12A1C50ABBA0032F983 /* SQLiteIDBTransaction.h */,
</ins><span class="cx">                                 516F7F6B1C31C79D00F111DC /* ServerOpenDBRequest.cpp */,
</span><span class="cx">                                 516F7F6C1C31C79D00F111DC /* ServerOpenDBRequest.h */,
</span><span class="cx">                                 518864DE1BBAF30F00E540C9 /* UniqueIDBDatabase.cpp */,
</span><span class="lines">@@ -26633,6 +26651,7 @@
</span><span class="cx">                                 1A762C780A074F2600989F5B /* JSXPathNSResolver.h in Headers */,
</span><span class="cx">                                 1A762C7A0A074F2600989F5B /* JSXPathResult.h in Headers */,
</span><span class="cx">                                 BCEFE1EB0DCA5F6400739219 /* JSXSLTProcessor.h in Headers */,
</span><ins>+                                511EC1301C50ABF50032F983 /* SQLiteIDBCursor.h in Headers */,
</ins><span class="cx">                                 85031B440A44EFC700F992E0 /* KeyboardEvent.h in Headers */,
</span><span class="cx">                                 1AE00D59182DAC8D00087DD7 /* KeyedCoding.h in Headers */,
</span><span class="cx">                                 517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */,
</span><span class="lines">@@ -27339,6 +27358,7 @@
</span><span class="cx">                                 078E094317D16E1C00420AA1 /* RTCSessionDescriptionDescriptor.h in Headers */,
</span><span class="cx">                                 078E094417D16E1C00420AA1 /* RTCSessionDescriptionRequest.h in Headers */,
</span><span class="cx">                                 078E092A17D14D1C00420AA1 /* RTCStatsReport.h in Headers */,
</span><ins>+                                511EC1281C50AACA0032F983 /* IDBSerialization.h in Headers */,
</ins><span class="cx">                                 078E094517D16E1C00420AA1 /* RTCStatsRequest.h in Headers */,
</span><span class="cx">                                 078E092C17D14D1C00420AA1 /* RTCStatsResponse.h in Headers */,
</span><span class="cx">                                 078E094617D16E1C00420AA1 /* RTCStatsResponseBase.h in Headers */,
</span><span class="lines">@@ -27647,6 +27667,7 @@
</span><span class="cx">                                 B22279A50D00BF220071B782 /* SVGComponentTransferFunctionElement.h in Headers */,
</span><span class="cx">                                 B22279A80D00BF220071B782 /* SVGCursorElement.h in Headers */,
</span><span class="cx">                                 B22279AE0D00BF220071B782 /* SVGDefsElement.h in Headers */,
</span><ins>+                                511EC12C1C50ABBF0032F983 /* SQLiteIDBTransaction.h in Headers */,
</ins><span class="cx">                                 B22279B10D00BF220071B782 /* SVGDescElement.h in Headers */,
</span><span class="cx">                                 B22279B40D00BF220071B782 /* SVGDocument.h in Headers */,
</span><span class="cx">                                 B28C6A280D00C44800334AA4 /* SVGDocumentExtensions.h in Headers */,
</span><span class="lines">@@ -30007,6 +30028,7 @@
</span><span class="cx">                                 C6F08FC91431000D00685849 /* JSMutationRecord.cpp in Sources */,
</span><span class="cx">                                 BCD9C2C00C17B69E005C90A2 /* JSNamedNodeMap.cpp in Sources */,
</span><span class="cx">                                 BCD9C2630C17AA67005C90A2 /* JSNamedNodeMapCustom.cpp in Sources */,
</span><ins>+                                511EC1271C50AACA0032F983 /* IDBSerialization.cpp in Sources */,
</ins><span class="cx">                                 A9D247F70D757E3400FDF959 /* JSNavigator.cpp in Sources */,
</span><span class="cx">                                 073BE34017D17E01002BD431 /* JSNavigatorUserMedia.cpp in Sources */,
</span><span class="cx">                                 073BE34817D17E7A002BD431 /* JSNavigatorUserMediaError.cpp in Sources */,
</span><span class="lines">@@ -31213,6 +31235,7 @@
</span><span class="cx">                                 B2227A020D00BF220071B782 /* SVGFESpotLightElement.cpp in Sources */,
</span><span class="cx">                                 B2227A050D00BF220071B782 /* SVGFETileElement.cpp in Sources */,
</span><span class="cx">                                 B2227A080D00BF220071B782 /* SVGFETurbulenceElement.cpp in Sources */,
</span><ins>+                                511EC12B1C50ABBF0032F983 /* SQLiteIDBTransaction.cpp in Sources */,
</ins><span class="cx">                                 845E72FB0FD2623900A87D79 /* SVGFilter.cpp in Sources */,
</span><span class="cx">                                 081EBF3A0FD34F4100DA7559 /* SVGFilterBuilder.cpp in Sources */,
</span><span class="cx">                                 B2227A0B0D00BF220071B782 /* SVGFilterElement.cpp in Sources */,
</span><span class="lines">@@ -31454,6 +31477,7 @@
</span><span class="cx">                                 CD336F6717FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.cpp in Sources */,
</span><span class="cx">                                 CD8B5A42180D149A008B8E65 /* VideoTrackPrivateMediaSourceAVFObjC.mm in Sources */,
</span><span class="cx">                                 CEF418CE1179678C009D112C /* ViewportArguments.cpp in Sources */,
</span><ins>+                                511EC12F1C50ABF50032F983 /* SQLiteIDBCursor.cpp in Sources */,
</ins><span class="cx">                                 26F9A83818A046AC00AEB88A /* ViewportConfiguration.cpp in Sources */,
</span><span class="cx">                                 3FFFF9AD159D9B060020BBD5 /* ViewportStyleResolver.cpp in Sources */,
</span><span class="cx">                                 93309E1F099E64920056E581 /* VisiblePosition.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorepagePagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/Page.cpp (195442 => 195443)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/Page.cpp        2016-01-22 05:54:31 UTC (rev 195442)
+++ trunk/Source/WebCore/page/Page.cpp        2016-01-22 06:39:57 UTC (rev 195443)
</span><span class="lines">@@ -1735,6 +1735,9 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(sessionID.isValid());
</span><span class="cx"> 
</span><ins>+    if (sessionID != m_sessionID)
+        m_idbIDBConnectionToServer = nullptr;
+
</ins><span class="cx">     bool privateBrowsingStateChanged = (sessionID.isEphemeral() != m_sessionID.isEphemeral());
</span><span class="cx"> 
</span><span class="cx">     m_sessionID = sessionID;
</span><span class="lines">@@ -1836,13 +1839,8 @@
</span><span class="cx"> #if ENABLE(INDEXED_DATABASE)
</span><span class="cx"> IDBClient::IDBConnectionToServer&amp; Page::idbConnection()
</span><span class="cx"> {
</span><del>-    if (!m_idbIDBConnectionToServer) {
-        if (usesEphemeralSession()) {
-            auto inProcessServer = InProcessIDBServer::create();
-            m_idbIDBConnectionToServer = &amp;inProcessServer-&gt;connectionToServer();
-        } else
-            m_idbIDBConnectionToServer = &amp;databaseProvider().idbConnectionToServerForSession(m_sessionID);
-    }
</del><ins>+    if (!m_idbIDBConnectionToServer)
+        m_idbIDBConnectionToServer = &amp;databaseProvider().idbConnectionToServerForSession(m_sessionID);
</ins><span class="cx">     
</span><span class="cx">     return *m_idbIDBConnectionToServer;
</span><span class="cx"> }
</span></span></pre>
</div>
</div>

</body>
</html>