Index: chrome/browser/extensions/extension_settings_leveldb_storage.cc |
diff --git a/chrome/browser/extensions/extension_settings_leveldb_storage.cc b/chrome/browser/extensions/extension_settings_leveldb_storage.cc |
index 5c86c027077102c43eb8c5a5df97c5ee821bdf4c..647c232931e3958540d656e7261b82523674d728 100644 |
--- a/chrome/browser/extensions/extension_settings_leveldb_storage.cc |
+++ b/chrome/browser/extensions/extension_settings_leveldb_storage.cc |
@@ -100,7 +100,7 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Get( |
if (setting.get()) { |
settings->SetWithoutPathExpansion(key, setting.release()); |
} |
- return Result(settings, NULL); |
+ return Result(settings, NULL, NULL); |
} |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Get( |
@@ -124,7 +124,7 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Get( |
} |
} |
- return Result(settings.release(), NULL); |
+ return Result(settings.release(), NULL, NULL); |
} |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Get() { |
@@ -154,7 +154,7 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Get() { |
return Result(kGenericOnFailureMessage); |
} |
- return Result(settings.release(), NULL); |
+ return Result(settings.release(), NULL, NULL); |
} |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Set( |
@@ -168,24 +168,29 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Set( |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Set( |
const DictionaryValue& settings) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ scoped_ptr<DictionaryValue> old_settings(new DictionaryValue()); |
scoped_ptr<std::set<std::string> > changed_keys(new std::set<std::string>()); |
std::string value_as_json; |
leveldb::WriteBatch batch; |
for (DictionaryValue::key_iterator it = settings.begin_keys(); |
it != settings.end_keys(); ++it) { |
- scoped_ptr<Value> original_value; |
- if (!ReadFromDb(leveldb::ReadOptions(), *it, &original_value)) { |
+ scoped_ptr<Value> old_value; |
+ if (!ReadFromDb(leveldb::ReadOptions(), *it, &old_value)) { |
return Result(kGenericOnFailureMessage); |
} |
Value* new_value = NULL; |
settings.GetWithoutPathExpansion(*it, &new_value); |
- if (!original_value.get() || !original_value->Equals(new_value)) { |
+ if (!old_value.get() || !old_value->Equals(new_value)) { |
changed_keys->insert(*it); |
base::JSONWriter::Write(new_value, false, &value_as_json); |
batch.Put(*it, value_as_json); |
} |
+ |
+ if (old_value.get()) { |
+ old_settings->SetWithoutPathExpansion(*it, old_value.release()); |
+ } |
} |
leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch); |
@@ -194,7 +199,8 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Set( |
return Result(kGenericOnFailureMessage); |
} |
- return Result(settings.DeepCopy(), changed_keys.release()); |
+ return Result( |
+ settings.DeepCopy(), old_settings.release(), changed_keys.release()); |
} |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Remove( |
@@ -208,18 +214,20 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Remove( |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Remove( |
const std::vector<std::string>& keys) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ scoped_ptr<DictionaryValue> old_settings(new DictionaryValue()); |
scoped_ptr<std::set<std::string> > changed_keys(new std::set<std::string>()); |
leveldb::WriteBatch batch; |
for (std::vector<std::string>::const_iterator it = keys.begin(); |
it != keys.end(); ++it) { |
- scoped_ptr<Value> original_value; |
- if (!ReadFromDb(leveldb::ReadOptions(), *it, &original_value)) { |
+ scoped_ptr<Value> old_value; |
+ if (!ReadFromDb(leveldb::ReadOptions(), *it, &old_value)) { |
return Result(kGenericOnFailureMessage); |
} |
- if (original_value.get()) { |
+ if (old_value.get()) { |
changed_keys->insert(*it); |
+ old_settings->SetWithoutPathExpansion(*it, old_value.release()); |
batch.Delete(*it); |
} |
} |
@@ -230,11 +238,12 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Remove( |
return Result(kGenericOnFailureMessage); |
} |
- return Result(NULL, changed_keys.release()); |
+ return Result(NULL, old_settings.release(), changed_keys.release()); |
} |
ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Clear() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
+ scoped_ptr<DictionaryValue> old_settings(new DictionaryValue()); |
scoped_ptr<std::set<std::string> > changed_keys(new std::set<std::string>()); |
leveldb::ReadOptions options; |
// All interaction with the db is done on the same thread, so snapshotting |
@@ -245,8 +254,17 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Clear() { |
options.snapshot = snapshot.get(); |
scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options)); |
for (it->SeekToFirst(); it->Valid(); it->Next()) { |
- changed_keys->insert(it->key().ToString()); |
- batch.Delete(it->key()); |
+ const std::string key = it->key().ToString(); |
+ const std::string old_value_as_json = it->value().ToString(); |
+ changed_keys->insert(key); |
+ Value* old_value = |
+ base::JSONReader().JsonToValue(old_value_as_json, false, false); |
+ if (old_value) { |
+ old_settings->SetWithoutPathExpansion(key, old_value); |
+ } else { |
+ LOG(ERROR) << "Invalid JSON in database: " << old_value_as_json; |
+ } |
+ batch.Delete(key); |
} |
if (!it->status().ok()) { |
@@ -260,7 +278,7 @@ ExtensionSettingsStorage::Result ExtensionSettingsLeveldbStorage::Clear() { |
return Result(kGenericOnFailureMessage); |
} |
- return Result(NULL, changed_keys.release()); |
+ return Result(NULL, old_settings.release(), changed_keys.release()); |
} |
bool ExtensionSettingsLeveldbStorage::ReadFromDb( |