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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 using blink::WebIDBDatabase; | 55 using blink::WebIDBDatabase; |
56 using blink::WebVector; | 56 using blink::WebVector; |
57 | 57 |
58 namespace blink { | 58 namespace blink { |
59 | 59 |
60 namespace { | 60 namespace { |
61 | 61 |
62 using IndexKeys = HeapVector<Member<IDBKey>>; | 62 using IndexKeys = HeapVector<Member<IDBKey>>; |
63 } | 63 } |
64 | 64 |
65 IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, | 65 IDBObjectStore::IDBObjectStore(RefPtr<IDBObjectStoreMetadata> metadata, |
66 IDBTransaction* transaction) | 66 IDBTransaction* transaction) |
67 : m_metadata(metadata), m_transaction(transaction) { | 67 : m_metadata(std::move(metadata)), m_transaction(transaction) { |
68 DCHECK(m_transaction); | 68 DCHECK(m_transaction); |
69 DCHECK(m_metadata.get()); | |
69 } | 70 } |
70 | 71 |
71 DEFINE_TRACE(IDBObjectStore) { | 72 DEFINE_TRACE(IDBObjectStore) { |
72 visitor->trace(m_transaction); | 73 visitor->trace(m_transaction); |
73 visitor->trace(m_indexMap); | 74 visitor->trace(m_indexMap); |
74 visitor->trace(m_createdIndexes); | |
75 } | 75 } |
76 | 76 |
77 void IDBObjectStore::setName(const String& name, | 77 void IDBObjectStore::setName(const String& name, |
78 ExceptionState& exceptionState) { | 78 ExceptionState& exceptionState) { |
79 if (!RuntimeEnabledFeatures::indexedDBExperimentalEnabled()) | 79 if (!RuntimeEnabledFeatures::indexedDBExperimentalEnabled()) |
80 return; | 80 return; |
81 | 81 |
82 IDB_TRACE("IDBObjectStore::setName"); | 82 IDB_TRACE("IDBObjectStore::setName"); |
83 if (!m_transaction->isVersionChange()) { | 83 if (!m_transaction->isVersionChange()) { |
84 exceptionState.throwDOMException( | 84 exceptionState.throwDOMException( |
(...skipping 23 matching lines...) Expand all Loading... | |
108 exceptionState.throwDOMException( | 108 exceptionState.throwDOMException( |
109 ConstraintError, IDBDatabase::objectStoreNameTakenErrorMessage); | 109 ConstraintError, IDBDatabase::objectStoreNameTakenErrorMessage); |
110 return; | 110 return; |
111 } | 111 } |
112 if (!backendDB()) { | 112 if (!backendDB()) { |
113 exceptionState.throwDOMException(InvalidStateError, | 113 exceptionState.throwDOMException(InvalidStateError, |
114 IDBDatabase::databaseClosedErrorMessage); | 114 IDBDatabase::databaseClosedErrorMessage); |
115 return; | 115 return; |
116 } | 116 } |
117 | 117 |
118 backendDB()->renameObjectStore(m_transaction->id(), id(), name); | 118 m_transaction->db()->renameObjectStore(id(), name); |
jsbell
2016/10/06 20:01:31
IDBIndex::setName calls WebIDBDatabase::renameInde
pwnall
2016/10/06 22:15:22
Done.
This is a great suggestion! Thank you!
| |
119 m_transaction->objectStoreRenamed(m_metadata.name, name); | |
120 m_metadata.name = name; | |
121 | |
122 // The name inside the database's version of the object store metadata is used | |
123 // by IDBDatabase.objectStoreNames(). If the transaction is aborted, this | |
124 // name will be reverted when the metadata is overwritten with the | |
125 // previousMetadata in IDBTransaction. | |
126 m_transaction->db()->objectStoreRenamed(id(), name); | |
127 } | 119 } |
128 | 120 |
129 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const { | 121 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const { |
130 return ScriptValue::from(scriptState, metadata().keyPath); | 122 return ScriptValue::from(scriptState, metadata().keyPath); |
131 } | 123 } |
132 | 124 |
133 DOMStringList* IDBObjectStore::indexNames() const { | 125 DOMStringList* IDBObjectStore::indexNames() const { |
134 IDB_TRACE("IDBObjectStore::indexNames"); | 126 IDB_TRACE("IDBObjectStore::indexNames"); |
135 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); | 127 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); |
136 for (const auto& it : metadata().indexes) | 128 for (const auto& it : metadata().indexes) |
137 indexNames->append(it.value.name); | 129 indexNames->append(it.value->name); |
138 indexNames->sort(); | 130 indexNames->sort(); |
139 return indexNames; | 131 return indexNames; |
140 } | 132 } |
141 | 133 |
142 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, | 134 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, |
143 const ScriptValue& key, | 135 const ScriptValue& key, |
144 ExceptionState& exceptionState) { | 136 ExceptionState& exceptionState) { |
145 IDB_TRACE("IDBObjectStore::get"); | 137 IDB_TRACE("IDBObjectStore::get"); |
146 if (isDeleted()) { | 138 if (isDeleted()) { |
147 exceptionState.throwDOMException( | 139 exceptionState.throwDOMException( |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 return nullptr; | 495 return nullptr; |
504 } | 496 } |
505 | 497 |
506 Vector<int64_t> indexIds; | 498 Vector<int64_t> indexIds; |
507 HeapVector<IndexKeys> indexKeys; | 499 HeapVector<IndexKeys> indexKeys; |
508 for (const auto& it : metadata().indexes) { | 500 for (const auto& it : metadata().indexes) { |
509 if (clone.isEmpty()) | 501 if (clone.isEmpty()) |
510 clone = | 502 clone = |
511 deserializeScriptValue(scriptState, serializedValue.get(), &blobInfo); | 503 deserializeScriptValue(scriptState, serializedValue.get(), &blobInfo); |
512 IndexKeys keys; | 504 IndexKeys keys; |
513 generateIndexKeysForValue(scriptState->isolate(), it.value, clone, &keys); | 505 generateIndexKeysForValue(scriptState->isolate(), *it.value, clone, &keys); |
514 indexIds.append(it.key); | 506 indexIds.append(it.key); |
515 indexKeys.append(keys); | 507 indexKeys.append(keys); |
516 } | 508 } |
517 | 509 |
518 IDBRequest* request = | 510 IDBRequest* request = |
519 IDBRequest::create(scriptState, source, m_transaction.get()); | 511 IDBRequest::create(scriptState, source, m_transaction.get()); |
520 Vector<char> wireBytes; | 512 Vector<char> wireBytes; |
521 serializedValue->toWireBytes(wireBytes); | 513 serializedValue->toWireBytes(wireBytes); |
522 RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes); | 514 RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes); |
523 | 515 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 // them from the SerializedScriptValue, for all the existing values in | 608 // them from the SerializedScriptValue, for all the existing values in |
617 // the objectStore. It only needs to be kept alive by virtue of being | 609 // the objectStore. It only needs to be kept alive by virtue of being |
618 // a listener on an IDBRequest object, in the same way that JavaScript | 610 // a listener on an IDBRequest object, in the same way that JavaScript |
619 // cursor success handlers are kept alive. | 611 // cursor success handlers are kept alive. |
620 class IndexPopulator final : public EventListener { | 612 class IndexPopulator final : public EventListener { |
621 public: | 613 public: |
622 static IndexPopulator* create(ScriptState* scriptState, | 614 static IndexPopulator* create(ScriptState* scriptState, |
623 IDBDatabase* database, | 615 IDBDatabase* database, |
624 int64_t transactionId, | 616 int64_t transactionId, |
625 int64_t objectStoreId, | 617 int64_t objectStoreId, |
626 const IDBIndexMetadata& indexMetadata) { | 618 RefPtr<const IDBIndexMetadata> indexMetadata) { |
627 return new IndexPopulator(scriptState, database, transactionId, | 619 return new IndexPopulator(scriptState, database, transactionId, |
628 objectStoreId, indexMetadata); | 620 objectStoreId, std::move(indexMetadata)); |
629 } | 621 } |
630 | 622 |
631 bool operator==(const EventListener& other) const override { | 623 bool operator==(const EventListener& other) const override { |
632 return this == &other; | 624 return this == &other; |
633 } | 625 } |
634 | 626 |
635 DEFINE_INLINE_VIRTUAL_TRACE() { | 627 DEFINE_INLINE_VIRTUAL_TRACE() { |
636 visitor->trace(m_database); | 628 visitor->trace(m_database); |
637 EventListener::trace(visitor); | 629 EventListener::trace(visitor); |
638 } | 630 } |
639 | 631 |
640 private: | 632 private: |
641 IndexPopulator(ScriptState* scriptState, | 633 IndexPopulator(ScriptState* scriptState, |
642 IDBDatabase* database, | 634 IDBDatabase* database, |
643 int64_t transactionId, | 635 int64_t transactionId, |
644 int64_t objectStoreId, | 636 int64_t objectStoreId, |
645 const IDBIndexMetadata& indexMetadata) | 637 RefPtr<const IDBIndexMetadata> indexMetadata) |
646 : EventListener(CPPEventListenerType), | 638 : EventListener(CPPEventListenerType), |
647 m_scriptState(scriptState), | 639 m_scriptState(scriptState), |
648 m_database(database), | 640 m_database(database), |
649 m_transactionId(transactionId), | 641 m_transactionId(transactionId), |
650 m_objectStoreId(objectStoreId), | 642 m_objectStoreId(objectStoreId), |
651 m_indexMetadata(indexMetadata) {} | 643 m_indexMetadata(std::move(indexMetadata)) { |
644 DCHECK(m_indexMetadata.get()); | |
645 } | |
652 | 646 |
653 const IDBIndexMetadata& indexMetadata() const { return m_indexMetadata; } | 647 const IDBIndexMetadata& indexMetadata() const { return *m_indexMetadata; } |
654 | 648 |
655 void handleEvent(ExecutionContext* executionContext, Event* event) override { | 649 void handleEvent(ExecutionContext* executionContext, Event* event) override { |
656 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext); | 650 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext); |
657 DCHECK_EQ(event->type(), EventTypeNames::success); | 651 DCHECK_EQ(event->type(), EventTypeNames::success); |
658 EventTarget* target = event->target(); | 652 EventTarget* target = event->target(); |
659 IDBRequest* request = static_cast<IDBRequest*>(target); | 653 IDBRequest* request = static_cast<IDBRequest*>(target); |
660 | 654 |
661 if (!m_database->backend()) // If database is stopped? | 655 if (!m_database->backend()) // If database is stopped? |
662 return; | 656 return; |
663 | 657 |
(...skipping 25 matching lines...) Expand all Loading... | |
689 m_database->backend()->setIndexesReady(m_transactionId, m_objectStoreId, | 683 m_database->backend()->setIndexesReady(m_transactionId, m_objectStoreId, |
690 indexIds); | 684 indexIds); |
691 m_database.clear(); | 685 m_database.clear(); |
692 } | 686 } |
693 } | 687 } |
694 | 688 |
695 RefPtr<ScriptState> m_scriptState; | 689 RefPtr<ScriptState> m_scriptState; |
696 Member<IDBDatabase> m_database; | 690 Member<IDBDatabase> m_database; |
697 const int64_t m_transactionId; | 691 const int64_t m_transactionId; |
698 const int64_t m_objectStoreId; | 692 const int64_t m_objectStoreId; |
699 const IDBIndexMetadata m_indexMetadata; | 693 RefPtr<const IDBIndexMetadata> m_indexMetadata; |
700 }; | 694 }; |
701 } // namespace | 695 } // namespace |
702 | 696 |
703 IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, | 697 IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, |
704 const String& name, | 698 const String& name, |
705 const IDBKeyPath& keyPath, | 699 const IDBKeyPath& keyPath, |
706 const IDBIndexParameters& options, | 700 const IDBIndexParameters& options, |
707 ExceptionState& exceptionState) { | 701 ExceptionState& exceptionState) { |
708 IDB_TRACE("IDBObjectStore::createIndex"); | 702 IDB_TRACE("IDBObjectStore::createIndex"); |
709 if (!m_transaction->isVersionChange()) { | 703 if (!m_transaction->isVersionChange()) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
742 InvalidAccessError, | 736 InvalidAccessError, |
743 "The keyPath argument was an array and the multiEntry option is true."); | 737 "The keyPath argument was an array and the multiEntry option is true."); |
744 return nullptr; | 738 return nullptr; |
745 } | 739 } |
746 if (!backendDB()) { | 740 if (!backendDB()) { |
747 exceptionState.throwDOMException(InvalidStateError, | 741 exceptionState.throwDOMException(InvalidStateError, |
748 IDBDatabase::databaseClosedErrorMessage); | 742 IDBDatabase::databaseClosedErrorMessage); |
749 return nullptr; | 743 return nullptr; |
750 } | 744 } |
751 | 745 |
752 int64_t indexId = m_metadata.maxIndexId + 1; | 746 int64_t indexId = m_metadata->maxIndexId + 1; |
753 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId); | 747 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId); |
754 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, | 748 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, |
755 options.unique(), options.multiEntry()); | 749 options.unique(), options.multiEntry()); |
756 | 750 |
757 ++m_metadata.maxIndexId; | 751 ++m_metadata->maxIndexId; |
758 | 752 |
759 IDBIndexMetadata indexMetadata(name, indexId, keyPath, options.unique(), | 753 RefPtr<IDBIndexMetadata> indexMetadata = adoptRef(new IDBIndexMetadata( |
760 options.multiEntry()); | 754 name, indexId, keyPath, options.unique(), options.multiEntry())); |
761 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()); | 755 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()); |
762 m_indexMap.set(name, index); | 756 m_indexMap.set(name, index); |
763 m_createdIndexes.add(index); | 757 m_metadata->indexes.set(indexId, indexMetadata); |
764 m_metadata.indexes.set(indexId, indexMetadata); | |
765 m_transaction->db()->indexCreated(id(), indexMetadata); | |
766 | 758 |
767 DCHECK(!exceptionState.hadException()); | 759 DCHECK(!exceptionState.hadException()); |
768 if (exceptionState.hadException()) | 760 if (exceptionState.hadException()) |
769 return nullptr; | 761 return nullptr; |
770 | 762 |
771 IDBRequest* indexRequest = | 763 IDBRequest* indexRequest = |
772 openCursor(scriptState, nullptr, WebIDBCursorDirectionNext, | 764 openCursor(scriptState, nullptr, WebIDBCursorDirectionNext, |
773 WebIDBTaskTypePreemptive); | 765 WebIDBTaskTypePreemptive); |
774 indexRequest->preventPropagation(); | 766 indexRequest->preventPropagation(); |
775 | 767 |
776 // This is kept alive by being the success handler of the request, which is in | 768 // This is kept alive by being the success handler of the request, which is in |
777 // turn kept alive by the owning transaction. | 769 // turn kept alive by the owning transaction. |
778 IndexPopulator* indexPopulator = | 770 IndexPopulator* indexPopulator = IndexPopulator::create( |
779 IndexPopulator::create(scriptState, transaction()->db(), | 771 scriptState, transaction()->db(), m_transaction->id(), id(), |
780 m_transaction->id(), id(), indexMetadata); | 772 std::move(indexMetadata)); |
781 indexRequest->setOnsuccess(indexPopulator); | 773 indexRequest->setOnsuccess(indexPopulator); |
782 return index; | 774 return index; |
783 } | 775 } |
784 | 776 |
785 IDBIndex* IDBObjectStore::index(const String& name, | 777 IDBIndex* IDBObjectStore::index(const String& name, |
786 ExceptionState& exceptionState) { | 778 ExceptionState& exceptionState) { |
787 IDB_TRACE("IDBObjectStore::index"); | 779 IDB_TRACE("IDBObjectStore::index"); |
788 if (isDeleted()) { | 780 if (isDeleted()) { |
789 exceptionState.throwDOMException( | 781 exceptionState.throwDOMException( |
790 InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); | 782 InvalidStateError, IDBDatabase::objectStoreDeletedErrorMessage); |
(...skipping 10 matching lines...) Expand all Loading... | |
801 return it->value; | 793 return it->value; |
802 | 794 |
803 int64_t indexId = findIndexId(name); | 795 int64_t indexId = findIndexId(name); |
804 if (indexId == IDBIndexMetadata::InvalidId) { | 796 if (indexId == IDBIndexMetadata::InvalidId) { |
805 exceptionState.throwDOMException(NotFoundError, | 797 exceptionState.throwDOMException(NotFoundError, |
806 IDBDatabase::noSuchIndexErrorMessage); | 798 IDBDatabase::noSuchIndexErrorMessage); |
807 return nullptr; | 799 return nullptr; |
808 } | 800 } |
809 | 801 |
810 DCHECK(metadata().indexes.contains(indexId)); | 802 DCHECK(metadata().indexes.contains(indexId)); |
811 const IDBIndexMetadata& indexMetadata = metadata().indexes.get(indexId); | 803 RefPtr<IDBIndexMetadata> indexMetadata = metadata().indexes.get(indexId); |
812 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()); | 804 DCHECK(indexMetadata.get()); |
805 IDBIndex* index = | |
806 IDBIndex::create(std::move(indexMetadata), this, m_transaction.get()); | |
813 m_indexMap.set(name, index); | 807 m_indexMap.set(name, index); |
814 return index; | 808 return index; |
815 } | 809 } |
816 | 810 |
817 void IDBObjectStore::deleteIndex(const String& name, | 811 void IDBObjectStore::deleteIndex(const String& name, |
818 ExceptionState& exceptionState) { | 812 ExceptionState& exceptionState) { |
819 IDB_TRACE("IDBObjectStore::deleteIndex"); | 813 IDB_TRACE("IDBObjectStore::deleteIndex"); |
820 if (!m_transaction->isVersionChange()) { | 814 if (!m_transaction->isVersionChange()) { |
821 exceptionState.throwDOMException( | 815 exceptionState.throwDOMException( |
822 InvalidStateError, | 816 InvalidStateError, |
(...skipping 22 matching lines...) Expand all Loading... | |
845 return; | 839 return; |
846 } | 840 } |
847 if (!backendDB()) { | 841 if (!backendDB()) { |
848 exceptionState.throwDOMException(InvalidStateError, | 842 exceptionState.throwDOMException(InvalidStateError, |
849 IDBDatabase::databaseClosedErrorMessage); | 843 IDBDatabase::databaseClosedErrorMessage); |
850 return; | 844 return; |
851 } | 845 } |
852 | 846 |
853 backendDB()->deleteIndex(m_transaction->id(), id(), indexId); | 847 backendDB()->deleteIndex(m_transaction->id(), id(), indexId); |
854 | 848 |
855 m_metadata.indexes.remove(indexId); | 849 m_metadata->indexes.remove(indexId); |
856 m_transaction->db()->indexDeleted(id(), indexId); | |
857 IDBIndexMap::iterator it = m_indexMap.find(name); | 850 IDBIndexMap::iterator it = m_indexMap.find(name); |
858 if (it != m_indexMap.end()) { | 851 if (it != m_indexMap.end()) { |
852 m_transaction->indexDeleted(it->value); | |
859 it->value->markDeleted(); | 853 it->value->markDeleted(); |
860 m_indexMap.remove(name); | 854 m_indexMap.remove(name); |
861 } | 855 } |
862 } | 856 } |
863 | 857 |
864 IDBRequest* IDBObjectStore::openCursor(ScriptState* scriptState, | 858 IDBRequest* IDBObjectStore::openCursor(ScriptState* scriptState, |
865 const ScriptValue& range, | 859 const ScriptValue& range, |
866 const String& directionString, | 860 const String& directionString, |
867 ExceptionState& exceptionState) { | 861 ExceptionState& exceptionState) { |
868 IDB_TRACE("IDBObjectStore::openCursor"); | 862 IDB_TRACE("IDBObjectStore::openCursor"); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
991 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), | 985 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), |
992 m_transaction.get()); | 986 m_transaction.get()); |
993 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, | 987 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, |
994 keyRange, WebIDBCallbacksImpl::create(request).release()); | 988 keyRange, WebIDBCallbacksImpl::create(request).release()); |
995 return request; | 989 return request; |
996 } | 990 } |
997 | 991 |
998 void IDBObjectStore::markDeleted() { | 992 void IDBObjectStore::markDeleted() { |
999 DCHECK(m_transaction->isVersionChange()) | 993 DCHECK(m_transaction->isVersionChange()) |
1000 << "An object store got deleted outside a versionchange transaction."; | 994 << "An object store got deleted outside a versionchange transaction."; |
995 | |
1001 m_deleted = true; | 996 m_deleted = true; |
997 m_metadata->indexes.clear(); | |
998 | |
999 for (auto& it : m_indexMap) { | |
1000 IDBIndex* index = it.value; | |
1001 index->markDeleted(); | |
1002 } | |
1002 } | 1003 } |
1003 | 1004 |
1004 void IDBObjectStore::abort() { | 1005 void IDBObjectStore::clearIndexCache() { |
1005 for (auto& index : m_createdIndexes) | 1006 DCHECK(!m_transaction->isActive() || |
1006 index->markDeleted(); | 1007 (isDeleted() && id() > m_transaction->oldMaxObjectStoreId())); |
1008 | |
1009 // There is no harm in having clearIndexCache() happen multiple times for | |
1010 // the same object. We assert that it is called once to uncover potential | |
1011 // object store accounting bugs. | |
1012 #if DCHECK_IS_ON() | |
1013 DCHECK(!m_clearIndexCacheCalled); | |
1014 m_clearIndexCacheCalled = true; | |
1015 #endif // DCHECK_IS_ON() | |
1016 | |
1017 m_indexMap.clear(); | |
1007 } | 1018 } |
1008 | 1019 |
1009 void IDBObjectStore::transactionFinished() { | 1020 void IDBObjectStore::revertMetadata( |
1021 RefPtr<IDBObjectStoreMetadata> oldMetadata) { | |
1022 DCHECK(m_transaction->isVersionChange()); | |
1010 DCHECK(!m_transaction->isActive()); | 1023 DCHECK(!m_transaction->isActive()); |
1024 DCHECK(oldMetadata.get()); | |
1025 DCHECK(id() == oldMetadata->id); | |
1011 | 1026 |
1012 // Break reference cycles. | 1027 // Index IDs are allocated sequentially, so we can tell if an index was |
1013 // TODO(jsbell): This can be removed c/o Oilpan. | 1028 // created in this transaction by comparing its ID with the object store's |
1014 m_indexMap.clear(); | 1029 // maximum index ID at the time when the transaction was started. |
1015 m_createdIndexes.clear(); | 1030 const int64_t oldMaxIndexId = oldMetadata->maxIndexId; |
1031 for (auto& it : m_indexMap) { | |
1032 IDBIndex* index = it.value; | |
1033 const int64_t indexId = index->id(); | |
1034 | |
1035 if (indexId > oldMaxIndexId) { | |
1036 // The index was created by this transaction. According to the spec, | |
1037 // its metadata will remain as-is. | |
1038 DCHECK(!oldMetadata->indexes.contains(indexId)); | |
1039 index->markDeleted(); | |
1040 continue; | |
1041 } | |
1042 | |
1043 // The index was created in a previous transaction. We need to revert | |
1044 // its metadata. The index might have been deleted, so we | |
1045 // unconditionally reset the deletion marker. | |
1046 DCHECK(oldMetadata->indexes.contains(indexId)); | |
1047 RefPtr<IDBIndexMetadata> oldIndexMetadata = | |
1048 oldMetadata->indexes.get(indexId); | |
1049 index->revertMetadata(std::move(oldIndexMetadata)); | |
1050 } | |
1051 m_metadata = std::move(oldMetadata); | |
1052 | |
1053 // An object store's metadata will only get reverted if the index was in the | |
1054 // database when the versionchange transaction started. | |
1055 m_deleted = false; | |
1016 } | 1056 } |
1017 | 1057 |
1018 void IDBObjectStore::indexRenamed(int64_t indexId, const String& newName) { | 1058 void IDBObjectStore::revertDeletedIndexMetadata(IDBIndex& deletedIndex) { |
1059 DCHECK(m_transaction->isVersionChange()); | |
1060 DCHECK(!m_transaction->isActive()); | |
1061 DCHECK(deletedIndex.objectStore() == this); | |
1062 DCHECK(deletedIndex.isDeleted()); | |
1063 | |
1064 const int64_t indexId = deletedIndex.id(); | |
1065 DCHECK(m_metadata->indexes.contains(indexId)) | |
1066 << "The object store's metadata was not correctly reverted"; | |
1067 RefPtr<IDBIndexMetadata> oldIndexMetadata = m_metadata->indexes.get(indexId); | |
1068 deletedIndex.revertMetadata(std::move(oldIndexMetadata)); | |
1069 } | |
1070 | |
1071 void IDBObjectStore::renameIndex(int64_t indexId, const String& newName) { | |
1019 DCHECK(m_transaction->isVersionChange()); | 1072 DCHECK(m_transaction->isVersionChange()); |
1020 DCHECK(m_transaction->isActive()); | 1073 DCHECK(m_transaction->isActive()); |
1021 | 1074 |
1022 auto metadataIterator = m_metadata.indexes.find(indexId); | 1075 auto metadataIterator = m_metadata->indexes.find(indexId); |
1023 DCHECK_NE(metadataIterator, m_metadata.indexes.end()) << "Invalid indexId"; | 1076 DCHECK_NE(metadataIterator, m_metadata->indexes.end()) << "Invalid indexId"; |
1024 const String& oldName = metadataIterator->value.name; | 1077 const String& oldName = metadataIterator->value->name; |
1025 | 1078 |
1026 DCHECK(m_indexMap.contains(oldName)) | 1079 DCHECK(m_indexMap.contains(oldName)) |
1027 << "The index had to be accessed in order to be renamed."; | 1080 << "The index had to be accessed in order to be renamed."; |
1028 DCHECK(!m_indexMap.contains(newName)); | 1081 DCHECK(!m_indexMap.contains(newName)); |
1029 m_indexMap.set(newName, m_indexMap.take(oldName)); | 1082 m_indexMap.set(newName, m_indexMap.take(oldName)); |
1030 | 1083 |
1031 metadataIterator->value.name = newName; | 1084 metadataIterator->value->name = newName; |
1032 } | 1085 } |
1033 | 1086 |
1034 int64_t IDBObjectStore::findIndexId(const String& name) const { | 1087 int64_t IDBObjectStore::findIndexId(const String& name) const { |
1035 for (const auto& it : metadata().indexes) { | 1088 for (const auto& it : metadata().indexes) { |
1036 if (it.value.name == name) { | 1089 if (it.value->name == name) { |
1037 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); | 1090 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); |
1038 return it.key; | 1091 return it.key; |
1039 } | 1092 } |
1040 } | 1093 } |
1041 return IDBIndexMetadata::InvalidId; | 1094 return IDBIndexMetadata::InvalidId; |
1042 } | 1095 } |
1043 | 1096 |
1044 WebIDBDatabase* IDBObjectStore::backendDB() const { | 1097 WebIDBDatabase* IDBObjectStore::backendDB() const { |
1045 return m_transaction->backendDB(); | 1098 return m_transaction->backendDB(); |
1046 } | 1099 } |
1047 | 1100 |
1048 } // namespace blink | 1101 } // namespace blink |
OLD | NEW |