Modern IDB: Support populating/extracting database metadata with SQLite backend.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Jan 2016 06:39:57 +0000 (06:39 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Jan 2016 06:39:57 +0000 (06:39 +0000)
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!)

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@195443 268f45cc-cd09-0410-ab3c-d52691b4dbfc

17 files changed:
LayoutTests/ChangeLog
LayoutTests/platform/mac-wk1/TestExpectations
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/client/IDBDatabaseImpl.cpp
Source/WebCore/Modules/indexeddb/client/IDBTransactionImpl.cpp
Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/IDBSerialization.h [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h
Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp [new file with mode: 0644]
Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h [new file with mode: 0644]
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/Page.cpp

index 32751f0..032a7d0 100644 (file)
@@ -1,3 +1,13 @@
+2016-01-21  Brady Eidson  <beidson@apple.com>
+
+        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!)
+
 2016-01-21  Nikita Vasilyev  <nvasilyev@apple.com>
 
         REGRESSION (r195305): Web Inspector: WebInspector.Object can dispatch constructor-level events multiple times
index fed4d48..07dddbe 100644 (file)
@@ -243,3 +243,451 @@ webgl/1.0.3/151055_asan.html [ Failure ]
 
 # Lacking WK1 TestRunner API that evaluates JavaScript through JSC APIs and not WebCore APIs
 inspector/script-profiler/event-type-API.html
+
+########################################
+### 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
+########################################
index 17b36dd..945fb75 100644 (file)
@@ -874,6 +874,7 @@ set(WebCore_SOURCES
     Modules/indexeddb/legacy/LegacyVersionChangeEvent.cpp
 
     Modules/indexeddb/server/IDBConnectionToClient.cpp
+    Modules/indexeddb/server/IDBSerialization.cpp
     Modules/indexeddb/server/IDBServer.cpp
     Modules/indexeddb/server/IndexValueEntry.cpp
     Modules/indexeddb/server/IndexValueStore.cpp
@@ -885,6 +886,8 @@ set(WebCore_SOURCES
     Modules/indexeddb/server/MemoryObjectStore.cpp
     Modules/indexeddb/server/MemoryObjectStoreCursor.cpp
     Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
+    Modules/indexeddb/server/SQLiteIDBCursor.cpp
+    Modules/indexeddb/server/SQLiteIDBTransaction.cpp
     Modules/indexeddb/server/ServerOpenDBRequest.cpp
     Modules/indexeddb/server/UniqueIDBDatabase.cpp
     Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
index 8998f3e..71dfd65 100644 (file)
@@ -1,3 +1,102 @@
+2016-01-21  Brady Eidson  <beidson@apple.com>
+
+        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.
+
 2016-01-21  Alex Christensen  <achristensen@webkit.org>
 
         CMake build fix after r195302.
index c09339e..5e944ed 100644 (file)
@@ -330,6 +330,9 @@ void IDBDatabase::willAbortTransaction(IDBTransaction& transaction)
     LOG(IndexedDB, "IDBDatabase::willAbortTransaction %s", transaction.info().identifier().loggingString().utf8().data());
 
     auto refTransaction = m_activeTransactions.take(transaction.info().identifier());
+    if (!refTransaction)
+        refTransaction = m_committingTransactions.take(transaction.info().identifier());
+
     ASSERT(refTransaction);
     m_abortingTransactions.set(transaction.info().identifier(), WTFMove(refTransaction));
 
index fadc141..e5288cb 100644 (file)
@@ -386,8 +386,10 @@ void IDBTransaction::didCommit(const IDBError& error)
     if (error.isNull()) {
         m_database->didCommitTransaction(*this);
         fireOnComplete();
-    } else
+    } else {
+        m_database->willAbortTransaction(*this);
         notifyDidAbort(error);
+    }
 
     finishAbortOrCommit();
 }
