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