31e7f5d4e762fccdbda431679499dabaaabad0f4
[WebKit-https.git] / Source / WebCore / Modules / indexeddb / IDBIndex.cpp
1 /*
2  * Copyright (C) 2010 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 #include "config.h"
27 #include "IDBIndex.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBCursorBackendInterface.h"
32 #include "IDBDatabaseException.h"
33 #include "IDBIndexBackendInterface.h"
34 #include "IDBKey.h"
35 #include "IDBKeyRange.h"
36 #include "IDBObjectStore.h"
37 #include "IDBRequest.h"
38 #include "IDBTracing.h"
39 #include "IDBTransaction.h"
40
41 namespace WebCore {
42
43 static const unsigned short defaultDirection = IDBCursor::NEXT;
44
45 IDBIndex::IDBIndex(const IDBIndexMetadata& metadata, PassRefPtr<IDBIndexBackendInterface> backend, IDBObjectStore* objectStore, IDBTransaction* transaction)
46     : m_metadata(metadata)
47     , m_backend(backend)
48     , m_objectStore(objectStore)
49     , m_transaction(transaction)
50     , m_deleted(false)
51 {
52     ASSERT(m_backend);
53     ASSERT(m_objectStore);
54     ASSERT(m_transaction);
55 }
56
57 IDBIndex::~IDBIndex()
58 {
59 }
60
61 PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec)
62 {
63     IDB_TRACE("IDBIndex::openCursor");
64     if (m_deleted) {
65         ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
66         return 0;
67     }
68     unsigned short direction = IDBCursor::stringToDirection(directionString, ec);
69     if (ec)
70         return 0;
71
72     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
73     request->setCursorType(IDBCursorBackendInterface::IndexCursor);
74     m_backend->openCursor(keyRange, direction, request, m_transaction->backend(), ec);
75     if (ec) {
76         request->markEarlyDeath();
77         return 0;
78     }
79     return request;
80 }
81
82 PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, ExceptionCode& ec)
83 {
84     IDB_TRACE("IDBIndex::openCursor");
85     DEFINE_STATIC_LOCAL(String, consoleMessage, ("Numeric direction values are deprecated in IDBIndex.openCursor. Use \"next\", \"nextunique\", \"prev\", or \"prevunique\"."));
86     context->addConsoleMessage(JSMessageSource, LogMessageType, WarningMessageLevel, consoleMessage);
87     const String& directionString = IDBCursor::directionToString(direction, ec);
88     if (ec)
89         return 0;
90     return openCursor(context, keyRange, directionString, ec);
91 }
92
93 PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, const String& direction, ExceptionCode& ec)
94 {
95     IDB_TRACE("IDBIndex::openCursor");
96     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
97     if (ec)
98         return 0;
99     return openCursor(context, keyRange.release(), ec);
100 }
101
102 PassRefPtr<IDBRequest> IDBIndex::openCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, unsigned short direction, ExceptionCode& ec)
103 {
104     IDB_TRACE("IDBIndex::openCursor");
105     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
106     if (ec)
107         return 0;
108     return openCursor(context, keyRange.release(), ec);
109 }
110
111 PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
112 {
113     IDB_TRACE("IDBIndex::count");
114     if (m_deleted) {
115         ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
116         return 0;
117     }
118     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
119     m_backend->count(keyRange, request, m_transaction->backend(), ec);
120     if (ec) {
121         request->markEarlyDeath();
122         return 0;
123     }
124     return request;
125 }
126
127 PassRefPtr<IDBRequest> IDBIndex::count(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
128 {
129     IDB_TRACE("IDBIndex::count");
130     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
131     if (ec)
132         return 0;
133     return count(context, keyRange.release(), ec);
134 }
135
136 PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, const String& directionString, ExceptionCode& ec)
137 {
138     IDB_TRACE("IDBIndex::openKeyCursor");
139     if (m_deleted) {
140         ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
141         return 0;
142     }
143
144     unsigned short direction = IDBCursor::stringToDirection(directionString, ec);
145     if (ec)
146         return 0;
147
148     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
149     request->setCursorType(IDBCursorBackendInterface::IndexKeyCursor);
150     m_backend->openKeyCursor(keyRange, direction, request, m_transaction->backend(), ec);
151     if (ec) {
152         request->markEarlyDeath();
153         return 0;
154     }
155     return request;
156 }
157
158 PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, unsigned short direction, ExceptionCode& ec)
159 {
160     IDB_TRACE("IDBIndex::openKeyCursor");
161     DEFINE_STATIC_LOCAL(String, consoleMessage, ("Numeric direction values are deprecated in IDBIndex.openKeyCursor. Use \"next\", \"nextunique\", \"prev\", or \"prevunique\"."));
162     context->addConsoleMessage(JSMessageSource, LogMessageType, WarningMessageLevel, consoleMessage);
163     const String& directionString = IDBCursor::directionToString(direction, ec);
164     if (ec)
165         return 0;
166     return openKeyCursor(context, keyRange, directionString, ec);
167 }
168
169 PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, const String& direction, ExceptionCode& ec)
170 {
171     IDB_TRACE("IDBIndex::openKeyCursor");
172     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
173     if (ec)
174         return 0;
175     return openKeyCursor(context, keyRange.release(), ec);
176 }
177
178 PassRefPtr<IDBRequest> IDBIndex::openKeyCursor(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, unsigned short direction, ExceptionCode& ec)
179 {
180     IDB_TRACE("IDBIndex::openKeyCursor");
181     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
182     if (ec)
183         return 0;
184     return openKeyCursor(context, keyRange.release(), ec);
185 }
186
187 PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
188 {
189     IDB_TRACE("IDBIndex::get");
190     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
191     if (ec)
192         return 0;
193     return get(context, keyRange.release(), ec);
194 }
195
196 PassRefPtr<IDBRequest> IDBIndex::get(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
197 {
198     IDB_TRACE("IDBIndex::get");
199     if (m_deleted) {
200         ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
201         return 0;
202     }
203     if (!keyRange) {
204         ec = IDBDatabaseException::DATA_ERR;
205         return 0;
206     }
207
208     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
209     m_backend->get(keyRange, request, m_transaction->backend(), ec);
210     if (ec) {
211         request->markEarlyDeath();
212         return 0;
213     }
214     return request;
215 }
216
217 PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRefPtr<IDBKey> key, ExceptionCode& ec)
218 {
219     IDB_TRACE("IDBIndex::getKey");
220     RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(key, ec);
221     if (ec)
222         return 0;
223
224     return getKey(context, keyRange.release(), ec);
225 }
226
227 PassRefPtr<IDBRequest> IDBIndex::getKey(ScriptExecutionContext* context, PassRefPtr<IDBKeyRange> keyRange, ExceptionCode& ec)
228 {
229     IDB_TRACE("IDBIndex::getKey");
230     if (m_deleted) {
231         ec = IDBDatabaseException::IDB_INVALID_STATE_ERR;
232         return 0;
233     }
234     if (!keyRange) {
235         ec = IDBDatabaseException::DATA_ERR;
236         return 0;
237     }
238
239     RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this), m_transaction.get());
240     m_backend->getKey(keyRange, request, m_transaction->backend(), ec);
241     if (ec) {
242         request->markEarlyDeath();
243         return 0;
244     }
245     return request;
246 }
247
248 } // namespace WebCore
249
250 #endif // ENABLE(INDEXED_DATABASE)