diff --git a/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp b/Source/WebCore/Modules/indexeddb/server/IDBSerialization.cpp
new file mode 100644 (file)
index 0000000..ce159aa
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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 "config.h"
+#include "IDBSerialization.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBKeyData.h"
+#include "IDBKeyPath.h"
+#include "KeyedCoding.h"
+
+namespace WebCore {
+
+RefPtr<SharedBuffer> serializeIDBKeyPath(const IDBKeyPath& keyPath)
+{
+    auto encoder = KeyedEncoder::encoder();
+    keyPath.encode(*encoder);
+    return encoder->finishEncoding();
+}
+
+bool deserializeIDBKeyPath(const uint8_t* data, size_t size, IDBKeyPath& result)
+{
+    if (!data || !size)
+        return false;
+
+    auto decoder = KeyedDecoder::decoder(data, size);
+    return IDBKeyPath::decode(*decoder, result);
+}
+
+RefPtr<SharedBuffer> serializeIDBKeyData(const IDBKeyData& key)
+{
+    auto encoder = KeyedEncoder::encoder();
+    key.encode(*encoder);
+    return encoder->finishEncoding();
+}
+
+bool deserializeIDBKeyData(const uint8_t* data, size_t size, IDBKeyData& result)
+{
+    if (!data || !size)
+        return false;
+
+    auto decoder = KeyedDecoder::decoder(data, size);
+    return IDBKeyData::decode(*decoder, result);
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h b/Source/WebCore/Modules/indexeddb/server/IDBSerialization.h
new file mode 100644 (file)
index 0000000..e644595
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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 "SharedBuffer.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class IDBKeyData;
+class IDBKeyPath;
+
+RefPtr<SharedBuffer> serializeIDBKeyPath(const IDBKeyPath&);
+bool deserializeIDBKeyPath(const uint8_t* buffer, size_t bufferSize, IDBKeyPath&);
+
+RefPtr<SharedBuffer> serializeIDBKeyData(const IDBKeyData&);
+bool deserializeIDBKeyData(const uint8_t* buffer, size_t bufferSize, IDBKeyData&);
+
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+#endif // IDBSerialization_h
index 848a9d7..b9f4e20 100644 (file)
@@ -117,9 +117,10 @@ std::unique_ptr<IDBBackingStore> IDBServer::createBackingStore(const IDBDatabase
 {
     ASSERT(!isMainThread());
 
-    // FIXME: Once the SQLite backing store is functional, conditionally make either a Memory or SQLite backing store.
+    if (m_databaseDirectoryPath.isEmpty())
+        return MemoryIDBBackingStore::create(identifier);
 
-    return MemoryIDBBackingStore::create(identifier);
+    return std::make_unique<SQLiteIDBBackingStore>(identifier, m_databaseDirectoryPath);
 }
 
 void IDBServer::openDatabase(const IDBRequestData& requestData)
index 8288755..03f804f 100644 (file)
 #include "FileSystem.h"
 #include "IDBDatabaseException.h"
 #include "IDBKeyData.h"
+#include "IDBSerialization.h"
+#include "IDBTransactionInfo.h"
 #include "Logging.h"
 #include "SQLiteDatabase.h"
 #include "SQLiteFileSystem.h"
+#include "SQLiteIDBCursor.h"
+#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
 #include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 namespace IDBServer {
 
+// 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<const uint8_t*>(aBuffer), aLength, a)) {
+        LOG_ERROR("Unable to deserialize key A in collation function.");
+
+        // There's no way to indicate an error to SQLite - we have to return a sorting decision.
+        // We arbitrarily choose "A > B"
+        return 1;
+    }
+    if (!deserializeIDBKeyData(static_cast<const uint8_t*>(bBuffer), bLength, b)) {
+        LOG_ERROR("Unable to deserialize key B in collation function.");
+
+        // There's no way to indicate an error to SQLite - we have to return a sorting decision.
+        // We arbitrarily choose "A > B"
+        return 1;
+    }
+
+    return a.compare(b);
+}
+
+static const String v1RecordsTableSchema(const String& tableName)
+{
+    return makeString("CREATE TABLE ", tableName, " (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)");
+}
+
+static const String& v1RecordsTableSchema()
+{
+    static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("Records"));
+    return v1RecordsTableSchemaString;
+}
+
+static const String& v1RecordsTableSchemaAlternate()
+{
+    static NeverDestroyed<WTF::String> v1RecordsTableSchemaString(v1RecordsTableSchema("\"Records\""));
+    return v1RecordsTableSchemaString;
+}
+
+static const String v2RecordsTableSchema(const String& tableName)
+{
+    return makeString("CREATE TABLE ", tableName, " (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL, key TEXT COLLATE IDBKEY NOT NULL ON CONFLICT FAIL, value NOT NULL ON CONFLICT FAIL)");
+}
+
+static const String& v2RecordsTableSchema()
+{
+    static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("Records"));
+    return v2RecordsTableSchemaString;
+}
+
+static const String& v2RecordsTableSchemaAlternate()
+{
+    static NeverDestroyed<WTF::String> v2RecordsTableSchemaString(v2RecordsTableSchema("\"Records\""));
+    return v2RecordsTableSchemaString;
+}
+
 SQLiteIDBBackingStore::SQLiteIDBBackingStore(const IDBDatabaseIdentifier& identifier, const String& databaseRootDirectory)
     : m_identifier(identifier)
 {
@@ -51,6 +114,282 @@ SQLiteIDBBackingStore::~SQLiteIDBBackingStore()
         m_sqliteDB->close();
 }
 
