e8ee6b6c880c625858956061649e3257ca6b62b5
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / IDBBackingStore.h
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 IDBBackingStore_h
27 #define IDBBackingStore_h
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBKey.h"
32 #include "IDBMetadata.h"
33 #include "IndexedDB.h"
34 #include "LevelDBTransaction.h"
35 #include <wtf/OwnPtr.h>
36 #include <wtf/RefCounted.h>
37 #include <wtf/WeakPtr.h>
38
39 namespace WebCore {
40
41 class LevelDBComparator;
42 class LevelDBDatabase;
43 class LevelDBTransaction;
44 class IDBKey;
45 class IDBKeyRange;
46 class SecurityOrigin;
47 class SharedBuffer;
48
49 class LevelDBFactory {
50 public:
51     virtual PassOwnPtr<LevelDBDatabase> openLevelDB(const String& fileName, const LevelDBComparator*) = 0;
52     virtual bool destroyLevelDB(const String& fileName) = 0;
53 };
54
55 class IDBBackingStore : public RefCounted<IDBBackingStore> {
56 public:
57     class Transaction;
58
59     virtual ~IDBBackingStore();
60     static PassRefPtr<IDBBackingStore> open(SecurityOrigin*, const String& pathBase, const String& fileIdentifier);
61     static PassRefPtr<IDBBackingStore> open(SecurityOrigin*, const String& pathBase, const String& fileIdentifier, LevelDBFactory*);
62     WeakPtr<IDBBackingStore> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
63
64     virtual Vector<String> getDatabaseNames();
65     virtual bool getIDBDatabaseMetaData(const String& name, IDBDatabaseMetadata*, bool& success) WARN_UNUSED_RETURN;
66     virtual bool createIDBDatabaseMetaData(const String& name, const String& version, int64_t intVersion, int64_t& rowId);
67     virtual bool updateIDBDatabaseMetaData(IDBBackingStore::Transaction*, int64_t rowId, const String& version);
68     virtual bool updateIDBDatabaseIntVersion(IDBBackingStore::Transaction*, int64_t rowId, int64_t intVersion);
69     virtual bool deleteDatabase(const String& name);
70
71     void getObjectStores(int64_t databaseId, IDBDatabaseMetadata::ObjectStoreMap*);
72     virtual bool createObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath&, bool autoIncrement);
73     virtual bool deleteObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId) WARN_UNUSED_RETURN;
74
75     class RecordIdentifier {
76         WTF_MAKE_NONCOPYABLE(RecordIdentifier);
77     public:
78         RecordIdentifier(const Vector<char>& primaryKey, int64_t version) : m_primaryKey(primaryKey), m_version(version) { ASSERT(!primaryKey.isEmpty()); }
79         RecordIdentifier() : m_primaryKey(), m_version(-1) { }
80
81         const Vector<char> primaryKey() const { return m_primaryKey; }
82         int64_t version() const { return m_version; }
83         void reset(const Vector<char>& primaryKey, int64_t version) { m_primaryKey = primaryKey; m_version = version; }
84
85     private:
86         Vector<char> m_primaryKey; // FIXME: Make it more clear that this is the *encoded* version of the key.
87         int64_t m_version;
88     };
89
90     virtual bool getRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, Vector<char>& record) WARN_UNUSED_RETURN;
91     virtual bool putRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, PassRefPtr<SharedBuffer> value, RecordIdentifier*) WARN_UNUSED_RETURN;
92     virtual void clearObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId);
93     virtual void deleteRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const RecordIdentifier&);
94     virtual bool getKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t& currentNumber) WARN_UNUSED_RETURN;
95     virtual bool maybeUpdateKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t newState, bool checkCurrent) WARN_UNUSED_RETURN;
96     virtual bool keyExistsInObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, RecordIdentifier* foundRecordIdentifier, bool& found) WARN_UNUSED_RETURN;
97
98     virtual bool createIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const String& name, const IDBKeyPath&, bool isUnique, bool isMultiEntry);
99     virtual void deleteIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId);
100     virtual void putIndexDataForRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const RecordIdentifier&);
101     virtual bool getPrimaryKeyViaIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, RefPtr<IDBKey>& primaryKey) WARN_UNUSED_RETURN;
102     virtual bool keyExistsInIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey, bool& exists) WARN_UNUSED_RETURN;
103
104     class Cursor : public RefCounted<Cursor> {
105     public:
106         enum IteratorState {
107             Ready = 0,
108             Seek
109         };
110
111         struct CursorOptions {
112             Vector<char> lowKey;
113             bool lowOpen;
114             Vector<char> highKey;
115             bool highOpen;
116             bool forward;
117             bool unique;
118         };
119
120         PassRefPtr<IDBKey> key() const { return m_currentKey; }
121         bool continueFunction(const IDBKey* = 0, IteratorState = Seek);
122         bool advance(unsigned long);
123         bool firstSeek();
124
125         virtual PassRefPtr<Cursor> clone() = 0;
126         virtual PassRefPtr<IDBKey> primaryKey() const { return m_currentKey; }
127         virtual PassRefPtr<SharedBuffer> value() const = 0;
128         virtual const RecordIdentifier& recordIdentifier() const { return m_recordIdentifier; }
129         virtual ~Cursor() { }
130         virtual bool loadCurrentRow() = 0;
131
132     protected:
133         Cursor(LevelDBTransaction* transaction, const CursorOptions& cursorOptions)
134             : m_transaction(transaction)
135             , m_cursorOptions(cursorOptions)
136         {
137         }
138         explicit Cursor(const IDBBackingStore::Cursor* other);
139
140         bool isPastBounds() const;
141         bool haveEnteredRange() const;
142
143         LevelDBTransaction* m_transaction;
144         const CursorOptions m_cursorOptions;
145         OwnPtr<LevelDBIterator> m_iterator;
146         RefPtr<IDBKey> m_currentKey;
147         IDBBackingStore::RecordIdentifier m_recordIdentifier;
148     };
149
150     virtual PassRefPtr<Cursor> openObjectStoreKeyCursor(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IndexedDB::CursorDirection);
151     virtual PassRefPtr<Cursor> openObjectStoreCursor(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IndexedDB::CursorDirection);
152     virtual PassRefPtr<Cursor> openIndexKeyCursor(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IndexedDB::CursorDirection);
153     virtual PassRefPtr<Cursor> openIndexCursor(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IndexedDB::CursorDirection);
154
155     class Transaction {
156     public:
157         explicit Transaction(IDBBackingStore*);
158         void begin();
159         bool commit();
160         void rollback();
161         void reset() { m_backingStore = 0; m_transaction = 0; }
162
163         static LevelDBTransaction* levelDBTransactionFrom(Transaction* transaction)
164         {
165             return static_cast<Transaction*>(transaction)->m_transaction.get();
166         }
167
168     private:
169         IDBBackingStore* m_backingStore;
170         RefPtr<LevelDBTransaction> m_transaction;
171     };
172
173 protected:
174     IDBBackingStore(const String& identifier, PassOwnPtr<LevelDBDatabase>);
175
176     // Should only used for mocking.
177     IDBBackingStore();
178
179 private:
180     bool findKeyInIndex(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, Vector<char>& foundEncodedPrimaryKey, bool& found);
181     void getIndexes(int64_t databaseId, int64_t objectStoreId, IDBObjectStoreMetadata::IndexMap*);
182
183     String m_identifier;
184
185     OwnPtr<LevelDBDatabase> m_db;
186     OwnPtr<LevelDBComparator> m_comparator;
187     WeakPtrFactory<IDBBackingStore> m_weakFactory;
188 };
189
190 } // namespace WebCore
191
192 #endif // ENABLE(INDEXED_DATABASE)
193
194 #endif // IDBBackingStore_h