Chromium Code Reviews| Index: content/browser/indexed_db/indexed_db_backing_store.cc |
| diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc |
| index 32c53bc92fe810d1cbddf112a9f75fda9eb268ce..a659daf0a4369ca8f3eb91025dd529afb16a4d03 100644 |
| --- a/content/browser/indexed_db/indexed_db_backing_store.cc |
| +++ b/content/browser/indexed_db/indexed_db_backing_store.cc |
| @@ -78,6 +78,8 @@ enum IndexedDBBackingStoreErrorSource { |
| DELETE_DATABASE, |
| TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro |
| GET_DATABASE_NAMES, |
| + DELETE_INDEX, |
| + CLEAR_OBJECT_STORE, |
| INTERNAL_ERROR_MAX, |
| }; |
| @@ -323,9 +325,9 @@ WARN_UNUSED_RESULT static bool SetUpMetadata( |
| const std::string stop_key = |
| DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); |
| scoped_ptr<LevelDBIterator> it = db->CreateIterator(); |
| - for (it->Seek(start_key); |
| - it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| - it->Next()) { |
| + for (s = it->Seek(start_key); |
| + s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| + s = it->Next()) { |
| int64 database_id = 0; |
| found = false; |
| s = GetInt(transaction.get(), it->Key(), &database_id, &found); |
| @@ -352,6 +354,11 @@ WARN_UNUSED_RESULT static bool SetUpMetadata( |
| } |
| } |
| + if (!s.ok()) { |
| + INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); |
| + return false; |
| + } |
| + |
| // All new values will be written using this serialization version. |
| found = false; |
| s = GetInt(transaction.get(), data_version_key, &db_data_version, &found); |
| @@ -810,7 +817,9 @@ scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( |
| return backing_store; |
| } |
| -std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() { |
| +std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames( |
| + leveldb::Status& s) { |
| + s = leveldb::Status::OK(); |
| std::vector<base::string16> found_names; |
| const std::string start_key = |
| DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); |
| @@ -820,9 +829,9 @@ std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() { |
| DCHECK(found_names.empty()); |
| scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| - for (it->Seek(start_key); |
| - it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| - it->Next()) { |
| + for (s = it->Seek(start_key); |
| + s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| + s = it->Next()) { |
| StringPiece slice(it->Key()); |
| DatabaseNameKey database_name_key; |
| if (!DatabaseNameKey::Decode(&slice, &database_name_key)) { |
| @@ -831,6 +840,10 @@ std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() { |
| } |
| found_names.push_back(database_name_key.database_name()); |
| } |
| + |
| + if (!s.ok()) |
| + INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES); |
| + |
| return found_names; |
| } |
| @@ -843,7 +856,7 @@ leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData( |
| leveldb::Status s = GetInt(db_.get(), key, &metadata->id, found); |
| if (!s.ok()) { |
| - INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); |
| + INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); |
| return s; |
| } |
| if (!*found) |
| @@ -959,13 +972,16 @@ bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( |
| return true; |
| } |
| -static void DeleteRange(LevelDBTransaction* transaction, |
| - const std::string& begin, |
| - const std::string& end) { |
| +static leveldb::Status DeleteRange(LevelDBTransaction* transaction, |
| + const std::string& begin, |
| + const std::string& end) { |
| scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); |
| - for (it->Seek(begin); it->IsValid() && CompareKeys(it->Key(), end) < 0; |
| - it->Next()) |
| + leveldb::Status s; |
| + for (s = it->Seek(begin); |
| + s.ok() && it->IsValid() && CompareKeys(it->Key(), end) < 0; |
| + s = it->Next()) |
| transaction->Remove(it->Key()); |
| + return s; |
| } |
| leveldb::Status IndexedDBBackingStore::DeleteDatabase( |
| @@ -987,10 +1003,14 @@ leveldb::Status IndexedDBBackingStore::DeleteDatabase( |
| const std::string stop_key = DatabaseMetaDataKey::Encode( |
| metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME); |
| scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| - for (it->Seek(start_key); |
| - it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| - it->Next()) |
| + for (s = it->Seek(start_key); |
| + s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| + s = it->Next()) |
| transaction->Remove(it->Key()); |
| + if (!s.ok()) { |
| + INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE); |
| + return s; |
| + } |
| const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); |
| transaction->Remove(key); |
| @@ -1038,8 +1058,8 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| DCHECK(object_stores->empty()); |
| scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| - it->Seek(start_key); |
| - while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { |
| + leveldb::Status s = it->Seek(start_key); |
| + while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { |
| StringPiece slice(it->Key()); |
| ObjectStoreMetaDataKey meta_data_key; |
| bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key); |
| @@ -1047,7 +1067,7 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| // Possible stale metadata, but don't fail the load. |
| - it->Next(); |
| + s = it->Next(); |
|
jsbell
2014/04/14 20:44:20
Check value of s here? (see next comment...)
|
| continue; |
| } |
| @@ -1062,7 +1082,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| } |
| - it->Next(); |
| + s = it->Next(); |
| + if (!s.ok()) |
| + continue; |
|
jsbell
2014/04/14 20:44:20
continue or break?
They'll do the same thing sinc
cmumford
2014/04/14 23:39:23
I'll do what you think is most obvious, but if we
|
| if (!CheckObjectStoreAndMetaDataType(it.get(), |
| stop_key, |
| object_store_id, |
| @@ -1077,7 +1099,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| } |
| - it->Next(); |
| + s = it->Next(); |
| + if (!s.ok()) |
| + continue; |
| if (!CheckObjectStoreAndMetaDataType( |
| it.get(), |
| stop_key, |
| @@ -1093,7 +1117,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| } |
| - it->Next(); // Is evicatble. |
| + s = it->Next(); // Is evicatble. |
| + if (!s.ok()) |
| + continue; |
| if (!CheckObjectStoreAndMetaDataType(it.get(), |
| stop_key, |
| object_store_id, |
| @@ -1102,7 +1128,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| break; |
| } |
| - it->Next(); // Last version. |
| + s = it->Next(); // Last version. |
| + if (!s.ok()) |
| + continue; |
| if (!CheckObjectStoreAndMetaDataType( |
| it.get(), |
| stop_key, |
| @@ -1112,7 +1140,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| break; |
| } |
| - it->Next(); // Maximum index id allocated. |
| + s = it->Next(); // Maximum index id allocated. |
| + if (!s.ok()) |
| + continue; |
| if (!CheckObjectStoreAndMetaDataType( |
| it.get(), |
| stop_key, |
| @@ -1128,7 +1158,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); |
| } |
| - it->Next(); // [optional] has key path (is not null) |
| + s = it->Next(); // [optional] has key path (is not null) |
| + if (!s.ok()) |
| + continue; |
| if (CheckObjectStoreAndMetaDataType(it.get(), |
| stop_key, |
| object_store_id, |
| @@ -1151,7 +1183,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| } |
| if (!has_key_path) |
| key_path = IndexedDBKeyPath(); |
| - it->Next(); |
| + s = it->Next(); |
| + if (!s.ok()) |
| + continue; |
| } |
| int64 key_generator_current_number = -1; |
| @@ -1168,7 +1202,9 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| // object store, and write lazily to backing store. For now, |
| // just assert that if it was written it was valid. |
| DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber); |
| - it->Next(); |
| + s = it->Next(); |
| + if (!s.ok()) |
| + continue; |
| } |
| IndexedDBObjectStoreMetadata metadata(object_store_name, |
| @@ -1176,13 +1212,16 @@ leveldb::Status IndexedDBBackingStore::GetObjectStores( |
| key_path, |
| auto_increment, |
| max_index_id); |
| - leveldb::Status s = |
| - GetIndexes(database_id, object_store_id, &metadata.indexes); |
| + s = GetIndexes(database_id, object_store_id, &metadata.indexes); |
| if (!s.ok()) |
| - return s; |
| + continue; |
| (*object_stores)[object_store_id] = metadata; |
| } |
| - return leveldb::Status::OK(); |
| + |
| + if (!s.ok()) |
| + INTERNAL_READ_ERROR_UNTESTED(GET_OBJECT_STORES); |
| + |
| + return s; |
| } |
| WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId( |
| @@ -1286,20 +1325,31 @@ leveldb::Status IndexedDBBackingStore::DeleteObjectStore( |
| return InternalInconsistencyStatus(); |
| } |
| - DeleteRange( |
| + s = DeleteRange( |
| leveldb_transaction, |
| ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), |
| ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); |
| - leveldb_transaction->Remove( |
| - ObjectStoreNamesKey::Encode(database_id, object_store_name)); |
| + if (s.ok()) { |
| + leveldb_transaction->Remove( |
| + ObjectStoreNamesKey::Encode(database_id, object_store_name)); |
| + |
| + s = DeleteRange( |
| + leveldb_transaction, |
| + IndexFreeListKey::Encode(database_id, object_store_id, 0), |
| + IndexFreeListKey::EncodeMaxKey(database_id, object_store_id)); |
| + } |
| - DeleteRange(leveldb_transaction, |
| - IndexFreeListKey::Encode(database_id, object_store_id, 0), |
| - IndexFreeListKey::EncodeMaxKey(database_id, object_store_id)); |
| - DeleteRange(leveldb_transaction, |
| - IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0), |
| - IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id)); |
| + if (s.ok()) { |
| + s = DeleteRange( |
| + leveldb_transaction, |
| + IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0), |
| + IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id)); |
| + } |
| + if (!s.ok()) { |
|
jsbell
2014/04/14 20:44:20
Nit: make the blank lines before the if()s consist
|
| + INTERNAL_WRITE_ERROR_UNTESTED(DELETE_OBJECT_STORE); |
| + return s; |
| + } |
| return ClearObjectStore(transaction, database_id, object_store_id); |
| } |
| @@ -1429,8 +1479,11 @@ leveldb::Status IndexedDBBackingStore::ClearObjectStore( |
| const std::string stop_key = |
| KeyPrefix(database_id, object_store_id + 1).Encode(); |
| - DeleteRange(transaction->transaction(), start_key, stop_key); |
| - return leveldb::Status::OK(); |
| + leveldb::Status s = |
| + DeleteRange(transaction->transaction(), start_key, stop_key); |
| + if (!s.ok()) |
| + INTERNAL_WRITE_ERROR_UNTESTED(CLEAR_OBJECT_STORE); |
| + return s; |
| } |
| leveldb::Status IndexedDBBackingStore::DeleteRecord( |
| @@ -1500,9 +1553,9 @@ leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( |
| scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); |
| int64 max_numeric_key = 0; |
| - for (it->Seek(start_key); |
| - it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| - it->Next()) { |
| + for (s = it->Seek(start_key); |
| + s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; |
| + s = it->Next()) { |
| StringPiece slice(it->Key()); |
| ObjectStoreDataKey data_key; |
| if (!ObjectStoreDataKey::Decode(&slice, &data_key)) { |
| @@ -1517,7 +1570,11 @@ leveldb::Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( |
| } |
| } |
| - *key_generator_current_number = max_numeric_key + 1; |
| + if (s.ok()) |
| + *key_generator_current_number = max_numeric_key + 1; |
| + else |
| + INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); |
| + |
| return s; |
| } |
| @@ -1624,8 +1681,8 @@ leveldb::Status IndexedDBBackingStore::GetIndexes( |
| DCHECK(indexes->empty()); |
| scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); |
| - it->Seek(start_key); |
| - while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { |
| + leveldb::Status s = it->Seek(start_key); |
| + while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { |
| StringPiece slice(it->Key()); |
| IndexMetaDataKey meta_data_key; |
| bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key); |
| @@ -1634,7 +1691,7 @@ leveldb::Status IndexedDBBackingStore::GetIndexes( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| // Possible stale metadata due to http://webkit.org/b/85557 but don't fail |
| // the load. |
| - it->Next(); |
| + s = it->Next(); |
|
jsbell
2014/04/14 20:44:20
Same as GetObjectStores here - `if(!s.ok()) break;
cmumford
2014/04/14 23:39:23
Done.
|
| continue; |
| } |
| @@ -1648,7 +1705,9 @@ leveldb::Status IndexedDBBackingStore::GetIndexes( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| } |
| - it->Next(); // unique flag |
| + s = it->Next(); // unique flag |
| + if (!s.ok()) |
| + continue; |
|
jsbell
2014/04/14 20:44:20
Same as GetObjectStores here - `continue` or `brea
cmumford
2014/04/14 23:39:23
Done.
|
| if (!CheckIndexAndMetaDataKey( |
| it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| @@ -1661,7 +1720,9 @@ leveldb::Status IndexedDBBackingStore::GetIndexes( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| } |
| - it->Next(); // key_path |
| + s = it->Next(); // key_path |
| + if (!s.ok()) |
| + continue; |
| if (!CheckIndexAndMetaDataKey( |
| it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| @@ -1674,7 +1735,9 @@ leveldb::Status IndexedDBBackingStore::GetIndexes( |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| } |
| - it->Next(); // [optional] multi_entry flag |
| + s = it->Next(); // [optional] multi_entry flag |
| + if (!s.ok()) |
| + continue; |
| bool index_multi_entry = false; |
| if (CheckIndexAndMetaDataKey( |
| it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { |
| @@ -1682,13 +1745,19 @@ leveldb::Status IndexedDBBackingStore::GetIndexes( |
| if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty()) |
| INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); |
| - it->Next(); |
| + s = it->Next(); |
| + if (!s.ok()) |
| + continue; |
| } |
| (*indexes)[index_id] = IndexedDBIndexMetadata( |
| index_name, index_id, key_path, index_unique, index_multi_entry); |
| } |
| - return leveldb::Status::OK(); |
| + |
| + if (!s.ok()) |
| + INTERNAL_READ_ERROR_UNTESTED(GET_INDEXES); |
| + |
| + return s; |
| } |
| WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( |
| @@ -1767,14 +1836,21 @@ leveldb::Status IndexedDBBackingStore::DeleteIndex( |
| IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0); |
| const std::string index_meta_data_end = |
| IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id); |
| - DeleteRange(leveldb_transaction, index_meta_data_start, index_meta_data_end); |
| + leveldb::Status s = DeleteRange( |
| + leveldb_transaction, index_meta_data_start, index_meta_data_end); |
| - const std::string index_data_start = |
| - IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); |
| - const std::string index_data_end = |
| - IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); |
| - DeleteRange(leveldb_transaction, index_data_start, index_data_end); |
| - return leveldb::Status::OK(); |
| + if (s.ok()) { |
| + const std::string index_data_start = |
| + IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); |
| + const std::string index_data_end = |
| + IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); |
| + s = DeleteRange(leveldb_transaction, index_data_start, index_data_end); |
| + } |
| + |
| + if (!s.ok()) |
| + INTERNAL_WRITE_ERROR_UNTESTED(DELETE_INDEX); |
| + |
| + return s; |
| } |
| leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord( |
| @@ -1810,19 +1886,22 @@ leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord( |
| static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, |
| const std::string& target, |
| - std::string* found_key) { |
| + std::string* found_key, |
| + leveldb::Status& s) { |
| scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); |
| - it->Seek(target); |
| + s = it->Seek(target); |
| + if (!s.ok()) |
| + return false; |
| if (!it->IsValid()) { |
| - it->SeekToLast(); |
| - if (!it->IsValid()) |
| + s = it->SeekToLast(); |
| + if (!s.ok() || !it->IsValid()) |
| return false; |
| } |
| while (CompareIndexKeys(it->Key(), target) > 0) { |
| - it->Prev(); |
| - if (!it->IsValid()) |
| + s = it->Prev(); |
| + if (!s.ok() || !it->IsValid()) |
| return false; |
| } |
| @@ -1830,8 +1909,8 @@ static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, |
| *found_key = it->Key().as_string(); |
| // There can be several index keys that compare equal. We want the last one. |
| - it->Next(); |
| - } while (it->IsValid() && !CompareIndexKeys(it->Key(), target)); |
| + s = it->Next(); |
| + } while (s.ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target)); |
| return true; |
| } |
| @@ -1880,7 +1959,11 @@ leveldb::Status IndexedDBBackingStore::FindKeyInIndex( |
| const std::string leveldb_key = |
| IndexDataKey::Encode(database_id, object_store_id, index_id, key); |
| scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); |
| - it->Seek(leveldb_key); |
| + leveldb::Status s = it->Seek(leveldb_key); |
| + if (!s.ok()) { |
| + INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); |
| + return s; |
| + } |
| for (;;) { |
| if (!it->IsValid()) |
| @@ -1898,18 +1981,18 @@ leveldb::Status IndexedDBBackingStore::FindKeyInIndex( |
| *found_encoded_primary_key = slice.as_string(); |
| bool exists = false; |
| - leveldb::Status s = VersionExists(leveldb_transaction, |
| - database_id, |
| - object_store_id, |
| - version, |
| - *found_encoded_primary_key, |
| - &exists); |
| + s = VersionExists(leveldb_transaction, |
| + database_id, |
| + object_store_id, |
| + version, |
| + *found_encoded_primary_key, |
| + &exists); |
| if (!s.ok()) |
| return s; |
| if (!exists) { |
| // Delete stale index data entry and continue. |
| leveldb_transaction->Remove(it->Key()); |
| - it->Next(); |
| + s = it->Next(); |
| continue; |
| } |
| *found = true; |
| @@ -2008,7 +2091,8 @@ IndexedDBBackingStore::Cursor::Cursor( |
| iterator_ = transaction_->CreateIterator(); |
| if (other->iterator_->IsValid()) { |
| - iterator_->Seek(other->iterator_->Key()); |
| + leveldb::Status s = iterator_->Seek(other->iterator_->Key()); |
| + // TODO(cmumford): Handle this error |
| DCHECK(iterator_->IsValid()); |
| } |
| } |
| @@ -2019,19 +2103,22 @@ IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction, |
| : transaction_(transaction), cursor_options_(cursor_options) {} |
| IndexedDBBackingStore::Cursor::~Cursor() {} |
| -bool IndexedDBBackingStore::Cursor::FirstSeek() { |
| +bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status& s) { |
| iterator_ = transaction_->CreateIterator(); |
| if (cursor_options_.forward) |
| - iterator_->Seek(cursor_options_.low_key); |
| + s = iterator_->Seek(cursor_options_.low_key); |
| else |
| - iterator_->Seek(cursor_options_.high_key); |
| + s = iterator_->Seek(cursor_options_.high_key); |
| + if (!s.ok()) |
| + return false; |
| - return Continue(0, READY); |
| + return Continue(0, READY, s); |
| } |
| -bool IndexedDBBackingStore::Cursor::Advance(uint32 count) { |
| +bool IndexedDBBackingStore::Cursor::Advance(uint32 count, leveldb::Status& s) { |
| + s = leveldb::Status::OK(); |
| while (count--) { |
| - if (!Continue()) |
| + if (!Continue(s)) |
| return false; |
| } |
| return true; |
| @@ -2039,9 +2126,11 @@ bool IndexedDBBackingStore::Cursor::Advance(uint32 count) { |
| bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, |
| const IndexedDBKey* primary_key, |
| - IteratorState next_state) { |
| + IteratorState next_state, |
| + leveldb::Status& s) { |
| DCHECK(!key || key->IsValid()); |
| DCHECK(!primary_key || primary_key->IsValid()); |
| + s = leveldb::Status::OK(); |
| // TODO(alecflett): avoid a copy here? |
| IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey(); |
| @@ -2065,13 +2154,15 @@ bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, |
| } else { |
| leveldb_key = EncodeKey(*key); |
| } |
| - iterator_->Seek(leveldb_key); |
| + s = iterator_->Seek(leveldb_key); |
| first_iteration = false; |
| } else if (forward) { |
| - iterator_->Next(); |
| + s = iterator_->Next(); |
| } else { |
| - iterator_->Prev(); |
| + s = iterator_->Prev(); |
| } |
| + if (!s.ok()) |
| + return false; |
| } else { |
| next_state = SEEK; // for subsequent iterations |
| } |
| @@ -2553,6 +2644,8 @@ bool ObjectStoreCursorOptions( |
| cursor_options->low_open = range.lowerOpen(); |
| } |
| + leveldb::Status s; |
| + |
| if (!upper_bound) { |
| cursor_options->high_key = |
| ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); |
| @@ -2561,9 +2654,11 @@ bool ObjectStoreCursorOptions( |
| cursor_options->high_open = true; // Not included. |
| } else { |
| // We need a key that exists. |
| + // TODO(cmumford): Handle this error |
| if (!FindGreatestKeyLessThanOrEqual(transaction, |
| cursor_options->high_key, |
| - &cursor_options->high_key)) |
| + &cursor_options->high_key, |
| + s)) |
| return false; |
| cursor_options->high_open = false; |
| } |
| @@ -2576,7 +2671,7 @@ bool ObjectStoreCursorOptions( |
| // For reverse cursors, we need a key that exists. |
| std::string found_high_key; |
| if (!FindGreatestKeyLessThanOrEqual( |
| - transaction, cursor_options->high_key, &found_high_key)) |
| + transaction, cursor_options->high_key, &found_high_key, s)) |
|
jsbell
2014/04/14 20:44:20
Add TODO here as well?
cmumford
2014/04/14 23:39:23
Done.
|
| return false; |
| // If the target key should not be included, but we end up with a smaller |
| @@ -2626,6 +2721,9 @@ bool IndexCursorOptions( |
| cursor_options->low_open = range.lowerOpen(); |
| } |
| + // TODO(cmumford): Handle this error |
|
jsbell
2014/04/14 20:44:20
Nit: be consistent in placing the TODOs - near the
cmumford
2014/04/14 23:39:23
Done.
|
| + leveldb::Status s; |
| + |
| if (!upper_bound) { |
| cursor_options->high_key = |
| IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); |
| @@ -2634,7 +2732,8 @@ bool IndexCursorOptions( |
| if (!cursor_options->forward) { // We need a key that exists. |
| if (!FindGreatestKeyLessThanOrEqual(transaction, |
| cursor_options->high_key, |
| - &cursor_options->high_key)) |
| + &cursor_options->high_key, |
| + s)) |
| return false; |
| cursor_options->high_open = false; |
| } |
| @@ -2646,7 +2745,7 @@ bool IndexCursorOptions( |
| std::string found_high_key; |
| // Seek to the *last* key in the set of non-unique keys |
| if (!FindGreatestKeyLessThanOrEqual( |
| - transaction, cursor_options->high_key, &found_high_key)) |
| + transaction, cursor_options->high_key, &found_high_key, s)) |
| return false; |
| // If the target key should not be included, but we end up with a smaller |
| @@ -2667,8 +2766,10 @@ IndexedDBBackingStore::OpenObjectStoreCursor( |
| int64 database_id, |
| int64 object_store_id, |
| const IndexedDBKeyRange& range, |
| - indexed_db::CursorDirection direction) { |
| + indexed_db::CursorDirection direction, |
| + leveldb::Status& s) { |
| IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor"); |
| + s = leveldb::Status::OK(); |
| LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| if (!ObjectStoreCursorOptions(leveldb_transaction, |
| @@ -2680,7 +2781,7 @@ IndexedDBBackingStore::OpenObjectStoreCursor( |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| scoped_ptr<ObjectStoreCursorImpl> cursor( |
| new ObjectStoreCursorImpl(leveldb_transaction, cursor_options)); |
| - if (!cursor->FirstSeek()) |
| + if (!cursor->FirstSeek(s)) |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |
| @@ -2692,8 +2793,10 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor( |
| int64 database_id, |
| int64 object_store_id, |
| const IndexedDBKeyRange& range, |
| - indexed_db::CursorDirection direction) { |
| + indexed_db::CursorDirection direction, |
| + leveldb::Status& s) { |
| IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); |
| + s = leveldb::Status::OK(); |
| LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| if (!ObjectStoreCursorOptions(leveldb_transaction, |
| @@ -2705,7 +2808,7 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor( |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| scoped_ptr<ObjectStoreKeyCursorImpl> cursor( |
| new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options)); |
| - if (!cursor->FirstSeek()) |
| + if (!cursor->FirstSeek(s)) |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |
| @@ -2718,8 +2821,10 @@ IndexedDBBackingStore::OpenIndexKeyCursor( |
| int64 object_store_id, |
| int64 index_id, |
| const IndexedDBKeyRange& range, |
| - indexed_db::CursorDirection direction) { |
| + indexed_db::CursorDirection direction, |
| + leveldb::Status& s) { |
| IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); |
| + s = leveldb::Status::OK(); |
| LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| if (!IndexCursorOptions(leveldb_transaction, |
| @@ -2732,7 +2837,7 @@ IndexedDBBackingStore::OpenIndexKeyCursor( |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| scoped_ptr<IndexKeyCursorImpl> cursor( |
| new IndexKeyCursorImpl(leveldb_transaction, cursor_options)); |
| - if (!cursor->FirstSeek()) |
| + if (!cursor->FirstSeek(s)) |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |
| @@ -2745,7 +2850,8 @@ IndexedDBBackingStore::OpenIndexCursor( |
| int64 object_store_id, |
| int64 index_id, |
| const IndexedDBKeyRange& range, |
| - indexed_db::CursorDirection direction) { |
| + indexed_db::CursorDirection direction, |
| + leveldb::Status& s) { |
| IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); |
| LevelDBTransaction* leveldb_transaction = transaction->transaction(); |
| IndexedDBBackingStore::Cursor::CursorOptions cursor_options; |
| @@ -2759,7 +2865,7 @@ IndexedDBBackingStore::OpenIndexCursor( |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| scoped_ptr<IndexCursorImpl> cursor( |
| new IndexCursorImpl(leveldb_transaction, cursor_options)); |
| - if (!cursor->FirstSeek()) |
| + if (!cursor->FirstSeek(s)) |
| return scoped_ptr<IndexedDBBackingStore::Cursor>(); |
| return cursor.PassAs<IndexedDBBackingStore::Cursor>(); |