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 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
48 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h" | 48 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h" |
49 #include <memory> | 49 #include <memory> |
50 #include <v8.h> | 50 #include <v8.h> |
51 | 51 |
52 using blink::WebBlobInfo; | 52 using blink::WebBlobInfo; |
53 using blink::WebIDBCallbacks; | 53 using blink::WebIDBCallbacks; |
54 using blink::WebIDBCursor; | 54 using blink::WebIDBCursor; |
55 using blink::WebIDBDatabase; | 55 using blink::WebIDBDatabase; |
56 using blink::WebVector; | 56 using blink::WebVector; |
57 | 57 |
58 | |
jsbell
2016/09/26 22:23:40
Nit: remove extra blank line
pwnall
2016/09/27 00:12:19
Done.
| |
58 namespace blink { | 59 namespace blink { |
59 | 60 |
60 namespace { | 61 namespace { |
61 | 62 |
62 using IndexKeys = HeapVector<Member<IDBKey>>; | 63 using IndexKeys = HeapVector<Member<IDBKey>>; |
63 | |
64 } | 64 } |
65 | 65 |
66 IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, IDBTransa ction* transaction) | 66 IDBObjectStore::IDBObjectStore(RefPtr<IDBObjectStoreMetadata> metadata, IDBTrans action* transaction) |
67 : m_metadata(metadata) | 67 : m_metadata(std::move(metadata)) |
68 , m_transaction(transaction) | 68 , m_transaction(transaction) |
69 { | 69 { |
70 DCHECK(m_transaction); | 70 DCHECK(m_transaction); |
71 DCHECK(m_metadata.get()); | |
71 } | 72 } |
72 | 73 |
73 DEFINE_TRACE(IDBObjectStore) | 74 DEFINE_TRACE(IDBObjectStore) |
74 { | 75 { |
75 visitor->trace(m_transaction); | 76 visitor->trace(m_transaction); |
76 visitor->trace(m_indexMap); | 77 visitor->trace(m_indexMap); |
77 visitor->trace(m_createdIndexes); | |
78 } | 78 } |
79 | 79 |
80 void IDBObjectStore::setName(const String& name, ExceptionState& exceptionState) | 80 void IDBObjectStore::setName(const String& name, ExceptionState& exceptionState) |
81 { | 81 { |
82 if (!RuntimeEnabledFeatures::indexedDBExperimentalEnabled()) | 82 if (!RuntimeEnabledFeatures::indexedDBExperimentalEnabled()) |
83 return; | 83 return; |
84 | 84 |
85 IDB_TRACE("IDBObjectStore::setName"); | 85 IDB_TRACE("IDBObjectStore::setName"); |
86 if (!m_transaction->isVersionChange()) { | 86 if (!m_transaction->isVersionChange()) { |
87 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); | 87 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); |
(...skipping 16 matching lines...) Expand all Loading... | |
104 return; | 104 return; |
105 if (m_transaction->db()->containsObjectStore(name)) { | 105 if (m_transaction->db()->containsObjectStore(name)) { |
106 exceptionState.throwDOMException(ConstraintError, IDBDatabase::objectSto reNameTakenErrorMessage); | 106 exceptionState.throwDOMException(ConstraintError, IDBDatabase::objectSto reNameTakenErrorMessage); |
107 return; | 107 return; |
108 } | 108 } |
109 if (!backendDB()) { | 109 if (!backendDB()) { |
110 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 110 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
111 return; | 111 return; |
112 } | 112 } |
113 | 113 |
114 backendDB()->renameObjectStore(m_transaction->id(), id(), name); | 114 m_transaction->db()->renameObjectStore(id(), name); |
115 m_transaction->objectStoreRenamed(m_metadata.name, name); | |
116 m_metadata.name = name; | |
117 | |
118 // The name inside the database's version of the object store metadata is us ed by IDBDatabase.objectStoreNames(). | |
119 // If the transaction is aborted, this name will be reverted when the metada ta is overwritten with the previousMetadata in IDBTransaction. | |
120 m_transaction->db()->objectStoreRenamed(id(), name); | |
121 } | 115 } |
122 | 116 |
123 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const | 117 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const |
124 { | 118 { |
125 return ScriptValue::from(scriptState, metadata().keyPath); | 119 return ScriptValue::from(scriptState, metadata().keyPath); |
126 } | 120 } |
127 | 121 |
128 DOMStringList* IDBObjectStore::indexNames() const | 122 DOMStringList* IDBObjectStore::indexNames() const |
129 { | 123 { |
130 IDB_TRACE("IDBObjectStore::indexNames"); | 124 IDB_TRACE("IDBObjectStore::indexNames"); |
131 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); | 125 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); |
132 for (const auto& it : metadata().indexes) | 126 for (const auto& it : metadata().indexes) |
133 indexNames->append(it.value.name); | 127 indexNames->append(it.value->name); |
134 indexNames->sort(); | 128 indexNames->sort(); |
135 return indexNames; | 129 return indexNames; |
136 } | 130 } |
137 | 131 |
138 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, const ScriptValue& key , ExceptionState& exceptionState) | 132 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, const ScriptValue& key , ExceptionState& exceptionState) |
139 { | 133 { |
140 IDB_TRACE("IDBObjectStore::get"); | 134 IDB_TRACE("IDBObjectStore::get"); |
141 if (isDeleted()) { | 135 if (isDeleted()) { |
142 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); | 136 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); |
143 return nullptr; | 137 return nullptr; |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
405 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 399 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
406 return nullptr; | 400 return nullptr; |
407 } | 401 } |
408 | 402 |
409 Vector<int64_t> indexIds; | 403 Vector<int64_t> indexIds; |
410 HeapVector<IndexKeys> indexKeys; | 404 HeapVector<IndexKeys> indexKeys; |
411 for (const auto& it : metadata().indexes) { | 405 for (const auto& it : metadata().indexes) { |
412 if (clone.isEmpty()) | 406 if (clone.isEmpty()) |
413 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); | 407 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); |
414 IndexKeys keys; | 408 IndexKeys keys; |
415 generateIndexKeysForValue(scriptState->isolate(), it.value, clone, &keys ); | 409 generateIndexKeysForValue(scriptState->isolate(), *it.value, clone, &key s); |
416 indexIds.append(it.key); | 410 indexIds.append(it.key); |
417 indexKeys.append(keys); | 411 indexKeys.append(keys); |
418 } | 412 } |
419 | 413 |
420 IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction. get()); | 414 IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction. get()); |
421 Vector<char> wireBytes; | 415 Vector<char> wireBytes; |
422 serializedValue->toWireBytes(wireBytes); | 416 serializedValue->toWireBytes(wireBytes); |
423 RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes); | 417 RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes); |
424 | 418 |
425 backendDB()->put(m_transaction->id(), id(), WebData(valueBuffer), blobInfo, key, static_cast<WebIDBPutMode>(putMode), WebIDBCallbacksImpl::create(request).r elease(), indexIds, indexKeys); | 419 backendDB()->put(m_transaction->id(), id(), WebData(valueBuffer), blobInfo, key, static_cast<WebIDBPutMode>(putMode), WebIDBCallbacksImpl::create(request).r elease(), indexIds, indexKeys); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
493 } | 487 } |
494 | 488 |
495 namespace { | 489 namespace { |
496 // This class creates the index keys for a given index by extracting | 490 // This class creates the index keys for a given index by extracting |
497 // them from the SerializedScriptValue, for all the existing values in | 491 // them from the SerializedScriptValue, for all the existing values in |
498 // the objectStore. It only needs to be kept alive by virtue of being | 492 // the objectStore. It only needs to be kept alive by virtue of being |
499 // a listener on an IDBRequest object, in the same way that JavaScript | 493 // a listener on an IDBRequest object, in the same way that JavaScript |
500 // cursor success handlers are kept alive. | 494 // cursor success handlers are kept alive. |
501 class IndexPopulator final : public EventListener { | 495 class IndexPopulator final : public EventListener { |
502 public: | 496 public: |
503 static IndexPopulator* create(ScriptState* scriptState, IDBDatabase* databas e, int64_t transactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMe tadata) | 497 static IndexPopulator* create(ScriptState* scriptState, IDBDatabase* databas e, int64_t transactionId, int64_t objectStoreId, RefPtr<const IDBIndexMetadata> indexMetadata) |
504 { | 498 { |
505 return new IndexPopulator(scriptState, database, transactionId, objectSt oreId, indexMetadata); | 499 return new IndexPopulator(scriptState, database, transactionId, objectSt oreId, std::move(indexMetadata)); |
506 } | 500 } |
507 | 501 |
508 bool operator==(const EventListener& other) const override | 502 bool operator==(const EventListener& other) const override |
509 { | 503 { |
510 return this == &other; | 504 return this == &other; |
511 } | 505 } |
512 | 506 |
513 DEFINE_INLINE_VIRTUAL_TRACE() | 507 DEFINE_INLINE_VIRTUAL_TRACE() |
514 { | 508 { |
515 visitor->trace(m_database); | 509 visitor->trace(m_database); |
516 EventListener::trace(visitor); | 510 EventListener::trace(visitor); |
517 } | 511 } |
518 | 512 |
519 private: | 513 private: |
520 IndexPopulator(ScriptState* scriptState, IDBDatabase* database, int64_t tran sactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata) | 514 IndexPopulator(ScriptState* scriptState, IDBDatabase* database, int64_t tran sactionId, int64_t objectStoreId, RefPtr<const IDBIndexMetadata> indexMetadata) |
521 : EventListener(CPPEventListenerType) | 515 : EventListener(CPPEventListenerType) |
522 , m_scriptState(scriptState) | 516 , m_scriptState(scriptState) |
523 , m_database(database) | 517 , m_database(database) |
524 , m_transactionId(transactionId) | 518 , m_transactionId(transactionId) |
525 , m_objectStoreId(objectStoreId) | 519 , m_objectStoreId(objectStoreId) |
526 , m_indexMetadata(indexMetadata) | 520 , m_indexMetadata(std::move(indexMetadata)) |
527 { | 521 { |
522 DCHECK(m_indexMetadata.get()); | |
528 } | 523 } |
529 | 524 |
530 const IDBIndexMetadata& indexMetadata() const { return m_indexMetadata; } | 525 const IDBIndexMetadata& indexMetadata() const { return *m_indexMetadata; } |
531 | 526 |
532 void handleEvent(ExecutionContext* executionContext, Event* event) override | 527 void handleEvent(ExecutionContext* executionContext, Event* event) override |
533 { | 528 { |
534 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext); | 529 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext); |
535 DCHECK_EQ(event->type(), EventTypeNames::success); | 530 DCHECK_EQ(event->type(), EventTypeNames::success); |
536 EventTarget* target = event->target(); | 531 EventTarget* target = event->target(); |
537 IDBRequest* request = static_cast<IDBRequest*>(target); | 532 IDBRequest* request = static_cast<IDBRequest*>(target); |
538 | 533 |
539 if (!m_database->backend()) // If database is stopped? | 534 if (!m_database->backend()) // If database is stopped? |
540 return; | 535 return; |
(...skipping 24 matching lines...) Expand all Loading... | |
565 m_database->backend()->setIndexesReady(m_transactionId, m_objectStor eId, indexIds); | 560 m_database->backend()->setIndexesReady(m_transactionId, m_objectStor eId, indexIds); |
566 m_database.clear(); | 561 m_database.clear(); |
567 } | 562 } |
568 | 563 |
569 } | 564 } |
570 | 565 |
571 RefPtr<ScriptState> m_scriptState; | 566 RefPtr<ScriptState> m_scriptState; |
572 Member<IDBDatabase> m_database; | 567 Member<IDBDatabase> m_database; |
573 const int64_t m_transactionId; | 568 const int64_t m_transactionId; |
574 const int64_t m_objectStoreId; | 569 const int64_t m_objectStoreId; |
575 const IDBIndexMetadata m_indexMetadata; | 570 RefPtr<const IDBIndexMetadata> m_indexMetadata; |
576 }; | 571 }; |
577 } // namespace | 572 } // namespace |
578 | 573 |
579 IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, const String& na me, const IDBKeyPath& keyPath, const IDBIndexParameters& options, ExceptionState & exceptionState) | 574 IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, const String& na me, const IDBKeyPath& keyPath, const IDBIndexParameters& options, ExceptionState & exceptionState) |
580 { | 575 { |
581 IDB_TRACE("IDBObjectStore::createIndex"); | 576 IDB_TRACE("IDBObjectStore::createIndex"); |
582 if (!m_transaction->isVersionChange()) { | 577 if (!m_transaction->isVersionChange()) { |
583 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); | 578 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); |
584 return nullptr; | 579 return nullptr; |
585 } | 580 } |
(...skipping 19 matching lines...) Expand all Loading... | |
605 } | 600 } |
606 if (keyPath.getType() == IDBKeyPath::ArrayType && options.multiEntry()) { | 601 if (keyPath.getType() == IDBKeyPath::ArrayType && options.multiEntry()) { |
607 exceptionState.throwDOMException(InvalidAccessError, "The keyPath argume nt was an array and the multiEntry option is true."); | 602 exceptionState.throwDOMException(InvalidAccessError, "The keyPath argume nt was an array and the multiEntry option is true."); |
608 return nullptr; | 603 return nullptr; |
609 } | 604 } |
610 if (!backendDB()) { | 605 if (!backendDB()) { |
611 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 606 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
612 return nullptr; | 607 return nullptr; |
613 } | 608 } |
614 | 609 |
615 int64_t indexId = m_metadata.maxIndexId + 1; | 610 int64_t indexId = m_metadata->maxIndexId + 1; |
616 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId); | 611 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId); |
617 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry()); | 612 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry()); |
618 | 613 |
619 ++m_metadata.maxIndexId; | 614 ++m_metadata->maxIndexId; |
620 | 615 |
621 IDBIndexMetadata indexMetadata(name, indexId, keyPath, options.unique(), opt ions.multiEntry()); | 616 RefPtr<IDBIndexMetadata> indexMetadata = adoptRef(new IDBIndexMetadata( |
617 name, indexId, keyPath, options.unique(), options.multiEntry())); | |
622 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; | 618 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; |
623 m_indexMap.set(name, index); | 619 m_indexMap.set(name, index); |
624 m_createdIndexes.add(index); | 620 m_metadata->indexes.set(indexId, indexMetadata); |
625 m_metadata.indexes.set(indexId, indexMetadata); | |
626 m_transaction->db()->indexCreated(id(), indexMetadata); | |
627 | 621 |
628 DCHECK(!exceptionState.hadException()); | 622 DCHECK(!exceptionState.hadException()); |
629 if (exceptionState.hadException()) | 623 if (exceptionState.hadException()) |
630 return nullptr; | 624 return nullptr; |
631 | 625 |
632 IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDire ctionNext, WebIDBTaskTypePreemptive); | 626 IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDire ctionNext, WebIDBTaskTypePreemptive); |
633 indexRequest->preventPropagation(); | 627 indexRequest->preventPropagation(); |
634 | 628 |
635 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. | 629 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. |
636 IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transac tion()->db(), m_transaction->id(), id(), indexMetadata); | 630 IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transac tion()->db(), m_transaction->id(), id(), std::move(indexMetadata)); |
637 indexRequest->setOnsuccess(indexPopulator); | 631 indexRequest->setOnsuccess(indexPopulator); |
638 return index; | 632 return index; |
639 } | 633 } |
640 | 634 |
641 IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionSta te) | 635 IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionSta te) |
642 { | 636 { |
643 IDB_TRACE("IDBObjectStore::index"); | 637 IDB_TRACE("IDBObjectStore::index"); |
644 if (isDeleted()) { | 638 if (isDeleted()) { |
645 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); | 639 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); |
646 return nullptr; | 640 return nullptr; |
647 } | 641 } |
648 if (m_transaction->isFinished() || m_transaction->isFinishing()) { | 642 if (m_transaction->isFinished() || m_transaction->isFinishing()) { |
649 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); | 643 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); |
650 return nullptr; | 644 return nullptr; |
651 } | 645 } |
652 | 646 |
653 IDBIndexMap::iterator it = m_indexMap.find(name); | 647 IDBIndexMap::iterator it = m_indexMap.find(name); |
654 if (it != m_indexMap.end()) | 648 if (it != m_indexMap.end()) |
655 return it->value; | 649 return it->value; |
656 | 650 |
657 int64_t indexId = findIndexId(name); | 651 int64_t indexId = findIndexId(name); |
658 if (indexId == IDBIndexMetadata::InvalidId) { | 652 if (indexId == IDBIndexMetadata::InvalidId) { |
659 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); | 653 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); |
660 return nullptr; | 654 return nullptr; |
661 } | 655 } |
662 | 656 |
663 DCHECK(metadata().indexes.contains(indexId)); | 657 DCHECK(metadata().indexes.contains(indexId)); |
664 const IDBIndexMetadata& indexMetadata = metadata().indexes.get(indexId); | 658 RefPtr<IDBIndexMetadata> indexMetadata = metadata().indexes.get(indexId); |
665 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; | 659 DCHECK(indexMetadata.get()); |
660 IDBIndex* index = IDBIndex::create(std::move(indexMetadata), this, m_transac tion.get()); | |
666 m_indexMap.set(name, index); | 661 m_indexMap.set(name, index); |
667 return index; | 662 return index; |
668 } | 663 } |
669 | 664 |
670 void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionSt ate) | 665 void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionSt ate) |
671 { | 666 { |
672 IDB_TRACE("IDBObjectStore::deleteIndex"); | 667 IDB_TRACE("IDBObjectStore::deleteIndex"); |
673 if (!m_transaction->isVersionChange()) { | 668 if (!m_transaction->isVersionChange()) { |
674 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); | 669 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); |
675 return; | 670 return; |
(...skipping 15 matching lines...) Expand all Loading... | |
691 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); | 686 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); |
692 return; | 687 return; |
693 } | 688 } |
694 if (!backendDB()) { | 689 if (!backendDB()) { |
695 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); | 690 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); |
696 return; | 691 return; |
697 } | 692 } |
698 | 693 |
699 backendDB()->deleteIndex(m_transaction->id(), id(), indexId); | 694 backendDB()->deleteIndex(m_transaction->id(), id(), indexId); |
700 | 695 |
701 m_metadata.indexes.remove(indexId); | 696 m_metadata->indexes.remove(indexId); |
702 m_transaction->db()->indexDeleted(id(), indexId); | |
703 IDBIndexMap::iterator it = m_indexMap.find(name); | 697 IDBIndexMap::iterator it = m_indexMap.find(name); |
704 if (it != m_indexMap.end()) { | 698 if (it != m_indexMap.end()) { |
699 m_transaction->indexDeleted(it->value); | |
705 it->value->markDeleted(); | 700 it->value->markDeleted(); |
706 m_indexMap.remove(name); | 701 m_indexMap.remove(name); |
707 } | 702 } |
708 } | 703 } |
709 | 704 |
710 IDBRequest* IDBObjectStore::openCursor(ScriptState* scriptState, const ScriptVal ue& range, const String& directionString, ExceptionState& exceptionState) | 705 IDBRequest* IDBObjectStore::openCursor(ScriptState* scriptState, const ScriptVal ue& range, const String& directionString, ExceptionState& exceptionState) |
711 { | 706 { |
712 IDB_TRACE("IDBObjectStore::openCursor"); | 707 IDB_TRACE("IDBObjectStore::openCursor"); |
713 if (isDeleted()) { | 708 if (isDeleted()) { |
714 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); | 709 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
804 } | 799 } |
805 | 800 |
806 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); | 801 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); |
807 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, k eyRange, WebIDBCallbacksImpl::create(request).release()); | 802 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, k eyRange, WebIDBCallbacksImpl::create(request).release()); |
808 return request; | 803 return request; |
809 } | 804 } |
810 | 805 |
811 void IDBObjectStore::markDeleted() | 806 void IDBObjectStore::markDeleted() |
812 { | 807 { |
813 DCHECK(m_transaction->isVersionChange()) << "An object store got deleted out side a versionchange transaction."; | 808 DCHECK(m_transaction->isVersionChange()) << "An object store got deleted out side a versionchange transaction."; |
809 | |
814 m_deleted = true; | 810 m_deleted = true; |
811 m_metadata->indexes.clear(); | |
812 | |
813 for (auto& it : m_indexMap) { | |
814 IDBIndex* index = it.value; | |
815 index->markDeleted(); | |
816 } | |
815 } | 817 } |
816 | 818 |
817 void IDBObjectStore::abort() | 819 void IDBObjectStore::clearIndexCache() |
818 { | 820 { |
819 for (auto& index : m_createdIndexes) | 821 DCHECK(!m_transaction->isActive() || (isDeleted() && id() > m_transaction->o ldMaxObjectStoreId())); |
820 index->markDeleted(); | 822 |
823 // There is no harm in having clearIndexCache() happen multiple times for | |
824 // the same object. We assert that it is called once to uncover potential | |
825 // object store accounting bugs. | |
826 #if DCHECK_IS_ON() | |
827 DCHECK(!m_clearIndexCacheCalled); | |
828 m_clearIndexCacheCalled = true; | |
829 #endif // DCHECK_IS_ON() | |
830 | |
831 m_indexMap.clear(); | |
821 } | 832 } |
822 | 833 |
823 void IDBObjectStore::transactionFinished() | 834 void IDBObjectStore::revertMetadata(RefPtr<IDBObjectStoreMetadata> oldMetadata) |
824 { | 835 { |
836 DCHECK(m_transaction->isVersionChange()); | |
825 DCHECK(!m_transaction->isActive()); | 837 DCHECK(!m_transaction->isActive()); |
838 DCHECK(oldMetadata.get()); | |
839 DCHECK(id() == oldMetadata->id); | |
826 | 840 |
827 // Break reference cycles. | 841 // Index IDs are allocated sequentially, so we can tell if an index was |
828 // TODO(jsbell): This can be removed c/o Oilpan. | 842 // created in this transaction by comparing its ID with the object store's |
829 m_indexMap.clear(); | 843 // maximum index ID at the time when the transaction was started. |
830 m_createdIndexes.clear(); | 844 const int64_t oldMaxIndexId = oldMetadata->maxIndexId; |
845 for (auto& it : m_indexMap) { | |
846 IDBIndex* index = it.value; | |
847 const int64_t indexId = index->id(); | |
848 | |
849 if (indexId > oldMaxIndexId) { | |
850 // The index was created by this transaction. According to the spec, | |
851 // its metadata will remain as-is. We just need to look up the | |
jsbell
2016/09/26 22:23:40
You can drop the second sentence here ("We just ne
pwnall
2016/09/27 00:12:19
Done.
Thanks, that's a very good point!
| |
852 // index's IDBIndex instance, and mark it as deleted. | |
853 DCHECK(!oldMetadata->indexes.contains(indexId)); | |
854 index->markDeleted(); | |
855 continue; | |
856 } | |
857 | |
858 // The index was created in a previous transaction. We need to revert | |
859 // its metadata. The index might have been deleted, so we | |
860 // unconditionally reset the deletion marker. We could find out if the | |
jsbell
2016/09/26 22:23:40
I think you can drop the alternative here ("We cou
pwnall
2016/09/27 00:12:19
Done.
Sure, as long as one of us remembers why I w
| |
861 // index was deleted by looking up the index ID in the store's metadata, | |
862 // but that would be more work than the unconditional reset. | |
863 DCHECK(oldMetadata->indexes.contains(indexId)); | |
864 RefPtr<IDBIndexMetadata> oldIndexMetadata = oldMetadata->indexes.get(ind exId); | |
865 index->revertMetadata(std::move(oldIndexMetadata)); | |
866 } | |
867 m_metadata = std::move(oldMetadata); | |
868 | |
869 // An object store's metadata will only get reverted if the index was in the | |
870 // database when the versionchange transaction started. | |
871 m_deleted = false; | |
831 } | 872 } |
832 | 873 |
833 void IDBObjectStore::indexRenamed(int64_t indexId, const String& newName) | 874 void IDBObjectStore::revertDeletedIndexMetadata(IDBIndex& deletedIndex) |
875 { | |
876 DCHECK(m_transaction->isVersionChange()); | |
877 DCHECK(!m_transaction->isActive()); | |
878 DCHECK(deletedIndex.objectStore() == this); | |
879 DCHECK(deletedIndex.isDeleted()); | |
880 | |
881 const int64_t indexId = deletedIndex.id(); | |
882 DCHECK(m_metadata->indexes.contains(indexId)) << "The object store's metadat a was not correctly reverted"; | |
883 RefPtr<IDBIndexMetadata> oldIndexMetadata = m_metadata->indexes.get(indexId) ; | |
884 deletedIndex.revertMetadata(std::move(oldIndexMetadata)); | |
885 } | |
886 | |
887 void IDBObjectStore::renameIndex(int64_t indexId, const String& newName) | |
834 { | 888 { |
835 DCHECK(m_transaction->isVersionChange()); | 889 DCHECK(m_transaction->isVersionChange()); |
836 DCHECK(m_transaction->isActive()); | 890 DCHECK(m_transaction->isActive()); |
837 | 891 |
838 auto metadataIterator = m_metadata.indexes.find(indexId); | 892 auto metadataIterator = m_metadata->indexes.find(indexId); |
839 DCHECK_NE(metadataIterator, m_metadata.indexes.end()) << "Invalid indexId"; | 893 DCHECK_NE(metadataIterator, m_metadata->indexes.end()) << "Invalid indexId"; |
840 const String& oldName = metadataIterator->value.name; | 894 const String& oldName = metadataIterator->value->name; |
841 | 895 |
842 DCHECK(m_indexMap.contains(oldName)) << "The index had to be accessed in ord er to be renamed."; | 896 DCHECK(m_indexMap.contains(oldName)) << "The index had to be accessed in ord er to be renamed."; |
843 DCHECK(!m_indexMap.contains(newName)); | 897 DCHECK(!m_indexMap.contains(newName)); |
844 m_indexMap.set(newName, m_indexMap.take(oldName)); | 898 m_indexMap.set(newName, m_indexMap.take(oldName)); |
845 | 899 |
846 metadataIterator->value.name = newName; | 900 metadataIterator->value->name = newName; |
847 } | 901 } |
848 | 902 |
849 int64_t IDBObjectStore::findIndexId(const String& name) const | 903 int64_t IDBObjectStore::findIndexId(const String& name) const |
850 { | 904 { |
851 for (const auto& it : metadata().indexes) { | 905 for (const auto& it : metadata().indexes) { |
852 if (it.value.name == name) { | 906 if (it.value->name == name) { |
853 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); | 907 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); |
854 return it.key; | 908 return it.key; |
855 } | 909 } |
856 } | 910 } |
857 return IDBIndexMetadata::InvalidId; | 911 return IDBIndexMetadata::InvalidId; |
858 } | 912 } |
859 | 913 |
860 WebIDBDatabase* IDBObjectStore::backendDB() const | 914 WebIDBDatabase* IDBObjectStore::backendDB() const |
861 { | 915 { |
862 return m_transaction->backendDB(); | 916 return m_transaction->backendDB(); |
863 } | 917 } |
864 | 918 |
865 } // namespace blink | 919 } // namespace blink |
OLD | NEW |