Home | History | Annotate | Download | only in leveldb_proto
      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