Source/WebCore: IndexedDB: Propagate more leveldb errors to IDBIndex and IDBObjectStore
authordgrogan@chromium.org <dgrogan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Dec 2012 00:36:59 +0000 (00:36 +0000)
committerdgrogan@chromium.org <dgrogan@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Dec 2012 00:36:59 +0000 (00:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=103782

Reviewed by Tony Chang.

index.get[Key]() and objectStore.get() will receive more error events.

* Modules/indexeddb/IDBBackingStore.cpp:
(WebCore::IDBBackingStore::getRecord):
(WebCore::versionExists):
(WebCore::IDBBackingStore::findKeyInIndex):
(WebCore::IDBBackingStore::getPrimaryKeyViaIndex):
(WebCore::IDBBackingStore::keyExistsInIndex):
* Modules/indexeddb/IDBBackingStore.h:
(IDBBackingStore):
* Modules/indexeddb/IDBIndexBackendImpl.cpp:
(WebCore::IDBIndexBackendImpl::getInternal):
(WebCore::IDBIndexBackendImpl::getKeyInternal):
* Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
(WebCore::IDBObjectStoreBackendImpl::getInternal):
(WebCore):

Source/WebKit/chromium: Unreviewed.  Rolled DEPS.

Patch by Stephen White <senorblanco@chromium.org> on 2012-12-04

* DEPS:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@136592 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp
Source/WebCore/Modules/indexeddb/IDBBackingStore.h
Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp
Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/IDBFakeBackingStore.h

index 7e2b885..fd5f322 100644 (file)
@@ -1,3 +1,27 @@
+2012-12-04  David Grogan  <dgrogan@chromium.org>
+
+        IndexedDB: Propagate more leveldb errors to IDBIndex and IDBObjectStore
+        https://bugs.webkit.org/show_bug.cgi?id=103782
+
+        Reviewed by Tony Chang.
+
+        index.get[Key]() and objectStore.get() will receive more error events.
+
+        * Modules/indexeddb/IDBBackingStore.cpp:
+        (WebCore::IDBBackingStore::getRecord):
+        (WebCore::versionExists):
+        (WebCore::IDBBackingStore::findKeyInIndex):
+        (WebCore::IDBBackingStore::getPrimaryKeyViaIndex):
+        (WebCore::IDBBackingStore::keyExistsInIndex):
+        * Modules/indexeddb/IDBBackingStore.h:
+        (IDBBackingStore):
+        * Modules/indexeddb/IDBIndexBackendImpl.cpp:
+        (WebCore::IDBIndexBackendImpl::getInternal):
+        (WebCore::IDBIndexBackendImpl::getKeyInternal):
+        * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
+        (WebCore::IDBObjectStoreBackendImpl::getInternal):
+        (WebCore):
+
 2012-12-04  Kentaro Hara  <haraken@chromium.org>
 
         [V8] Remove IntegerCache::m_initialized
index f7455b8..b76157e 100644 (file)
@@ -64,6 +64,9 @@ enum IDBLevelDBBackingStoreInternalErrorType {
     IDBLevelDBBackingStoreReadErrorKeyExistsInObjectStore,
     IDBLevelDBBackingStoreReadErrorLoadCurrentRow,
     IDBLevelDBBackingStoreReadErrorSetupMetadata,
+    IDBLevelDBBackingStoreReadErrorGetPrimaryKeyViaIndex,
+    IDBLevelDBBackingStoreReadErrorKeyExistsInIndex,
+    IDBLevelDBBackingStoreReadErrorVersionExists,
     IDBLevelDBBackingStoreInternalErrorMax,
 };
 static inline void recordInternalError(IDBLevelDBBackingStoreInternalErrorType type)
@@ -637,7 +640,7 @@ void IDBBackingStore::deleteObjectStore(IDBBackingStore::Transaction* transactio
     clearObjectStore(transaction, databaseId, objectStoreId);
 }
 
-String IDBBackingStore::getRecord(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key)
+bool IDBBackingStore::getRecord(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, String& record)
 {
     IDB_TRACE("IDBBackingStore::getRecord");
     LevelDBTransaction* levelDBTransaction = IDBBackingStore::Transaction::levelDBTransactionFrom(transaction);
@@ -645,18 +648,24 @@ String IDBBackingStore::getRecord(IDBBackingStore::Transaction* transaction, int
     const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
     Vector<char> data;
 
-    if (!levelDBTransaction->get(leveldbKey, data))
-        return String();
+    bool found = false;
+    bool ok = levelDBTransaction->safeGet(leveldbKey, data, found);
+    if (!ok) {
+        record = String();
+        InternalError(IDBLevelDBBackingStoreReadErrorGetRecord);
+        return false;
+    }
 
     int64_t version;
     const char* p = decodeVarInt(data.begin(), data.end(), version);
     if (!p) {
         InternalError(IDBLevelDBBackingStoreReadErrorGetRecord);
-        return String();
+        record = String();
+        return false;
     }
-    (void) version;
 
-    return decodeString(p, data.end());
+    record = decodeString(p, data.end());
+    return true;
 }
 
 static int64_t getNewVersionNumber(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId)
@@ -974,21 +983,28 @@ static bool findGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, cons
     return true;
 }
 
-static bool versionExists(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey)
+static bool versionExists(LevelDBTransaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t version, const Vector<char>& encodedPrimaryKey, bool& exists)
 {
     const Vector<char> key = ExistsEntryKey::encode(databaseId, objectStoreId, encodedPrimaryKey);
     Vector<char> data;
 
-    if (!transaction->get(key, data))
+    bool ok = transaction->safeGet(key, data, exists);
+    if (!ok) {
+        InternalError(IDBLevelDBBackingStoreReadErrorVersionExists);
         return false;
+    }
+    if (!exists)
+        return true;
 
-    return decodeInt(data.begin(), data.end()) == version;
+    exists = (decodeInt(data.begin(), data.end()) == version);
+    return true;
 }
 
-bool IDBBackingStore::findKeyInIndex(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, Vector<char>& foundEncodedPrimaryKey)
+bool IDBBackingStore::findKeyInIndex(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, Vector<char>& foundEncodedPrimaryKey, bool& found)
 {
     IDB_TRACE("IDBBackingStore::findKeyInIndex");
     ASSERT(foundEncodedPrimaryKey.isEmpty());
+    found = false;
 
     LevelDBTransaction* levelDBTransaction = IDBBackingStore::Transaction::levelDBTransactionFrom(transaction);
     const Vector<char> leveldbKey = IndexDataKey::encode(databaseId, objectStoreId, indexId, key);
@@ -997,9 +1013,9 @@ bool IDBBackingStore::findKeyInIndex(IDBBackingStore::Transaction* transaction,
 
     for (;;) {
         if (!it->isValid())
-            return false;
+            return true;
         if (compareIndexKeys(it->key(), leveldbKey) > 0)
-            return false;
+            return true;
 
         int64_t version;
         const char* p = decodeVarInt(it->value().begin(), it->value().end(), version);
@@ -1009,38 +1025,53 @@ bool IDBBackingStore::findKeyInIndex(IDBBackingStore::Transaction* transaction,
         }
         foundEncodedPrimaryKey.append(p, it->value().end() - p);
 
-        if (!versionExists(levelDBTransaction, databaseId, objectStoreId, version, foundEncodedPrimaryKey)) {
+        bool exists = false;
+        bool ok = versionExists(levelDBTransaction, databaseId, objectStoreId, version, foundEncodedPrimaryKey, exists);
+        if (!ok)
+            return false;
+        if (!exists) {
             // Delete stale index data entry and continue.
             levelDBTransaction->remove(it->key());
             it->next();
             continue;
         }
-
+        found = true;
         return true;
     }
 }
 
-PassRefPtr<IDBKey> IDBBackingStore::getPrimaryKeyViaIndex(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key)
+bool IDBBackingStore::getPrimaryKeyViaIndex(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& key, RefPtr<IDBKey>& primaryKey)
 {
     IDB_TRACE("IDBBackingStore::getPrimaryKeyViaIndex");
 
+    bool found = false;
     Vector<char> foundEncodedPrimaryKey;
-    if (findKeyInIndex(transaction, databaseId, objectStoreId, indexId, key, foundEncodedPrimaryKey)) {
-        RefPtr<IDBKey> primaryKey;
+    bool ok = findKeyInIndex(transaction, databaseId, objectStoreId, indexId, key, foundEncodedPrimaryKey, found);
+    if (!ok) {
+        InternalError(IDBLevelDBBackingStoreReadErrorGetPrimaryKeyViaIndex);
+        return false;
+    }
+    if (found) {
         decodeIDBKey(foundEncodedPrimaryKey.begin(), foundEncodedPrimaryKey.end(), primaryKey);
-        return primaryKey.release();
+        return true;
     }
 
-    return 0;
+    return true;
 }
 
-bool IDBBackingStore::keyExistsInIndex(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey)
+bool IDBBackingStore::keyExistsInIndex(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey, bool& exists)
 {
     IDB_TRACE("IDBBackingStore::keyExistsInIndex");
 
+    exists = false;
     Vector<char> foundEncodedPrimaryKey;
-    if (!findKeyInIndex(transaction, databaseId, objectStoreId, indexId, indexKey, foundEncodedPrimaryKey))
+    bool ok = findKeyInIndex(transaction, databaseId, objectStoreId, indexId, indexKey, foundEncodedPrimaryKey, exists);
+    if (!ok) {
+        InternalError(IDBLevelDBBackingStoreReadErrorKeyExistsInIndex);
         return false;
+    }
+    if (!exists)
+        return true;
 
     decodeIDBKey(foundEncodedPrimaryKey.begin(), foundEncodedPrimaryKey.end(), foundPrimaryKey);
     return true;
index 4f55968..d3a3cf9 100644 (file)
@@ -77,7 +77,7 @@ public:
         int64_t m_version;
     };
 
-    virtual String getRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&);
+    virtual bool getRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, String& record) WARN_UNUSED_RETURN;
     virtual void putRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, RecordIdentifier*);
     virtual void clearObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId);
     virtual void deleteRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const RecordIdentifier&);
