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