| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/value_store/leveldb_value_store.h" | 5 #include "chrome/browser/value_store/leveldb_value_store.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 } | 327 } |
| 328 if (!status.ok()) | 328 if (!status.ok()) |
| 329 return WriteFailure("clear", status.ToString()); | 329 return WriteFailure("clear", status.ToString()); |
| 330 return MakeWriteResult(changes.release()); | 330 return MakeWriteResult(changes.release()); |
| 331 } | 331 } |
| 332 | 332 |
| 333 std::string LeveldbValueStore::EnsureDbIsOpen() { | 333 std::string LeveldbValueStore::EnsureDbIsOpen() { |
| 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 335 | 335 |
| 336 if (db_.get()) | 336 if (db_.get()) |
| 337 return ""; | 337 return std::string(); |
| 338 | 338 |
| 339 #if defined(OS_POSIX) | 339 #if defined(OS_POSIX) |
| 340 std::string os_path(db_path_.value()); | 340 std::string os_path(db_path_.value()); |
| 341 #elif defined(OS_WIN) | 341 #elif defined(OS_WIN) |
| 342 std::string os_path = base::SysWideToUTF8(db_path_.value()); | 342 std::string os_path = base::SysWideToUTF8(db_path_.value()); |
| 343 #endif | 343 #endif |
| 344 | 344 |
| 345 leveldb::Options options; | 345 leveldb::Options options; |
| 346 options.create_if_missing = true; | 346 options.create_if_missing = true; |
| 347 leveldb::DB* db; | 347 leveldb::DB* db; |
| 348 leveldb::Status status = leveldb::DB::Open(options, os_path, &db); | 348 leveldb::Status status = leveldb::DB::Open(options, os_path, &db); |
| 349 if (!status.ok()) { | 349 if (!status.ok()) { |
| 350 // |os_path| may contain sensitive data, and these strings are passed | 350 // |os_path| may contain sensitive data, and these strings are passed |
| 351 // through to the extension, so strip that out. | 351 // through to the extension, so strip that out. |
| 352 std::string status_string = status.ToString(); | 352 std::string status_string = status.ToString(); |
| 353 ReplaceSubstringsAfterOffset(&status_string, 0u, os_path, "..."); | 353 ReplaceSubstringsAfterOffset(&status_string, 0u, os_path, "..."); |
| 354 return base::StringPrintf("Failed to open database: %s", | 354 return base::StringPrintf("Failed to open database: %s", |
| 355 status_string.c_str()); | 355 status_string.c_str()); |
| 356 } | 356 } |
| 357 | 357 |
| 358 db_.reset(db); | 358 db_.reset(db); |
| 359 return ""; | 359 return std::string(); |
| 360 } | 360 } |
| 361 | 361 |
| 362 std::string LeveldbValueStore::ReadFromDb( | 362 std::string LeveldbValueStore::ReadFromDb( |
| 363 leveldb::ReadOptions options, | 363 leveldb::ReadOptions options, |
| 364 const std::string& key, | 364 const std::string& key, |
| 365 scoped_ptr<Value>* setting) { | 365 scoped_ptr<Value>* setting) { |
| 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 367 DCHECK(setting != NULL); | 367 DCHECK(setting != NULL); |
| 368 std::string value_as_json; | 368 std::string value_as_json; |
| 369 leveldb::Status s = db_->Get(options, key, &value_as_json); | 369 leveldb::Status s = db_->Get(options, key, &value_as_json); |
| 370 | 370 |
| 371 if (s.IsNotFound()) { | 371 if (s.IsNotFound()) { |
| 372 // Despite there being no value, it was still a success. | 372 // Despite there being no value, it was still a success. |
| 373 // Check this first because ok() is false on IsNotFound. | 373 // Check this first because ok() is false on IsNotFound. |
| 374 return ""; | 374 return std::string(); |
| 375 } | 375 } |
| 376 | 376 |
| 377 if (!s.ok()) | 377 if (!s.ok()) |
| 378 return s.ToString(); | 378 return s.ToString(); |
| 379 | 379 |
| 380 Value* value = base::JSONReader().ReadToValue(value_as_json); | 380 Value* value = base::JSONReader().ReadToValue(value_as_json); |
| 381 if (value == NULL) { | 381 if (value == NULL) { |
| 382 // TODO(kalman): clear the offending non-JSON value from the database. | 382 // TODO(kalman): clear the offending non-JSON value from the database. |
| 383 return kInvalidJson; | 383 return kInvalidJson; |
| 384 } | 384 } |
| 385 | 385 |
| 386 setting->reset(value); | 386 setting->reset(value); |
| 387 return ""; | 387 return std::string(); |
| 388 } | 388 } |
| 389 | 389 |
| 390 std::string LeveldbValueStore::AddToBatch( | 390 std::string LeveldbValueStore::AddToBatch( |
| 391 ValueStore::WriteOptions options, | 391 ValueStore::WriteOptions options, |
| 392 const std::string& key, | 392 const std::string& key, |
| 393 const base::Value& value, | 393 const base::Value& value, |
| 394 leveldb::WriteBatch* batch, | 394 leveldb::WriteBatch* batch, |
| 395 ValueStoreChangeList* changes) { | 395 ValueStoreChangeList* changes) { |
| 396 scoped_ptr<Value> old_value; | 396 scoped_ptr<Value> old_value; |
| 397 if (!(options & NO_CHECK_OLD_VALUE)) { | 397 if (!(options & NO_CHECK_OLD_VALUE)) { |
| 398 std::string error = ReadFromDb(leveldb::ReadOptions(), key, &old_value); | 398 std::string error = ReadFromDb(leveldb::ReadOptions(), key, &old_value); |
| 399 if (!error.empty()) | 399 if (!error.empty()) |
| 400 return error; | 400 return error; |
| 401 } | 401 } |
| 402 | 402 |
| 403 if (!old_value.get() || !old_value->Equals(&value)) { | 403 if (!old_value.get() || !old_value->Equals(&value)) { |
| 404 if (!(options & NO_GENERATE_CHANGES)) { | 404 if (!(options & NO_GENERATE_CHANGES)) { |
| 405 changes->push_back( | 405 changes->push_back( |
| 406 ValueStoreChange(key, old_value.release(), value.DeepCopy())); | 406 ValueStoreChange(key, old_value.release(), value.DeepCopy())); |
| 407 } | 407 } |
| 408 std::string value_as_json; | 408 std::string value_as_json; |
| 409 base::JSONWriter::Write(&value, &value_as_json); | 409 base::JSONWriter::Write(&value, &value_as_json); |
| 410 batch->Put(key, value_as_json); | 410 batch->Put(key, value_as_json); |
| 411 } | 411 } |
| 412 | 412 |
| 413 return ""; | 413 return std::string(); |
| 414 } | 414 } |
| 415 | 415 |
| 416 std::string LeveldbValueStore::WriteToDb(leveldb::WriteBatch* batch) { | 416 std::string LeveldbValueStore::WriteToDb(leveldb::WriteBatch* batch) { |
| 417 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch); | 417 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch); |
| 418 if (status.IsNotFound()) { | 418 if (status.IsNotFound()) { |
| 419 NOTREACHED() << "IsNotFound() but writing?!"; | 419 NOTREACHED() << "IsNotFound() but writing?!"; |
| 420 return ""; | 420 return std::string(); |
| 421 } | 421 } |
| 422 return status.ok() ? "" : status.ToString(); | 422 return status.ok() ? std::string() : status.ToString(); |
| 423 } | 423 } |
| 424 | 424 |
| 425 bool LeveldbValueStore::IsEmpty() { | 425 bool LeveldbValueStore::IsEmpty() { |
| 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 426 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 427 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); | 427 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(leveldb::ReadOptions())); |
| 428 | 428 |
| 429 it->SeekToFirst(); | 429 it->SeekToFirst(); |
| 430 bool is_empty = !it->Valid(); | 430 bool is_empty = !it->Valid(); |
| 431 if (!it->status().ok()) { | 431 if (!it->status().ok()) { |
| 432 LOG(ERROR) << "Checking DB emptiness failed: " << it->status().ToString(); | 432 LOG(ERROR) << "Checking DB emptiness failed: " << it->status().ToString(); |
| 433 return false; | 433 return false; |
| 434 } | 434 } |
| 435 return is_empty; | 435 return is_empty; |
| 436 } | 436 } |
| OLD | NEW |