+static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase& database)
+{
+    String currentSchema;
+    {
+        // Fetch the schema for an existing records table.
+        SQLiteStatement statement(database, "SELECT type, sql FROM sqlite_master WHERE tbl_name='Records'");
+        if (statement.prepare() != SQLITE_OK) {
+            LOG_ERROR("Unable to prepare statement to fetch schema for the Records table.");
+            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("Could not create Records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
+                return false;
+            }
+
+            return true;
+        }
+
+        if (sqliteResult != SQLITE_ROW) {
+            LOG_ERROR("Error executing statement to fetch schema for the Records table.");
+            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() && 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("_Temp_Records"))) {
+        LOG_ERROR("Could not create temporary records table in database (%i) - %s", database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    if (!database.executeCommand("INSERT INTO _Temp_Records SELECT * FROM Records")) {
+        LOG_ERROR("Could not migrate existing Records content (%i) - %s", database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    if (!database.executeCommand("DROP TABLE Records")) {
+        LOG_ERROR("Could not drop existing Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    if (!database.executeCommand("ALTER TABLE _Temp_Records RENAME TO Records")) {
+        LOG_ERROR("Could not rename temporary Records table (%i) - %s", database.lastError(), database.lastErrorMsg());
+        return false;
+    }
+
+    transaction.commit();
+
+    return true;
+}
+
+bool SQLiteIDBBackingStore::ensureValidRecordsTable()
+{
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB->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->executeCommand("CREATE UNIQUE INDEX IF NOT EXISTS RecordsIndex ON Records (objectStoreID, key);")) {
+        LOG_ERROR("Could not create RecordsIndex on Records table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        return false;
+    }
+
+    return true;
+}
+
+std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::createAndPopulateInitialDatabaseInfo()
+{
+    ASSERT(m_sqliteDB);
+    ASSERT(m_sqliteDB->isOpen());
+
+    if (!m_sqliteDB->executeCommand("CREATE TABLE IDBDatabaseInfo (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, value TEXT NOT NULL ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create IDBDatabaseInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    if (!m_sqliteDB->executeCommand("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);")) {
+        LOG_ERROR("Could not create ObjectStoreInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    if (!m_sqliteDB->executeCommand("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);")) {
+        LOG_ERROR("Could not create IndexInfo table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    if (!m_sqliteDB->executeCommand("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);")) {
+        LOG_ERROR("Could not create IndexRecords table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    if (!m_sqliteDB->executeCommand("CREATE TABLE KeyGenerators (objectStoreID INTEGER NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE, currentKey INTEGER NOT NULL ON CONFLICT FAIL);")) {
+        LOG_ERROR("Could not create KeyGenerators table in database (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+        m_sqliteDB = nullptr;
+        return nullptr;
+    }
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MetadataVersion', ?);"));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindInt(1, currentMetadataVersion) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR("Could not insert database metadata version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            m_sqliteDB = nullptr;
+            return nullptr;
+        }
+    }
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseName', ?);"));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindText(1, m_identifier.databaseName()) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR("Could not insert database name into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->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("INSERT INTO IDBDatabaseInfo VALUES ('DatabaseVersion', ?);"));
+        if (sql.prepare() != SQLITE_OK
+            || sql.bindText(1, String::number(0)) != SQLITE_OK
+            || sql.step() != SQLITE_DONE) {
+            LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+            m_sqliteDB = nullptr;
+            return nullptr;
+        }
+    }
+
+    if (!m_sqliteDB->executeCommand(ASCIILiteral("INSERT INTO IDBDatabaseInfo VALUES ('MaxObjectStoreID', 1);"))) {
+        LOG_ERROR("Could not insert default version into IDBDatabaseInfo table (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->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<IDBDatabaseInfo>(m_identifier.databaseName(), 0);
+}
+
+std::unique_ptr<IDBDatabaseInfo> SQLiteIDBBackingStore::extractExistingDatabaseInfo()
+{
+    ASSERT(m_sqliteDB);
+
+    if (!m_sqliteDB->tableExists(ASCIILiteral("IDBDatabaseInfo")))
+        return nullptr;
+
+    String databaseName;
+    {
+        SQLiteStatement sql(*m_sqliteDB, "SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseName';");
+        if (sql.isColumnNull(0))
+            return nullptr;
+        databaseName = sql.getColumnText(0);
+        if (databaseName != m_identifier.databaseName()) {
+            LOG_ERROR("Database name in the info database ('%s') does not match the expected name ('%s')", databaseName.utf8().data(), m_identifier.databaseName().utf8().data());
+            return nullptr;
+        }
+    }
+    uint64_t databaseVersion;
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT value FROM IDBDatabaseInfo WHERE key = 'DatabaseVersion';"));
+        if (sql.isColumnNull(0))
+            return nullptr;
+        String stringVersion = sql.getColumnText(0);
+        bool ok;
+        databaseVersion = stringVersion.toUInt64Strict(&ok);
+        if (!ok) {
+            LOG_ERROR("Database version on disk ('%s') does not cleanly convert to an unsigned 64-bit integer version", stringVersion.utf8().data());
+            return nullptr;
+        }
+    }
+
+    auto databaseInfo = std::make_unique<IDBDatabaseInfo>(databaseName, databaseVersion);
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, keyPath, autoInc, maxIndexID FROM ObjectStoreInfo;"));
+        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<char> keyPathBuffer;
+            sql.getColumnBlobAsVector(2, keyPathBuffer);
+
+            IDBKeyPath objectStoreKeyPath;
+            if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), objectStoreKeyPath)) {
+                LOG_ERROR("Unable to extract key path from database");
+                return nullptr;
+            }
+
+            bool autoIncrement = sql.getColumnInt(3);
+
+            databaseInfo->addExistingObjectStore({ objectStoreID, objectStoreName, objectStoreKeyPath, autoIncrement });
+
+            result = sql.step();
+        }
+
+        if (result != SQLITE_DONE) {
+            LOG_ERROR("Error fetching object store info from database on disk");
+            return nullptr;
+        }
+    }
+
+    {
+        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT id, name, objectStoreID, keyPath, isUnique, multiEntry FROM IndexInfo;"));
+        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<char> keyPathBuffer;
+            sql.getColumnBlobAsVector(3, keyPathBuffer);
+
+            IDBKeyPath indexKeyPath;
+            if (!deserializeIDBKeyPath(reinterpret_cast<const uint8_t*>(keyPathBuffer.data()), keyPathBuffer.size(), indexKeyPath)) {
+                LOG_ERROR("Unable to extract key path from database");
+                return nullptr;
+            }
+
+            bool unique = sql.getColumnInt(4);
+            bool multiEntry = sql.getColumnInt(5);
+
+            auto objectStore = databaseInfo->infoForExistingObjectStore(objectStoreID);
+            if (!objectStore) {
+                LOG_ERROR("Found index referring to a non-existant object store");
+                return nullptr;
+            }
+
+            objectStore->addExistingIndex({ indexID, objectStoreID, indexName, indexKeyPath, unique, multiEntry });
+
+            result = sql.step();
+        }
+
+        if (result != SQLITE_DONE) {
+            LOG_ERROR("Error fetching index info from database on disk");
+            return nullptr;
+        }
+    }
+
+    return databaseInfo;
+}
+
 const IDBDatabaseInfo& SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()
 {
     LOG(IndexedDB, "SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s", m_identifier.databaseName().utf8().data());
@@ -73,29 +412,57 @@ const IDBDatabaseInfo& SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()
     if (!m_sqliteDB)
         return *m_databaseInfo;
 
-    // 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.
+    m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) {
+        return idbKeyCollate(aLength, a, bLength, b);
+    });
+
+    if (!ensureValidRecordsTable()) {
+        LOG_ERROR("Error creating or migrating Records table in database");
+        m_sqliteDB = nullptr;
+        return *m_databaseInfo;
+    }
+
+    auto databaseInfo = extractExistingDatabaseInfo();
+    if (!databaseInfo)
+        databaseInfo = createAndPopulateInitialDatabaseInfo();
+
+    if (!databaseInfo)
+        LOG_ERROR("Unable to establish IDB database at path '%s'", dbFilename.utf8().data());
+    else
+        m_databaseInfo = WTFMove(databaseInfo);
 
     return *m_databaseInfo;
 }
 
-IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo&)
+IDBError SQLiteIDBBackingStore::beginTransaction(const IDBTransactionInfo& info)
 {
+    LOG(IndexedDB, "SQLiteIDBBackingStore::beginTransaction - %s", info.identifier().loggingString().utf8().data());
+    UNUSED_PARAM(info);
+
     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
 }
 
-IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier&)
+IDBError SQLiteIDBBackingStore::abortTransaction(const IDBResourceIdentifier& identifier)
 {
+    LOG(IndexedDB, "SQLiteIDBBackingStore::abortTransaction - %s", identifier.loggingString().utf8().data());
+    UNUSED_PARAM(identifier);
+
     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
 }
 
-IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier&)
+IDBError SQLiteIDBBackingStore::commitTransaction(const IDBResourceIdentifier& identifier)
 {
+    LOG(IndexedDB, "SQLiteIDBBackingStore::commitTransaction - %s", identifier.loggingString().utf8().data());
+    UNUSED_PARAM(identifier);
+
     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
 }
 
-IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier&, const IDBObjectStoreInfo&)
+IDBError SQLiteIDBBackingStore::createObjectStore(const IDBResourceIdentifier&, const IDBObjectStoreInfo& info)
 {
+    LOG(IndexedDB, "SQLiteIDBBackingStore::createObjectStore - adding OS %s with ID %" PRIu64, info.name().utf8().data(), info.identifier());
+    UNUSED_PARAM(info);
+
     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
 }
 
@@ -189,6 +556,12 @@ void SQLiteIDBBackingStore::deleteBackingStore()
     SQLiteFileSystem::deleteEmptyDatabaseDirectory(m_absoluteDatabaseDirectory);
 }
 
+void SQLiteIDBBackingStore::unregisterCursor(SQLiteIDBCursor& cursor)
+{
+    ASSERT(m_cursors.contains(cursor.identifier()));
+    m_cursors.remove(cursor.identifier());
+}
+
 } // namespace IDBServer
 } // namespace WebCore
 
index 09bddf2..a6bd9be 100644 (file)
@@ -31,6 +31,9 @@
 #include "IDBBackingStore.h"
 #include "IDBDatabaseIdentifier.h"
 #include "IDBDatabaseInfo.h"
+#include "IDBResourceIdentifier.h"
+#include "SQLiteIDBTransaction.h"
+#include <wtf/HashMap.h>
 
 namespace WebCore {
 
@@ -38,6 +41,8 @@ class SQLiteDatabase;
 
 namespace IDBServer {
 
+class SQLiteIDBCursor;
+
 class SQLiteIDBBackingStore : public IDBBackingStore {
 public:
     SQLiteIDBBackingStore(const IDBDatabaseIdentifier&, const String& databaseRootDirectory);
@@ -68,12 +73,21 @@ public:
 
     virtual void deleteBackingStore() override final;
 
+    void unregisterCursor(SQLiteIDBCursor&);
+
 private:
+    bool ensureValidRecordsTable();
+    std::unique_ptr<IDBDatabaseInfo> createAndPopulateInitialDatabaseInfo();
+    std::unique_ptr<IDBDatabaseInfo> extractExistingDatabaseInfo();
+
     IDBDatabaseIdentifier m_identifier;
     std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
 
     std::unique_ptr<SQLiteDatabase> m_sqliteDB;
 
+    HashMap<IDBResourceIdentifier, std::unique_ptr<SQLiteIDBTransaction>> m_transactions;
+    HashMap<IDBResourceIdentifier, SQLiteIDBCursor*> m_cursors;
+
     String m_absoluteDatabaseDirectory;
 };
 
diff --git a/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp b/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp
new file mode 100644 (file)
index 0000000..30eb259
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * 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 "config.h"
+#include "SQLiteIDBCursor.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBCursorInfo.h"
+#include "IDBSerialization.h"
+#include "Logging.h"
+#include "SQLiteIDBTransaction.h"
+#include "SQLiteStatement.h"
+#include "SQLiteTransaction.h"
+#include <sqlite3.h>
+
+namespace WebCore {
+namespace IDBServer {
+
+std::unique_ptr<SQLiteIDBCursor> SQLiteIDBCursor::maybeCreate(SQLiteIDBTransaction& transaction, const IDBCursorInfo& info)
+{
+    auto cursor = std::unique_ptr<SQLiteIDBCursor>(new SQLiteIDBCursor(transaction, info));
+
+    if (!cursor->establishStatement())
+        return nullptr;
+
+    if (!cursor->advance(1))
+        return nullptr;
+
+    return cursor;
+}
+
+SQLiteIDBCursor::SQLiteIDBCursor(SQLiteIDBTransaction& transaction, const IDBCursorInfo& info)
+    : m_transaction(&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& keyRange, IndexedDB::CursorDirection cursorDirection)
+{
+    StringBuilder builder;
+
+    builder.appendLiteral("SELECT rowid, key, value FROM IndexRecords WHERE indexID = ? AND key ");
+    if (!keyRange.lowerKey.isNull() && !keyRange.lowerOpen)
+        builder.appendLiteral(">=");
+    else
+        builder.append('>');
+
+    builder.appendLiteral(" CAST(? AS TEXT) AND key ");
+    if (!keyRange.upperKey.isNull() && !keyRange.upperOpen)
+        builder.appendLiteral("<=");
+    else
+        builder.append('<');
+
+    builder.appendLiteral(" CAST(? AS TEXT) ORDER BY key");
+    if (cursorDirection == IndexedDB::CursorDirection::Prev || cursorDirection == IndexedDB::CursorDirection::PrevNoDuplicate)
+        builder.appendLiteral(" DESC");
+
+    builder.appendLiteral(", value");
+    if (cursorDirection == IndexedDB::CursorDirection::Prev)
+        builder.appendLiteral(" DESC");
+
+    builder.append(';');
+
+    return builder.toString();
+}
+
+static String buildObjectStoreStatement(const IDBKeyRangeData& keyRange, IndexedDB::CursorDirection cursorDirection)
+{
+    StringBuilder builder;
+
+    builder.appendLiteral("SELECT rowid, key, value FROM Records WHERE objectStoreID = ? AND key ");
+
+    if (!keyRange.lowerKey.isNull() && !keyRange.lowerOpen)
+        builder.appendLiteral(">=");
+    else
+        builder.append('>');
+
+    builder.appendLiteral(" CAST(? AS TEXT) AND key ");
+
+    if (!keyRange.upperKey.isNull() && !keyRange.upperOpen)
+        builder.appendLiteral("<=");
+    else
+        builder.append('<');
+
+    builder.appendLiteral(" CAST(? AS TEXT) ORDER BY key");
+
+    if (cursorDirection == IndexedDB::CursorDirection::Prev || cursorDirection == IndexedDB::CursorDirection::PrevNoDuplicate)
+        builder.appendLiteral(" DESC");
+
+    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& sql)
+{
+    LOG(IndexedDB, "Creating cursor with SQL query: \"%s\"", sql.utf8().data());
+
+    ASSERT(!m_currentLowerKey.isNull());
+    ASSERT(!m_currentUpperKey.isNull());
+    ASSERT(m_transaction->sqliteTransaction());
+
+    m_statement = std::make_unique<SQLiteStatement>(m_transaction->sqliteTransaction()->database(), sql);
+
+    if (m_statement->prepare() != SQLITE_OK) {
+        LOG_ERROR("Could not create cursor statement (prepare/id) - '%s'", m_transaction->sqliteTransaction()->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->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->reset() != SQLITE_OK) {
+        LOG_ERROR("Could not reset cursor statement to respond to object store changes");
+        return;
+    }
+
+    bindArguments();
+}
+
+bool SQLiteIDBCursor::bindArguments()
+{
+    if (m_statement->bindInt64(1, m_boundID) != SQLITE_OK) {
+        LOG_ERROR("Could not bind id argument (bound ID)");
+        return false;
+    }
+
+    RefPtr<SharedBuffer> buffer = serializeIDBKeyData(m_currentLowerKey);
+    if (m_statement->bindBlob(2, buffer->data(), buffer->size()) != SQLITE_OK) {
+        LOG_ERROR("Could not create cursor statement (lower key)");
+        return false;
+    }
+
+    buffer = serializeIDBKeyData(m_currentUpperKey);
+    if (m_statement->bindBlob(3, buffer->data(), buffer->size()) != SQLITE_OK) {
+        LOG_ERROR("Could not create cursor statement (upper key)");
+        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 < 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->sqliteTransaction());
+    ASSERT(m_statement);
+
+    if (m_completed) {
+        LOG_ERROR("Attempt to advance a completed cursor");
+        return AdvanceResult::Failure;
+    }
+
+    int result = m_statement->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("Error advancing cursor - (%i) %s", result, m_transaction->sqliteTransaction()->database().lastErrorMsg());
+        m_completed = true;
+        m_errored = true;
+        return AdvanceResult::Failure;
+    }
+
+    int64_t recordID = m_statement->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<uint8_t> keyData;
+    m_statement->getColumnBlobAsVector(1, keyData);
+
+    if (!deserializeIDBKeyData(keyData.data(), keyData.size(), m_currentKey)) {
+        LOG_ERROR("Unable to deserialize key data from database while advancing cursor");
+        m_completed = true;
+        m_errored = true;
+        return AdvanceResult::Failure;
+    }
+
+    m_statement->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("Unable to deserialize value data from database while advancing index cursor");
+            m_completed = true;
+            m_errored = true;
+            return AdvanceResult::Failure;
+        }
+
+        SQLiteStatement objectStoreStatement(m_statement->database(), "SELECT value FROM Records WHERE key = CAST(? AS TEXT) and objectStoreID = ?;");
+
+        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("Could not create index cursor statement into object store records (%i) '%s'", m_statement->database().lastError(), m_statement->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("Could not step index cursor statement into object store records (%i) '%s'", m_statement->database().lastError(), m_statement->database().lastErrorMsg());
+            m_completed = true;
+            m_errored = true;
+            return AdvanceResult::Failure;
+
+        }
+    }
+
+    return AdvanceResult::Success;
+}
+
+bool SQLiteIDBCursor::iterate(const WebCore::IDBKeyData& targetKey)
+{
+    ASSERT(m_transaction->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 >= the target if the cursor is a Next cursor, or the next key <= if the cursor is a Previous cursor.
+        if (m_cursorDirection == IndexedDB::CursorDirection::Next || m_cursorDirection == IndexedDB::CursorDirection::NextNoDuplicate) {
+            if (m_currentKey.compare(targetKey) >= 0)
+                break;
+        } else if (m_currentKey.compare(targetKey) <= 0)
+            break;
+
+        result = advance(1);
+    }
+
+    return result;
+}
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h b/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h
new file mode 100644 (file)
index 0000000..4a671e1
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * 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 "IDBDatabaseBackend.h"
+#include "IDBKeyData.h"
+#include "IDBKeyRangeData.h"
+#include "IDBResourceIdentifier.h"
+#include "SQLiteStatement.h"
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+class IDBCursorInfo;
+
+namespace IDBServer {
+
+class SQLiteIDBTransaction;
+
+class SQLiteIDBCursor {
+    WTF_MAKE_NONCOPYABLE(SQLiteIDBCursor);
+public:
+    static std::unique_ptr<SQLiteIDBCursor> maybeCreate(SQLiteIDBTransaction&, const IDBCursorInfo&);
+
+    const IDBResourceIdentifier& identifier() const { return m_cursorIdentifier; }
+    SQLiteIDBTransaction* transaction() const { return m_transaction; }
+
+    int64_t objectStoreID() const { return m_objectStoreID; }
+
+    const IDBKeyData& currentKey() const { return m_currentKey; }
+    const IDBKeyData& currentPrimaryKey() const { return m_currentPrimaryKey; }
+    const Vector<uint8_t>& currentValueBuffer() const { return m_currentValueBuffer; }
+
+    bool advance(uint64_t count);
+    bool iterate(const IDBKeyData& targetKey);
+
+    bool didError() const { return m_errored; }
+
+    void objectStoreRecordsChanged();
+
+private:
+    SQLiteIDBCursor(SQLiteIDBTransaction&, const IDBCursorInfo&);
+
+    bool establishStatement();
+    bool createSQLiteStatement(const String& 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<uint8_t> m_currentValueBuffer;
+
+    std::unique_ptr<SQLiteStatement> 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
diff --git a/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp b/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp
new file mode 100644 (file)
index 0000000..f7ce8ef
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * 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 "config.h"
+#include "SQLiteIDBTransaction.h"
+
+#if ENABLE(INDEXED_DATABASE)
+
+#include "IDBCursorInfo.h"
+#include "IndexedDB.h"
+#include "SQLiteIDBBackingStore.h"
+#include "SQLiteIDBCursor.h"
+#include "SQLiteTransaction.h"
+
+namespace WebCore {
+namespace IDBServer {
+
+SQLiteIDBTransaction::SQLiteIDBTransaction(SQLiteIDBBackingStore& backingStore, const IDBResourceIdentifier& transactionIdentifier, IndexedDB::TransactionMode mode)
+    : m_identifier(transactionIdentifier)
+    , m_mode(mode)
+    , m_backingStore(backingStore)
+{
+}
+
+SQLiteIDBTransaction::~SQLiteIDBTransaction()
+{
+    if (inProgress())
+        m_sqliteTransaction->rollback();
+
+    // Explicitly clear cursors, as that also unregisters them from the backing store.
+    clearCursors();
+}
+
+
+bool SQLiteIDBTransaction::begin(SQLiteDatabase& database)
+{
+    ASSERT(!m_sqliteTransaction);
+    m_sqliteTransaction = std::make_unique<SQLiteTransaction>(database, m_mode == IndexedDB::TransactionMode::ReadOnly);
+
+    m_sqliteTransaction->begin();
+
+    return m_sqliteTransaction->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->inProgress())
+        return false;
+
+    m_sqliteTransaction->commit();
+
+    return !m_sqliteTransaction->inProgress();
+}
+
+bool SQLiteIDBTransaction::reset()
+{
+    m_sqliteTransaction = nullptr;
+    clearCursors();
+
+    return true;
+}
+
+bool SQLiteIDBTransaction::rollback()
+{
+    ASSERT(m_sqliteTransaction);
+    if (m_sqliteTransaction->inProgress())
+        m_sqliteTransaction->rollback();
+
+    return true;
+}
+
+SQLiteIDBCursor* SQLiteIDBTransaction::maybeOpenCursor(const IDBCursorInfo& info)
+{
+    ASSERT(m_sqliteTransaction);
+    if (!m_sqliteTransaction->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->value) {
+        m_cursors.remove(addResult.iterator);
+        return nullptr;
+    }
+
+    return addResult.iterator->value.get();
+}
+
+void SQLiteIDBTransaction::closeCursor(SQLiteIDBCursor& cursor)
+{
+    ASSERT(m_cursors.contains(cursor.identifier()));
+
+    m_backingStore.unregisterCursor(cursor);
+    m_cursors.remove(cursor.identifier());
+}
+
+void SQLiteIDBTransaction::notifyCursorsOfChanges(int64_t objectStoreID)
+{
+    for (auto& i : m_cursors) {
+        if (i.value->objectStoreID() == objectStoreID)
+            i.value->objectStoreRecordsChanged();
+    }
+}
+
+void SQLiteIDBTransaction::clearCursors()
+{
+    for (auto& cursor : m_cursors.values())
+        m_backingStore.unregisterCursor(*cursor);
+
+    m_cursors.clear();
+}
+
+bool SQLiteIDBTransaction::inProgress() const
+{
+    return m_sqliteTransaction && m_sqliteTransaction->inProgress();
+}
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h b/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h
new file mode 100644 (file)
index 0000000..4968543
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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 "IDBResourceIdentifier.h"
+#include "IndexedDB.h"
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+
+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&, const IDBResourceIdentifier& transactionIdentifier, IndexedDB::TransactionMode);
+    ~SQLiteIDBTransaction();
+
+    const IDBResourceIdentifier& transactionIdentifier() const { return m_identifier; }
+
+    bool begin(SQLiteDatabase&);
+    bool commit();
+    bool reset();
+    bool rollback();
+
+    SQLiteIDBCursor* maybeOpenCursor(const IDBCursorInfo&);
+
+    void closeCursor(SQLiteIDBCursor&);
+    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& m_backingStore;
+    std::unique_ptr<SQLiteTransaction> m_sqliteTransaction;
+    HashMap<IDBResourceIdentifier, std::unique_ptr<SQLiteIDBCursor>> m_cursors;
+};
+
+} // namespace IDBServer
+} // namespace WebCore
+
+#endif // ENABLE(INDEXED_DATABASE)
+#endif // SQLiteIDBTransaction_h
index cb2a7fe..a93d960 100644 (file)
                510D4A36103165EE0049EA54 /* SocketStreamHandleBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510D4A30103165EE0049EA54 /* SocketStreamHandleBase.cpp */; };
                510D4A37103165EE0049EA54 /* SocketStreamHandleBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A31103165EE0049EA54 /* SocketStreamHandleBase.h */; };
                510D4A38103165EE0049EA54 /* SocketStreamHandleClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */; };
