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 |