1/*
2 * Copyright (C) 2015 Apple 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 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#if ENABLE(INDEXED_DATABASE)
29
30#include "IDBKeyData.h"
31#include "IDBObjectStoreInfo.h"
32#include "MemoryIndex.h"
33#include "MemoryObjectStoreCursor.h"
34#include "ThreadSafeDataBuffer.h"
35#include <wtf/HashMap.h>
36#include <wtf/RefCounted.h>
37
38namespace WebCore {
39
40class IDBCursorInfo;
41class IDBError;
42class IDBGetAllResult;
43class IDBKeyData;
44class IDBValue;
45
46struct IDBKeyRangeData;
47
48namespace IndexedDB {
49enum class GetAllType;
50enum class IndexRecordType;
51}
52
53namespace IDBServer {
54
55class MemoryBackingStoreTransaction;
56
57typedef HashMap<IDBKeyData, ThreadSafeDataBuffer, IDBKeyDataHash, IDBKeyDataHashTraits> KeyValueMap;
58
59class MemoryObjectStore : public RefCounted<MemoryObjectStore> {
60public:
61 static Ref<MemoryObjectStore> create(const IDBObjectStoreInfo&);
62
63 ~MemoryObjectStore();
64
65 void writeTransactionStarted(MemoryBackingStoreTransaction&);
66 void writeTransactionFinished(MemoryBackingStoreTransaction&);
67 MemoryBackingStoreTransaction* writeTransaction() { return m_writeTransaction; }
68
69 IDBError createIndex(MemoryBackingStoreTransaction&, const IDBIndexInfo&);
70 IDBError deleteIndex(MemoryBackingStoreTransaction&, uint64_t indexIdentifier);
71 void deleteAllIndexes(MemoryBackingStoreTransaction&);
72 void registerIndex(Ref<MemoryIndex>&&);
73
74 bool containsRecord(const IDBKeyData&);
75 void deleteRecord(const IDBKeyData&);
76 void deleteRange(const IDBKeyRangeData&);
77 IDBError addRecord(MemoryBackingStoreTransaction&, const IDBKeyData&, const IDBValue&);
78
79 uint64_t currentKeyGeneratorValue() const { return m_keyGeneratorValue; }
80 void setKeyGeneratorValue(uint64_t value) { m_keyGeneratorValue = value; }
81
82 void clear();
83 void replaceKeyValueStore(std::unique_ptr<KeyValueMap>&&, std::unique_ptr<IDBKeyDataSet>&&);
84
85 ThreadSafeDataBuffer valueForKey(const IDBKeyData&) const;
86 ThreadSafeDataBuffer valueForKeyRange(const IDBKeyRangeData&) const;
87 IDBKeyData lowestKeyWithRecordInRange(const IDBKeyRangeData&) const;
88 IDBGetResult indexValueForKeyRange(uint64_t indexIdentifier, IndexedDB::IndexRecordType, const IDBKeyRangeData&) const;
89 uint64_t countForKeyRange(uint64_t indexIdentifier, const IDBKeyRangeData&) const;
90
91 void getAllRecords(const IDBKeyRangeData&, Optional<uint32_t> count, IndexedDB::GetAllType, IDBGetAllResult&) const;
92
93 const IDBObjectStoreInfo& info() const { return m_info; }
94
95 MemoryObjectStoreCursor* maybeOpenCursor(const IDBCursorInfo&);
96
97 IDBKeyDataSet* orderedKeys() { return m_orderedKeys.get(); }
98
99 MemoryIndex* indexForIdentifier(uint64_t);
100
101 void maybeRestoreDeletedIndex(Ref<MemoryIndex>&&);
102
103 void rename(const String& newName) { m_info.rename(newName); }
104 void renameIndex(MemoryIndex&, const String& newName);
105
106private:
107 MemoryObjectStore(const IDBObjectStoreInfo&);
108
109 IDBKeyDataSet::iterator lowestIteratorInRange(const IDBKeyRangeData&, bool reverse) const;
110
111 IDBError populateIndexWithExistingRecords(MemoryIndex&);
112 IDBError updateIndexesForPutRecord(const IDBKeyData&, const ThreadSafeDataBuffer& value);
113 void updateIndexesForDeleteRecord(const IDBKeyData& value);
114 void updateCursorsForPutRecord(IDBKeyDataSet::iterator);
115 void updateCursorsForDeleteRecord(const IDBKeyData&);
116
117 RefPtr<MemoryIndex> takeIndexByIdentifier(uint64_t indexIdentifier);
118
119 IDBObjectStoreInfo m_info;
120
121 MemoryBackingStoreTransaction* m_writeTransaction { nullptr };
122 uint64_t m_keyGeneratorValue { 1 };
123
124 std::unique_ptr<KeyValueMap> m_keyValueStore;
125 std::unique_ptr<IDBKeyDataSet> m_orderedKeys;
126
127 void unregisterIndex(MemoryIndex&);
128 HashMap<uint64_t, RefPtr<MemoryIndex>> m_indexesByIdentifier;
129 HashMap<String, RefPtr<MemoryIndex>> m_indexesByName;
130 HashMap<IDBResourceIdentifier, std::unique_ptr<MemoryObjectStoreCursor>> m_cursors;
131};
132
133} // namespace IDBServer
134} // namespace WebCore
135
136#endif // ENABLE(INDEXED_DATABASE)
137