+               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 */; };
                511EF2C017F0FD3500E4FA16 /* JSIDBAny.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2A817F0FC4800E4FA16 /* JSIDBAny.cpp */; };
                511EF2C117F0FD3500E4FA16 /* JSIDBCursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2A917F0FC4800E4FA16 /* JSIDBCursor.cpp */; };
                511EF2C217F0FD3500E4FA16 /* JSIDBCursorWithValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 511EF2AA17F0FC4800E4FA16 /* JSIDBCursorWithValue.cpp */; };
                510D4A30103165EE0049EA54 /* SocketStreamHandleBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SocketStreamHandleBase.cpp; sourceTree = "<group>"; };
                510D4A31103165EE0049EA54 /* SocketStreamHandleBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamHandleBase.h; sourceTree = "<group>"; };
                510D4A32103165EE0049EA54 /* SocketStreamHandleClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SocketStreamHandleClient.h; sourceTree = "<group>"; };
+               511EC1251C50AA570032F983 /* IDBSerialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBSerialization.cpp; sourceTree = "<group>"; };
+               511EC1261C50AA570032F983 /* IDBSerialization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBSerialization.h; sourceTree = "<group>"; };
+               511EC1291C50ABBA0032F983 /* SQLiteIDBTransaction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteIDBTransaction.cpp; sourceTree = "<group>"; };
+               511EC12A1C50ABBA0032F983 /* SQLiteIDBTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteIDBTransaction.h; sourceTree = "<group>"; };
+               511EC12D1C50ABEC0032F983 /* SQLiteIDBCursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SQLiteIDBCursor.cpp; sourceTree = "<group>"; };
+               511EC12E1C50ABEC0032F983 /* SQLiteIDBCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SQLiteIDBCursor.h; sourceTree = "<group>"; };
                511EC1A5188DACA400BA3EB6 /* IDBKeyData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IDBKeyData.h; sourceTree = "<group>"; };
                511EC1A7188DAE7B00BA3EB6 /* IDBKeyData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IDBKeyData.cpp; sourceTree = "<group>"; };
                511EF2A817F0FC4800E4FA16 /* JSIDBAny.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSIDBAny.cpp; sourceTree = "<group>"; };
                                516D7D6D1BB5F06500AF7C77 /* IDBConnectionToClient.cpp */,
                                510A58FE1BB07AA500C19282 /* IDBConnectionToClient.h */,
                                516D7D6E1BB5F06500AF7C77 /* IDBConnectionToClientDelegate.h */,
