Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (195494 => 195495)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2016-01-23 00:24:02 UTC (rev 195494)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2016-01-23 00:41:06 UTC (rev 195495)
@@ -91,9 +91,9 @@
storage/indexeddb/connection-leak-private.html [ Skip ]
storage/indexeddb/connection-leak.html [ Skip ]
storage/indexeddb/cursor-leak-private.html [ Failure ]
-storage/indexeddb/cursor-leak.html [ Failure ]
+storage/indexeddb/cursor-leak.html [ Skip ]
storage/indexeddb/cursor-request-cycle-private.html [ Failure ]
-storage/indexeddb/cursor-request-cycle.html [ Failure ]
+storage/indexeddb/cursor-request-cycle.html [ Skip ]
storage/indexeddb/delete-closed-database-object-private.html [ Skip ]
storage/indexeddb/delete-closed-database-object.html [ Skip ]
storage/indexeddb/request-leak-private.html [ Failure ]
@@ -254,9 +254,6 @@
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 ]
@@ -423,11 +420,9 @@
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 ]
@@ -440,15 +435,10 @@
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/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 ]
@@ -466,14 +456,11 @@
storage/indexeddb/cursor-update-value-argument-required.html [ Failure ]
storage/indexeddb/cursor-update.html [ Failure ]
storage/indexeddb/cursor-value.html [ Failure ]
-storage/indexeddb/database-close.html [ Failure ]
storage/indexeddb/database-wrapper.html [ Failure ]
storage/indexeddb/delete-range.html [ Failure ]
storage/indexeddb/deleteIndex.html [ Failure ]
storage/indexeddb/deleted-objects.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 ]
@@ -487,8 +474,6 @@
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-infinity.html [ Failure ]
storage/indexeddb/keypath-arrays.html [ Failure ]
storage/indexeddb/keypath-edges.html [ Failure ]
storage/indexeddb/keypath-fetch-key.html [ Failure ]
@@ -499,13 +484,8 @@
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/create-index-failures.html [ Failure ]
-storage/indexeddb/modern/createobjectstore-basic.html [ Failure ]
storage/indexeddb/modern/cursor-1.html [ Failure ]
storage/indexeddb/modern/cursor-2.html [ Failure ]
storage/indexeddb/modern/cursor-3.html [ Failure ]
@@ -514,52 +494,32 @@
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/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/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-5.html [ Failure ]
-storage/indexeddb/modern/transaction-scheduler-6.html [ Failure ]
storage/indexeddb/modern/transactions-stop-on-navigation.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 ]
@@ -578,47 +538,29 @@
storage/indexeddb/mozilla/odd-result-order.html [ Failure ]
storage/indexeddb/mozilla/put-get-values.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/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/opencursor-key.html [ Failure ]
storage/indexeddb/optional-arguments.html [ Failure ]
-storage/indexeddb/pending-activity.html [ Failure ]
storage/indexeddb/prefetch-bugfix-108071.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/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-coordination-across-databases.html [ Failure ]
-storage/indexeddb/transaction-coordination-within-database.html [ Failure ]
storage/indexeddb/transaction-error.html [ Failure ]
-storage/indexeddb/transaction-event-propagation.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/value-undefined.html [ Failure ]
storage/indexeddb/values-odd-types.html [ Failure ]
-storage/indexeddb/version-change-exclusive.html [ Failure ]
# SQLite backend tests that timeout
crypto/subtle/rsa-indexeddb.html [ Skip ]
@@ -637,10 +579,34 @@
storage/indexeddb/prefetch-invalidation.html [ Skip ]
storage/indexeddb/primary-key-unique-to-objectstore.html [ Skip ]
storage/indexeddb/transaction-ordering.html [ Skip ]
+storage/indexeddb/closed-cursor.html [ Skip ]
+storage/indexeddb/cursor-cast.html [ Skip ]
+storage/indexeddb/noblobs.html [ Skip ]
+storage/indexeddb/prefetch-race.html [ Skip ]
+storage/indexeddb/request-result-cache.html [ Skip ]
# SQLite backend tests that ASSERT
+imported/w3c/indexeddb/idbcursor-direction-objectstore-keyrange.htm [ Skip ]
+imported/w3c/indexeddb/idbcursor-direction-objectstore.htm [ Skip ]
+imported/w3c/indexeddb/idbcursor-direction.htm [ Skip ]
+imported/w3c/indexeddb/key_valid.html [ Skip ]
+imported/w3c/indexeddb/writer-starvation.htm [ Skip ]
+storage/indexeddb/database-close.html [ Skip ]
storage/indexeddb/database-odd-names.html [ Skip ]
storage/indexeddb/dont-wedge.html [ Skip ]
+storage/indexeddb/modern/transaction-scheduler-1.html [ Skip ]
+storage/indexeddb/modern/transaction-scheduler-2.html [ Skip ]
+storage/indexeddb/modern/transaction-scheduler-5.html [ Skip ]
+storage/indexeddb/modern/transaction-scheduler-6.html [ Skip ]
+storage/indexeddb/odd-strings.html [ Skip ]
+storage/indexeddb/pending-activity.html [ Skip ]
+storage/indexeddb/transaction-coordination-within-database.html [ Skip ]
+storage/indexeddb/transaction-overlapping.html [ Skip ]
+storage/indexeddb/transaction-read-only.html [ Skip ]
+# SQLite backend tests that wedge the entire testing harness
+imported/w3c/indexeddb/keyorder.htm [ Skip ]
+storage/indexeddb/key-type-array.html [ Skip ]
+
### END OF (3) IndexedDB failures with SQLite
########################################
Modified: trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp (195494 => 195495)
--- trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2016-01-23 00:24:02 UTC (rev 195494)
+++ trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp 2016-01-23 00:41:06 UTC (rev 195495)
@@ -41,6 +41,7 @@
#include "SQLiteIDBCursor.h"
#include "SQLiteStatement.h"
#include "SQLiteTransaction.h"
+#include "ThreadSafeDataBuffer.h"
#include <wtf/NeverDestroyed.h>
using namespace JSC;
@@ -653,26 +654,240 @@
return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
}
-IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier&, uint64_t, const IDBKeyData&, bool&)
+IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, bool& keyExists)
{
- return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
+ LOG(IndexedDB, "SQLiteIDBBackingStore::keyExistsInObjectStore - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
+
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+
+ keyExists = false;
+
+ auto* transaction = m_transactions.get(transactionIdentifier);
+ if (!transaction || !transaction->inProgress()) {
+ LOG_ERROR("Attempt to see if key exists in objectstore without an in-progress transaction");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to see if key exists in objectstore without an in-progress transaction") };
+ }
+
+ RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
+ if (!keyBuffer) {
+ LOG_ERROR("Unable to serialize IDBKey to check for existence in object store");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for existence in object store") };
+ }
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT key FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT) LIMIT 1;"));
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindInt64(1, objectStoreID) != SQLITE_OK
+ || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
+ LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to check for existence of IDBKey in object store") };
+ }
+
+ int sqlResult = sql.step();
+ if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
+ return { };
+
+ if (sqlResult != SQLITE_ROW) {
+ // There was an error fetching the record from the database.
+ LOG_ERROR("Could not check if key exists in object store (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in object store") };
+ }
+
+ keyExists = true;
+ return { };
}
-IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier&, uint64_t, const IDBKeyRangeData&)
+IDBError SQLiteIDBBackingStore::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const IDBKeyData& keyData)
{
- return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
+ LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
+
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+ ASSERT(transaction.inProgress());
+ ASSERT(transaction.mode() != IndexedDB::TransactionMode::ReadOnly);
+ UNUSED_PARAM(transaction);
+
+ RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
+ if (!keyBuffer) {
+ LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyData to be removed from the database") };
+ }
+
+ // Delete record from object store
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
+
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindInt64(1, objectStoreID) != SQLITE_OK
+ || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
+ || sql.step() != SQLITE_DONE) {
+ LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
+ }
+ }
+
+ // Delete record from indexes store
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
+
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindInt64(1, objectStoreID) != SQLITE_OK
+ || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
+ || sql.step() != SQLITE_DONE) {
+ LOG_ERROR("Could not delete record from indexes for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete index entries for object store record") };
+ }
+ }
+
+ return { };
}
-IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier&, uint64_t, const IDBKeyData&, const ThreadSafeDataBuffer&)
+IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange)
{
- return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
+ LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRange - range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
+
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+
+ auto* transaction = m_transactions.get(transactionIdentifier);
+ if (!transaction || !transaction->inProgress()) {
+ LOG_ERROR("Attempt to delete range from database without an in-progress transaction");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete range from database without an in-progress transaction") };
+ }
+ if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
+ LOG_ERROR("Attempt to delete records from an object store in a read-only transaction");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete records from an object store in a read-only transaction") };
+ }
+
+ // If the range to delete is exactly one key we can delete it right now.
+ if (keyRange.isExactlyOneKey()) {
+ auto error = deleteRecord(*transaction, objectStoreID, keyRange.lowerKey);
+ if (!error.isNull()) {
+ LOG_ERROR("Failed to delete record for key '%s'", keyRange.lowerKey.loggingString().utf8().data());
+ return error;
+ }
+
+ return { };
+ }
+
+ // FIXME: Once cursor support is in place, use a cursor to delete every record in the range.
+ LOG_ERROR("Currently unable to delete all records in a multi-key range");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Currently unable to delete all records in a multi-key range") };
}
-IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier&, uint64_t, const IDBKeyRangeData&, ThreadSafeDataBuffer&)
+IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
{
- return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
+ LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
+
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+ ASSERT(value.data());
+
+ auto* transaction = m_transactions.get(transactionIdentifier);
+ if (!transaction || !transaction->inProgress()) {
+ LOG_ERROR("Attempt to store a record in an object store without an in-progress transaction");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store without an in-progress transaction") };
+ }
+ if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
+ LOG_ERROR("Attempt to store a record in an object store in a read-only transaction");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store in a read-only transaction") };
+ }
+
+ RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
+ if (!keyBuffer) {
+ LOG_ERROR("Unable to serialize IDBKey to be stored in an object store");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to be stored in an object store") };
+ }
+ {
+ SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?);"));
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindInt64(1, objectStoreID) != SQLITE_OK
+ || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
+ || sql.bindBlob(3, value.data()->data(), value.data()->size()) != SQLITE_OK
+ || sql.step() != SQLITE_DONE) {
+ LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
+ }
+ }
+
+ return { };
}
+IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange, ThreadSafeDataBuffer& resultValue)
+{
+ LOG(IndexedDB, "SQLiteIDBBackingStore::getRecord - key range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
+
+ ASSERT(m_sqliteDB);
+ ASSERT(m_sqliteDB->isOpen());
+
+ auto* transaction = m_transactions.get(transactionIdentifier);
+ if (!transaction || !transaction->inProgress()) {
+ LOG_ERROR("Attempt to get a record from database without an in-progress transaction");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get a record from database without an in-progress transaction") };
+ }
+
+ RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(IDBKeyData(keyRange.lowerKey));
+ if (!lowerBuffer) {
+ LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
+ }
+
+ RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(IDBKeyData(keyRange.upperKey));
+ if (!upperBuffer) {
+ LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
+ }
+
+ {
+ static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
+ static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
+ static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
+ static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
+
+ const ASCIILiteral* query = nullptr;
+
+ if (keyRange.lowerOpen) {
+ if (keyRange.upperOpen)
+ query = &lowerOpenUpperOpen.get();
+ else
+ query = &lowerOpenUpperClosed.get();
+ } else {
+ if (keyRange.upperOpen)
+ query = &lowerClosedUpperOpen.get();
+ else
+ query = &lowerClosedUpperClosed.get();
+ }
+
+ ASSERT(query);
+
+ SQLiteStatement sql(*m_sqliteDB, *query);
+ if (sql.prepare() != SQLITE_OK
+ || sql.bindInt64(1, objectStoreID) != SQLITE_OK
+ || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
+ || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
+ LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
+ }
+
+ int sqlResult = sql.step();
+
+ if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
+ // There was no record for the key in the database.
+ return { };
+ }
+ if (sqlResult != SQLITE_ROW) {
+ // There was an error fetching the record from the database.
+ LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
+ return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
+ }
+
+ Vector<uint8_t> buffer;
+ sql.getColumnBlobAsVector(0, buffer);
+ resultValue = ThreadSafeDataBuffer::adoptVector(buffer);
+ }
+
+ return { };
+}
+
IDBError SQLiteIDBBackingStore::getIndexRecord(const IDBResourceIdentifier&, uint64_t, uint64_t, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult&)
{
return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };