Changeset 195517 in webkit


Ignore:
Timestamp:
Jan 24, 2016 3:42:11 PM (8 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: Support IDBObjectStore.createIndex in the SQLite backing store.
https://bugs.webkit.org/show_bug.cgi?id=153410

Reviewed by Darin Adler.

Source/WebCore:

No new tests (Covered by unskipping many existing tests).

  • Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:

(WebCore::IDBServer::SQLiteIDBBackingStore::~SQLiteIDBBackingStore):
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedHasIndexRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedPutIndexRecord):

  • Modules/indexeddb/server/SQLiteIDBBackingStore.h:
  • Modules/indexeddb/server/SQLiteIDBCursor.cpp:

(WebCore::IDBServer::SQLiteIDBCursor::maybeCreateBackingStoreCursor):
(WebCore::IDBServer::SQLiteIDBCursor::SQLiteIDBCursor):

  • Modules/indexeddb/server/SQLiteIDBCursor.h:
  • Modules/indexeddb/server/SQLiteIDBTransaction.cpp:

(WebCore::IDBServer::SQLiteIDBTransaction::maybeOpenBackingStoreCursor):

  • Modules/indexeddb/server/SQLiteIDBTransaction.h:

LayoutTests:

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

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195516 r195517  
     12016-01-24  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Support IDBObjectStore.createIndex in the SQLite backing store.
     4        https://bugs.webkit.org/show_bug.cgi?id=153410
     5
     6        Reviewed by Darin Adler.
     7
     8        * platform/mac-wk1/TestExpectations:
     9
    1102016-01-24  Simon Fraser  <simon.fraser@apple.com>
    211
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r195508 r195517  
    440440imported/w3c/indexeddb/value_recursive.htm [ Failure ]
    441441imported/w3c/indexeddb/writer-starvation.htm [ Failure ]
    442 storage/indexeddb/createIndex-after-failure.html [ Failure ]
    443442storage/indexeddb/cursor-added-bug.html [ Failure ]
    444443storage/indexeddb/cursor-advance.html [ Failure ]
     
    461460storage/indexeddb/cursor-update.html [ Failure ]
    462461storage/indexeddb/cursor-value.html [ Failure ]
    463 storage/indexeddb/database-wrapper.html [ Failure ]
    464462storage/indexeddb/delete-range.html [ Failure ]
    465 storage/indexeddb/deleteIndex.html [ Failure ]
    466463storage/indexeddb/deleted-objects.html [ Failure ]
    467464storage/indexeddb/duplicates.html [ Failure ]
    468465storage/indexeddb/exceptions.html [ Failure ]
    469 storage/indexeddb/factory-deletedatabase.html [ Failure ]
    470466storage/indexeddb/get-keyrange.html [ Failure ]
    471467storage/indexeddb/index-basics.html [ Failure ]
     
    485481storage/indexeddb/lazy-index-population.html [ Failure ]
    486482storage/indexeddb/lazy-index-types.html [ Failure ]
    487 storage/indexeddb/list-ordering.html [ Failure ]
    488 storage/indexeddb/metadata-race.html [ Failure ]
    489 storage/indexeddb/metadata.html [ Failure ]
    490 storage/indexeddb/modern/abort-objectstore-info.html [ Failure ]
    491483storage/indexeddb/modern/autoincrement-abort.html [ Failure ]
    492 storage/indexeddb/modern/create-index-failures.html [ Failure ]
    493484storage/indexeddb/modern/cursor-1.html [ Failure ]
    494485storage/indexeddb/modern/cursor-2.html [ Failure ]
     
    501492storage/indexeddb/modern/deleteindex-1.html [ Failure ]
    502493storage/indexeddb/modern/deleteindex-2.html [ Failure ]
    503 storage/indexeddb/modern/get-index-failures.html [ Failure ]
    504494storage/indexeddb/modern/get-keyrange.html [ Failure ]
    505 storage/indexeddb/modern/idbindex-properties-basic.html [ Failure ]
    506495storage/indexeddb/modern/idbobjectstore-clear-1.html [ Failure ]
    507496storage/indexeddb/modern/idbobjectstore-clear-2.html [ Failure ]
     
    517506storage/indexeddb/modern/index-get-count-basic.html [ Failure ]
    518507storage/indexeddb/modern/index-get-count-failures.html [ Failure ]
    519 storage/indexeddb/modern/memory-index-not-deleted-with-objectstore.html [ Failure ]
    520 storage/indexeddb/modern/objectstore-attributes.html [ Failure ]
    521508storage/indexeddb/modern/objectstore-cursor-advance-failures.html [ Failure ]
    522509storage/indexeddb/modern/objectstore-cursor-continue-failures.html [ Failure ]
    523 storage/indexeddb/modern/opencursor-failures.html [ Failure ]
    524510storage/indexeddb/modern/request-readystate.html [ Failure ]
    525 storage/indexeddb/modern/transactions-stop-on-navigation.html [ Failure ]
    526511storage/indexeddb/mozilla/autoincrement-indexes.html [ Failure ]
    527512storage/indexeddb/mozilla/clear.html [ Failure ]
    528 storage/indexeddb/mozilla/create-index-with-integer-keys.html [ Failure ]
    529513storage/indexeddb/mozilla/cursor-mutation-objectstore-only.html [ Failure ]
    530514storage/indexeddb/mozilla/cursor-mutation.html [ Failure ]
     
    537521storage/indexeddb/mozilla/key-requirements.html [ Failure ]
    538522storage/indexeddb/mozilla/object-cursors.html [ Failure ]
    539 storage/indexeddb/mozilla/object-identity.html [ Failure ]
    540523storage/indexeddb/mozilla/object-store-inline-autoincrement-key-added-on-put.html [ Failure ]
    541524storage/indexeddb/mozilla/object-store-remove-values.html [ Failure ]
     
    550533storage/indexeddb/objectstore-count.html [ Failure ]
    551534storage/indexeddb/objectstore-cursor.html [ Failure ]
    552 storage/indexeddb/objectstore-removeobjectstore.html [ Failure ]
    553535storage/indexeddb/open-cursor.html [ Failure ]
    554536storage/indexeddb/opencursor-key.html [ Failure ]
    555537storage/indexeddb/optional-arguments.html [ Failure ]
    556538storage/indexeddb/prefetch-bugfix-108071.html [ Failure ]
    557 storage/indexeddb/queued-commands.html [ Failure ]
    558539storage/indexeddb/readonly.html [ Failure ]
    559 storage/indexeddb/structured-clone.html [ Failure ]
    560540storage/indexeddb/transaction-active-flag.html [ Failure ]
    561 storage/indexeddb/transaction-and-objectstore-calls.html [ Failure ]
    562 storage/indexeddb/transaction-basics.html [ Failure ]
    563 storage/indexeddb/transaction-error.html [ Failure ]
    564541storage/indexeddb/transaction-rollback.html [ Failure ]
    565542storage/indexeddb/value-undefined.html [ Failure ]
  • trunk/Source/WebCore/ChangeLog

    r195516 r195517  
     12016-01-24  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: Support IDBObjectStore.createIndex in the SQLite backing store.
     4        https://bugs.webkit.org/show_bug.cgi?id=153410
     5
     6        Reviewed by Darin Adler.
     7
     8        No new tests (Covered by unskipping many existing tests).
     9
     10        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
     11        (WebCore::IDBServer::SQLiteIDBBackingStore::~SQLiteIDBBackingStore):
     12        (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
     13        (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedHasIndexRecord):
     14        (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedPutIndexRecord):
     15        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
     16
     17        * Modules/indexeddb/server/SQLiteIDBCursor.cpp:
     18        (WebCore::IDBServer::SQLiteIDBCursor::maybeCreateBackingStoreCursor):
     19        (WebCore::IDBServer::SQLiteIDBCursor::SQLiteIDBCursor):
     20        * Modules/indexeddb/server/SQLiteIDBCursor.h:
     21
     22        * Modules/indexeddb/server/SQLiteIDBTransaction.cpp:
     23        (WebCore::IDBServer::SQLiteIDBTransaction::maybeOpenBackingStoreCursor):
     24        * Modules/indexeddb/server/SQLiteIDBTransaction.h:
     25
    1262016-01-24  Simon Fraser  <simon.fraser@apple.com>
    227
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

    r195508 r195517  
    119119    if (m_sqliteDB)
    120120        m_sqliteDB->close();
     121
     122    if (m_vm) {
     123        JSLockHolder locker(m_vm.get());
     124        m_vm = nullptr;
     125    }
    121126}
    122127
     
    679684}
    680685
    681 IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier&, const IDBIndexInfo&)
    682 {
    683     return { IDBDatabaseException::UnknownError, ASCIILiteral("Not implemented") };
    684 }
     686IDBError SQLiteIDBBackingStore::createIndex(const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info)
     687{
     688    ASSERT(m_sqliteDB);
     689    ASSERT(m_sqliteDB->isOpen());
     690
     691    auto* transaction = m_transactions.get(transactionIdentifier);
     692    if (!transaction || !transaction->inProgress()) {
     693        LOG_ERROR("Attempt to create an index without an in-progress transaction");
     694        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index without an in-progress transaction") };
     695    }
     696    if (transaction->mode() != IndexedDB::TransactionMode::VersionChange) {
     697        LOG_ERROR("Attempt to create an index in a non-version-change transaction");
     698        return { IDBDatabaseException::UnknownError, ASCIILiteral("Attempt to create an index in a non-version-change transaction") };
     699    }
     700
     701    RefPtr<SharedBuffer> keyPathBlob = serializeIDBKeyPath(info.keyPath());
     702    if (!keyPathBlob) {
     703        LOG_ERROR("Unable to serialize IDBKeyPath to save in database");
     704        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKeyPath to create index in database") };
     705    }
     706
     707    SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexInfo VALUES (?, ?, ?, ?, ?, ?);"));
     708    if (sql.prepare() != SQLITE_OK
     709        || sql.bindInt64(1, info.identifier()) != SQLITE_OK
     710        || sql.bindText(2, info.name()) != SQLITE_OK
     711        || sql.bindInt64(3, info.objectStoreIdentifier()) != SQLITE_OK
     712        || sql.bindBlob(4, keyPathBlob->data(), keyPathBlob->size()) != SQLITE_OK
     713        || sql.bindInt(5, info.unique()) != SQLITE_OK
     714        || sql.bindInt(6, info.multiEntry()) != SQLITE_OK
     715        || sql.step() != SQLITE_DONE) {
     716        LOG_ERROR("Could not add index '%s' to IndexInfo table (%i) - %s", info.name().utf8().data(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     717        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to create index in database") };
     718    }
     719
     720    // Write index records for any records that already exist in this object store.
     721
     722    auto cursor = transaction->maybeOpenBackingStoreCursor(info.objectStoreIdentifier());
     723
     724    if (!cursor) {
     725        LOG_ERROR("Cannot open cursor to populate indexes in database");
     726        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to populate indexes in database") };
     727    }
     728
     729    if (!m_vm) {
     730        ASSERT(!m_globalObject);
     731        m_vm = VM::create();
     732    }
     733
     734    JSLockHolder locker(m_vm.get());
     735
     736    if (!m_globalObject)
     737        m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
     738
     739    while (!cursor->currentKey().isNull()) {
     740        auto& key = cursor->currentKey();
     741        auto& valueBuffer = cursor->currentValueBuffer();
     742
     743        auto value = deserializeIDBValueBuffer(m_globalObject->globalExec(), Vector<uint8_t>(valueBuffer), true);
     744
     745        IndexKey indexKey;
     746        generateIndexKeyForValue(*m_globalObject->globalExec(), info, value.jsValue(), indexKey);
     747
     748        if (!info.multiEntry()) {
     749            IDBError error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey.asOneKey());
     750            if (!error.isNull()) {
     751                LOG_ERROR("Unable to put index record for newly created index");
     752                return error;
     753            }
     754        }
     755
     756        Vector<IDBKeyData> indexKeys = indexKey.multiEntry();
     757
     758        if (info.unique()) {
     759            bool hasRecord;
     760            IDBError error;
     761            for (auto& indexKey : indexKeys) {
     762                error = uncheckedHasIndexRecord(info.identifier(), indexKey, hasRecord);
     763                if (hasRecord)
     764                    return IDBError(IDBDatabaseException::ConstraintError);
     765                if (!error.isNull())
     766                    return error;
     767            }
     768        }
     769
     770        for (auto& indexKey : indexKeys) {
     771            IDBError error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey);
     772            if (!error.isNull()) {
     773                LOG_ERROR("Unable to put index record for newly created index");
     774                return error;
     775            }
     776        }
     777
     778        if (!cursor->advance(1)) {
     779            LOG_ERROR("Error advancing cursor while indexing existing records for new index.");
     780            return { IDBDatabaseException::UnknownError, ASCIILiteral("Error advancing cursor while indexing existing records for new index") };
     781        }
     782    }
     783
     784    return { };
     785}
     786
     787IDBError SQLiteIDBBackingStore::uncheckedHasIndexRecord(int64_t indexID, const IDBKeyData& indexKey, bool& hasRecord)
     788{
     789    hasRecord = false;
     790
     791    RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
     792    if (!indexKeyBuffer) {
     793        LOG_ERROR("Unable to serialize index key to be stored in the database");
     794        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize IDBKey to check for index record in database") };
     795    }
     796
     797    SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("SELECT rowid FROM IndexRecords WHERE indexID = ? AND key = CAST(? AS TEXT);"));
     798    if (sql.prepare() != SQLITE_OK
     799        || sql.bindInt64(1, indexID) != SQLITE_OK
     800        || sql.bindBlob(2, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK) {
     801        LOG_ERROR("Error checking for index record in database");
     802        return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for index record in database") };
     803    }
     804
     805    int sqlResult = sql.step();
     806    if (sqlResult == SQLITE_OK || sqlResult == SQLITE_DONE)
     807        return { };
     808
     809    if (sqlResult != SQLITE_ROW) {
     810        // There was an error fetching the record from the database.
     811        LOG_ERROR("Could not check if key exists in index (%i) - %s", m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     812        return { IDBDatabaseException::UnknownError, ASCIILiteral("Error checking for existence of IDBKey in index") };
     813    }
     814
     815    hasRecord = true;
     816    return { };
     817}
     818
     819
     820IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey)
     821{
     822    RefPtr<SharedBuffer> indexKeyBuffer = serializeIDBKeyData(indexKey);
     823    if (!indexKeyBuffer) {
     824        LOG_ERROR("Unable to serialize index key to be stored in the database");
     825        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize index key to be stored in the database") };
     826    }
     827
     828    RefPtr<SharedBuffer> valueBuffer = serializeIDBKeyData(keyValue);
     829    if (!valueBuffer) {
     830        LOG_ERROR("Unable to serialize the value to be stored in the database");
     831        return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to serialize value to be stored in the database") };
     832    }
     833
     834    {
     835        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO IndexRecords VALUES (?, ?, CAST(? AS TEXT), CAST(? AS TEXT));"));
     836        if (sql.prepare() != SQLITE_OK
     837            || sql.bindInt64(1, indexID) != SQLITE_OK
     838            || sql.bindInt64(2, objectStoreID) != SQLITE_OK
     839            || sql.bindBlob(3, indexKeyBuffer->data(), indexKeyBuffer->size()) != SQLITE_OK
     840            || sql.bindBlob(4, valueBuffer->data(), valueBuffer->size()) != SQLITE_OK
     841            || sql.step() != SQLITE_DONE) {
     842            LOG_ERROR("Could not put index record for index %" PRIi64 " in object store %" PRIi64 " in Records table (%i) - %s", indexID, objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     843            return { IDBDatabaseException::UnknownError, ASCIILiteral("Error putting index record into database") };
     844        }
     845    }
     846
     847    return { };
     848}
     849
    685850
    686851IDBError SQLiteIDBBackingStore::deleteIndex(const IDBResourceIdentifier&, uint64_t, const String&)
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h

    r195499 r195517  
    3434#include "IDBResourceIdentifier.h"
    3535#include "SQLiteIDBTransaction.h"
     36#include <JavaScriptCore/Strong.h>
    3637#include <wtf/HashMap.h>
    3738
     
    8788
    8889    IDBError deleteRecord(SQLiteIDBTransaction&, int64_t objectStoreID, const IDBKeyData&);
     90    IDBError uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey);
     91    IDBError uncheckedHasIndexRecord(int64_t indexID, const IDBKeyData&, bool& hasRecord);
    8992
    9093    IDBDatabaseIdentifier m_identifier;
     
    97100
    98101    String m_absoluteDatabaseDirectory;
     102
     103    RefPtr<JSC::VM> m_vm;
     104    JSC::Strong<JSC::JSGlobalObject> m_globalObject;
    99105};
    100106
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.cpp

    r195443 r195517  
    4141std::unique_ptr<SQLiteIDBCursor> SQLiteIDBCursor::maybeCreate(SQLiteIDBTransaction& transaction, const IDBCursorInfo& info)
    4242{
    43     auto cursor = std::unique_ptr<SQLiteIDBCursor>(new SQLiteIDBCursor(transaction, info));
     43    auto cursor = std::make_unique<SQLiteIDBCursor>(transaction, info);
     44
     45    if (!cursor->establishStatement())
     46        return nullptr;
     47
     48    if (!cursor->advance(1))
     49        return nullptr;
     50
     51    return cursor;
     52}
     53
     54std::unique_ptr<SQLiteIDBCursor> SQLiteIDBCursor::maybeCreateBackingStoreCursor(SQLiteIDBTransaction& transaction, const uint64_t objectStoreIdentifier)
     55{
     56    auto cursor = std::make_unique<SQLiteIDBCursor>(transaction, objectStoreIdentifier);
    4457
    4558    if (!cursor->establishStatement())
     
    5972    , m_cursorDirection(info.cursorDirection())
    6073    , m_keyRange(info.range())
    61     , m_currentRecordID(-1)
    62     , m_statementNeedsReset(false)
    63     , m_boundID(0)
    64     , m_completed(false)
    65     , m_errored(false)
     74{
     75    ASSERT(m_objectStoreID);
     76}
     77
     78SQLiteIDBCursor::SQLiteIDBCursor(SQLiteIDBTransaction& transaction, uint64_t objectStoreID)
     79    : m_transaction(&transaction)
     80    , m_cursorIdentifier(transaction.transactionIdentifier())
     81    , m_objectStoreID(objectStoreID)
     82    , m_cursorDirection(IndexedDB::CursorDirection::Next)
    6683{
    6784    ASSERT(m_objectStoreID);
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBCursor.h

    r195443 r195517  
    4747public:
    4848    static std::unique_ptr<SQLiteIDBCursor> maybeCreate(SQLiteIDBTransaction&, const IDBCursorInfo&);
     49    static std::unique_ptr<SQLiteIDBCursor> maybeCreateBackingStoreCursor(SQLiteIDBTransaction&, const uint64_t objectStoreIdentifier);
     50
     51    SQLiteIDBCursor(SQLiteIDBTransaction&, const IDBCursorInfo&);
     52    SQLiteIDBCursor(SQLiteIDBTransaction&, uint64_t objectStoreID);
    4953
    5054    const IDBResourceIdentifier& identifier() const { return m_cursorIdentifier; }
     
    6569
    6670private:
    67     SQLiteIDBCursor(SQLiteIDBTransaction&, const IDBCursorInfo&);
    68 
    6971    bool establishStatement();
    7072    bool createSQLiteStatement(const String& sql);
     
    8688    IDBResourceIdentifier m_cursorIdentifier;
    8789    int64_t m_objectStoreID;
    88     int64_t m_indexID;
    89     IndexedDB::CursorDirection m_cursorDirection;
     90    int64_t m_indexID { IDBIndexMetadata::InvalidId };
     91    IndexedDB::CursorDirection m_cursorDirection { IndexedDB::CursorDirection::Next };
    9092    IDBKeyRangeData m_keyRange;
    9193
     
    9395    IDBKeyData m_currentUpperKey;
    9496
    95     int64_t m_currentRecordID;
     97    int64_t m_currentRecordID { -1 };
    9698    IDBKeyData m_currentKey;
    9799    IDBKeyData m_currentPrimaryKey;
     
    99101
    100102    std::unique_ptr<SQLiteStatement> m_statement;
    101     bool m_statementNeedsReset;
    102     int64_t m_boundID;
     103    bool m_statementNeedsReset { false };
     104    int64_t m_boundID { 0 };
    103105
    104     bool m_completed;
    105     bool m_errored;
     106    bool m_completed { false };
     107    bool m_errored { false };
    106108};
    107109
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.cpp

    r195467 r195517  
    100100}
    101101
     102std::unique_ptr<SQLiteIDBCursor> SQLiteIDBTransaction::maybeOpenBackingStoreCursor(uint64_t objectStoreID)
     103{
     104    ASSERT(m_sqliteTransaction);
     105    ASSERT(m_sqliteTransaction->inProgress());
     106
     107    return SQLiteIDBCursor::maybeCreateBackingStoreCursor(*this, objectStoreID);
     108}
     109
    102110SQLiteIDBCursor* SQLiteIDBTransaction::maybeOpenCursor(const IDBCursorInfo& info)
    103111{
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBTransaction.h

    r195467 r195517  
    6060    IDBError abort();
    6161
     62    std::unique_ptr<SQLiteIDBCursor> maybeOpenBackingStoreCursor(uint64_t objectStoreID);
    6263    SQLiteIDBCursor* maybeOpenCursor(const IDBCursorInfo&);
    6364
Note: See TracChangeset for help on using the changeset viewer.