Rework the way allowed argument classes are stored
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / MemoryObjectStore.cpp
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 #include "config.h"
27 #include "MemoryObjectStore.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBDatabaseException.h"
32 #include "IDBError.h"
33 #include "IDBKeyRangeData.h"
34 #include "Logging.h"
35 #include "MemoryBackingStoreTransaction.h"
36
37 namespace WebCore {
38 namespace IDBServer {
39
40 std::unique_ptr<MemoryObjectStore> MemoryObjectStore::create(const IDBObjectStoreInfo& info)
41 {
42     return std::make_unique<MemoryObjectStore>(info);
43 }
44
45 MemoryObjectStore::MemoryObjectStore(const IDBObjectStoreInfo& info)
46     : m_info(info)
47 {
48 }
49
50 MemoryObjectStore::~MemoryObjectStore()
51 {
52     ASSERT(!m_writeTransaction);
53 }
54
55 void MemoryObjectStore::writeTransactionStarted(MemoryBackingStoreTransaction& transaction)
56 {
57     LOG(IndexedDB, "MemoryObjectStore::writeTransactionStarted");
58
59     ASSERT(!m_writeTransaction);
60     m_writeTransaction = &transaction;
61 }
62
63 void MemoryObjectStore::writeTransactionFinished(MemoryBackingStoreTransaction& transaction)
64 {
65     LOG(IndexedDB, "MemoryObjectStore::writeTransactionFinished");
66
67     ASSERT_UNUSED(transaction, m_writeTransaction == &transaction);
68     m_writeTransaction = nullptr;
69 }
70
71 IDBError MemoryObjectStore::createIndex(MemoryBackingStoreTransaction& transaction, const IDBIndexInfo& info)
72 {
73     LOG(IndexedDB, "MemoryObjectStore::createIndex");
74
75     if (!m_writeTransaction || !m_writeTransaction->isVersionChange() || m_writeTransaction != &transaction)
76         return IDBError(IDBExceptionCode::ConstraintError);
77
78     ASSERT(!m_indexesByIdentifier.contains(info.identifier()));
79     auto index = MemoryIndex::create(info);
80
81     m_info.addExistingIndex(info);
82
83     transaction.addNewIndex(*index);
84     registerIndex(WTF::move(index));
85
86     return { };
87 }
88
89 bool MemoryObjectStore::containsRecord(const IDBKeyData& key)
90 {
91     if (!m_keyValueStore)
92         return false;
93
94     return m_keyValueStore->contains(key);
95 }
96
97 void MemoryObjectStore::clear()
98 {
99     LOG(IndexedDB, "MemoryObjectStore::clear");
100     ASSERT(m_writeTransaction);
101
102     m_writeTransaction->objectStoreCleared(*this, WTF::move(m_keyValueStore));
103 }
104
105 void MemoryObjectStore::replaceKeyValueStore(std::unique_ptr<KeyValueMap>&& store)
106 {
107     ASSERT(m_writeTransaction);
108     ASSERT(m_writeTransaction->isAborting());
109
110     m_keyValueStore = WTF::move(store);
111 }
112
113 void MemoryObjectStore::deleteRecord(const IDBKeyData& key)
114 {
115     LOG(IndexedDB, "MemoryObjectStore::deleteRecord");
116
117     ASSERT(m_writeTransaction);
118     m_writeTransaction->recordValueChanged(*this, key);
119
120     if (!m_keyValueStore)
121         return;
122
123     ASSERT(m_orderedKeys);
124
125     m_keyValueStore->remove(key);
126     m_orderedKeys->erase(key);
127 }
128
129 void MemoryObjectStore::deleteRange(const IDBKeyRangeData& inputRange)
130 {
131     LOG(IndexedDB, "MemoryObjectStore::deleteRange");
132
133     ASSERT(m_writeTransaction);
134
135     if (inputRange.isExactlyOneKey()) {
136         deleteRecord(inputRange.lowerKey);
137         return;
138     }
139
140     IDBKeyRangeData range = inputRange;
141     while (true) {
142         auto key = lowestKeyWithRecordInRange(range);
143         if (key.isNull())
144             break;
145
146         deleteRecord(key);
147
148         range.lowerKey = key;
149         range.lowerOpen = true;
150     }
151 }
152
153 void MemoryObjectStore::putRecord(MemoryBackingStoreTransaction& transaction, const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
154 {
155     LOG(IndexedDB, "MemoryObjectStore::putRecord");
156
157     ASSERT(m_writeTransaction);
158     ASSERT_UNUSED(transaction, m_writeTransaction == &transaction);
159
160     m_writeTransaction->recordValueChanged(*this, keyData);
161
162     setKeyValue(keyData, value);
163 }
164
165 void MemoryObjectStore::setKeyValue(const IDBKeyData& keyData, const ThreadSafeDataBuffer& value)
166 {
167     if (!m_keyValueStore) {
168         ASSERT(!m_orderedKeys);
169         m_keyValueStore = std::make_unique<KeyValueMap>();
170         m_orderedKeys = std::make_unique<std::set<IDBKeyData>>();
171     }
172
173     auto result = m_keyValueStore->set(keyData, value);
174     if (result.isNewEntry)
175         m_orderedKeys->insert(keyData);
176 }
177
178 uint64_t MemoryObjectStore::countForKeyRange(uint64_t indexIdentifier, const IDBKeyRangeData& inRange) const
179 {
180     LOG(IndexedDB, "MemoryObjectStore::countForKeyRange");
181
182     if (indexIdentifier) {
183         auto* index = m_indexesByIdentifier.get(indexIdentifier);
184         ASSERT(index);
185         return index->countForKeyRange(inRange);
186     }
187
188     if (!m_keyValueStore)
189         return 0;
190
191     uint64_t count = 0;
192     IDBKeyRangeData range = inRange;
193     while (true) {
194         auto key = lowestKeyWithRecordInRange(range);
195         if (key.isNull())
196             break;
197
198         ++count;
199         range.lowerKey = key;
200         range.lowerOpen = true;
201     }
202
203     return count;
204 }
205
206 ThreadSafeDataBuffer MemoryObjectStore::valueForKeyRange(const IDBKeyRangeData& keyRangeData) const
207 {
208     LOG(IndexedDB, "MemoryObjectStore::valueForKey");
209
210     IDBKeyData key = lowestKeyWithRecordInRange(keyRangeData);
211     if (key.isNull())
212         return ThreadSafeDataBuffer();
213
214     ASSERT(m_keyValueStore);
215     return m_keyValueStore->get(key);
216 }
217
218 IDBGetResult MemoryObjectStore::indexValueForKeyRange(uint64_t indexIdentifier, IndexedDB::IndexRecordType recordType, const IDBKeyRangeData& range) const
219 {
220     LOG(IndexedDB, "MemoryObjectStore::indexValueForKeyRange");
221
222     auto* index = m_indexesByIdentifier.get(indexIdentifier);
223     ASSERT(index);
224     return index->valueForKeyRange(recordType, range);
225 }
226
227 IDBKeyData MemoryObjectStore::lowestKeyWithRecordInRange(const IDBKeyRangeData& keyRangeData) const
228 {
229     if (!m_keyValueStore)
230         return { };
231
232     if (keyRangeData.isExactlyOneKey() && m_keyValueStore->contains(keyRangeData.lowerKey))
233         return keyRangeData.lowerKey;
234
235     ASSERT(m_orderedKeys);
236
237     auto lowestInRange = m_orderedKeys->lower_bound(keyRangeData.lowerKey);
238
239     if (lowestInRange == m_orderedKeys->end())
240         return { };
241
242     if (keyRangeData.lowerOpen && *lowestInRange == keyRangeData.lowerKey)
243         ++lowestInRange;
244
245     if (lowestInRange == m_orderedKeys->end())
246         return { };
247
248     if (!keyRangeData.upperKey.isNull()) {
249         if (lowestInRange->compare(keyRangeData.upperKey) > 0)
250             return { };
251         if (keyRangeData.upperOpen && *lowestInRange == keyRangeData.upperKey)
252             return { };
253     }
254
255     return *lowestInRange;
256 }
257
258 void MemoryObjectStore::registerIndex(std::unique_ptr<MemoryIndex>&& index)
259 {
260     ASSERT(index);
261     ASSERT(!m_indexesByIdentifier.contains(index->info().identifier()));
262     ASSERT(!m_indexesByName.contains(index->info().name()));
263
264     m_indexesByName.set(index->info().name(), index.get());
265     m_indexesByIdentifier.set(index->info().identifier(), WTF::move(index));
266 }
267
268 void MemoryObjectStore::unregisterIndex(MemoryIndex& index)
269 {
270     ASSERT(m_indexesByIdentifier.contains(index.info().identifier()));
271     ASSERT(m_indexesByName.contains(index.info().name()));
272
273     m_indexesByName.remove(index.info().name());
274     m_indexesByIdentifier.remove(index.info().identifier());
275 }
276
277 } // namespace IDBServer
278 } // namespace WebCore
279
280 #endif // ENABLE(INDEXED_DATABASE)