@@ -89,8 +89,8 @@ public:
     virtual bool createIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry);
     virtual void deleteIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId);
     virtual void putIndexDataForRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const RecordIdentifier&);
-    virtual PassRefPtr<IDBKey> getPrimaryKeyViaIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&);
-    virtual bool keyExistsInIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey);
+    virtual bool getPrimaryKeyViaIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, RefPtr<IDBKey>& primaryKey) WARN_UNUSED_RETURN;
+    virtual bool keyExistsInIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey, bool& exists) WARN_UNUSED_RETURN;
 
     class Cursor : public RefCounted<Cursor> {
     public:
@@ -168,7 +168,7 @@ protected:
     IDBBackingStore();
 
 private:
-    bool findKeyInIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, Vector<char>& foundEncodedPrimaryKey);
+    bool findKeyInIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, Vector<char>& foundEncodedPrimaryKey, bool& found);
 
     String m_identifier;
     RefPtr<IDBFactoryBackendImpl> m_factory;
index 9ad4b8d..9f7c297 100644 (file)
@@ -187,9 +187,19 @@ void IDBIndexBackendImpl::IndexReferencedValueRetrievalOperation::perform(Script
         key = backingStoreCursor->key();
     }
 
-    RefPtr<IDBKey> primaryKey = index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *key);
+    RefPtr<IDBKey> primaryKey;
+    bool ok = index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *key, primaryKey);
+    if (!ok) {
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
+        return;
+    }
 
