1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "components/leveldb_proto/leveldb_database.h" 6 7 #include <string> 8 #include <vector> 9 10 #include "base/file_util.h" 11 #include "base/files/file_path.h" 12 #include "base/memory/scoped_ptr.h" 13 #include "base/threading/thread_checker.h" 14 #include "third_party/leveldatabase/src/include/leveldb/db.h" 15 #include "third_party/leveldatabase/src/include/leveldb/iterator.h" 16 #include "third_party/leveldatabase/src/include/leveldb/options.h" 17 #include "third_party/leveldatabase/src/include/leveldb/slice.h" 18 #include "third_party/leveldatabase/src/include/leveldb/status.h" 19 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 20 21 namespace leveldb_proto { 22 23 LevelDB::LevelDB() {} 24 25 LevelDB::~LevelDB() { DFAKE_SCOPED_LOCK(thread_checker_); } 26 27 bool LevelDB::Init(const base::FilePath& database_dir) { 28 DFAKE_SCOPED_LOCK(thread_checker_); 29 30 leveldb::Options options; 31 options.create_if_missing = true; 32 options.max_open_files = 0; // Use minimum. 33 34 std::string path = database_dir.AsUTF8Unsafe(); 35 36 leveldb::DB* db = NULL; 37 leveldb::Status status = leveldb::DB::Open(options, path, &db); 38 if (status.IsCorruption()) { 39 base::DeleteFile(database_dir, true); 40 status = leveldb::DB::Open(options, path, &db); 41 } 42 43 if (status.ok()) { 44 CHECK(db); 45 db_.reset(db); 46 return true; 47 } 48 49 LOG(WARNING) << "Unable to open " << database_dir.value() << ": " 50 << status.ToString(); 51 return false; 52 } 53 54 bool LevelDB::Save( 55 const std::vector<std::pair<std::string, std::string> >& entries_to_save, 56 const std::vector<std::string>& keys_to_remove) { 57 DFAKE_SCOPED_LOCK(thread_checker_); 58 59 leveldb::WriteBatch updates; 60 for (std::vector<std::pair<std::string, std::string> >::const_iterator it = 61 entries_to_save.begin(); 62 it != entries_to_save.end(); ++it) { 63 updates.Put(leveldb::Slice(it->first), leveldb::Slice(it->second)); 64 } 65 for (std::vector<std::string>::const_iterator it = keys_to_remove.begin(); 66 it != keys_to_remove.end(); ++it) { 67 updates.Delete(leveldb::Slice(*it)); 68 } 69 70 leveldb::WriteOptions options; 71 options.sync = true; 72 leveldb::Status status = db_->Write(options, &updates); 73 if (status.ok()) return true; 74 75 DLOG(WARNING) << "Failed writing leveldb_proto entries: " 76 << status.ToString(); 77 return false; 78 } 79 80 bool LevelDB::Load(std::vector<std::string>* entries) { 81 DFAKE_SCOPED_LOCK(thread_checker_); 82 83 leveldb::ReadOptions options; 84 scoped_ptr<leveldb::Iterator> db_iterator(db_->NewIterator(options)); 85 for (db_iterator->SeekToFirst(); db_iterator->Valid(); db_iterator->Next()) { 86 leveldb::Slice value_slice = db_iterator->value(); 87 std::string entry(value_slice.data(), value_slice.size()); 88 entries->push_back(entry); 89 } 90 return true; 91 } 92 93 } // namespace leveldb_proto 94