• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/files/file_path.h"
11 #include "base/files/file_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_split.h"
14 #include "base/threading/thread_checker.h"
15 #include "third_party/leveldatabase/src/include/leveldb/db.h"
16 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
17 #include "third_party/leveldatabase/src/include/leveldb/options.h"
18 #include "third_party/leveldatabase/src/include/leveldb/slice.h"
19 #include "third_party/leveldatabase/src/include/leveldb/status.h"
20 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
21 
22 namespace leveldb_proto {
23 
LevelDB()24 LevelDB::LevelDB() {}
25 
~LevelDB()26 LevelDB::~LevelDB() { DFAKE_SCOPED_LOCK(thread_checker_); }
27 
Init(const base::FilePath & database_dir)28 bool LevelDB::Init(const base::FilePath& database_dir) {
29   DFAKE_SCOPED_LOCK(thread_checker_);
30 
31   leveldb::Options options;
32   options.create_if_missing = true;
33   options.max_open_files = 0;  // Use minimum.
34 
35   std::string path = database_dir.AsUTF8Unsafe();
36 
37   leveldb::DB* db = NULL;
38   leveldb::Status status = leveldb::DB::Open(options, path, &db);
39   if (status.IsCorruption()) {
40     base::DeleteFile(database_dir, true);
41     status = leveldb::DB::Open(options, path, &db);
42   }
43 
44   if (status.ok()) {
45     CHECK(db);
46     db_.reset(db);
47     return true;
48   }
49 
50   LOG(WARNING) << "Unable to open " << database_dir.value() << ": "
51                << status.ToString();
52   return false;
53 }
54 
Save(const base::StringPairs & entries_to_save,const std::vector<std::string> & keys_to_remove)55 bool LevelDB::Save(const base::StringPairs& 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 (base::StringPairs::const_iterator it = entries_to_save.begin();
61        it != entries_to_save.end();
62        ++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 
Load(std::vector<std::string> * entries)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