[WebIDL] Remove (most) custom bindings for the IndexedDB code
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / server / MemoryIndexCursor.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 "MemoryIndexCursor.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBCursorInfo.h"
32 #include "IDBGetResult.h"
33 #include "IndexValueStore.h"
34 #include "Logging.h"
35 #include "MemoryCursor.h"
36 #include "MemoryIndex.h"
37 #include "MemoryObjectStore.h"
38
39 namespace WebCore {
40 namespace IDBServer {
41
42 MemoryIndexCursor::MemoryIndexCursor(MemoryIndex& index, const IDBCursorInfo& info)
43     : MemoryCursor(info)
44     , m_index(index)
45 {
46     LOG(IndexedDB, "MemoryIndexCursor::MemoryIndexCursor %s", info.range().loggingString().utf8().data());
47
48     auto* valueStore = m_index.valueStore();
49     if (!valueStore)
50         return;
51
52     if (m_info.isDirectionForward())
53         m_currentIterator = valueStore->find(m_info.range().lowerKey, m_info.range().lowerOpen);
54     else
55         m_currentIterator = valueStore->reverseFind(m_info.range().upperKey, m_info.duplicity(), m_info.range().upperOpen);
56
57     if (m_currentIterator.isValid() && m_info.range().containsKey(m_currentIterator.key())) {
58         m_currentKey = m_currentIterator.key();
59         m_currentPrimaryKey = m_currentIterator.primaryKey();
60         m_index.cursorDidBecomeClean(*this);
61     } else
62         m_currentIterator.invalidate();
63 }
64
65 MemoryIndexCursor::~MemoryIndexCursor()
66 {
67 }
68
69 void MemoryIndexCursor::currentData(IDBGetResult& getResult)
70 {
71     if (!m_currentIterator.isValid()) {
72         getResult = { };
73         return;
74     }
75
76     if (m_info.cursorType() == IndexedDB::CursorType::KeyOnly)
77         getResult = { m_currentKey, m_currentPrimaryKey };
78     else {
79         IDBValue value = { m_index.objectStore().valueForKey(m_currentPrimaryKey), { }, { } };
80         getResult = { m_currentKey, m_currentPrimaryKey, WTFMove(value) };
81     }
82 }
83
84 void MemoryIndexCursor::iterate(const IDBKeyData& key, const IDBKeyData& primaryKey, uint32_t count, IDBGetResult& getResult)
85 {
86     LOG(IndexedDB, "MemoryIndexCursor::iterate to key %s, %u count", key.loggingString().utf8().data(), count);
87
88 #ifndef NDEBUG
89     if (primaryKey.isValid())
90         ASSERT(key.isValid());
91 #endif
92
93     if (key.isValid()) {
94         // Cannot iterate by both a count and to a key
95         ASSERT(!count);
96
97         auto* valueStore = m_index.valueStore();
98         if (!valueStore) {
99             m_currentKey = { };
100             m_currentPrimaryKey = { };
101             getResult = { };
102             return;
103         }
104
105         if (primaryKey.isValid()) {
106             if (m_info.isDirectionForward())
107                 m_currentIterator = valueStore->find(key, primaryKey);
108             else
109                 m_currentIterator = valueStore->reverseFind(key, primaryKey, m_info.duplicity());
110         } else {
111             if (m_info.isDirectionForward())
112                 m_currentIterator = valueStore->find(key);
113             else
114                 m_currentIterator = valueStore->reverseFind(key, m_info.duplicity());
115         }
116
117         if (m_currentIterator.isValid() && !m_info.range().containsKey(m_currentIterator.key()))
118             m_currentIterator.invalidate();
119
120         if (!m_currentIterator.isValid()) {
121             m_currentKey = { };
122             m_currentPrimaryKey = { };
123             getResult = { };
124             return;
125         }
126
127         m_index.cursorDidBecomeClean(*this);
128
129         m_currentKey = m_currentIterator.key();
130         m_currentPrimaryKey = m_currentIterator.primaryKey();
131         currentData(getResult);
132
133         return;
134     }
135
136     // If there was not a valid key argument and no positive count argument
137     // that means the default iteration count of "1"
138     if (!count)
139         count = 1;
140
141     if (!m_currentIterator.isValid()) {
142         auto* valueStore = m_index.valueStore();
143         if (!valueStore) {
144             m_currentKey = { };
145             m_currentPrimaryKey = { };
146             getResult = { };
147             return;
148         }
149
150         switch (m_info.cursorDirection()) {
151         case IndexedDB::CursorDirection::Next:
152             m_currentIterator = valueStore->find(m_currentKey, m_currentPrimaryKey);
153             break;
154         case IndexedDB::CursorDirection::Nextunique:
155             m_currentIterator = valueStore->find(m_currentKey, true);
156             break;
157         case IndexedDB::CursorDirection::Prev:
158             m_currentIterator = valueStore->reverseFind(m_currentKey, m_currentPrimaryKey, m_info.duplicity());
159             break;
160         case IndexedDB::CursorDirection::Prevunique:
161             m_currentIterator = valueStore->reverseFind(m_currentKey, m_info.duplicity(), true);
162             break;
163         }
164
165         if (!m_currentIterator.isValid()) {
166             m_currentKey = { };
167             m_currentPrimaryKey = { };
168             getResult = { };
169             return;
170         }
171
172         m_index.cursorDidBecomeClean(*this);
173
174         // If we restored the current iterator and it does *not* match the current key/primaryKey,
175         // then it is the next record in line and we should consider that an iteration.
176         if (m_currentKey != m_currentIterator.key() || m_currentPrimaryKey != m_currentIterator.primaryKey())
177             --count;
178     }
179
180     ASSERT(m_currentIterator.isValid());
181
182     while (count) {
183         if (m_info.duplicity() == CursorDuplicity::NoDuplicates)
184             m_currentIterator.nextIndexEntry();
185         else
186             ++m_currentIterator;
187
188         if (!m_currentIterator.isValid())
189             break;
190
191         --count;
192     }
193
194     if (m_currentIterator.isValid() && !m_info.range().containsKey(m_currentIterator.key()))
195         m_currentIterator.invalidate();
196
197     // Not having a valid iterator after finishing any iteration means we've reached the end of the cursor.
198     if (!m_currentIterator.isValid()) {
199         m_currentKey = { };
200         m_currentPrimaryKey = { };
201         getResult = { };
202         return;
203     }
204
205     m_currentKey = m_currentIterator.key();
206     m_currentPrimaryKey = m_currentIterator.primaryKey();
207     currentData(getResult);
208 }
209
210 void MemoryIndexCursor::indexRecordsAllChanged()
211 {
212     m_currentIterator.invalidate();
213     m_index.cursorDidBecomeDirty(*this);
214 }
215
216 void MemoryIndexCursor::indexValueChanged(const IDBKeyData& key, const IDBKeyData& primaryKey)
217 {
218     if (m_currentKey != key || m_currentPrimaryKey != primaryKey)
219         return;
220
221     m_currentIterator.invalidate();
222     m_index.cursorDidBecomeDirty(*this);
223 }
224
225 } // namespace IDBServer
226 } // namespace WebCore
227
228 #endif // ENABLE(INDEXED_DATABASE)