Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: Source/modules/indexeddb/IDBRequest.cpp

Issue 18590006: Blob support for IDB [Blink] (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: small cleanup Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
(...skipping 22 matching lines...) Expand all
33 #include "bindings/v8/ExceptionStatePlaceholder.h" 33 #include "bindings/v8/ExceptionStatePlaceholder.h"
34 #include "bindings/v8/IDBBindingUtilities.h" 34 #include "bindings/v8/IDBBindingUtilities.h"
35 #include "core/dom/ExecutionContext.h" 35 #include "core/dom/ExecutionContext.h"
36 #include "core/events/EventQueue.h" 36 #include "core/events/EventQueue.h"
37 #include "modules/indexeddb/IDBCursorWithValue.h" 37 #include "modules/indexeddb/IDBCursorWithValue.h"
38 #include "modules/indexeddb/IDBDatabase.h" 38 #include "modules/indexeddb/IDBDatabase.h"
39 #include "modules/indexeddb/IDBEventDispatcher.h" 39 #include "modules/indexeddb/IDBEventDispatcher.h"
40 #include "modules/indexeddb/IDBTracing.h" 40 #include "modules/indexeddb/IDBTracing.h"
41 #include "modules/indexeddb/IDBTransaction.h" 41 #include "modules/indexeddb/IDBTransaction.h"
42 #include "platform/SharedBuffer.h" 42 #include "platform/SharedBuffer.h"
43 #include "platform/blob/BlobInfo.h"
43 #include "public/platform/WebIDBCursor.h" 44 #include "public/platform/WebIDBCursor.h"
44 45
45 namespace WebCore { 46 namespace WebCore {
46 47
47 PassRefPtr<IDBRequest> IDBRequest::create(ExecutionContext* context, PassRefPtr< IDBAny> source, IDBTransaction* transaction) 48 PassRefPtr<IDBRequest> IDBRequest::create(ExecutionContext* context, PassRefPtr< IDBAny> source, IDBTransaction* transaction)
48 { 49 {
49 RefPtr<IDBRequest> request(adoptRef(new IDBRequest(context, source, transact ion))); 50 RefPtr<IDBRequest> request(adoptRef(new IDBRequest(context, source, transact ion)));
50 request->suspendIfNeeded(); 51 request->suspendIfNeeded();
51 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames ) are not associated with transactions. 52 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames ) are not associated with transactions.
52 if (transaction) 53 if (transaction)
(...skipping 16 matching lines...) Expand all
69 , m_preventPropagation(false) 70 , m_preventPropagation(false)
70 , m_resultDirty(true) 71 , m_resultDirty(true)
71 , m_requestState(context) 72 , m_requestState(context)
72 { 73 {
73 ScriptWrappable::init(this); 74 ScriptWrappable::init(this);
74 } 75 }
75 76
76 IDBRequest::~IDBRequest() 77 IDBRequest::~IDBRequest()
77 { 78 {
78 ASSERT(m_readyState == DONE || m_readyState == EarlyDeath || !executionConte xt()); 79 ASSERT(m_readyState == DONE || m_readyState == EarlyDeath || !executionConte xt());
80 handleBlobAcks();
79 } 81 }
80 82
81 ScriptValue IDBRequest::result(ExceptionState& exceptionState) 83 ScriptValue IDBRequest::result(ExceptionState& exceptionState)
82 { 84 {
83 if (m_readyState != DONE) { 85 if (m_readyState != DONE) {
84 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::request NotFinishedErrorMessage); 86 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::request NotFinishedErrorMessage);
85 return ScriptValue(); 87 return ScriptValue();
86 } 88 }
87 m_resultDirty = false; 89 m_resultDirty = false;
88 return idbAnyToScriptValue(&m_requestState, m_result); 90 ScriptValue value = idbAnyToScriptValue(&m_requestState, m_result);
91 handleBlobAcks();
92 return value;
89 } 93 }
90 94
91 PassRefPtr<DOMError> IDBRequest::error(ExceptionState& exceptionState) const 95 PassRefPtr<DOMError> IDBRequest::error(ExceptionState& exceptionState) const
92 { 96 {
93 if (m_readyState != DONE) { 97 if (m_readyState != DONE) {
94 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::request NotFinishedErrorMessage); 98 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::request NotFinishedErrorMessage);
95 return 0; 99 return 0;
96 } 100 }
97 return m_error; 101 return m_error;
98 } 102 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 { 186 {
183 if (!m_result) 187 if (!m_result)
184 return 0; 188 return 0;
185 if (m_result->type() == IDBAny::IDBCursorType) 189 if (m_result->type() == IDBAny::IDBCursorType)
186 return m_result->idbCursor(); 190 return m_result->idbCursor();
187 if (m_result->type() == IDBAny::IDBCursorWithValueType) 191 if (m_result->type() == IDBAny::IDBCursorWithValueType)
188 return m_result->idbCursorWithValue(); 192 return m_result->idbCursorWithValue();
189 return 0; 193 return 0;
190 } 194 }
191 195
192 void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey > key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value) 196 void IDBRequest::ackReceivedBlobs(const Vector<BlobInfo>* blobInfo)
197 {
198 ASSERT(blobInfo);
199 if (!blobInfo->size())
200 return;
201 Vector<BlobInfo>::const_iterator iter;
202 Vector<String> uuids;
203 uuids.reserveCapacity(blobInfo->size());
204 for (iter = blobInfo->begin(); iter != blobInfo->end(); ++iter) {
205 uuids.append(iter->uuid());
206 }
207 m_transaction->db()->backend()->ackReceivedBlobs(uuids);
208 }
209
210 void IDBRequest::setResultCursor(PassRefPtr<IDBCursor> cursor, PassRefPtr<IDBKey > key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value, PassOwnPtr <Vector<BlobInfo> > blobInfo)
193 { 211 {
194 ASSERT(m_readyState == PENDING); 212 ASSERT(m_readyState == PENDING);
195 m_cursorKey = key; 213 m_cursorKey = key;
196 m_cursorPrimaryKey = primaryKey; 214 m_cursorPrimaryKey = primaryKey;
197 m_cursorValue = value; 215 m_cursorValue = value;
216 ASSERT(!m_blobInfo.get());
217 m_blobInfo = blobInfo;
198 218
199 onSuccessInternal(IDBAny::create(cursor)); 219 onSuccessInternal(IDBAny::create(cursor));
200 } 220 }
201 221
202 void IDBRequest::checkForReferenceCycle() 222 void IDBRequest::checkForReferenceCycle()
203 { 223 {
204 // If this request and its cursor have the only references 224 // If this request and its cursor have the only references
205 // to each other, then explicitly break the cycle. 225 // to each other, then explicitly break the cycle.
206 IDBCursor* cursor = getResultCursor(); 226 IDBCursor* cursor = getResultCursor();
207 if (!cursor || cursor->request() != this) 227 if (!cursor || cursor->request() != this)
208 return; 228 return;
209 229
210 if (!hasOneRef() || !cursor->hasOneRef()) 230 if (!hasOneRef() || !cursor->hasOneRef())
211 return; 231 return;
212 232
213 m_result.clear(); 233 m_result.clear();
214 } 234 }
215 235
236 void IDBRequest::handleBlobAcks()
237 {
238 if (m_blobInfo.get()) {
239 ackReceivedBlobs(m_blobInfo.get());
240 m_blobInfo.clear();
241 }
242 }
243
216 bool IDBRequest::shouldEnqueueEvent() const 244 bool IDBRequest::shouldEnqueueEvent() const
217 { 245 {
218 if (m_contextStopped || !executionContext()) 246 if (m_contextStopped || !executionContext())
219 return false; 247 return false;
220 ASSERT(m_readyState == PENDING || m_readyState == DONE); 248 ASSERT(m_readyState == PENDING || m_readyState == DONE);
221 if (m_requestAborted) 249 if (m_requestAborted)
222 return false; 250 return false;
223 ASSERT(m_readyState == PENDING); 251 ASSERT(m_readyState == PENDING);
224 ASSERT(!m_error && !m_result); 252 ASSERT(!m_error && !m_result);
225 return true; 253 return true;
(...skipping 15 matching lines...) Expand all
241 IDB_TRACE("IDBRequest::onSuccess(StringList)"); 269 IDB_TRACE("IDBRequest::onSuccess(StringList)");
242 if (!shouldEnqueueEvent()) 270 if (!shouldEnqueueEvent())
243 return; 271 return;
244 272
245 RefPtr<DOMStringList> domStringList = DOMStringList::create(); 273 RefPtr<DOMStringList> domStringList = DOMStringList::create();
246 for (size_t i = 0; i < stringList.size(); ++i) 274 for (size_t i = 0; i < stringList.size(); ++i)
247 domStringList->append(stringList[i]); 275 domStringList->append(stringList[i]);
248 onSuccessInternal(IDBAny::create(domStringList.release())); 276 onSuccessInternal(IDBAny::create(domStringList.release()));
249 } 277 }
250 278
251 void IDBRequest::onSuccess(PassOwnPtr<blink::WebIDBCursor> backend, PassRefPtr<I DBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value) 279 void IDBRequest::onSuccess(PassOwnPtr<blink::WebIDBCursor> backend, PassRefPtr<I DBKey> key, PassRefPtr<IDBKey> primaryKey, PassRefPtr<SharedBuffer> value, PassO wnPtr<Vector<BlobInfo> > blobInfo)
252 { 280 {
253 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); 281 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)");
254 if (!shouldEnqueueEvent()) 282 if (!shouldEnqueueEvent())
255 return; 283 return;
256 284
257 ASSERT(!m_pendingCursor); 285 ASSERT(!m_pendingCursor);
258 RefPtr<IDBCursor> cursor; 286 RefPtr<IDBCursor> cursor;
259 switch (m_cursorType) { 287 switch (m_cursorType) {
260 case IndexedDB::CursorKeyOnly: 288 case IndexedDB::CursorKeyOnly:
261 cursor = IDBCursor::create(backend, m_cursorDirection, this, m_source.ge t(), m_transaction.get()); 289 cursor = IDBCursor::create(backend, m_cursorDirection, this, m_source.ge t(), m_transaction.get());
262 break; 290 break;
263 case IndexedDB::CursorKeyAndValue: 291 case IndexedDB::CursorKeyAndValue:
264 cursor = IDBCursorWithValue::create(backend, m_cursorDirection, this, m_ source.get(), m_transaction.get()); 292 cursor = IDBCursorWithValue::create(backend, m_cursorDirection, this, m_ source.get(), m_transaction.get());
265 break; 293 break;
266 default: 294 default:
267 ASSERT_NOT_REACHED(); 295 ASSERT_NOT_REACHED();
268 } 296 }
269 setResultCursor(cursor, key, primaryKey, value); 297 setResultCursor(cursor, key, primaryKey, value, blobInfo);
270 } 298 }
271 299
272 void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey) 300 void IDBRequest::onSuccess(PassRefPtr<IDBKey> idbKey)
273 { 301 {
274 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); 302 IDB_TRACE("IDBRequest::onSuccess(IDBKey)");
275 if (!shouldEnqueueEvent()) 303 if (!shouldEnqueueEvent())
276 return; 304 return;
277 305
278 if (idbKey && idbKey->isValid()) 306 if (idbKey && idbKey->isValid())
279 onSuccessInternal(IDBAny::create(idbKey)); 307 onSuccessInternal(IDBAny::create(idbKey));
280 else 308 else
281 onSuccessInternal(IDBAny::createUndefined()); 309 onSuccessInternal(IDBAny::createUndefined());
282 } 310 }
283 311
284 void IDBRequest::onSuccess(PassRefPtr<SharedBuffer> valueBuffer) 312 void IDBRequest::onSuccess(PassRefPtr<SharedBuffer> valueBuffer, PassOwnPtr<Vect or<BlobInfo> > blobInfo)
285 { 313 {
286 IDB_TRACE("IDBRequest::onSuccess(SharedBuffer)"); 314 IDB_TRACE("IDBRequest::onSuccess(SharedBuffer)");
287 if (!shouldEnqueueEvent()) 315 if (!shouldEnqueueEvent())
288 return; 316 return;
289 317
290 if (m_pendingCursor) { 318 if (m_pendingCursor) {
291 // Value should be null, signifying the end of the cursor's range. 319 // Value should be null, signifying the end of the cursor's range.
292 ASSERT(!valueBuffer.get()); 320 ASSERT(!valueBuffer.get());
jsbell 2013/12/20 19:13:54 ASSERT that blobInfo is empty too?
ericu 2014/02/12 19:12:55 Done.
293 m_pendingCursor->close(); 321 m_pendingCursor->close();
294 m_pendingCursor.clear(); 322 m_pendingCursor.clear();
295 } 323 }
296 324
297 onSuccessInternal(IDBAny::create(valueBuffer)); 325 ASSERT(!m_blobInfo.get());
326 m_blobInfo = blobInfo;
327 onSuccessInternal(IDBAny::create(valueBuffer, m_blobInfo.get()));
298 } 328 }
299 329
300 #ifndef NDEBUG 330 #ifndef NDEBUG
301 static PassRefPtr<IDBObjectStore> effectiveObjectStore(PassRefPtr<IDBAny> source ) 331 static PassRefPtr<IDBObjectStore> effectiveObjectStore(PassRefPtr<IDBAny> source )
302 { 332 {
303 if (source->type() == IDBAny::IDBObjectStoreType) 333 if (source->type() == IDBAny::IDBObjectStoreType)
304 return source->idbObjectStore(); 334 return source->idbObjectStore();
305 if (source->type() == IDBAny::IDBIndexType) 335 if (source->type() == IDBAny::IDBIndexType)
306 return source->idbIndex()->objectStore(); 336 return source->idbIndex()->objectStore();
307 337
308 ASSERT_NOT_REACHED(); 338 ASSERT_NOT_REACHED();
309 return 0; 339 return 0;
310 } 340 }
311 #endif 341 #endif
312 342
313 void IDBRequest::onSuccess(PassRefPtr<SharedBuffer> prpValueBuffer, PassRefPtr<I DBKey> prpPrimaryKey, const IDBKeyPath& keyPath) 343 void IDBRequest::onSuccess(PassRefPtr<SharedBuffer> prpValueBuffer, PassOwnPtr<V ector<BlobInfo> > blobInfo, PassRefPtr<IDBKey> prpPrimaryKey, const IDBKeyPath& keyPath)
314 { 344 {
315 IDB_TRACE("IDBRequest::onSuccess(SharedBuffer, IDBKey, IDBKeyPath)"); 345 IDB_TRACE("IDBRequest::onSuccess(SharedBuffer, IDBKey, IDBKeyPath)");
316 if (!shouldEnqueueEvent()) 346 if (!shouldEnqueueEvent())
317 return; 347 return;
318 348
319 #ifndef NDEBUG 349 #ifndef NDEBUG
320 ASSERT(keyPath == effectiveObjectStore(m_source)->metadata().keyPath); 350 ASSERT(keyPath == effectiveObjectStore(m_source)->metadata().keyPath);
321 #endif 351 #endif
322 352
323 RefPtr<SharedBuffer> valueBuffer = prpValueBuffer; 353 RefPtr<SharedBuffer> valueBuffer = prpValueBuffer;
324 RefPtr<IDBKey> primaryKey = prpPrimaryKey; 354 RefPtr<IDBKey> primaryKey = prpPrimaryKey;
355 ASSERT(!m_blobInfo.get());
356 m_blobInfo = blobInfo;
325 357
326 #ifndef NDEBUG 358 #ifndef NDEBUG
327 assertPrimaryKeyValidOrInjectable(&m_requestState, valueBuffer, primaryKey, keyPath); 359 assertPrimaryKeyValidOrInjectable(&m_requestState, valueBuffer, m_blobInfo.g et(), primaryKey, keyPath);
328 #endif 360 #endif
329 361
330 onSuccessInternal(IDBAny::create(valueBuffer, primaryKey, keyPath)); 362 onSuccessInternal(IDBAny::create(valueBuffer, m_blobInfo.get(), primaryKey, keyPath));
331 } 363 }
332 364
333 void IDBRequest::onSuccess(int64_t value) 365 void IDBRequest::onSuccess(int64_t value)
334 { 366 {
335 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); 367 IDB_TRACE("IDBRequest::onSuccess(int64_t)");
336 if (!shouldEnqueueEvent()) 368 if (!shouldEnqueueEvent())
337 return; 369 return;
338 onSuccessInternal(IDBAny::create(value)); 370 onSuccessInternal(IDBAny::create(value));
339 } 371 }
340 372
(...skipping 12 matching lines...) Expand all
353 setResult(result); 385 setResult(result);
354 enqueueEvent(Event::create(EventTypeNames::success)); 386 enqueueEvent(Event::create(EventTypeNames::success));
355 } 387 }
356 388
357 void IDBRequest::setResult(PassRefPtr<IDBAny> result) 389 void IDBRequest::setResult(PassRefPtr<IDBAny> result)
358 { 390 {
359 m_result = result; 391 m_result = result;
360 m_resultDirty = true; 392 m_resultDirty = true;
361 } 393 }
362 394
363 void IDBRequest::onSuccess(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey , PassRefPtr<SharedBuffer> value) 395 void IDBRequest::onSuccess(PassRefPtr<IDBKey> key, PassRefPtr<IDBKey> primaryKey , PassRefPtr<SharedBuffer> value, PassOwnPtr<Vector<BlobInfo> > blobInfo)
364 { 396 {
365 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); 397 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)");
366 if (!shouldEnqueueEvent()) 398 if (!shouldEnqueueEvent())
367 return; 399 return;
368 400
369 ASSERT(m_pendingCursor); 401 ASSERT(m_pendingCursor);
370 setResultCursor(m_pendingCursor.release(), key, primaryKey, value); 402 setResultCursor(m_pendingCursor.release(), key, primaryKey, value, blobInfo) ;
371 } 403 }
372 404
373 bool IDBRequest::hasPendingActivity() const 405 bool IDBRequest::hasPendingActivity() const
374 { 406 {
375 // FIXME: In an ideal world, we should return true as long as anyone has a o r can 407 // FIXME: In an ideal world, we should return true as long as anyone has a o r can
376 // get a handle to us and we have event listeners. This is order to h andle 408 // get a handle to us and we have event listeners. This is order to h andle
377 // user generated events properly. 409 // user generated events properly.
378 return m_hasPendingActivity && !m_contextStopped; 410 return m_hasPendingActivity && !m_contextStopped;
379 } 411 }
380 412
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 // this object to actually hold a reference to the database (to ensure 461 // this object to actually hold a reference to the database (to ensure
430 // it stays alive). 462 // it stays alive).
431 targets.append(m_transaction->db()); 463 targets.append(m_transaction->db());
432 } 464 }
433 465
434 // Cursor properties should not updated until the success event is being dis patched. 466 // Cursor properties should not updated until the success event is being dis patched.
435 RefPtr<IDBCursor> cursorToNotify; 467 RefPtr<IDBCursor> cursorToNotify;
436 if (event->type() == EventTypeNames::success) { 468 if (event->type() == EventTypeNames::success) {
437 cursorToNotify = getResultCursor(); 469 cursorToNotify = getResultCursor();
438 if (cursorToNotify) 470 if (cursorToNotify)
439 cursorToNotify->setValueReady(m_cursorKey.release(), m_cursorPrimary Key.release(), m_cursorValue.release()); 471 cursorToNotify->setValueReady(m_cursorKey.release(), m_cursorPrimary Key.release(), m_cursorValue.release(), m_blobInfo.release());
440 } 472 }
441 473
442 if (event->type() == EventTypeNames::upgradeneeded) { 474 if (event->type() == EventTypeNames::upgradeneeded) {
443 ASSERT(!m_didFireUpgradeNeededEvent); 475 ASSERT(!m_didFireUpgradeNeededEvent);
444 m_didFireUpgradeNeededEvent = true; 476 m_didFireUpgradeNeededEvent = true;
445 } 477 }
446 478
447 // FIXME: When we allow custom event dispatching, this will probably need to change. 479 // FIXME: When we allow custom event dispatching, this will probably need to change.
448 ASSERT_WITH_MESSAGE(event->type() == EventTypeNames::success || event->type( ) == EventTypeNames::error || event->type() == EventTypeNames::blocked || event- >type() == EventTypeNames::upgradeneeded, "event type was %s", event->type().str ing().utf8().data()); 480 ASSERT_WITH_MESSAGE(event->type() == EventTypeNames::success || event->type( ) == EventTypeNames::error || event->type() == EventTypeNames::blocked || event- >type() == EventTypeNames::upgradeneeded, "event type was %s", event->type().str ing().utf8().data());
449 const bool setTransactionActive = m_transaction && (event->type() == EventTy peNames::success || event->type() == EventTypeNames::upgradeneeded || (event->ty pe() == EventTypeNames::error && !m_requestAborted)); 481 const bool setTransactionActive = m_transaction && (event->type() == EventTy peNames::success || event->type() == EventTypeNames::upgradeneeded || (event->ty pe() == EventTypeNames::error && !m_requestAborted));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 ASSERT_WITH_MESSAGE(m_readyState == PENDING || m_didFireUpgradeNeededEvent, "When queueing event %s, m_readyState was %d", event->type().string().utf8().dat a(), m_readyState); 538 ASSERT_WITH_MESSAGE(m_readyState == PENDING || m_didFireUpgradeNeededEvent, "When queueing event %s, m_readyState was %d", event->type().string().utf8().dat a(), m_readyState);
507 539
508 EventQueue* eventQueue = executionContext()->eventQueue(); 540 EventQueue* eventQueue = executionContext()->eventQueue();
509 event->setTarget(this); 541 event->setTarget(this);
510 542
511 if (eventQueue->enqueueEvent(event.get())) 543 if (eventQueue->enqueueEvent(event.get()))
512 m_enqueuedEvents.append(event); 544 m_enqueuedEvents.append(event);
513 } 545 }
514 546
515 } // namespace WebCore 547 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698