Changeset 136194 in webkit
- Timestamp:
- Nov 29, 2012, 6:22:20 PM (14 years ago)
- Location:
- trunk/Source
- Files:
-
- 12 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/Modules/indexeddb/IDBBackingStore.cpp (modified) (6 diffs)
-
WebCore/Modules/indexeddb/IDBBackingStore.h (modified) (1 diff)
-
WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp (modified) (5 diffs)
-
WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h (modified) (1 diff)
-
WebCore/platform/leveldb/LevelDBDatabase.cpp (modified) (2 diffs)
-
WebCore/platform/leveldb/LevelDBDatabase.h (modified) (1 diff)
-
WebCore/platform/leveldb/LevelDBTransaction.cpp (modified) (2 diffs)
-
WebCore/platform/leveldb/LevelDBTransaction.h (modified) (1 diff)
-
WebKit/chromium/ChangeLog (modified) (1 diff)
-
WebKit/chromium/tests/IDBFakeBackingStore.h (modified) (1 diff)
-
WebKit/chromium/tests/LevelDBTest.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r136191 r136194 1 2012-11-29 David Grogan <dgrogan@chromium.org> 2 3 IndexedDB: Propagate more leveldb errors to script 4 https://bugs.webkit.org/show_bug.cgi?id=103580 5 6 Reviewed by Tony Chang. 7 8 LevelDBDatabase used a single return value to indicate both I/O problems 9 and a missing key. Now an out variable is used to indicate if the 10 requested key was found. The return value is used to report corruption 11 or disk error. 12 13 This is a small step toward propagating low level errors everywhere 14 possible. So far only one scenario will newly cause script to receive 15 an error: when leveldb has trouble looking for existing keys during an 16 objectstore->add. 17 18 * Modules/indexeddb/IDBBackingStore.cpp: 19 (WebCore::getInt): 20 (WebCore::getVarInt): 21 (WebCore::getString): 22 (WebCore::IDBBackingStore::getKeyGeneratorCurrentNumber): 23 (WebCore::IDBBackingStore::maybeUpdateKeyGeneratorCurrentNumber): 24 (WebCore::IDBBackingStore::keyExistsInObjectStore): 25 * Modules/indexeddb/IDBBackingStore.h: 26 (IDBBackingStore): 27 * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp: 28 (WebCore::IDBObjectStoreBackendImpl::setIndexKeys): 29 (WebCore::IDBObjectStoreBackendImpl::putInternal): 30 (WebCore::IDBObjectStoreBackendImpl::generateKey): 31 (WebCore::IDBObjectStoreBackendImpl::updateKeyGenerator): 32 * Modules/indexeddb/IDBObjectStoreBackendImpl.h: 33 (IDBObjectStoreBackendImpl): 34 * platform/leveldb/LevelDBDatabase.cpp: 35 (WebCore::LevelDBDatabase::safeGet): 36 * platform/leveldb/LevelDBDatabase.h: 37 (LevelDBDatabase): 38 * platform/leveldb/LevelDBTransaction.cpp: 39 (WebCore::LevelDBTransaction::safeGet): 40 (WebCore): 41 (WebCore::LevelDBTransaction::get): 42 * platform/leveldb/LevelDBTransaction.h: 43 (LevelDBTransaction): 44 1 45 2012-11-29 Sheriff Bot <webkit.review.bot@gmail.com> 2 46 -
trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp
r135177 r136194 92 92 { 93 93 Vector<char> result; 94 if (!db->get(key, result)) 94 bool found = false; 95 bool ok = db->safeGet(key, result, found); 96 // FIXME: Notify the caller if !ok. 97 ASSERT_UNUSED(ok, ok); 98 if (!found) 95 99 return false; 96 100 … … 109 113 { 110 114 Vector<char> result; 111 if (!db->get(key, result)) 115 bool found = false; 116 bool ok = db->safeGet(key, result, found); 117 // FIXME: Notify the caller if !ok. 118 ASSERT_UNUSED(ok, ok); 119 if (!found) 112 120 return false; 113 121 … … 124 132 { 125 133 Vector<char> result; 126 if (!db->get(key, result)) 134 bool found = false; 135 bool ok = db->safeGet(key, result, found); 136 // FIXME: Notify the caller if !ok. 137 ASSERT_UNUSED(ok, ok); 138 if (!found) 127 139 return false; 128 140 … … 700 712 701 713 702 int64_t IDBBackingStore::getKeyGeneratorCurrentNumber(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId)714 bool IDBBackingStore::getKeyGeneratorCurrentNumber(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t& keyGeneratorCurrentNumber) 703 715 { 704 716 LevelDBTransaction* levelDBTransaction = IDBBackingStore::Transaction::levelDBTransactionFrom(transaction); … … 706 718 const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::KeyGeneratorCurrentNumber); 707 719 708 int64_tkeyGeneratorCurrentNumber = -1;720 keyGeneratorCurrentNumber = -1; 709 721 Vector<char> data; 710 722 711 if (levelDBTransaction->get(keyGeneratorCurrentNumberKey, data)) 723 bool found = false; 724 bool ok = levelDBTransaction->safeGet(keyGeneratorCurrentNumberKey, data, found); 725 if (!ok) { 726 InternalError(IDBLevelDBBackingStoreReadError); 727 return false; 728 } 729 if (found) 712 730 keyGeneratorCurrentNumber = decodeInt(data.begin(), data.end()); 713 731 else { … … 742 760 } 743 761 744 voidIDBBackingStore::maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent)762 bool IDBBackingStore::maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent) 745 763 { 746 764 LevelDBTransaction* levelDBTransaction = IDBBackingStore::Transaction::levelDBTransactionFrom(transaction); 747 765 748 766 if (checkCurrent) { 749 int64_t currentNumber = getKeyGeneratorCurrentNumber(transaction, databaseId, objectStoreId); 767 int64_t currentNumber; 768 bool ok = getKeyGeneratorCurrentNumber(transaction, databaseId, objectStoreId, currentNumber); 769 if (!ok) 770 return false; 750 771 if (newNumber <= currentNumber) 751 return ;772 return true; 752 773 } 753 774 754 775 const Vector<char> keyGeneratorCurrentNumberKey = ObjectStoreMetaDataKey::encode(databaseId, objectStoreId, ObjectStoreMetaDataKey::KeyGeneratorCurrentNumber); 755 776 putInt(levelDBTransaction, keyGeneratorCurrentNumberKey, newNumber); 756 } 757 758 bool IDBBackingStore::keyExistsInObjectStore(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, RecordIdentifier* foundRecordIdentifier) 777 return true; 778 } 779 780 bool IDBBackingStore::keyExistsInObjectStore(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, RecordIdentifier* foundRecordIdentifier, bool& found) 759 781 { 760 782 IDB_TRACE("IDBBackingStore::keyExistsInObjectStore"); 783 found = false; 761 784 LevelDBTransaction* levelDBTransaction = IDBBackingStore::Transaction::levelDBTransactionFrom(transaction); 762 785 const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key); 763 786 Vector<char> data; 764 787 765 if (!levelDBTransaction->get(leveldbKey, data)) 766 return false; 788 bool ok = levelDBTransaction->safeGet(leveldbKey, data, found); 789 if (!ok) { 790 InternalError(IDBLevelDBBackingStoreReadError); 791 return false; 792 } 793 if (!found) 794 return true; 767 795 768 796 int64_t version; -
trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.h
r136079 r136194 82 82 virtual void clearObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId); 83 83 virtual void deleteRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const RecordIdentifier&); 84 virtual int64_t getKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId);85 virtual void maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t newState, bool checkCurrent);86 virtual bool keyExistsInObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RecordIdentifier* foundRecordIdentifier );84 virtual bool getKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t& currentNumber) WARN_UNUSED_RETURN; 85 virtual bool maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t newState, bool checkCurrent) WARN_UNUSED_RETURN; 86 virtual bool keyExistsInObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RecordIdentifier* foundRecordIdentifier, bool& found) WARN_UNUSED_RETURN; 87 87 88 88 virtual Vector<IDBIndexMetadata> getIndexes(int64_t databaseId, int64_t objectStoreId); -
trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp
r136084 r136194 232 232 // FIXME: This method could be asynchronous, but we need to evaluate if it's worth the extra complexity. 233 233 IDBBackingStore::RecordIdentifier recordIdentifier; 234 if (!backingStore()->keyExistsInObjectStore(transaction->backingStoreTransaction(), databaseId(), id(), *primaryKey, &recordIdentifier)) { 234 bool found = false; 235 bool ok = backingStore()->keyExistsInObjectStore(transaction->backingStoreTransaction(), databaseId(), id(), *primaryKey, &recordIdentifier, found); 236 if (!ok) { 237 LOG_ERROR("keyExistsInObjectStore reported an error"); 238 transaction->abort(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error setting index keys.")); 239 return; 240 } 241 if (!found) { 235 242 transaction->abort(); 236 243 return; … … 301 308 302 309 IDBBackingStore::RecordIdentifier recordIdentifier; 303 if (putMode == AddOnly && objectStore->backingStore()->keyExistsInObjectStore(transaction->backingStoreTransaction(), objectStore->databaseId(), objectStore->id(), *key, &recordIdentifier)) { 304 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store.")); 305 return; 310 if (putMode == AddOnly) { 311 bool found = false; 312 bool ok = objectStore->backingStore()->keyExistsInObjectStore(transaction->backingStoreTransaction(), objectStore->databaseId(), objectStore->id(), *key, &recordIdentifier, found); 313 if (!ok) { 314 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error checking key existence.")); 315 return; 316 } 317 if (found) { 318 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::CONSTRAINT_ERR, "Key already exists in the object store.")); 319 return; 320 } 306 321 } 307 322 … … 322 337 } 323 338 324 if (autoIncrement && putMode != CursorUpdate && key->type() == IDBKey::NumberType) 325 objectStore->updateKeyGenerator(transaction, key.get(), !keyWasGenerated); 339 if (autoIncrement && putMode != CursorUpdate && key->type() == IDBKey::NumberType) { 340 bool ok = objectStore->updateKeyGenerator(transaction, key.get(), !keyWasGenerated); 341 if (!ok) { 342 callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UNKNOWN_ERR, "Internal error updating key generator.")); 343 return; 344 } 345 } 326 346 327 347 callbacks->onSuccess(key.release()); … … 526 546 { 527 547 const int64_t maxGeneratorValue = 9007199254740992LL; // Maximum integer storable as ECMAScript number. 528 int64_t currentNumber = backingStore()->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id()); 548 int64_t currentNumber; 549 bool ok = backingStore()->getKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), currentNumber); 550 if (!ok) { 551 LOG_ERROR("Failed to getKeyGeneratorCurrentNumber"); 552 return IDBKey::createInvalid(); 553 } 529 554 if (currentNumber < 0 || currentNumber > maxGeneratorValue) 530 555 return IDBKey::createInvalid(); … … 533 558 } 534 559 535 voidIDBObjectStoreBackendImpl::updateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl> transaction, const IDBKey* key, bool checkCurrent)560 bool IDBObjectStoreBackendImpl::updateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl> transaction, const IDBKey* key, bool checkCurrent) 536 561 { 537 562 ASSERT(key && key->type() == IDBKey::NumberType); 538 backingStore()->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), static_cast<int64_t>(floor(key->number())) + 1, checkCurrent);563 return backingStore()->maybeUpdateKeyGeneratorCurrentNumber(transaction->backingStoreTransaction(), databaseId(), id(), static_cast<int64_t>(floor(key->number())) + 1, checkCurrent); 539 564 } 540 565 -
trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.h
r134095 r136194 97 97 void loadIndexes(); 98 98 PassRefPtr<IDBKey> generateKey(PassRefPtr<IDBTransactionBackendImpl>); 99 voidupdateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl>, const IDBKey*, bool checkCurrent);99 bool updateKeyGenerator(PassRefPtr<IDBTransactionBackendImpl>, const IDBKey*, bool checkCurrent); 100 100 101 101 static void getInternal(ScriptExecutionContext*, PassRefPtr<IDBObjectStoreBackendImpl>, PassRefPtr<IDBKeyRange>, PassRefPtr<IDBCallbacks>, PassRefPtr<IDBTransactionBackendImpl>); -
trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.cpp
r133963 r136194 199 199 } 200 200 201 bool LevelDBDatabase::get(const LevelDBSlice& key, Vector<char>& value, const LevelDBSnapshot* snapshot) 202 { 201 bool LevelDBDatabase::safeGet(const LevelDBSlice& key, Vector<char>& value, bool& found, const LevelDBSnapshot* snapshot) 202 { 203 found = false; 203 204 std::string result; 204 205 leveldb::ReadOptions readOptions; … … 208 209 const leveldb::Status s = m_db->Get(readOptions, makeSlice(key), &result); 209 210 if (s.ok()) { 211 found = true; 210 212 value = makeVector(result); 211 213 return true; 212 214 } 213 215 if (s.IsNotFound()) 214 return false;216 return true; 215 217 LOG_ERROR("LevelDB get failed: %s", s.ToString().c_str()); 216 218 return false; -
trunk/Source/WebCore/platform/leveldb/LevelDBDatabase.h
r133963 r136194 70 70 bool put(const LevelDBSlice& key, const Vector<char>& value); 71 71 bool remove(const LevelDBSlice& key); 72 bool get(const LevelDBSlice& key, Vector<char>& value, const LevelDBSnapshot* = 0);72 bool safeGet(const LevelDBSlice& key, Vector<char>& value, bool& found, const LevelDBSnapshot* = 0); 73 73 bool write(LevelDBWriteBatch&); 74 74 PassOwnPtr<LevelDBIterator> createIterator(const LevelDBSnapshot* = 0); -
trunk/Source/WebCore/platform/leveldb/LevelDBTransaction.cpp
r133963 r136194 108 108 } 109 109 110 bool LevelDBTransaction::get(const LevelDBSlice& key, Vector<char>& value) 111 { 110 bool LevelDBTransaction::safeGet(const LevelDBSlice& key, Vector<char>& value, bool& found) 111 { 112 found = false; 112 113 ASSERT(!m_finished); 113 114 AVLTreeNode* node = m_tree.search(key); … … 115 116 if (node) { 116 117 if (node->deleted) 117 return false;118 return true; 118 119 119 120 value = node->value; 121 found = true; 120 122 return true; 121 123 } 122 124 123 return m_db->get(key, value, &m_snapshot); 125 bool ok = m_db->safeGet(key, value, found, &m_snapshot); 126 if (!ok) { 127 ASSERT(!found); 128 return false; 129 } 130 return true; 131 } 132 133 bool LevelDBTransaction::get(const LevelDBSlice& key, Vector<char>& value) 134 { 135 bool found = false; 136 bool ok = safeGet(key, value, found); 137 if (!ok) { 138 ASSERT(!found); 139 ASSERT_NOT_REACHED(); 140 } 141 return ok && found; 124 142 } 125 143 -
trunk/Source/WebCore/platform/leveldb/LevelDBTransaction.h
r133963 r136194 55 55 void put(const LevelDBSlice& key, const Vector<char>& value); 56 56 void remove(const LevelDBSlice& key); 57 bool safeGet(const LevelDBSlice& key, Vector<char>& value, bool& found); 58 // FIXME: Convert all callers of get to safeGet then remove get. 57 59 bool get(const LevelDBSlice& key, Vector<char>& value); 58 60 bool commit(); -
trunk/Source/WebKit/chromium/ChangeLog
r136191 r136194 1 2012-11-29 David Grogan <dgrogan@chromium.org> 2 3 IndexedDB: Propagate more leveldb errors to script 4 https://bugs.webkit.org/show_bug.cgi?id=103580 5 6 Reviewed by Tony Chang. 7 8 * tests/IDBFakeBackingStore.h: 9 Update method signatures. 10 1 11 2012-11-29 Sheriff Bot <webkit.review.bot@gmail.com> 2 12 -
trunk/Source/WebKit/chromium/tests/IDBFakeBackingStore.h
r135177 r136194 48 48 virtual void clearObjectStore(Transaction*, int64_t databaseId, int64_t objectStoreId) OVERRIDE { } 49 49 virtual void deleteRecord(Transaction*, int64_t databaseId, int64_t objectStoreId, const RecordIdentifier&) OVERRIDE { } 50 virtual int64_t getKeyGeneratorCurrentNumber(Transaction*, int64_t databaseId, int64_t objectStoreId) OVERRIDE { return 0; }51 virtual void maybeUpdateKeyGeneratorCurrentNumber(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent) OVERRIDE {}52 virtual bool keyExistsInObjectStore(Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RecordIdentifier* foundRecordIdentifier ) OVERRIDE { return false; }50 virtual bool getKeyGeneratorCurrentNumber(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t& currentNumber) OVERRIDE { return true; } 51 virtual bool maybeUpdateKeyGeneratorCurrentNumber(Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t newNumber, bool checkCurrent) OVERRIDE { return true; } 52 virtual bool keyExistsInObjectStore(Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RecordIdentifier* foundRecordIdentifier, bool& found) OVERRIDE { return true; } 53 53 54 54 virtual Vector<IDBIndexMetadata> getIndexes(int64_t databaseId, int64_t objectStoreId) OVERRIDE { return Vector<IDBIndexMetadata>(); } -
trunk/Source/WebKit/chromium/tests/LevelDBTest.cpp
r133963 r136194 80 80 leveldb = LevelDBDatabase::open(path, &comparator); 81 81 EXPECT_TRUE(leveldb); 82 success = leveldb->get(key, gotValue); 83 EXPECT_TRUE(success); 82 bool found = false; 83 success = leveldb->safeGet(key, gotValue, found); 84 EXPECT_TRUE(success); 85 EXPECT_TRUE(found); 84 86 EXPECT_EQ(putValue, gotValue); 85 87 leveldb.release(); … … 99 101 leveldb = LevelDBDatabase::open(path, &comparator); 100 102 EXPECT_TRUE(leveldb); 101 success = leveldb->get(key, gotValue); 102 EXPECT_FALSE(success); 103 success = leveldb->safeGet(key, gotValue, found); 104 EXPECT_TRUE(success); 105 EXPECT_FALSE(found); 103 106 } 104 107 … … 130 133 EXPECT_EQ(comparator.compare(gotValue, oldValue), 0); 131 134 132 success = leveldb->get(key, gotValue); 133 EXPECT_TRUE(success); 135 bool found = false; 136 success = leveldb->safeGet(key, gotValue, found); 137 EXPECT_TRUE(success); 138 EXPECT_TRUE(found); 134 139 EXPECT_EQ(comparator.compare(gotValue, newValue), 0); 135 140 … … 139 144 EXPECT_TRUE(success); 140 145 141 success = leveldb->get(addedKey, gotValue); 142 EXPECT_TRUE(success); 146 success = leveldb->safeGet(addedKey, gotValue, found); 147 EXPECT_TRUE(success); 148 EXPECT_TRUE(found); 143 149 EXPECT_EQ(comparator.compare(gotValue, addedValue), 0); 144 150
Note:
See TracChangeset
for help on using the changeset viewer.