12daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch/*
22daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Copyright (C) 2011 Google Inc. All rights reserved.
32daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *
42daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * Redistribution and use in source and binary forms, with or without
52daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * modification, are permitted provided that the following conditions
62daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * are met:
72daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *
82daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 1.  Redistributions of source code must retain the above copyright
92daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *     notice, this list of conditions and the following disclaimer.
102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * 2.  Redistributions in binary form must reproduce the above copyright
112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *     notice, this list of conditions and the following disclaimer in the
122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *     documentation and/or other materials provided with the distribution.
132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch *
142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch */
252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "config.h"
272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBDatabase.h"
282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if ENABLE(LEVELDB)
302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBComparator.h"
322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBIterator.h"
332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "LevelDBSlice.h"
342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <leveldb/comparator.h>
352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <leveldb/db.h>
362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <leveldb/slice.h>
372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <string>
382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <wtf/PassOwnPtr.h>
392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <wtf/text/CString.h>
402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <wtf/text/WTFString.h>
412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace WebCore {
432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic leveldb::Slice makeSlice(const Vector<char>& value)
452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return leveldb::Slice(value.data(), value.size());
472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic leveldb::Slice makeSlice(const LevelDBSlice& s)
502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return leveldb::Slice(s.begin(), s.end() - s.begin());
522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic LevelDBSlice makeLevelDBSlice(const leveldb::Slice& s)
552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return LevelDBSlice(s.data(), s.data() + s.size());
572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstatic Vector<char> makeVector(const std::string& s)
602daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
612daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    Vector<char> res;
622daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    res.append(s.c_str(), s.length());
632daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return res;
642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochnamespace {
672daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochclass ComparatorAdapter : public leveldb::Comparator {
682daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochpublic:
692daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ComparatorAdapter(const LevelDBComparator* comparator)
702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        : m_comparator(comparator)
712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const
752daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    {
762daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return m_comparator->compare(makeLevelDBSlice(a), makeLevelDBSlice(b));
772daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
792daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual const char* Name() const { return m_comparator->name(); }
802daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // FIXME: Support the methods below in the future.
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual void FindShortestSeparator(std::string* start, const leveldb::Slice& limit) const { }
832daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    virtual void FindShortSuccessor(std::string* key) const { }
842daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
852daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochprivate:
862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    const LevelDBComparator* m_comparator;
872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch};
882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
902daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochLevelDBDatabase::LevelDBDatabase()
912daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    : m_db(0)
922daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
932daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
942daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochLevelDBDatabase::~LevelDBDatabase()
962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochLevelDBDatabase* LevelDBDatabase::open(const String& fileName, const LevelDBComparator* comparator)
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    OwnPtr<ComparatorAdapter> comparatorAdapter(new ComparatorAdapter(comparator));
1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    LevelDBDatabase* result = new LevelDBDatabase();
1042daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1052daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    leveldb::Options options;
1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    options.comparator = comparatorAdapter.get();
1072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    options.create_if_missing = true;
1082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    leveldb::DB* db;
1092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    leveldb::Status s = leveldb::DB::Open(options, fileName.utf8().data(), &db);
1102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!s.ok()) {
1122daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        delete result;
1132daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return 0;
1142daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->m_db = WTF::adoptPtr(db);
1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    result->m_comparatorAdapter = comparatorAdapter.release();
1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return result;
1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool LevelDBDatabase::put(const LevelDBSlice& key, const Vector<char>& value)
1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    leveldb::WriteOptions writeOptions;
1262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    writeOptions.sync = false;
1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_db->Put(writeOptions, makeSlice(key), makeSlice(value)).ok();
1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool LevelDBDatabase::remove(const LevelDBSlice& key)
1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    leveldb::WriteOptions writeOptions;
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    writeOptions.sync = false;
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return m_db->Delete(writeOptions, makeSlice(key)).ok();
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1382daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1392daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochbool LevelDBDatabase::get(const LevelDBSlice& key, Vector<char>& value)
1402daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1412daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    std::string result;
1422daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!m_db->Get(leveldb::ReadOptions(), makeSlice(key), &result).ok())
1432daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return false;
1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    value = makeVector(result);
1462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return true;
1472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1492daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochLevelDBIterator* LevelDBDatabase::newIterator()
1502daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
1512daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    leveldb::Iterator* i = m_db->NewIterator(leveldb::ReadOptions());
1522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!i) // FIXME: Double check if we actually need to check this.
1532daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return 0;
1542daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    return new LevelDBIterator(i);
1552daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1562daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1572daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch} // namespace WebCore
1582daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1592daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif // ENABLE(LEVELDB)
160