Changeset 195689 in webkit


Ignore:
Timestamp:
Jan 27, 2016 1:57:22 PM (8 years ago)
Author:
beidson@apple.com
Message:

Modern IDB: SQLite backend doesn't update index records as object records are added.
https://bugs.webkit.org/show_bug.cgi?id=153548

Reviewed by Alex Christensen.

Source/WebCore:

No new tests (4 more tests pass, others improve).

  • Modules/indexeddb/server/IDBBackingStore.h:
  • Modules/indexeddb/server/MemoryIDBBackingStore.cpp:

(WebCore::IDBServer::MemoryIDBBackingStore::addRecord):

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

(WebCore::IDBServer::SQLiteIDBBackingStore::initializeVM):
(WebCore::IDBServer::SQLiteIDBBackingStore::vm):
(WebCore::IDBServer::SQLiteIDBBackingStore::globalObject):
(WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
(WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedPutIndexKey):
(WebCore::IDBServer::SQLiteIDBBackingStore::updateIndexesForAddRecord):
(WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):

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

(WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):

  • Modules/indexeddb/shared/IDBObjectStoreInfo.h:

LayoutTests:

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

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195688 r195689  
     12016-01-27  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: SQLite backend doesn't update index records as object records are added.
     4        https://bugs.webkit.org/show_bug.cgi?id=153548
     5
     6        Reviewed by Alex Christensen.
     7
     8        * platform/mac-wk1/TestExpectations:
     9
    1102016-01-27  Brady Eidson  <beidson@apple.com>
    211
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r195648 r195689  
    465465storage/indexeddb/cursor-index-delete.html [ Failure ]
    466466storage/indexeddb/cursor-key-order.html [ Failure ]
    467 storage/indexeddb/cursor-overloads.html [ Failure ]
    468467storage/indexeddb/cursor-prev-no-duplicate.html [ Failure ]
    469468storage/indexeddb/cursor-primary-key-order.html [ Failure ]
    470 storage/indexeddb/cursor-properties.html [ Failure ]
    471 storage/indexeddb/cursor-reverse-bug.html [ Failure ]
    472469storage/indexeddb/cursor-skip-deleted.html [ Failure ]
    473470storage/indexeddb/cursor-update.html [ Failure ]
     
    516513storage/indexeddb/modern/objectstore-cursor-continue-failures.html [ Failure ]
    517514storage/indexeddb/modern/request-readystate.html [ Failure ]
    518 storage/indexeddb/mozilla/autoincrement-indexes.html [ Failure ]
    519515storage/indexeddb/mozilla/clear.html [ Failure ]
    520516storage/indexeddb/mozilla/cursor-mutation-objectstore-only.html [ Failure ]
  • trunk/Source/WebCore/ChangeLog

    r195686 r195689  
     12016-01-27  Brady Eidson  <beidson@apple.com>
     2
     3        Modern IDB: SQLite backend doesn't update index records as object records are added.
     4        https://bugs.webkit.org/show_bug.cgi?id=153548
     5
     6        Reviewed by Alex Christensen.
     7
     8        No new tests (4 more tests pass, others improve).
     9
     10        * Modules/indexeddb/server/IDBBackingStore.h:
     11       
     12        * Modules/indexeddb/server/MemoryIDBBackingStore.cpp:
     13        (WebCore::IDBServer::MemoryIDBBackingStore::addRecord):
     14        * Modules/indexeddb/server/MemoryIDBBackingStore.h:
     15       
     16        * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp:
     17        (WebCore::IDBServer::SQLiteIDBBackingStore::initializeVM):
     18        (WebCore::IDBServer::SQLiteIDBBackingStore::vm):
     19        (WebCore::IDBServer::SQLiteIDBBackingStore::globalObject):
     20        (WebCore::IDBServer::SQLiteIDBBackingStore::createIndex):
     21        (WebCore::IDBServer::SQLiteIDBBackingStore::uncheckedPutIndexKey):
     22        (WebCore::IDBServer::SQLiteIDBBackingStore::updateIndexesForAddRecord):
     23        (WebCore::IDBServer::SQLiteIDBBackingStore::addRecord):
     24        * Modules/indexeddb/server/SQLiteIDBBackingStore.h:
     25       
     26        * Modules/indexeddb/server/UniqueIDBDatabase.cpp:
     27        (WebCore::IDBServer::UniqueIDBDatabase::performPutOrAdd):
     28       
     29        * Modules/indexeddb/shared/IDBObjectStoreInfo.h:
     30
    1312016-01-27  Ryosuke Niwa  <rniwa@webkit.org>
    232
  • trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h

    r195527 r195689  
    6868    virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) = 0;
    6969    virtual IDBError deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&) = 0;
    70     virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) = 0;
     70    virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&, const IDBKeyData&, const ThreadSafeDataBuffer& value) = 0;
    7171    virtual IDBError getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&, ThreadSafeDataBuffer& outValue) = 0;
    7272    virtual IDBError getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult& outValue) = 0;
  • trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp

    r195527 r195689  
    267267}
    268268
    269 IDBError MemoryIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
     269IDBError MemoryIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
    270270{
    271271    LOG(IndexedDB, "MemoryIDBBackingStore::addRecord");
    272272
    273     ASSERT(objectStoreIdentifier);
     273    ASSERT(objectStoreInfo.identifier());
    274274
    275275    auto transaction = m_transactions.get(transactionIdentifier);
     
    277277        return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store transaction found to put record"));
    278278
    279     MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreIdentifier);
     279    MemoryObjectStore* objectStore = m_objectStoresByIdentifier.get(objectStoreInfo.identifier());
    280280    if (!objectStore)
    281281        return IDBError(IDBDatabaseException::UnknownError, ASCIILiteral("No backing store object store found to put record"));
  • trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h

    r195527 r195689  
    6060    virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) override final;
    6161    virtual IDBError deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&) override final;
    62     virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) override final;
     62    virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&, const IDBKeyData&, const ThreadSafeDataBuffer& value) override final;
    6363    virtual IDBError getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&, ThreadSafeDataBuffer& outValue) override final;
    6464    virtual IDBError getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult& outValue) override final;
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp

    r195648 r195689  
    3434#include "IDBGetResult.h"
    3535#include "IDBKeyData.h"
     36#include "IDBObjectStoreInfo.h"
    3637#include "IDBSerialization.h"
    3738#include "IDBTransactionInfo.h"
     
    127128}
    128129
     130
     131void SQLiteIDBBackingStore::initializeVM()
     132{
     133    if (!m_vm) {
     134        ASSERT(!m_globalObject);
     135        m_vm = VM::create();
     136
     137        JSLockHolder locker(m_vm.get());
     138        m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
     139    }
     140}
     141
     142VM& SQLiteIDBBackingStore::vm()
     143{
     144    initializeVM();
     145    return *m_vm;
     146}
     147
     148JSGlobalObject& SQLiteIDBBackingStore::globalObject()
     149{
     150    initializeVM();
     151    return **m_globalObject;
     152}
     153
    129154static bool createOrMigrateRecordsTableIfNecessary(SQLiteDatabase& database)
    130155{
     
    728753    }
    729754
    730     if (!m_vm) {
    731         ASSERT(!m_globalObject);
    732         m_vm = VM::create();
    733     }
    734 
    735     JSLockHolder locker(m_vm.get());
    736 
    737     if (!m_globalObject)
    738         m_globalObject.set(*m_vm, JSGlobalObject::create(*m_vm, JSGlobalObject::createStructure(*m_vm, jsNull())));
     755    JSLockHolder locker(vm());
    739756
    740757    while (!cursor->currentKey().isNull()) {
     
    818835}
    819836
     837IDBError SQLiteIDBBackingStore::uncheckedPutIndexKey(const IDBIndexInfo& info, const IDBKeyData& key, const IndexKey& indexKey)
     838{
     839    if (!info.multiEntry()) {
     840        auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey.asOneKey());
     841        if (!error.isNull()) {
     842            LOG_ERROR("Unable to put index record for newly created index");
     843            return error;
     844        }
     845    }
     846
     847    Vector<IDBKeyData> indexKeys = indexKey.multiEntry();
     848
     849    if (info.unique()) {
     850        bool hasRecord;
     851        IDBError error;
     852        for (auto& indexKey : indexKeys) {
     853            error = uncheckedHasIndexRecord(info.identifier(), indexKey, hasRecord);
     854            if (!error.isNull())
     855                return error;
     856            if (hasRecord)
     857                return IDBError(IDBDatabaseException::ConstraintError);
     858        }
     859    }
     860
     861    for (auto& indexKey : indexKeys) {
     862        auto error = uncheckedPutIndexRecord(info.objectStoreIdentifier(), info.identifier(), key, indexKey);
     863        if (!error.isNull()) {
     864            LOG_ERROR("Unable to put index record for newly created index");
     865            return error;
     866        }
     867    }
     868
     869    return { };
     870}
    820871
    821872IDBError SQLiteIDBBackingStore::uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const WebCore::IDBKeyData& keyValue, const WebCore::IDBKeyData& indexKey)
     
    10131064}
    10141065
    1015 IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreID, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
    1016 {
    1017     LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreID);
     1066IDBError SQLiteIDBBackingStore::updateIndexesForAddRecord(const IDBObjectStoreInfo& info, const IDBKeyData& key, const ThreadSafeDataBuffer& value)
     1067{
     1068    JSLockHolder locker(vm());
     1069
     1070    auto jsValue = deserializeIDBValueDataToJSValue(*globalObject().globalExec(), value);
     1071    if (jsValue.isUndefinedOrNull())
     1072        return { };
     1073
     1074    IDBError error;
     1075    Vector<std::pair<uint64_t, IndexKey>> changedIndexRecords;
     1076
     1077    for (auto& index : info.indexMap().values()) {
     1078        IndexKey indexKey;
     1079        generateIndexKeyForValue(*m_globalObject->globalExec(), index, jsValue, indexKey);
     1080
     1081        if (indexKey.isNull())
     1082            continue;
     1083
     1084        error = uncheckedPutIndexKey(index, key, indexKey);
     1085        if (!error.isNull())
     1086            break;
     1087
     1088        changedIndexRecords.append(std::make_pair(index.identifier(), indexKey));
     1089    }
     1090
     1091    // FIXME: If any of the index puts failed, revert the ones that went through (changedIndexRecords).
     1092
     1093    return error;
     1094}
     1095
     1096IDBError SQLiteIDBBackingStore::addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& objectStoreInfo, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
     1097{
     1098    LOG(IndexedDB, "SQLiteIDBBackingStore::addRecord - key %s, object store %" PRIu64, keyData.loggingString().utf8().data(), objectStoreInfo.identifier());
    10181099
    10191100    ASSERT(m_sqliteDB);
     
    10391120        SQLiteStatement sql(*m_sqliteDB, ASCIILiteral("INSERT INTO Records VALUES (?, CAST(? AS TEXT), ?);"));
    10401121        if (sql.prepare() != SQLITE_OK
    1041             || sql.bindInt64(1, objectStoreID) != SQLITE_OK
     1122            || sql.bindInt64(1, objectStoreInfo.identifier()) != SQLITE_OK
    10421123            || sql.bindBlob(2, keyBuffer->data(), keyBuffer->size()) != SQLITE_OK
    10431124            || sql.bindBlob(3, value.data()->data(), value.data()->size()) != SQLITE_OK
    10441125            || sql.step() != SQLITE_DONE) {
    1045             LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreID, m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
     1126            LOG_ERROR("Could not put record for object store %" PRIi64 " in Records table (%i) - %s", objectStoreInfo.identifier(), m_sqliteDB->lastError(), m_sqliteDB->lastErrorMsg());
    10461127            return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to store record in object store") };
    10471128        }
    10481129    }
    10491130
    1050     return { };
     1131    auto error = updateIndexesForAddRecord(objectStoreInfo, keyData, value);
     1132
     1133    // FIXME: If there was an error indexing this record, remove it.
     1134
     1135    return error;
    10511136}
    10521137
  • trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h

    r195648 r195689  
    3939namespace WebCore {
    4040
     41class IndexKey;
    4142class SQLiteDatabase;
    4243
     
    6364    virtual IDBError keyExistsInObjectStore(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, bool& keyExists) override final;
    6465    virtual IDBError deleteRange(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&) override final;
    65     virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const ThreadSafeDataBuffer& value) override final;
     66    virtual IDBError addRecord(const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&, const IDBKeyData&, const ThreadSafeDataBuffer& value) override final;
    6667    virtual IDBError getRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&, ThreadSafeDataBuffer& outValue) override final;
    6768    virtual IDBError getIndexRecord(const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&, IDBGetResult& outValue) override final;
     
    8889
    8990    IDBError deleteRecord(SQLiteIDBTransaction&, int64_t objectStoreID, const IDBKeyData&);
     91    IDBError uncheckedPutIndexKey(const IDBIndexInfo&, const IDBKeyData& keyValue, const IndexKey&);
    9092    IDBError uncheckedPutIndexRecord(int64_t objectStoreID, int64_t indexID, const IDBKeyData& keyValue, const IDBKeyData& indexKey);
    9193    IDBError uncheckedHasIndexRecord(int64_t indexID, const IDBKeyData&, bool& hasRecord);
    9294    IDBError uncheckedGetKeyGeneratorValue(int64_t objectStoreID, uint64_t& outValue);
    9395    IDBError uncheckedSetKeyGeneratorValue(int64_t objectStoreID, uint64_t value);
     96    IDBError updateIndexesForAddRecord(const IDBObjectStoreInfo&, const IDBKeyData&, const ThreadSafeDataBuffer& value);
     97
     98    JSC::VM& vm();
     99    JSC::JSGlobalObject& globalObject();
     100    void initializeVM();
    94101
    95102    IDBDatabaseIdentifier m_identifier;
  • trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp

    r195527 r195689  
    792792    }
    793793
    794     error = m_backingStore->addRecord(transactionIdentifier, objectStoreIdentifier, usedKey, injectedRecordValue.data() ? injectedRecordValue : originalRecordValue);
     794    error = m_backingStore->addRecord(transactionIdentifier, *objectStoreInfo, usedKey, injectedRecordValue.data() ? injectedRecordValue : originalRecordValue);
    795795    if (!error.isNull()) {
    796796        m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, error, usedKey));
  • trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.h

    r195527 r195689  
    5858
    5959    Vector<String> indexNames() const;
     60    const HashMap<uint64_t, IDBIndexInfo>& indexMap() const { return m_indexMap; }
    6061
    6162    void deleteIndex(const String& indexName);
Note: See TracChangeset for help on using the changeset viewer.