OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
11 * notice, this list of conditions and the following disclaimer in the | 11 * notice, this list of conditions and the following disclaimer in the |
12 * documentation and/or other materials provided with the distribution. | 12 * documentation and/or other materials provided with the distribution. |
13 * | 13 * |
14 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | 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 | 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 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 | 17 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
19 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 */ | 24 */ |
25 | 25 |
26 #include "config.h" | 26 #include "config.h" |
27 #include "modules/indexeddb/IDBCursor.h" | 27 #include "modules/indexeddb/IDBCursor.h" |
28 | 28 |
29 #include "bindings/v8/ExceptionMessages.h" | |
30 #include "bindings/v8/ExceptionState.h" | 29 #include "bindings/v8/ExceptionState.h" |
31 #include "bindings/v8/IDBBindingUtilities.h" | 30 #include "bindings/v8/IDBBindingUtilities.h" |
32 #include "core/dom/ExceptionCode.h" | 31 #include "core/dom/ExceptionCode.h" |
33 #include "core/dom/ExecutionContext.h" | 32 #include "core/dom/ExecutionContext.h" |
34 #include "core/inspector/ScriptCallStack.h" | 33 #include "core/inspector/ScriptCallStack.h" |
35 #include "modules/indexeddb/IDBAny.h" | 34 #include "modules/indexeddb/IDBAny.h" |
36 #include "modules/indexeddb/IDBDatabase.h" | 35 #include "modules/indexeddb/IDBDatabase.h" |
37 #include "modules/indexeddb/IDBKey.h" | 36 #include "modules/indexeddb/IDBKey.h" |
38 #include "modules/indexeddb/IDBObjectStore.h" | 37 #include "modules/indexeddb/IDBObjectStore.h" |
39 #include "modules/indexeddb/IDBRequest.h" | 38 #include "modules/indexeddb/IDBRequest.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 | 100 |
102 IDBCursor::~IDBCursor() | 101 IDBCursor::~IDBCursor() |
103 { | 102 { |
104 } | 103 } |
105 | 104 |
106 PassRefPtr<IDBRequest> IDBCursor::update(ScriptState* state, ScriptValue& value,
ExceptionState& exceptionState) | 105 PassRefPtr<IDBRequest> IDBCursor::update(ScriptState* state, ScriptValue& value,
ExceptionState& exceptionState) |
107 { | 106 { |
108 IDB_TRACE("IDBCursor::update"); | 107 IDB_TRACE("IDBCursor::update"); |
109 | 108 |
110 if (!m_gotValue) { | 109 if (!m_gotValue) { |
111 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("update", "IDBCursor", IDBDatabase::noValueErrorMessage)); | 110 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValue
ErrorMessage); |
112 return 0; | 111 return 0; |
113 } | 112 } |
114 if (isKeyCursor()) { | 113 if (isKeyCursor()) { |
115 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("update", "IDBCursor", IDBDatabase::isKeyCursorErrorMessage)); | 114 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::isKeyCu
rsorErrorMessage); |
116 return 0; | 115 return 0; |
117 } | 116 } |
118 if (isDeleted()) { | 117 if (isDeleted()) { |
119 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("update", "IDBCursor", IDBDatabase::sourceDeletedErrorMessage)); | 118 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceD
eletedErrorMessage); |
120 return 0; | 119 return 0; |
121 } | 120 } |
122 if (m_transaction->isFinished()) { | 121 if (m_transaction->isFinished()) { |
123 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("update", "IDBCursor", IDBDatabase::transactionFinishedErr
orMessage)); | 122 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionFinishedErrorMessage); |
124 return 0; | 123 return 0; |
125 } | 124 } |
126 if (!m_transaction->isActive()) { | 125 if (!m_transaction->isActive()) { |
127 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("update", "IDBCursor", IDBDatabase::transactionInactiveErr
orMessage)); | 126 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionInactiveErrorMessage); |
128 return 0; | 127 return 0; |
129 } | 128 } |
130 if (m_transaction->isReadOnly()) { | 129 if (m_transaction->isReadOnly()) { |
131 exceptionState.throwDOMException(ReadOnlyError, ExceptionMessages::faile
dToExecute("update", "IDBCursor", "The record may not be updated inside a read-o
nly transaction.")); | 130 exceptionState.throwDOMException(ReadOnlyError, "The record may not be u
pdated inside a read-only transaction."); |
132 return 0; | 131 return 0; |
133 } | 132 } |
134 | 133 |
135 RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); | 134 RefPtr<IDBObjectStore> objectStore = effectiveObjectStore(); |
136 const IDBKeyPath& keyPath = objectStore->metadata().keyPath; | 135 const IDBKeyPath& keyPath = objectStore->metadata().keyPath; |
137 const bool usesInLineKeys = !keyPath.isNull(); | 136 const bool usesInLineKeys = !keyPath.isNull(); |
138 if (usesInLineKeys) { | 137 if (usesInLineKeys) { |
139 RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(m_requ
est->requestState(), value, keyPath); | 138 RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(m_requ
est->requestState(), value, keyPath); |
140 if (!keyPathKey || !keyPathKey->isEqual(m_primaryKey.get())) { | 139 if (!keyPathKey || !keyPathKey->isEqual(m_primaryKey.get())) { |
141 exceptionState.throwDOMException(DataError, ExceptionMessages::faile
dToExecute("update", "IDBCursor", "The effective object store of this cursor use
s in-line keys and evaluating the key path of the value parameter results in a d
ifferent value than the cursor's effective key.")); | 140 exceptionState.throwDOMException(DataError, "The effective object st
ore of this cursor uses in-line keys and evaluating the key path of the value pa
rameter results in a different value than the cursor's effective key."); |
142 return 0; | 141 return 0; |
143 } | 142 } |
144 } | 143 } |
145 | 144 |
146 return objectStore->put(WebIDBDatabase::CursorUpdate, IDBAny::create(this),
state, value, m_primaryKey, exceptionState); | 145 return objectStore->put(WebIDBDatabase::CursorUpdate, IDBAny::create(this),
state, value, m_primaryKey, exceptionState); |
147 } | 146 } |
148 | 147 |
149 void IDBCursor::advance(unsigned long count, ExceptionState& exceptionState) | 148 void IDBCursor::advance(unsigned long count, ExceptionState& exceptionState) |
150 { | 149 { |
151 IDB_TRACE("IDBCursor::advance"); | 150 IDB_TRACE("IDBCursor::advance"); |
152 if (!m_gotValue) { | 151 if (!m_gotValue) { |
153 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("advance", "IDBCursor", IDBDatabase::noValueErrorMessage)); | 152 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValue
ErrorMessage); |
154 return; | 153 return; |
155 } | 154 } |
156 if (isDeleted()) { | 155 if (isDeleted()) { |
157 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("advance", "IDBCursor", IDBDatabase::sourceDeletedErrorMessage)); | 156 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceD
eletedErrorMessage); |
158 return; | 157 return; |
159 } | 158 } |
160 | 159 |
161 if (m_transaction->isFinished()) { | 160 if (m_transaction->isFinished()) { |
162 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("advance", "IDBCursor", IDBDatabase::transactionFinishedEr
rorMessage)); | 161 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionFinishedErrorMessage); |
163 return; | 162 return; |
164 } | 163 } |
165 if (!m_transaction->isActive()) { | 164 if (!m_transaction->isActive()) { |
166 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("advance", "IDBCursor", IDBDatabase::transactionInactiveEr
rorMessage)); | 165 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionInactiveErrorMessage); |
167 return; | 166 return; |
168 } | 167 } |
169 | 168 |
170 if (!count) { | 169 if (!count) { |
171 exceptionState.throwUninformativeAndGenericTypeError(); | 170 exceptionState.throwUninformativeAndGenericTypeError(); |
172 return; | 171 return; |
173 } | 172 } |
174 | 173 |
175 m_request->setPendingCursor(this); | 174 m_request->setPendingCursor(this); |
176 m_gotValue = false; | 175 m_gotValue = false; |
177 m_backend->advance(count, WebIDBCallbacksImpl::create(m_request).leakPtr()); | 176 m_backend->advance(count, WebIDBCallbacksImpl::create(m_request).leakPtr()); |
178 } | 177 } |
179 | 178 |
180 void IDBCursor::continueFunction(ExecutionContext* context, const ScriptValue& k
eyValue, ExceptionState& exceptionState) | 179 void IDBCursor::continueFunction(ExecutionContext* context, const ScriptValue& k
eyValue, ExceptionState& exceptionState) |
181 { | 180 { |
182 DOMRequestState requestState(context); | 181 DOMRequestState requestState(context); |
183 RefPtr<IDBKey> key = keyValue.isUndefined() ? 0 : scriptValueToIDBKey(&reque
stState, keyValue); | 182 RefPtr<IDBKey> key = keyValue.isUndefined() ? 0 : scriptValueToIDBKey(&reque
stState, keyValue); |
184 continueFunction(key.release(), exceptionState); | 183 continueFunction(key.release(), exceptionState); |
185 } | 184 } |
186 | 185 |
187 void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionState& excepti
onState) | 186 void IDBCursor::continueFunction(PassRefPtr<IDBKey> key, ExceptionState& excepti
onState) |
188 { | 187 { |
189 IDB_TRACE("IDBCursor::continue"); | 188 IDB_TRACE("IDBCursor::continue"); |
190 if (key && !key->isValid()) { | 189 if (key && !key->isValid()) { |
191 exceptionState.throwDOMException(DataError, ExceptionMessages::failedToE
xecute("continue", "IDBCursor", IDBDatabase::notValidKeyErrorMessage)); | 190 exceptionState.throwDOMException(DataError, IDBDatabase::notValidKeyErro
rMessage); |
192 return; | 191 return; |
193 } | 192 } |
194 | 193 |
195 if (m_transaction->isFinished()) { | 194 if (m_transaction->isFinished()) { |
196 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("continue", "IDBCursor", IDBDatabase::transactionFinishedE
rrorMessage)); | 195 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionFinishedErrorMessage); |
197 return; | 196 return; |
198 } | 197 } |
199 if (!m_transaction->isActive()) { | 198 if (!m_transaction->isActive()) { |
200 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("continue", "IDBCursor", IDBDatabase::transactionInactiveE
rrorMessage)); | 199 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionInactiveErrorMessage); |
201 return; | 200 return; |
202 } | 201 } |
203 | 202 |
204 if (!m_gotValue) { | 203 if (!m_gotValue) { |
205 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("continue", "IDBCursor", IDBDatabase::noValueErrorMessage)); | 204 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValue
ErrorMessage); |
206 return; | 205 return; |
207 } | 206 } |
208 | 207 |
209 if (isDeleted()) { | 208 if (isDeleted()) { |
210 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("continue", "IDBCursor", IDBDatabase::sourceDeletedErrorMessage))
; | 209 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceD
eletedErrorMessage); |
211 return; | 210 return; |
212 } | 211 } |
213 | 212 |
214 if (key) { | 213 if (key) { |
215 ASSERT(m_key); | 214 ASSERT(m_key); |
216 if (m_direction == IndexedDB::CursorNext || m_direction == IndexedDB::Cu
rsorNextNoDuplicate) { | 215 if (m_direction == IndexedDB::CursorNext || m_direction == IndexedDB::Cu
rsorNextNoDuplicate) { |
217 if (!m_key->isLessThan(key.get())) { | 216 if (!m_key->isLessThan(key.get())) { |
218 exceptionState.throwDOMException(DataError, ExceptionMessages::f
ailedToExecute("continue", "IDBCursor", "The parameter is less than or equal to
this cursor's position.")); | 217 exceptionState.throwDOMException(DataError, "The parameter is le
ss than or equal to this cursor's position."); |
219 return; | 218 return; |
220 } | 219 } |
221 } else { | 220 } else { |
222 if (!key->isLessThan(m_key.get())) { | 221 if (!key->isLessThan(m_key.get())) { |
223 exceptionState.throwDOMException(DataError, ExceptionMessages::f
ailedToExecute("continue", "IDBCursor", "The parameter is greater than or equal
to this cursor's position.")); | 222 exceptionState.throwDOMException(DataError, "The parameter is gr
eater than or equal to this cursor's position."); |
224 return; | 223 return; |
225 } | 224 } |
226 } | 225 } |
227 } | 226 } |
228 | 227 |
229 // FIXME: We're not using the context from when continue was called, which m
eans the callback | 228 // FIXME: We're not using the context from when continue was called, which m
eans the callback |
230 // will be on the original context openCursor was called on. Is this
right? | 229 // will be on the original context openCursor was called on. Is this
right? |
231 m_request->setPendingCursor(this); | 230 m_request->setPendingCursor(this); |
232 m_gotValue = false; | 231 m_gotValue = false; |
233 m_backend->continueFunction(key, WebIDBCallbacksImpl::create(m_request).leak
Ptr()); | 232 m_backend->continueFunction(key, WebIDBCallbacksImpl::create(m_request).leak
Ptr()); |
234 } | 233 } |
235 | 234 |
236 PassRefPtr<IDBRequest> IDBCursor::deleteFunction(ExecutionContext* context, Exce
ptionState& exceptionState) | 235 PassRefPtr<IDBRequest> IDBCursor::deleteFunction(ExecutionContext* context, Exce
ptionState& exceptionState) |
237 { | 236 { |
238 IDB_TRACE("IDBCursor::delete"); | 237 IDB_TRACE("IDBCursor::delete"); |
239 if (m_transaction->isFinished()) { | 238 if (m_transaction->isFinished()) { |
240 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("delete", "IDBCursor", IDBDatabase::transactionFinishedErr
orMessage)); | 239 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionFinishedErrorMessage); |
241 return 0; | 240 return 0; |
242 } | 241 } |
243 if (!m_transaction->isActive()) { | 242 if (!m_transaction->isActive()) { |
244 exceptionState.throwDOMException(TransactionInactiveError, ExceptionMess
ages::failedToExecute("delete", "IDBCursor", IDBDatabase::transactionInactiveErr
orMessage)); | 243 exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::
transactionInactiveErrorMessage); |
245 return 0; | 244 return 0; |
246 } | 245 } |
247 if (m_transaction->isReadOnly()) { | 246 if (m_transaction->isReadOnly()) { |
248 exceptionState.throwDOMException(ReadOnlyError, ExceptionMessages::faile
dToExecute("delete", "IDBCursor", "The record may not be deleted inside a read-o
nly transaction.")); | 247 exceptionState.throwDOMException(ReadOnlyError, "The record may not be d
eleted inside a read-only transaction."); |
249 return 0; | 248 return 0; |
250 } | 249 } |
251 | 250 |
252 if (!m_gotValue) { | 251 if (!m_gotValue) { |
253 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("delete", "IDBCursor", IDBDatabase::noValueErrorMessage)); | 252 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValue
ErrorMessage); |
254 return 0; | 253 return 0; |
255 } | 254 } |
256 if (isKeyCursor()) { | 255 if (isKeyCursor()) { |
257 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("delete", "IDBCursor", IDBDatabase::isKeyCursorErrorMessage)); | 256 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::isKeyCu
rsorErrorMessage); |
258 return 0; | 257 return 0; |
259 } | 258 } |
260 if (isDeleted()) { | 259 if (isDeleted()) { |
261 exceptionState.throwDOMException(InvalidStateError, ExceptionMessages::f
ailedToExecute("delete", "IDBCursor", IDBDatabase::sourceDeletedErrorMessage)); | 260 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceD
eletedErrorMessage); |
262 return 0; | 261 return 0; |
263 } | 262 } |
264 | 263 |
265 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(m_primaryKey, exceptionStat
e); | 264 RefPtr<IDBKeyRange> keyRange = IDBKeyRange::only(m_primaryKey, exceptionStat
e); |
266 ASSERT(!exceptionState.hadException()); | 265 ASSERT(!exceptionState.hadException()); |
267 | 266 |
268 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this
), m_transaction.get()); | 267 RefPtr<IDBRequest> request = IDBRequest::create(context, IDBAny::create(this
), m_transaction.get()); |
269 m_transaction->backendDB()->deleteRange(m_transaction->id(), effectiveObject
Store()->id(), keyRange.release(), WebIDBCallbacksImpl::create(request).leakPtr(
)); | 268 m_transaction->backendDB()->deleteRange(m_transaction->id(), effectiveObject
Store()->id(), keyRange.release(), WebIDBCallbacksImpl::create(request).leakPtr(
)); |
270 return request.release(); | 269 return request.release(); |
271 } | 270 } |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 case IndexedDB::CursorPrevNoDuplicate: | 398 case IndexedDB::CursorPrevNoDuplicate: |
400 return IDBCursor::directionPrevUnique(); | 399 return IDBCursor::directionPrevUnique(); |
401 | 400 |
402 default: | 401 default: |
403 ASSERT_NOT_REACHED(); | 402 ASSERT_NOT_REACHED(); |
404 return IDBCursor::directionNext(); | 403 return IDBCursor::directionNext(); |
405 } | 404 } |
406 } | 405 } |
407 | 406 |
408 } // namespace WebCore | 407 } // namespace WebCore |
OLD | NEW |