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

Unified Diff: chrome/browser/extensions/api/storage/storage_api.cc

Issue 165223003: Add a Restore() method to ValueStore and make StorageAPI use it (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Latest master Created 6 years, 10 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
Index: chrome/browser/extensions/api/storage/storage_api.cc
diff --git a/chrome/browser/extensions/api/storage/storage_api.cc b/chrome/browser/extensions/api/storage/storage_api.cc
index 1d6b361110b9b72aa7694a844be3f8073014ee09..2bf88d7558a07215eeb91603146b30c73285a372 100644
--- a/chrome/browser/extensions/api/storage/storage_api.cc
+++ b/chrome/browser/extensions/api/storage/storage_api.cc
@@ -73,23 +73,21 @@ void SettingsFunction::AsyncRunWithStorage(ValueStore* storage) {
base::Bind(&SettingsFunction::SendResponse, this, success));
}
-bool SettingsFunction::UseReadResult(ValueStore::ReadResult read_result) {
- if (read_result->HasError()) {
- error_ = read_result->error().message;
- return false;
- }
-
- base::DictionaryValue* result = new base::DictionaryValue();
- result->Swap(&read_result->settings());
- SetResult(result);
+bool SettingsFunction::UseReadResult(ValueStore::ReadResult result,
+ ValueStore* storage) {
+ if (result->HasError())
+ return HandleError(result->error(), storage);
+
+ base::DictionaryValue* dict = new base::DictionaryValue();
+ dict->Swap(&result->settings());
+ SetResult(dict);
return true;
}
-bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) {
- if (result->HasError()) {
- error_ = result->error().message;
- return false;
- }
+bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result,
+ ValueStore* storage) {
+ if (result->HasError())
+ return HandleError(result->error(), storage);
if (!result->changes().empty()) {
observers_->Notify(
@@ -102,6 +100,29 @@ bool SettingsFunction::UseWriteResult(ValueStore::WriteResult result) {
return true;
}
+bool SettingsFunction::HandleError(const ValueStore::Error& error,
+ ValueStore* storage) {
+ // If the method failed due to corruption, and we haven't tried to fix it, we
+ // can try to restore the storage and re-run it. Otherwise, the method has
+ // failed.
+ if (error.code == ValueStore::CORRUPTION && !tried_restoring_storage_) {
+ tried_restoring_storage_ = true;
+
+ // If the corruption is on a particular key, try to restore that key and
+ // re-run.
+ if (error.key.get() && storage->RestoreKey(*error.key))
+ return RunWithStorage(storage);
+
+ // If the full database is corrupted, try to restore the whole thing and
+ // re-run.
+ if (storage->Restore())
+ return RunWithStorage(storage);
+ }
+
+ error_ = error.message;
+ return false;
+}
+
// Concrete settings functions
namespace {
@@ -161,32 +182,34 @@ bool StorageStorageAreaGetFunction::RunWithStorage(ValueStore* storage) {
switch (input->GetType()) {
case base::Value::TYPE_NULL:
- return UseReadResult(storage->Get());
+ return UseReadResult(storage->Get(), storage);
case base::Value::TYPE_STRING: {
std::string as_string;
input->GetAsString(&as_string);
- return UseReadResult(storage->Get(as_string));
+ return UseReadResult(storage->Get(as_string), storage);
}
case base::Value::TYPE_LIST: {
std::vector<std::string> as_string_list;
AddAllStringValues(*static_cast<base::ListValue*>(input),
&as_string_list);
- return UseReadResult(storage->Get(as_string_list));
+ return UseReadResult(storage->Get(as_string_list), storage);
}
case base::Value::TYPE_DICTIONARY: {
- base::DictionaryValue* as_dict = static_cast<base::DictionaryValue*>(input);
+ base::DictionaryValue* as_dict =
+ static_cast<base::DictionaryValue*>(input);
ValueStore::ReadResult result = storage->Get(GetKeys(*as_dict));
if (result->HasError()) {
- return UseReadResult(result.Pass());
+ return UseReadResult(result.Pass(), storage);
}
base::DictionaryValue* with_default_values = as_dict->DeepCopy();
with_default_values->MergeDictionary(&result->settings());
return UseReadResult(
- ValueStore::MakeReadResult(make_scoped_ptr(with_default_values)));
+ ValueStore::MakeReadResult(make_scoped_ptr(with_default_values)),
+ storage);
}
default:
@@ -234,7 +257,7 @@ bool StorageStorageAreaGetBytesInUseFunction::RunWithStorage(
bool StorageStorageAreaSetFunction::RunWithStorage(ValueStore* storage) {
base::DictionaryValue* input = NULL;
EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &input));
- return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input));
+ return UseWriteResult(storage->Set(ValueStore::DEFAULTS, *input), storage);
}
void StorageStorageAreaSetFunction::GetQuotaLimitHeuristics(
@@ -250,14 +273,14 @@ bool StorageStorageAreaRemoveFunction::RunWithStorage(ValueStore* storage) {
case base::Value::TYPE_STRING: {
std::string as_string;
input->GetAsString(&as_string);
- return UseWriteResult(storage->Remove(as_string));
+ return UseWriteResult(storage->Remove(as_string), storage);
}
case base::Value::TYPE_LIST: {
std::vector<std::string> as_string_list;
AddAllStringValues(*static_cast<base::ListValue*>(input),
&as_string_list);
- return UseWriteResult(storage->Remove(as_string_list));
+ return UseWriteResult(storage->Remove(as_string_list), storage);
}
default:
@@ -272,7 +295,7 @@ void StorageStorageAreaRemoveFunction::GetQuotaLimitHeuristics(
}
bool StorageStorageAreaClearFunction::RunWithStorage(ValueStore* storage) {
- return UseWriteResult(storage->Clear());
+ return UseWriteResult(storage->Clear(), storage);
}
void StorageStorageAreaClearFunction::GetQuotaLimitHeuristics(
« no previous file with comments | « chrome/browser/extensions/api/storage/storage_api.h ('k') | chrome/browser/extensions/api/storage/storage_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698