-    String value = index->backingStore()->getRecord(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), *primaryKey);
+    String value;
+    ok = index->backingStore()->getRecord(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), *primaryKey, value);
+    if (!ok) {
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
+        return;
+    }
 
     if (value.isNull()) {
         callbacks->onSuccess();
@@ -216,7 +226,12 @@ void IDBIndexBackendImpl::IndexValueRetrievalOperation::perform(ScriptExecutionC
         return;
     }
 
-    RefPtr<IDBKey> keyResult = index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *backingStoreCursor->key());
+    RefPtr<IDBKey> keyResult;
+    bool ok = index->backingStore()->getPrimaryKeyViaIndex(transaction->backingStoreTransaction(), index->databaseId(), index->m_objectStoreBackend->id(), index->id(), *backingStoreCursor->key(), keyResult);
+    if (!ok) {
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getPrimaryKeyViaIndex."));
+        return;
+    }
     if (!keyResult) {
         callbacks->onSuccess(static_cast<IDBKey*>(0));
         return;
index ca8ad61..9f611cb 100644 (file)
@@ -199,7 +199,12 @@ void IDBObjectStoreBackendImpl::ObjectStoreRetrievalOperation::perform(ScriptExe
         key = backingStoreCursor->key();
     }
 
-    String wireData = objectStore->backingStore()->getRecord(transaction->backingStoreTransaction(), objectStore->databaseId(), objectStore->id(), *key);
+    String wireData;
+    bool ok = objectStore->backingStore()->getRecord(transaction->backingStoreTransaction(), objectStore->databaseId(), objectStore->id(), *key, wireData);
+    if (!ok) {
+        callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
+        return;
+    }
     if (wireData.isNull()) {
         callbacks->onSuccess();
         return;
@@ -277,7 +282,10 @@ private:
             return true;
 
         RefPtr<IDBKey> foundPrimaryKey;
-        bool found = backingStore.keyExistsInIndex(transaction, databaseId, objectStoreId, indexId, *indexKey, foundPrimaryKey);
+        bool found = false;
+        bool ok = backingStore.keyExistsInIndex(transaction, databaseId, objectStoreId, indexId, *indexKey, foundPrimaryKey, found);
+        // FIXME: Propagate this error up to script.
+        ASSERT_UNUSED(ok, ok);
         if (!found)
             return true;
         if (primaryKey && foundPrimaryKey->isEqual(primaryKey))
index 6d7ea7e..110bc90 100644 (file)
@@ -4,6 +4,16 @@
 
         * DEPS:
 
+2012-11-30  David Grogan  <dgrogan@chromium.org>
+
+        IndexedDB: Propagate more leveldb errors to IDBIndex and IDBObjectStore
+        https://bugs.webkit.org/show_bug.cgi?id=103782
+
+        Reviewed by Tony Chang.
+
+        * tests/IDBFakeBackingStore.h:
+          Remove changed methods that are no longer necessary.
+
 2012-12-04  Stephen White  <senorblanco@chromium.org>
 
         Rolled DEPS (w/Linux build fix).  Unreviewed.
index 7418ba3..55ff5b8 100644 (file)
@@ -43,7 +43,6 @@ public:
     virtual bool createObjectStore(Transaction*, int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath&, bool autoIncrement) OVERRIDE { return false; };
     virtual void deleteObjectStore(Transaction*, int64_t databaseId, int64_t objectStoreId) OVERRIDE { }
 
-    virtual String getRecord(Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&) OVERRIDE { return String(); }
     virtual void putRecord(Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, RecordIdentifier*) OVERRIDE { }
     virtual void clearObjectStore(Transaction*, int64_t databaseId, int64_t objectStoreId) OVERRIDE { }
     virtual void deleteRecord(Transaction*, int64_t databaseId, int64_t objectStoreId, const RecordIdentifier&) OVERRIDE { }
@@ -55,8 +54,6 @@ public:
     virtual bool createIndex(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry) OVERRIDE { return false; };
     virtual void deleteIndex(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId) OVERRIDE { }
     virtual void putIndexDataForRecord(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const RecordIdentifier&) OVERRIDE { }
-    virtual PassRefPtr<IDBKey> getPrimaryKeyViaIndex(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&) OVERRIDE { return PassRefPtr<IDBKey>(); }
-    virtual bool keyExistsInIndex(Transaction*, int64_t databaseid, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey) OVERRIDE { return false; }
 
     virtual PassRefPtr<Cursor> openObjectStoreKeyCursor(Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IDBCursor::Direction) OVERRIDE { return PassRefPtr<Cursor>(); }
     virtual PassRefPtr<Cursor> openObjectStoreCursor(Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IDBCursor::Direction) OVERRIDE { return PassRefPtr<Cursor>(); }