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#ifndef IDBBackingStoreLevelDB_h
27#define IDBBackingStoreLevelDB_h
28
29#if ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
30
31#include "IDBBackingStoreCursorLevelDB.h"
32#include "IDBBackingStoreTransactionLevelDB.h"
33#include "IDBDatabaseMetadata.h"
34#include "IDBKey.h"
35#include "IDBRecordIdentifier.h"
36#include "IndexedDB.h"
37#include "LevelDBIterator.h"
38#include "LevelDBTransaction.h"
39#include <functional>
40#include <memory>
41#include <wtf/RefCounted.h>
42#include <wtf/WeakPtr.h>
43
44namespace WebCore {
45
46class LevelDBComparator;
47class LevelDBDatabase;
48class LevelDBTransaction;
49class IDBIndexWriterLevelDB;
50class IDBKey;
51class IDBKeyRange;
52class IDBTransactionBackend;
53class SecurityOrigin;
54class SharedBuffer;
55
56class LevelDBFactory {
57public:
58    virtual ~LevelDBFactory() { }
59    virtual std::unique_ptr<LevelDBDatabase> openLevelDB(const String& fileName, const LevelDBComparator*) = 0;
60    virtual bool destroyLevelDB(const String& fileName) = 0;
61};
62
63class IDBBackingStoreLevelDB : public RefCounted<IDBBackingStoreLevelDB> {
64public:
65    class Transaction;
66
67    virtual ~IDBBackingStoreLevelDB();
68    static PassRefPtr<IDBBackingStoreLevelDB> open(const SecurityOrigin&, const String& pathBase, const String& fileIdentifier);
69    static PassRefPtr<IDBBackingStoreLevelDB> open(const SecurityOrigin&, const String& pathBase, const String& fileIdentifier, LevelDBFactory*);
70    static PassRefPtr<IDBBackingStoreLevelDB> openInMemory(const String& identifier);
71    static PassRefPtr<IDBBackingStoreLevelDB> openInMemory(const String& identifier, LevelDBFactory*);
72    WeakPtr<IDBBackingStoreLevelDB> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
73
74    void establishBackingStoreTransaction(int64_t transactionID);
75
76    Vector<String> getDatabaseNames();
77
78    // New-style asynchronous callbacks
79    void getOrEstablishIDBDatabaseMetadata(const String& name, std::function<void (const IDBDatabaseMetadata&, bool success)> callbackFunction);
80    void deleteDatabase(const String& name, std::function<void (bool success)> successCallback);
81
82    // Old-style synchronous callbacks
83    bool updateIDBDatabaseVersion(IDBBackingStoreTransactionLevelDB&, int64_t rowId, uint64_t version);
84
85    bool createObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath&, bool autoIncrement);
86    bool deleteObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId) WARN_UNUSED_RETURN;
87
88    bool getRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, Vector<char>& record) WARN_UNUSED_RETURN;
89    bool putRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, PassRefPtr<SharedBuffer> value, IDBRecordIdentifier*) WARN_UNUSED_RETURN;
90    bool clearObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId) WARN_UNUSED_RETURN;
91    bool deleteRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBRecordIdentifier&) WARN_UNUSED_RETURN;
92    bool getKeyGeneratorCurrentNumber(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t& currentNumber) WARN_UNUSED_RETURN;
93    bool maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t newState, bool checkCurrent) WARN_UNUSED_RETURN;
94    bool keyExistsInObjectStore(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RefPtr<IDBRecordIdentifier>& foundIDBRecordIdentifier) WARN_UNUSED_RETURN;
95
96    bool createIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry) WARN_UNUSED_RETURN;
97    bool deleteIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId) WARN_UNUSED_RETURN;
98    bool putIndexDataForRecord(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const IDBRecordIdentifier*) WARN_UNUSED_RETURN;
99    bool getPrimaryKeyViaIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, RefPtr<IDBKey>& primaryKey) WARN_UNUSED_RETURN;
100    bool keyExistsInIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey, bool& exists) WARN_UNUSED_RETURN;
101
102    virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openObjectStoreKeyCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, const IDBKeyRange*, IndexedDB::CursorDirection);
103    virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openObjectStoreCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, const IDBKeyRange*, IndexedDB::CursorDirection);
104    virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openIndexKeyCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IndexedDB::CursorDirection);
105    virtual PassRefPtr<IDBBackingStoreCursorLevelDB> openIndexCursor(int64_t cursorID, IDBBackingStoreTransactionLevelDB&, int64_t databaseID, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IndexedDB::CursorDirection);
106
107    bool makeIndexWriters(int64_t transactionID, int64_t databaseId, const IDBObjectStoreMetadata&, IDBKey& primaryKey, bool keyWasGenerated, const Vector<int64_t>& indexIds, const Vector<Vector<RefPtr<IDBKey>>>&, Vector<RefPtr<IDBIndexWriterLevelDB>>& indexWriters, String* errorMessage, bool& completed) WARN_UNUSED_RETURN;
108
109    virtual PassRefPtr<IDBKey> generateKey(IDBTransactionBackend&, int64_t databaseId, int64_t objectStoreId);
110    bool updateKeyGenerator(IDBTransactionBackend&, int64_t databaseId, int64_t objectStoreId, const IDBKey&, bool checkCurrent);
111
112    LevelDBDatabase* levelDBDatabase() { return m_db.get(); }
113
114    static int compareIndexKeys(const LevelDBSlice&, const LevelDBSlice&);
115
116    void removeBackingStoreTransaction(IDBBackingStoreTransactionLevelDB*);
117
118private:
119    IDBBackingStoreLevelDB(const String& identifier, std::unique_ptr<LevelDBDatabase>, std::unique_ptr<LevelDBComparator>);
120    static PassRefPtr<IDBBackingStoreLevelDB> create(const String& identifier, std::unique_ptr<LevelDBDatabase>, std::unique_ptr<LevelDBComparator>);
121
122    // FIXME: LevelDB needs to support uint64_t as the version type.
123    bool createIDBDatabaseMetaData(IDBDatabaseMetadata&);
124    bool getIDBDatabaseMetaData(const String& name, IDBDatabaseMetadata*, bool& success) WARN_UNUSED_RETURN;
125    bool getObjectStores(int64_t databaseId, IDBDatabaseMetadata::ObjectStoreMap* objectStores) WARN_UNUSED_RETURN;
126
127    bool findKeyInIndex(IDBBackingStoreTransactionLevelDB&, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, Vector<char>& foundEncodedPrimaryKey, bool& found);
128    bool getIndexes(int64_t databaseId, int64_t objectStoreId, IDBObjectStoreMetadata::IndexMap*) WARN_UNUSED_RETURN;
129
130    String m_identifier;
131
132    std::unique_ptr<LevelDBDatabase> m_db;
133    std::unique_ptr<LevelDBComparator> m_comparator;
134    WeakPtrFactory<IDBBackingStoreLevelDB> m_weakFactory;
135
136    HashMap<int64_t, RefPtr<IDBBackingStoreTransactionLevelDB>> m_backingStoreTransactions;
137};
138
139} // namespace WebCore
140
141#endif // ENABLE(INDEXED_DATABASE) && USE(LEVELDB)
142
143#endif // IDBBackingStoreLevelDB_h
144