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