Changeset 92950 in webkit


Ignore:
Timestamp:
Aug 12, 2011, 1:51:14 AM (14 years ago)
Author:
hans@chromium.org
Message:

IndexedDB: Overwriting key in unique index should be possible
https://bugs.webkit.org/show_bug.cgi?id=65993

Reviewed by Tony Chang.

Source/WebCore:

It should be possible to overwrite an object store record even if
there is a derived key for that record in an index with the unique flag set.

  • storage/IDBBackingStore.h:
  • storage/IDBIndexBackendImpl.cpp:

(WebCore::IDBIndexBackendImpl::addingKeyAllowed):

  • storage/IDBIndexBackendImpl.h:
  • storage/IDBLevelDBBackingStore.cpp:

(WebCore::IDBLevelDBBackingStore::keyExistsInIndex):

  • storage/IDBLevelDBBackingStore.h:
  • storage/IDBObjectStoreBackendImpl.cpp:

(WebCore::IDBObjectStoreBackendImpl::putInternal):

  • storage/IDBSQLiteBackingStore.cpp:

(WebCore::IDBSQLiteBackingStore::keyExistsInIndex):

  • storage/IDBSQLiteBackingStore.h:

LayoutTests:

Test that it's possible to overwrite an object store record even if there
is a derived key for that record in an index with the unique flag set.

  • storage/indexeddb/index-unique-expected.txt:
  • storage/indexeddb/index-unique.html:
Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r92946 r92950  
     12011-08-10  Hans Wennborg  <hans@chromium.org>
     2
     3        IndexedDB: Overwriting key in unique index should be possible
     4        https://bugs.webkit.org/show_bug.cgi?id=65993
     5
     6        Reviewed by Tony Chang.
     7
     8        Test that it's possible to overwrite an object store record even if there
     9        is a derived key for that record in an index with the unique flag set.
     10
     11        * storage/indexeddb/index-unique-expected.txt:
     12        * storage/indexeddb/index-unique.html:
     13
    1142011-08-11  Yuta Kitamura  <yutak@chromium.org>
    215
  • trunk/LayoutTests/storage/indexeddb/index-unique-expected.txt

    r92364 r92950  
    3535transaction.objectStore('store').put({x: 1}, 'baz')
    3636finalAddSuccess():
     37transaction.objectStore('store').put({x: 1}, 'baz')
    3738PASS successfullyParsed is true
    3839
  • trunk/LayoutTests/storage/indexeddb/index-unique.html

    r92364 r92950  
    135135function finalAddSuccess() {
    136136    debug("finalAddSuccess():");
    137     done();
     137
     138    // An overwrite should be ok.
     139    request = evalAndLog("transaction.objectStore('store').put({x: 1}, 'baz')");
     140    request.onerror = unexpectedErrorCallback;
     141    request.onsuccess = done;
    138142}
    139143
  • trunk/Source/WebCore/ChangeLog

    r92946 r92950  
     12011-08-10  Hans Wennborg  <hans@chromium.org>
     2
     3        IndexedDB: Overwriting key in unique index should be possible
     4        https://bugs.webkit.org/show_bug.cgi?id=65993
     5
     6        Reviewed by Tony Chang.
     7
     8        It should be possible to overwrite an object store record even if
     9        there is a derived key for that record in an index with the unique flag set.
     10
     11        * storage/IDBBackingStore.h:
     12        * storage/IDBIndexBackendImpl.cpp:
     13        (WebCore::IDBIndexBackendImpl::addingKeyAllowed):
     14        * storage/IDBIndexBackendImpl.h:
     15        * storage/IDBLevelDBBackingStore.cpp:
     16        (WebCore::IDBLevelDBBackingStore::keyExistsInIndex):
     17        * storage/IDBLevelDBBackingStore.h:
     18        * storage/IDBObjectStoreBackendImpl.cpp:
     19        (WebCore::IDBObjectStoreBackendImpl::putInternal):
     20        * storage/IDBSQLiteBackingStore.cpp:
     21        (WebCore::IDBSQLiteBackingStore::keyExistsInIndex):
     22        * storage/IDBSQLiteBackingStore.h:
     23
    1242011-08-11  Yuta Kitamura  <yutak@chromium.org>
    225
  • trunk/Source/WebCore/storage/IDBBackingStore.h

    r88358 r92950  
    8282    virtual String getObjectViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&) = 0;
    8383    virtual PassRefPtr<IDBKey> getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&) = 0;
    84     virtual bool keyExistsInIndex(int64_t databaseid, int64_t objectStoreId, int64_t indexId, const IDBKey&) = 0;
     84    virtual bool keyExistsInIndex(int64_t databaseid, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey) = 0;
    8585
    8686    class Cursor : public RefCounted<Cursor> {
  • trunk/Source/WebCore/storage/IDBIndexBackendImpl.cpp

    r83443 r92950  
    159159}
    160160
    161 bool IDBIndexBackendImpl::addingKeyAllowed(IDBKey* key)
     161bool IDBIndexBackendImpl::addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey)
    162162{
    163163    if (!m_unique)
    164164        return true;
    165165
    166     return !m_backingStore->keyExistsInIndex(m_databaseId, m_objectStoreBackend->id(), m_id, *key);
     166    RefPtr<IDBKey> foundPrimaryKey;
     167    bool found = m_backingStore->keyExistsInIndex(m_databaseId, m_objectStoreBackend->id(), m_id, *indexKey, foundPrimaryKey);
     168    if (!found)
     169        return true;
     170    if (foundPrimaryKey->isEqual(primaryKey))
     171        return true;
     172    return false;
    167173}
    168174
  • trunk/Source/WebCore/storage/IDBIndexBackendImpl.h

    r83443 r92950  
    5959    bool hasValidId() const { return m_id != InvalidId; };
    6060
    61     bool addingKeyAllowed(IDBKey*);
     61    bool addingKeyAllowed(const IDBKey* indexKey, const IDBKey* primaryKey);
    6262
    6363    // Implements IDBIndexBackendInterface.
  • trunk/Source/WebCore/storage/IDBLevelDBBackingStore.cpp

    r92468 r92950  
    792792}
    793793
    794 bool IDBLevelDBBackingStore::keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key)
     794bool IDBLevelDBBackingStore::keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey)
    795795{
    796796    ASSERT(m_currentTransaction);
    797797
    798798    Vector<char> foundEncodedPrimaryKey;
    799     if (findKeyInIndex(m_currentTransaction.get(), databaseId, objectStoreId, indexId, key, foundEncodedPrimaryKey))
    800         return true;
    801 
    802     return false;
     799    if (!findKeyInIndex(m_currentTransaction.get(), databaseId, objectStoreId, indexId, indexKey, foundEncodedPrimaryKey))
     800        return false;
     801
     802    decodeIDBKey(foundEncodedPrimaryKey.begin(), foundEncodedPrimaryKey.end(), foundPrimaryKey);
     803    return true;
    803804}
    804805
  • trunk/Source/WebCore/storage/IDBLevelDBBackingStore.h

    r89948 r92950  
    6868    virtual String getObjectViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
    6969    virtual PassRefPtr<IDBKey> getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
    70     virtual bool keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
     70    virtual bool keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey);
    7171
    7272    virtual PassRefPtr<Cursor> openObjectStoreCursor(int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IDBCursor::Direction);
  • trunk/Source/WebCore/storage/IDBObjectStoreBackendImpl.cpp

    r92364 r92950  
    227227    Vector<RefPtr<IDBKey> > indexKeys;
    228228    for (IndexMap::iterator it = objectStore->m_indexes.begin(); it != objectStore->m_indexes.end(); ++it) {
    229         RefPtr<IDBKey> key = fetchKeyFromKeyPath(value.get(), it->second->keyPath());
    230         if (!key) {
     229        const RefPtr<IDBIndexBackendImpl>& index = it->second;
     230
     231        RefPtr<IDBKey> indexKey = fetchKeyFromKeyPath(value.get(), index->keyPath());
     232        if (!indexKey) {
    231233            callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "The key could not be fetched from an index's keyPath."));
    232234            return;
    233235        }
    234         if (key->type() == IDBKey::NullType) {
     236        if (indexKey->type() == IDBKey::NullType) {
    235237            callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::DATA_ERR, "One of the derived (from a keyPath) keys for an index is NULL."));
    236238            return;
    237239        }
    238         if (!it->second->addingKeyAllowed(key.get())) {
     240        if (!index->addingKeyAllowed(indexKey.get(), key.get())) { // So problem is that if key() is the same as the old key for this record in this index, then we're not really *adding it*, just updating it...
    239241            callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "One of the derived (from a keyPath) keys for an index does not satisfy its uniqueness requirements."));
    240242            return;
    241243        }
    242         indexKeys.append(key.release());
     244        indexKeys.append(indexKey.release());
    243245    }
    244246
  • trunk/Source/WebCore/storage/IDBSQLiteBackingStore.cpp

    r89948 r92950  
    676676}
    677677
    678 bool IDBSQLiteBackingStore::keyExistsInIndex(int64_t, int64_t, int64_t indexId, const IDBKey& key)
    679 {
    680     String sql = String("SELECT id FROM IndexData WHERE indexId = ? AND ") + whereSyntaxForKey(key);
     678bool IDBSQLiteBackingStore::keyExistsInIndex(int64_t, int64_t, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey)
     679{
     680    String sql = String("SELECT id FROM IndexData WHERE indexId = ? AND ") + whereSyntaxForKey(indexKey);
    681681    SQLiteStatement query(m_db, sql);
    682682    bool ok = query.prepare() == SQLResultOk;
     
    684684
    685685    query.bindInt64(1, indexId);
    686     bindKeyToQuery(query, 2, key);
    687 
    688     return query.step() == SQLResultRow;
     686    bindKeyToQuery(query, 2, indexKey);
     687
     688    if (query.step() != SQLResultRow)
     689        return false;
     690
     691    foundPrimaryKey = getPrimaryKeyViaIndex(0, 0, indexId, indexKey);
     692    ASSERT(foundPrimaryKey);
     693    return true;
    689694}
    690695
  • trunk/Source/WebCore/storage/IDBSQLiteBackingStore.h

    r89948 r92950  
    6363    virtual String getObjectViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
    6464    virtual PassRefPtr<IDBKey> getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
    65     virtual bool keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
     65    virtual bool keyExistsInIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey);
    6666
    6767    virtual PassRefPtr<Cursor> openObjectStoreCursor(int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IDBCursor::Direction);
Note: See TracChangeset for help on using the changeset viewer.