Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2298)

Unified Diff: chrome/browser/value_store/leveldb_value_store.cc

Issue 10956008: Revert 157713 - Make database failures in LeveldbValueStore more descriptive. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/value_store/leveldb_value_store.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/value_store/leveldb_value_store.cc
===================================================================
--- chrome/browser/value_store/leveldb_value_store.cc (revision 157722)
+++ chrome/browser/value_store/leveldb_value_store.cc (working copy)
@@ -8,7 +8,6 @@
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
-#include "base/stringprintf.h"
#include "base/sys_string_conversions.h"
#include "content/public/browser/browser_thread.h"
#include "third_party/leveldatabase/src/include/leveldb/iterator.h"
@@ -18,40 +17,9 @@
namespace {
-const char* kInvalidJson = "Invalid JSON";
+// Generic error message on failure.
+const char kGenericOnFailureMessage[] = "Failure accessing database";
-ValueStore::ReadResult ReadFailure(const std::string& action,
- const std::string& reason) {
- CHECK_NE("", reason);
- return ValueStore::MakeReadResult(base::StringPrintf(
- "Failure to %s: %s", action.c_str(), reason.c_str()));
-}
-
-ValueStore::ReadResult ReadFailureForKey(const std::string& action,
- const std::string& key,
- const std::string& reason) {
- CHECK_NE("", reason);
- return ValueStore::MakeReadResult(base::StringPrintf(
- "Failure to %s for key %s: %s",
- action.c_str(), key.c_str(), reason.c_str()));
-}
-
-ValueStore::WriteResult WriteFailure(const std::string& action,
- const std::string& reason) {
- CHECK_NE("", reason);
- return ValueStore::MakeWriteResult(base::StringPrintf(
- "Failure to %s: %s", action.c_str(), reason.c_str()));
-}
-
-ValueStore::WriteResult WriteFailureForKey(const std::string& action,
- const std::string& key,
- const std::string& reason) {
- CHECK_NE("", reason);
- return ValueStore::MakeWriteResult(base::StringPrintf(
- "Failure to %s for key %s: %s",
- action.c_str(), key.c_str(), reason.c_str()));
-}
-
// Scoped leveldb snapshot which releases the snapshot on destruction.
class ScopedSnapshot {
public:
@@ -137,24 +105,23 @@
return 0;
}
-ValueStore::ReadResult LeveldbValueStore::Get(const std::string& key) {
+ValueStore::ReadResult LeveldbValueStore::Get(
+ const std::string& key) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
scoped_ptr<Value> setting;
- std::string error = ReadFromDb(leveldb::ReadOptions(), key, &setting);
- if (!error.empty())
- return ReadFailureForKey("get", key, error);
-
+ if (!ReadFromDb(leveldb::ReadOptions(), key, &setting)) {
+ return MakeReadResult(kGenericOnFailureMessage);
+ }
DictionaryValue* settings = new DictionaryValue();
- if (setting.get())
+ if (setting.get()) {
settings->SetWithoutPathExpansion(key, setting.release());
+ }
return MakeReadResult(settings);
}
ValueStore::ReadResult LeveldbValueStore::Get(
const std::vector<std::string>& keys) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
leveldb::ReadOptions options;
scoped_ptr<DictionaryValue> settings(new DictionaryValue());
@@ -165,11 +132,12 @@
for (std::vector<std::string>::const_iterator it = keys.begin();
it != keys.end(); ++it) {
scoped_ptr<Value> setting;
- std::string error = ReadFromDb(options, *it, &setting);
- if (!error.empty())
- return ReadFailureForKey("get multiple items", *it, error);
- if (setting.get())
+ if (!ReadFromDb(options, *it, &setting)) {
+ return MakeReadResult(kGenericOnFailureMessage);
+ }
+ if (setting.get()) {
settings->SetWithoutPathExpansion(*it, setting.release());
+ }
}
return MakeReadResult(settings.release());
@@ -177,7 +145,6 @@
ValueStore::ReadResult LeveldbValueStore::Get() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
-
base::JSONReader json_reader;
leveldb::ReadOptions options = leveldb::ReadOptions();
// All interaction with the db is done on the same thread, so snapshotting
@@ -188,23 +155,20 @@
options.snapshot = snapshot.get();
scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options));
for (it->SeekToFirst(); it->Valid(); it->Next()) {
- std::string key = it->key().ToString();
Value* value = json_reader.ReadToValue(it->value().ToString());
- if (value == NULL) {
+ if (value != NULL) {
+ settings->SetWithoutPathExpansion(it->key().ToString(), value);
+ } else {
// TODO(kalman): clear the offending non-JSON value from the database.
- return ReadFailureForKey("get all", key, kInvalidJson);
+ LOG(ERROR) << "Invalid JSON: " << it->value().ToString();
}
- settings->SetWithoutPathExpansion(key, value);
}
- if (it->status().IsNotFound()) {
- NOTREACHED() << "IsNotFound() but iterating over all keys?!";
- return MakeReadResult(settings.release());
+ if (!it->status().ok()) {
+ LOG(ERROR) << "DB iteration failed: " << it->status().ToString();
+ return MakeReadResult(kGenericOnFailureMessage);
}
- if (!it->status().ok())
- return ReadFailure("get all items", it->status().ToString());
-
return MakeReadResult(settings.release());
}
@@ -214,15 +178,8 @@
leveldb::WriteBatch batch;
scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
- std::string read_error =
- AddToBatch(options, key, value, &batch, changes.get());
- if (!read_error.empty())
- return WriteFailureForKey("find changes to set", key, read_error);
-
- std::string write_error = WriteToDb(&batch);
- if (!write_error.empty())
- return WriteFailureForKey("set", key, write_error);
- return MakeWriteResult(changes.release());
+ AddToBatch(options, key, value, &batch, changes.get());
+ return WriteToDb(&batch, changes.Pass());
}
ValueStore::WriteResult LeveldbValueStore::Set(
@@ -233,24 +190,19 @@
scoped_ptr<ValueStoreChangeList> changes(new ValueStoreChangeList());
for (DictionaryValue::Iterator it(settings); it.HasNext(); it.Advance()) {
- std::string read_error =
- AddToBatch(options, it.key(), it.value(), &batch, changes.get());
- if (!read_error.empty()) {
- return WriteFailureForKey("find changes to set multiple items",
- it.key(),
- read_error);
- }
+ if (!AddToBatch(options, it.key(), it.value(), &batch, changes.get()))
+ return MakeWriteResult(kGenericOnFailureMessage);
}
- std::string write_error = WriteToDb(&batch);
- if (!write_error.empty())
- return WriteFailure("set multiple items", write_error);
- return MakeWriteResult(changes.release());
+ return WriteToDb(&batch, changes.Pass());
}
-ValueStore::WriteResult LeveldbValueStore::Remove(const std::string& key) {
+ValueStore::WriteResult LeveldbValueStore::Remove(
+ const std::string& key) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
- return Remove(std::vector<std::string>(1, key));
+ std::vector<std::string> keys;
+ keys.push_back(key);
+ return Remove(keys);
}
ValueStore::WriteResult LeveldbValueStore::Remove(
@@ -263,23 +215,23 @@
for (std::vector<std::string>::const_iterator it = keys.begin();
it != keys.end(); ++it) {
scoped_ptr<Value> old_value;
- std::string read_error =
- ReadFromDb(leveldb::ReadOptions(), *it, &old_value);
- if (!read_error.empty()) {
- return WriteFailureForKey("find changes to remove multiple items",
- *it,
- read_error);
+ if (!ReadFromDb(leveldb::ReadOptions(), *it, &old_value)) {
+ return MakeWriteResult(kGenericOnFailureMessage);
}
if (old_value.get()) {
- changes->push_back(ValueStoreChange(*it, old_value.release(), NULL));
+ changes->push_back(
+ ValueStoreChange(*it, old_value.release(), NULL));
batch.Delete(*it);
}
}
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
- if (!status.ok() && !status.IsNotFound())
- return WriteFailure("remove multiple items", status.ToString());
+ if (!status.ok() && !status.IsNotFound()) {
+ LOG(WARNING) << "DB batch delete failed: " << status.ToString();
+ return MakeWriteResult(kGenericOnFailureMessage);
+ }
+
return MakeWriteResult(changes.release());
}
@@ -299,30 +251,29 @@
const std::string key = it->key().ToString();
const std::string old_value_json = it->value().ToString();
Value* old_value = base::JSONReader().ReadToValue(old_value_json);
- if (!old_value) {
- // TODO: delete the bad JSON.
- return WriteFailureForKey("find changes to clear", key, kInvalidJson);
+ if (old_value) {
+ changes->push_back(ValueStoreChange(key, old_value, NULL));
+ } else {
+ LOG(ERROR) << "Invalid JSON in database: " << old_value_json;
}
- changes->push_back(ValueStoreChange(key, old_value, NULL));
batch.Delete(key);
}
- if (it->status().IsNotFound())
- NOTREACHED() << "IsNotFound() but clearing?!";
- else if (!it->status().ok())
- return WriteFailure("find changes to clear", it->status().ToString());
+ if (!it->status().ok()) {
+ LOG(WARNING) << "Clear iteration failed: " << it->status().ToString();
+ return MakeWriteResult(kGenericOnFailureMessage);
+ }
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
- if (status.IsNotFound()) {
- NOTREACHED() << "IsNotFound() but clearing?!";
- return MakeWriteResult(changes.release());
+ if (!status.ok() && !status.IsNotFound()) {
+ LOG(WARNING) << "Clear failed: " << status.ToString();
+ return MakeWriteResult(kGenericOnFailureMessage);
}
- if (!status.ok())
- return WriteFailure("clear", status.ToString());
+
return MakeWriteResult(changes.release());
}
-std::string LeveldbValueStore::ReadFromDb(
+bool LeveldbValueStore::ReadFromDb(
leveldb::ReadOptions options,
const std::string& key,
scoped_ptr<Value>* setting) {
@@ -333,24 +284,26 @@
if (s.IsNotFound()) {
// Despite there being no value, it was still a success.
- // Check this first because ok() is false on IsNotFound.
- return "";
+ return true;
}
- if (!s.ok())
- return s.ToString();
+ if (!s.ok()) {
+ LOG(ERROR) << "Error reading from database: " << s.ToString();
+ return false;
+ }
Value* value = base::JSONReader().ReadToValue(value_as_json);
if (value == NULL) {
// TODO(kalman): clear the offending non-JSON value from the database.
- return kInvalidJson;
+ LOG(ERROR) << "Invalid JSON in database: " << value_as_json;
+ return false;
}
setting->reset(value);
- return "";
+ return true;
}
-std::string LeveldbValueStore::AddToBatch(
+bool LeveldbValueStore::AddToBatch(
ValueStore::WriteOptions options,
const std::string& key,
const base::Value& value,
@@ -358,9 +311,8 @@
ValueStoreChangeList* changes) {
scoped_ptr<Value> old_value;
if (!(options & NO_CHECK_OLD_VALUE)) {
- std::string error = ReadFromDb(leveldb::ReadOptions(), key, &old_value);
- if (!error.empty())
- return error;
+ if (!ReadFromDb(leveldb::ReadOptions(), key, &old_value))
+ return false;
}
if (!old_value.get() || !old_value->Equals(&value)) {
@@ -373,16 +325,19 @@
batch->Put(key, value_as_json);
}
- return "";
+ return true;
}
-std::string LeveldbValueStore::WriteToDb(leveldb::WriteBatch* batch) {
+ValueStore::WriteResult LeveldbValueStore::WriteToDb(
+ leveldb::WriteBatch* batch,
+ scoped_ptr<ValueStoreChangeList> changes) {
leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch);
- if (status.IsNotFound()) {
- NOTREACHED() << "IsNotFound() but writing?!";
- return "";
+ if (!status.ok()) {
+ LOG(WARNING) << "DB batch write failed: " << status.ToString();
+ return MakeWriteResult(kGenericOnFailureMessage);
}
- return status.ok() ? "" : status.ToString();
+
+ return MakeWriteResult(changes.release());
}
bool LeveldbValueStore::IsEmpty() {
« no previous file with comments | « chrome/browser/value_store/leveldb_value_store.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698