1 /* 2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "LevelDBDatabase.h" 28 29 #if ENABLE(LEVELDB) 30 31 #include "LevelDBComparator.h" 32 #include "LevelDBIterator.h" 33 #include "LevelDBSlice.h" 34 #include <leveldb/comparator.h> 35 #include <leveldb/db.h> 36 #include <leveldb/slice.h> 37 #include <string> 38 #include <wtf/PassOwnPtr.h> 39 #include <wtf/text/CString.h> 40 #include <wtf/text/WTFString.h> 41 42 namespace WebCore { 43 44 static leveldb::Slice makeSlice(const Vector<char>& value) 45 { 46 return leveldb::Slice(value.data(), value.size()); 47 } 48 49 static leveldb::Slice makeSlice(const LevelDBSlice& s) 50 { 51 return leveldb::Slice(s.begin(), s.end() - s.begin()); 52 } 53 54 static LevelDBSlice makeLevelDBSlice(const leveldb::Slice& s) 55 { 56 return LevelDBSlice(s.data(), s.data() + s.size()); 57 } 58 59 static Vector<char> makeVector(const std::string& s) 60 { 61 Vector<char> res; 62 res.append(s.c_str(), s.length()); 63 return res; 64 } 65 66 namespace { 67 class ComparatorAdapter : public leveldb::Comparator { 68 public: 69 ComparatorAdapter(const LevelDBComparator* comparator) 70 : m_comparator(comparator) 71 { 72 } 73 74 virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const 75 { 76 return m_comparator->compare(makeLevelDBSlice(a), makeLevelDBSlice(b)); 77 } 78 79 virtual const char* Name() const { return m_comparator->name(); } 80 81 // FIXME: Support the methods below in the future. 82 virtual void FindShortestSeparator(std::string* start, const leveldb::Slice& limit) const { } 83 virtual void FindShortSuccessor(std::string* key) const { } 84 85 private: 86 const LevelDBComparator* m_comparator; 87 }; 88 } 89 90 LevelDBDatabase::LevelDBDatabase() 91 : m_db(0) 92 { 93 } 94 95 LevelDBDatabase::~LevelDBDatabase() 96 { 97 } 98 99 LevelDBDatabase* LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator) 100 { 101 OwnPtr<ComparatorAdapter> comparatorAdapter(new ComparatorAdapter(comparator)); 102 103 LevelDBDatabase* result = new LevelDBDatabase(); 104 105 leveldb::Options options; 106 options.comparator = comparatorAdapter.get(); 107 options.create_if_missing = true; 108 leveldb::DB* db; 109 leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db); 110 111 if (!s.ok()) { 112 delete result; 113 return 0; 114 } 115 116 result->m_db = WTF::adoptPtr(db); 117 result->m_comparatorAdapter = comparatorAdapter.release(); 118 119 return result; 120 } 121 122 123 bool LevelDBDatabase::put(const LevelDBSlice& key, const Vector<char>& value) 124 { 125 leveldb::WriteOptions writeOptions; 126 writeOptions.sync = false; 127 128 return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok(); 129 } 130 131 bool LevelDBDatabase::remove(const LevelDBSlice& key) 132 { 133 leveldb::WriteOptions writeOptions; 134 writeOptions.sync = false; 135 136 return m_db->Delete(writeOptions, makeSlice(key)).ok(); 137 } 138 139 bool LevelDBDatabase::get(const LevelDBSlice& key, Vector<char>& value) 140 { 141 std::string result; 142 if (!m_db->Get(leveldb::ReadOptions(), makeSlice(key), &result).ok()) 143 return false; 144 145 value = makeVector(result); 146 return true; 147 } 148 149 LevelDBIterator* LevelDBDatabase::newIterator() 150 { 151 leveldb::Iterator* i = m_db->NewIterator(leveldb::ReadOptions()); 152 if (!i) // FIXME: Double check if we actually need to check this. 153 return 0; 154 return new LevelDBIterator(i); 155 } 156 157 } // namespace WebCore 158 159 #endif // ENABLE(LEVELDB) 160