Changeset 195495 in webkit


Ignore:
Timestamp:
Jan 22, 2016 4:41:06 PM (8 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: Implement put, get, and delete records for the SQLite backend.
https://bugs.webkit.org/show_bug.cgi?id=153375

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (Covered by many existing tests now passing).

  • Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:

(WebCore::IDBServer::SQLiteIDBBackingStore::keyExistsInObjectStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::deleteRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::deleteRange):
(WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):

  • Modules/indexeddb/server/SQLiteIDBBackingStore.h:

LayoutTests:

  • platform/mac-wk1/TestExpectations:
Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195493 r195495  
     12016-01-22  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Implement put, get, and delete records for the SQLite backend.
     4        https://bugs.webkit.org/show_bug.cgi?id=153375
     5
     6        Reviewed by Alex Christensen.
     7
     8        * platform/mac-wk1/TestExpectations:
     9
    1102016-01-22  Daniel Bates  <dabates@apple.com>
    211
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r195467 r195495  
    9292storage/indexeddb/connection-leak.html [ Skip ]
    9393storage/indexeddb/cursor-leak-private.html [ Failure ]
    94 storage/indexeddb/cursor-leak.html [ Failure ]
     94storage/indexeddb/cursor-leak.html [ Skip ]
    9595storage/indexeddb/cursor-request-cycle-private.html [ Failure ]
    96 storage/indexeddb/cursor-request-cycle.html [ Failure ]
     96storage/indexeddb/cursor-request-cycle.html [ Skip ]
    9797storage/indexeddb/delete-closed-database-object-private.html [ Skip ]
    9898storage/indexeddb/delete-closed-database-object.html [ Skip ]
     
    255255imported/w3c/indexeddb/idbcursor-direction-index-keyrange.htm [ Failure ]
    256256imported/w3c/indexeddb/idbcursor-direction-index.htm [ Failure ]
    257 imported/w3c/indexeddb/idbcursor-direction-objectstore-keyrange.htm [ Failure ]
    258 imported/w3c/indexeddb/idbcursor-direction-objectstore.htm [ Failure ]
    259 imported/w3c/indexeddb/idbcursor-direction.htm [ Failure ]
    260257imported/w3c/indexeddb/idbcursor-key.htm [ Failure ]
    261258imported/w3c/indexeddb/idbcursor-primarykey.htm [ Failure ]
     
    424421imported/w3c/indexeddb/idbversionchangeevent.htm [ Failure ]
    425422imported/w3c/indexeddb/index_sort_order.htm [ Failure ]
    426 imported/w3c/indexeddb/key_valid.html [ Failure ]
    427423imported/w3c/indexeddb/keygenerator-constrainterror.htm [ Failure ]
    428424imported/w3c/indexeddb/keygenerator-overflow.htm [ Failure ]
    429425imported/w3c/indexeddb/keygenerator.htm [ Failure ]
    430 imported/w3c/indexeddb/keyorder.htm [ Failure ]
    431426imported/w3c/indexeddb/keypath_maxsize.htm [ Failure ]
    432427imported/w3c/indexeddb/list_ordering.htm [ Failure ]
     
    441436imported/w3c/indexeddb/value.htm [ Failure ]
    442437imported/w3c/indexeddb/value_recursive.htm [ Failure ]
    443 imported/w3c/indexeddb/writer-starvation.htm [ Failure ]
    444 storage/indexeddb/closed-cursor.html [ Failure ]
    445 storage/indexeddb/create-and-remove-object-store.html [ Failure ]
    446 storage/indexeddb/create-object-store-options.html [ Failure ]
    447438storage/indexeddb/createIndex-after-failure.html [ Failure ]
    448439storage/indexeddb/cursor-added-bug.html [ Failure ]
    449440storage/indexeddb/cursor-advance.html [ Failure ]
    450441storage/indexeddb/cursor-basics.html [ Failure ]
    451 storage/indexeddb/cursor-cast.html [ Failure ]
    452442storage/indexeddb/cursor-continue-dir.html [ Failure ]
    453443storage/indexeddb/cursor-continue-validity.html [ Failure ]
     
    467457storage/indexeddb/cursor-update.html [ Failure ]
    468458storage/indexeddb/cursor-value.html [ Failure ]
    469 storage/indexeddb/database-close.html [ Failure ]
    470459storage/indexeddb/database-wrapper.html [ Failure ]
    471460storage/indexeddb/delete-range.html [ Failure ]
     
    473462storage/indexeddb/deleted-objects.html [ Failure ]
    474463storage/indexeddb/duplicates.html [ Failure ]
    475 storage/indexeddb/error-causes-abort-by-default.html [ Failure ]
    476 storage/indexeddb/exception-in-event-aborts.html [ Failure ]
    477464storage/indexeddb/exceptions.html [ Failure ]
    478465storage/indexeddb/factory-deletedatabase.html [ Failure ]
     
    488475storage/indexeddb/key-sort-order-across-types.html [ Failure ]
    489476storage/indexeddb/key-sort-order-date.html [ Failure ]
    490 storage/indexeddb/key-type-array.html [ Failure ]
    491 storage/indexeddb/key-type-infinity.html [ Failure ]
    492477storage/indexeddb/keypath-arrays.html [ Failure ]
    493478storage/indexeddb/keypath-edges.html [ Failure ]
     
    500485storage/indexeddb/metadata.html [ Failure ]
    501486storage/indexeddb/modern/abort-objectstore-info.html [ Failure ]
    502 storage/indexeddb/modern/abort-requests-cancelled.html [ Failure ]
    503 storage/indexeddb/modern/aborted-put.html [ Failure ]
    504487storage/indexeddb/modern/autoincrement-abort.html [ Failure ]
    505 storage/indexeddb/modern/basic-add.html [ Failure ]
    506 storage/indexeddb/modern/basic-put.html [ Failure ]
    507488storage/indexeddb/modern/create-index-failures.html [ Failure ]
    508 storage/indexeddb/modern/createobjectstore-basic.html [ Failure ]
    509489storage/indexeddb/modern/cursor-1.html [ Failure ]
    510490storage/indexeddb/modern/cursor-2.html [ Failure ]
     
    515495storage/indexeddb/modern/cursor-7.html [ Failure ]
    516496storage/indexeddb/modern/cursor-8.html [ Failure ]
    517 storage/indexeddb/modern/date-basic.html [ Failure ]
    518 storage/indexeddb/modern/deletedatabase-1.html [ Failure ]
    519 storage/indexeddb/modern/deletedatabase-2.html [ Failure ]
    520497storage/indexeddb/modern/deleteindex-1.html [ Failure ]
    521498storage/indexeddb/modern/deleteindex-2.html [ Failure ]
    522 storage/indexeddb/modern/deleteobjectstore-1.html [ Failure ]
    523499storage/indexeddb/modern/get-index-failures.html [ Failure ]
    524500storage/indexeddb/modern/get-keyrange.html [ Failure ]
    525 storage/indexeddb/modern/idbdatabase-deleteobjectstore-failures.html [ Failure ]
    526 storage/indexeddb/modern/idbdatabase-transaction-failures.html [ Failure ]
    527501storage/indexeddb/modern/idbindex-properties-basic.html [ Failure ]
    528502storage/indexeddb/modern/idbobjectstore-clear-1.html [ Failure ]
    529503storage/indexeddb/modern/idbobjectstore-clear-2.html [ Failure ]
    530504storage/indexeddb/modern/idbobjectstore-count-1.html [ Failure ]
    531 storage/indexeddb/modern/idbobjectstore-count-failures.html [ Failure ]
    532505storage/indexeddb/modern/idbobjectstore-delete-1.html [ Failure ]
    533 storage/indexeddb/modern/idbobjectstore-delete-2.html [ Failure ]
    534 storage/indexeddb/modern/idbobjectstore-delete-failures.html [ Failure ]
    535 storage/indexeddb/modern/idbobjectstore-get-failures.html [ Failure ]
    536 storage/indexeddb/modern/idbobjectstore-put-and-clear-failures.html [ Failure ]
    537506storage/indexeddb/modern/index-1.html [ Failure ]
    538507storage/indexeddb/modern/index-2.html [ Failure ]
    539508storage/indexeddb/modern/index-3.html [ Failure ]
    540509storage/indexeddb/modern/index-4.html [ Failure ]
    541 storage/indexeddb/modern/index-5.html [ Failure ]
    542510storage/indexeddb/modern/index-cursor-1.html [ Failure ]
    543511storage/indexeddb/modern/index-cursor-2.html [ Failure ]
     
    545513storage/indexeddb/modern/index-get-count-basic.html [ Failure ]
    546514storage/indexeddb/modern/index-get-count-failures.html [ Failure ]
    547 storage/indexeddb/modern/keypath-basic.html [ Failure ]
    548515storage/indexeddb/modern/memory-index-not-deleted-with-objectstore.html [ Failure ]
    549516storage/indexeddb/modern/objectstore-attributes.html [ Failure ]
     
    552519storage/indexeddb/modern/opencursor-failures.html [ Failure ]
    553520storage/indexeddb/modern/request-readystate.html [ Failure ]
    554 storage/indexeddb/modern/transaction-scheduler-1.html [ Failure ]
    555 storage/indexeddb/modern/transaction-scheduler-2.html [ Failure ]
    556 storage/indexeddb/modern/transaction-scheduler-3.html [ Failure ]
    557 storage/indexeddb/modern/transaction-scheduler-5.html [ Failure ]
    558 storage/indexeddb/modern/transaction-scheduler-6.html [ Failure ]
    559521storage/indexeddb/modern/transactions-stop-on-navigation.html [ Failure ]
    560 storage/indexeddb/mozilla/add-twice-failure.html [ Failure ]
    561522storage/indexeddb/mozilla/autoincrement-indexes.html [ Failure ]
    562 storage/indexeddb/mozilla/bad-keypath.html [ Failure ]
    563523storage/indexeddb/mozilla/clear.html [ Failure ]
    564524storage/indexeddb/mozilla/create-index-with-integer-keys.html [ Failure ]
     
    579539storage/indexeddb/mozilla/put-get-values.html [ Failure ]
    580540storage/indexeddb/mozilla/readwrite-transactions.html [ Failure ]
    581 storage/indexeddb/mozilla/readyState.html [ Failure ]
    582541storage/indexeddb/mozilla/remove-objectstore.html [ Failure ]
    583542storage/indexeddb/mutating-cursor.html [ Failure ]
    584 storage/indexeddb/noblobs.html [ Failure ]
    585543storage/indexeddb/objectstore-autoincrement.html [ Failure ]
    586544storage/indexeddb/objectstore-basics.html [ Failure ]
     
    589547storage/indexeddb/objectstore-cursor.html [ Failure ]
    590548storage/indexeddb/objectstore-removeobjectstore.html [ Failure ]
    591 storage/indexeddb/odd-strings.html [ Failure ]
    592549storage/indexeddb/open-cursor.html [ Failure ]
    593 storage/indexeddb/open-during-transaction.html [ Failure ]
    594550storage/indexeddb/opencursor-key.html [ Failure ]
    595551storage/indexeddb/optional-arguments.html [ Failure ]
    596 storage/indexeddb/pending-activity.html [ Failure ]
    597552storage/indexeddb/prefetch-bugfix-108071.html [ Failure ]
    598 storage/indexeddb/prefetch-race.html [ Failure ]
    599553storage/indexeddb/queued-commands.html [ Failure ]
    600554storage/indexeddb/readonly.html [ Failure ]
    601555storage/indexeddb/request-continue-abort.html [ Failure ]
    602 storage/indexeddb/request-event-propagation.html [ Failure ]
    603 storage/indexeddb/request-result-cache.html [ Failure ]
    604556storage/indexeddb/structured-clone.html [ Failure ]
    605 storage/indexeddb/transaction-abort.html [ Failure ]
    606557storage/indexeddb/transaction-active-flag.html [ Failure ]
    607 storage/indexeddb/transaction-after-close.html [ Failure ]
    608558storage/indexeddb/transaction-and-objectstore-calls.html [ Failure ]
    609559storage/indexeddb/transaction-basics.html [ Failure ]
    610 storage/indexeddb/transaction-coordination-across-databases.html [ Failure ]
    611 storage/indexeddb/transaction-coordination-within-database.html [ Failure ]
    612560storage/indexeddb/transaction-error.html [ Failure ]
    613 storage/indexeddb/transaction-event-propagation.html [ Failure ]
    614 storage/indexeddb/transaction-overlapping.html [ Failure ]
    615 storage/indexeddb/transaction-read-only.html [ Failure ]
    616 storage/indexeddb/transaction-readwrite-exclusive.html [ Failure ]
    617561storage/indexeddb/transaction-rollback.html [ Failure ]
    618 storage/indexeddb/transaction-scope-sequencing.html [ Failure ]
    619562storage/indexeddb/value-undefined.html [ Failure ]
    620563storage/indexeddb/values-odd-types.html [ Failure ]
    621 storage/indexeddb/version-change-exclusive.html [ Failure ]
    622564
    623565# SQLite backend tests that timeout
     
    638580storage/indexeddb/primary-key-unique-to-objectstore.html [ Skip ]
    639581storage/indexeddb/transaction-ordering.html [ Skip ]
     582storage/indexeddb/closed-cursor.html [ Skip ]
     583storage/indexeddb/cursor-cast.html [ Skip ]
     584storage/indexeddb/noblobs.html [ Skip ]
     585storage/indexeddb/prefetch-race.html [ Skip ]
     586storage/indexeddb/request-result-cache.html [ Skip ]
    640587
    641588# SQLite backend tests that ASSERT
     589imported/w3c/indexeddb/idbcursor-direction-objectstore-keyrange.htm [ Skip ]
     590imported/w3c/indexeddb/idbcursor-direction-objectstore.htm [ Skip ]
     591imported/w3c/indexeddb/idbcursor-direction.htm [ Skip ]
     592imported/w3c/indexeddb/key_valid.html [ Skip ]
     593imported/w3c/indexeddb/writer-starvation.htm [ Skip ]
     594storage/indexeddb/database-close.html [ Skip ]
    642595storage/indexeddb/database-odd-names.html [ Skip ]
    643596storage/indexeddb/dont-wedge.html [ Skip ]
     597storage/indexeddb/modern/transaction-scheduler-1.html [ Skip ]
     598storage/indexeddb/modern/transaction-scheduler-2.html [ Skip ]
     599storage/indexeddb/modern/transaction-scheduler-5.html [ Skip ]
     600storage/indexeddb/modern/transaction-scheduler-6.html [ Skip ]
     601storage/indexeddb/odd-strings.html [ Skip ]
     602storage/indexeddb/pending-activity.html [ Skip ]
     603storage/indexeddb/transaction-coordination-within-database.html [ Skip ]
     604storage/indexeddb/transaction-overlapping.html [ Skip ]
     605storage/indexeddb/transaction-read-only.html [ Skip ]
     606
     607# SQLite backend tests that wedge the entire testing harness
     608imported/w3c/indexeddb/keyorder.htm [ Skip ]
     609storage/indexeddb/key-type-array.html [ Skip ]
    644610
    645611### END OF (3) IndexedDB failures with SQLite
  • trunk/Source/WebCore/ChangeLog

    r195494 r195495  
     12016-01-22  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Implement put, get, and delete records for the SQLite backend.
     4        https://bugs.webkit.org/show_bug.cgi?id=153375
     5
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (Covered by many existing tests now passing).
     9
     10        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
     11        (WebCore::IDBServer::SQLiteIDBBackingStore::keyExistsInObjectStore):
     12        (WebCore::IDBServer::SQLiteIDBBackingStore::deleteRecord):
     13        (WebCore::IDBServer::SQLiteIDBBackingStore::deleteRange):
     14        (WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):
     15        (WebCore::IDBServer::SQLiteIDBBackingStore::getRecord):
     16        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
     17
    1182016-01-22  Enrica Casucci  <enrica@apple.com>
    219
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

    r195467 r195495  
    4242#include "SQLiteStatement.h"
    4343#include "SQLiteTransaction.h"
     44#include "ThreadSafeDataBuffer.h"
    4445#include <wtf/NeverDestroyed.h>
    4546
     
    654655}
    655656
    656 IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier&, uint64_t, const IDBKeyData&, bool&)
    657 {
    658     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
    659 }
    660 
    661 IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier&, uint64_t, const IDBKeyRangeData&)
    662 {
    663     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
    664 }
    665 
    666 IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier&, uint64_t, const IDBKeyData&, const ThreadSafeDataBuffer&)
    667 {
    668     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
    669 }
    670 
    671 IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier&, uint64_t, const IDBKeyRangeData&, ThreadSafeDataBuffer&)
    672 {
    673     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
     657IDBError SQLiteIDBBackingStore::keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, bool& keyExists)
     658{
     659    LOG(IndexedDB, "SQLiteIDBBackingStore::keyExistsInObjectStore - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
     660
     661    ASSERT(m_sqliteDB);
     662    ASSERT(m_sqliteDB->isOpen());
     663
     664    keyExists = false;
     665
     666    auto* transaction = m_transactions.get(transactionIdentifier);
     667    if (!transaction || !transaction->inProgress()) {
     668        LOG_ERROR("Attempt to see if key exists in objectstore without an in-progress transaction");
     669        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to see if key exists in objectstore without an in-progress transaction") };
     670    }
     671
     672    RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
     673    if (!keyBuffer) {
     674        LOG_ERROR("Unable to serialize IDBKey to check for existence in object store");
     675        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for existence in object store") };
     676    }
     677    SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT key FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT) LIMIT 1;"));
     678    if (sql.prepare() != SQLITE_OK
     679        || sql.bindInt64(1, objectStoreID) != SQLITE_OK
     680        || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK) {
     681        LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     682        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to check for existence of IDBKey in object store") };
     683    }
     684
     685    int sqlResult = sql.step();
     686    if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
     687        return { };
     688
     689    if (sqlResult != SQLITE_ROW) {
     690        // There was an error fetching the record from the database.
     691        LOG_ERROR("Could not check if key exists in object store (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     692        return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in object store") };
     693    }
     694
     695    keyExists = true;
     696    return { };
     697}
     698
     699IDBError SQLiteIDBBackingStore::deleteRecord(SQLiteIDBTransaction& transaction, int64_t objectStoreID, const IDBKeyData& keyData)
     700{
     701    LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
     702
     703    ASSERT(m_sqliteDB);
     704    ASSERT(m_sqliteDB->isOpen());
     705    ASSERT(transaction.inProgress());
     706    ASSERT(transaction.mode() != IndexedDB::TransactionMode::ReadOnly);
     707    UNUSED_PARAM(transaction);
     708
     709    RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
     710    if (!keyBuffer) {
     711        LOG_ERROR("Unable to serialize IDBKeyData to be removed from the database");
     712        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyData to be removed from the database") };
     713    }
     714
     715    // Delete record from object store
     716    {
     717        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM Records WHERE objectStoreID = ? AND key = CAST(? AS TEXT);"));
     718
     719        if (sql.prepare() != SQLITE_OK
     720            || sql.bindInt64(1, objectStoreID) != SQLITE_OK
     721            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
     722            || sql.step() != SQLITE_DONE) {
     723            LOG_ERROR("Could not delete record from object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     724            return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete record from object store") };
     725        }
     726    }
     727
     728    // Delete record from indexes store
     729    {
     730        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("DELETE FROM IndexRecords WHERE objectStoreID = ? AND value = CAST(? AS TEXT);"));
     731
     732        if (sql.prepare() != SQLITE_OK
     733            || sql.bindInt64(1, objectStoreID) != SQLITE_OK
     734            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
     735            || sql.step() != SQLITE_DONE) {
     736            LOG_ERROR("Could not delete record from indexes for object store %" PRIi64 " (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     737            return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to delete index entries for object store record") };
     738        }
     739    }
     740
     741    return { };
     742}
     743
     744IDBError SQLiteIDBBackingStore::deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange)
     745{
     746    LOG(IndexedDB, "SQLiteIDBBackingStore::deleteRange - range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
     747
     748    ASSERT(m_sqliteDB);
     749    ASSERT(m_sqliteDB->isOpen());
     750
     751    auto* transaction = m_transactions.get(transactionIdentifier);
     752    if (!transaction || !transaction->inProgress()) {
     753        LOG_ERROR("Attempt to delete range from database without an in-progress transaction");
     754        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete range from database without an in-progress transaction") };
     755    }
     756    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
     757        LOG_ERROR("Attempt to delete records from an object store in a read-only transaction");
     758        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to delete records from an object store in a read-only transaction") };
     759    }
     760
     761    // If the range to delete is exactly one key we can delete it right now.
     762    if (keyRange.isExactlyOneKey()) {
     763        auto error = deleteRecord(*transaction, objectStoreID, keyRange.lowerKey);
     764        if (!error.isNull()) {
     765            LOG_ERROR("Failed to delete record for key '%s'", keyRange.lowerKey.loggingString().utf8().data());
     766            return error;
     767        }
     768
     769        return { };
     770    }
     771
     772    // FIXME: Once cursor support is in place, use a cursor to delete every record in the range.
     773    LOG_ERROR("Currently unable to delete all records in a multi-key range");
     774    return { IDBDatabaseException::UnknownError, ASCIILiteral("Currently unable to delete all records in a multi-key range") };
     775}
     776
     777IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
     778{
     779    LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
     780
     781    ASSERT(m_sqliteDB);
     782    ASSERT(m_sqliteDB->isOpen());
     783    ASSERT(value.data());
     784
     785    auto* transaction = m_transactions.get(transactionIdentifier);
     786    if (!transaction || !transaction->inProgress()) {
     787        LOG_ERROR("Attempt to store a record in an object store without an in-progress transaction");
     788        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store without an in-progress transaction") };
     789    }
     790    if (transaction->mode() == IndexedDB::TransactionMode::ReadOnly) {
     791        LOG_ERROR("Attempt to store a record in an object store in a read-only transaction");
     792        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to store a record in an object store in a read-only transaction") };
     793    }
     794
     795    RefPtr<SharedBuffer> keyBuffer = serializeIDBKeyData(keyData);
     796    if (!keyBuffer) {
     797        LOG_ERROR("Unable to serialize IDBKey to be stored in an object store");
     798        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to be stored in an object store") };
     799    }
     800    {
     801        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?);"));
     802        if (sql.prepare() != SQLITE_OK
     803            || sql.bindInt64(1, objectStoreID) != SQLITE_OK
     804            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
     805            || sql.bindBlob(3, value.data()->data(), value.data()->size()) != SQLITE_OK
     806            || sql.step() != SQLITE_DONE) {
     807            LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     808            return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
     809        }
     810    }
     811
     812    return { };
     813}
     814
     815IDBError SQLiteIDBBackingStore::getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyRangeData& keyRange, ThreadSafeDataBuffer& resultValue)
     816{
     817    LOG(IndexedDB, "SQLiteIDBBackingStore::getRecord - key range %s, object store %" PRIu64, keyRange.loggingString().utf8().data(), objectStoreID);
     818
     819    ASSERT(m_sqliteDB);
     820    ASSERT(m_sqliteDB->isOpen());
     821
     822    auto* transaction = m_transactions.get(transactionIdentifier);
     823    if (!transaction || !transaction->inProgress()) {
     824        LOG_ERROR("Attempt to get a record from database without an in-progress transaction");
     825        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to get a record from database without an in-progress transaction") };
     826    }
     827
     828    RefPtr<SharedBuffer> lowerBuffer = serializeIDBKeyData(IDBKeyData(keyRange.lowerKey));
     829    if (!lowerBuffer) {
     830        LOG_ERROR("Unable to serialize lower IDBKey in lookup range");
     831        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize lower IDBKey in lookup range") };
     832    }
     833
     834    RefPtr<SharedBuffer> upperBuffer = serializeIDBKeyData(IDBKeyData(keyRange.upperKey));
     835    if (!upperBuffer) {
     836        LOG_ERROR("Unable to serialize upper IDBKey in lookup range");
     837        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize upper IDBKey in lookup range") };
     838    }
     839
     840    {
     841        static NeverDestroyed<const ASCIILiteral> lowerOpenUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
     842        static NeverDestroyed<const ASCIILiteral> lowerOpenUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key > CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
     843        static NeverDestroyed<const ASCIILiteral> lowerClosedUpperOpen("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key < CAST(? AS TEXT) ORDER BY key;");
     844        static NeverDestroyed<const ASCIILiteral> lowerClosedUpperClosed("SELECT value FROM Records WHERE objectStoreID = ? AND key >= CAST(? AS TEXT) AND key <= CAST(? AS TEXT) ORDER BY key;");
     845
     846        const ASCIILiteral* query = nullptr;
     847
     848        if (keyRange.lowerOpen) {
     849            if (keyRange.upperOpen)
     850                query = &lowerOpenUpperOpen.get();
     851            else
     852                query = &lowerOpenUpperClosed.get();
     853        } else {
     854            if (keyRange.upperOpen)
     855                query = &lowerClosedUpperOpen.get();
     856            else
     857                query = &lowerClosedUpperClosed.get();
     858        }
     859
     860        ASSERT(query);
     861
     862        SQLiteStatement sql(*m_sqliteDB, *query);
     863        if (sql.prepare() != SQLITE_OK
     864            || sql.bindInt64(1, objectStoreID) != SQLITE_OK
     865            || sql.bindBlob(2, lowerBuffer->data(), lowerBuffer->size()) != SQLITE_OK
     866            || sql.bindBlob(3, upperBuffer->data(), upperBuffer->size()) != SQLITE_OK) {
     867            LOG_ERROR("Could not get key range record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     868            return { IDBDatabaseException::UnknownError, ASCIILiteral("Failed to look up record in object store by key range") };
     869        }
     870
     871        int sqlResult = sql.step();
     872
     873        if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE) {
     874            // There was no record for the key in the database.
     875            return { };
     876        }
     877        if (sqlResult != SQLITE_ROW) {
     878            // There was an error fetching the record from the database.
     879            LOG_ERROR("Could not get record from object store %" PRIi64 " from Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     880            return { IDBDatabaseException::UnknownError, ASCIILiteral("Error looking up record in object store by key range") };
     881        }
     882
     883        Vector<uint8_t> buffer;
     884        sql.getColumnBlobAsVector(0, buffer);
     885        resultValue = ThreadSafeDataBuffer::adoptVector(buffer);
     886    }
     887
     888    return { };
    674889}
    675890
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h

    r195467 r195495  
    8585    std::unique_ptr<IDBDatabaseInfo> extractExistingDatabaseInfo();
    8686
     87    IDBError deleteRecord(SQLiteIDBTransaction&, int64_t objectStoreID, const IDBKeyData&);
     88
    8789    IDBDatabaseIdentifier m_identifier;
    8890    std::unique_ptr<IDBDatabaseInfo> m_databaseInfo;
Note: See TracChangeset for help on using the changeset viewer.