+                               511EC1251C50AA570032F983 /* IDBSerialization.cpp */,
+                               511EC1261C50AA570032F983 /* IDBSerialization.h */,
                                510A58EF1BAB720F00C19282 /* IDBServer.cpp */,
                                510A58F01BAB720F00C19282 /* IDBServer.h */,
                                51EEAA711BEFFA7900218008 /* IndexValueEntry.cpp */,
                                517139041BF64DE3000D5F01 /* MemoryObjectStoreCursor.h */,
                                512BDB481C456FAB006494DF /* SQLiteIDBBackingStore.cpp */,
                                512BDB491C456FAB006494DF /* SQLiteIDBBackingStore.h */,
+                               511EC12D1C50ABEC0032F983 /* SQLiteIDBCursor.cpp */,
+                               511EC12E1C50ABEC0032F983 /* SQLiteIDBCursor.h */,
+                               511EC1291C50ABBA0032F983 /* SQLiteIDBTransaction.cpp */,
+                               511EC12A1C50ABBA0032F983 /* SQLiteIDBTransaction.h */,
                                516F7F6B1C31C79D00F111DC /* ServerOpenDBRequest.cpp */,
                                516F7F6C1C31C79D00F111DC /* ServerOpenDBRequest.h */,
                                518864DE1BBAF30F00E540C9 /* UniqueIDBDatabase.cpp */,
                                1A762C780A074F2600989F5B /* JSXPathNSResolver.h in Headers */,
                                1A762C7A0A074F2600989F5B /* JSXPathResult.h in Headers */,
                                BCEFE1EB0DCA5F6400739219 /* JSXSLTProcessor.h in Headers */,
+                               511EC1301C50ABF50032F983 /* SQLiteIDBCursor.h in Headers */,
                                85031B440A44EFC700F992E0 /* KeyboardEvent.h in Headers */,
                                1AE00D59182DAC8D00087DD7 /* KeyedCoding.h in Headers */,
                                517A63C51B74318F00E7DCDC /* KeyedDecoderCF.h in Headers */,
                                078E094317D16E1C00420AA1 /* RTCSessionDescriptionDescriptor.h in Headers */,
                                078E094417D16E1C00420AA1 /* RTCSessionDescriptionRequest.h in Headers */,
                                078E092A17D14D1C00420AA1 /* RTCStatsReport.h in Headers */,
+                               511EC1281C50AACA0032F983 /* IDBSerialization.h in Headers */,
                                078E094517D16E1C00420AA1 /* RTCStatsRequest.h in Headers */,
                                078E092C17D14D1C00420AA1 /* RTCStatsResponse.h in Headers */,
                                078E094617D16E1C00420AA1 /* RTCStatsResponseBase.h in Headers */,
                                B22279A50D00BF220071B782 /* SVGComponentTransferFunctionElement.h in Headers */,
                                B22279A80D00BF220071B782 /* SVGCursorElement.h in Headers */,
                                B22279AE0D00BF220071B782 /* SVGDefsElement.h in Headers */,
+                               511EC12C1C50ABBF0032F983 /* SQLiteIDBTransaction.h in Headers */,
                                B22279B10D00BF220071B782 /* SVGDescElement.h in Headers */,
                                B22279B40D00BF220071B782 /* SVGDocument.h in Headers */,
                                B28C6A280D00C44800334AA4 /* SVGDocumentExtensions.h in Headers */,
                                C6F08FC91431000D00685849 /* JSMutationRecord.cpp in Sources */,
                                BCD9C2C00C17B69E005C90A2 /* JSNamedNodeMap.cpp in Sources */,
                                BCD9C2630C17AA67005C90A2 /* JSNamedNodeMapCustom.cpp in Sources */,
+                               511EC1271C50AACA0032F983 /* IDBSerialization.cpp in Sources */,
                                A9D247F70D757E3400FDF959 /* JSNavigator.cpp in Sources */,
                                073BE34017D17E01002BD431 /* JSNavigatorUserMedia.cpp in Sources */,
                                073BE34817D17E7A002BD431 /* JSNavigatorUserMediaError.cpp in Sources */,
                                B2227A020D00BF220071B782 /* SVGFESpotLightElement.cpp in Sources */,
                                B2227A050D00BF220071B782 /* SVGFETileElement.cpp in Sources */,
                                B2227A080D00BF220071B782 /* SVGFETurbulenceElement.cpp in Sources */,
+                               511EC12B1C50ABBF0032F983 /* SQLiteIDBTransaction.cpp in Sources */,
                                845E72FB0FD2623900A87D79 /* SVGFilter.cpp in Sources */,
                                081EBF3A0FD34F4100DA7559 /* SVGFilterBuilder.cpp in Sources */,
                                B2227A0B0D00BF220071B782 /* SVGFilterElement.cpp in Sources */,
                                CD336F6717FA0AC600DDDCD0 /* VideoTrackPrivateAVFObjC.cpp in Sources */,
                                CD8B5A42180D149A008B8E65 /* VideoTrackPrivateMediaSourceAVFObjC.mm in Sources */,
                                CEF418CE1179678C009D112C /* ViewportArguments.cpp in Sources */,
+                               511EC12F1C50ABF50032F983 /* SQLiteIDBCursor.cpp in Sources */,
                                26F9A83818A046AC00AEB88A /* ViewportConfiguration.cpp in Sources */,
                                3FFFF9AD159D9B060020BBD5 /* ViewportStyleResolver.cpp in Sources */,
                                93309E1F099E64920056E581 /* VisiblePosition.cpp in Sources */,
index 1d06c7a..3cd2eaa 100644 (file)
@@ -1735,6 +1735,9 @@ void Page::setSessionID(SessionID sessionID)
 {
     ASSERT(sessionID.isValid());
 
+    if (sessionID != m_sessionID)
+        m_idbIDBConnectionToServer = nullptr;
+
     bool privateBrowsingStateChanged = (sessionID.isEphemeral() != m_sessionID.isEphemeral());
 
     m_sessionID = sessionID;
@@ -1836,13 +1839,8 @@ void Page::setAllowsMediaDocumentInlinePlayback(bool flag)
 #if ENABLE(INDEXED_DATABASE)
 IDBClient::IDBConnectionToServer& Page::idbConnection()
 {
-    if (!m_idbIDBConnectionToServer) {
-        if (usesEphemeralSession()) {
-            auto inProcessServer = InProcessIDBServer::create();
-            m_idbIDBConnectionToServer = &inProcessServer->connectionToServer();
-        } else
-            m_idbIDBConnectionToServer = &databaseProvider().idbConnectionToServerForSession(m_sessionID);
-    }
+    if (!m_idbIDBConnectionToServer)
+        m_idbIDBConnectionToServer = &databaseProvider().idbConnectionToServerForSession(m_sessionID);
     
     return *m_idbIDBConnectionToServer;
 }