| 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 | |
| 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() || (isDeleted() && isNewlyCreated())); |
| 1006 index->markDeleted(); | 1007 |
| 1008 // There is no harm in having clearIndexCache() happen multiple times for |
| 1009 // the same object. We assert that it is called once to uncover potential |
| 1010 // object store accounting bugs. |
| 1011 #if DCHECK_IS_ON() |
| 1012 DCHECK(!m_clearIndexCacheCalled); |
| 1013 m_clearIndexCacheCalled = true; |
| 1014 #endif // DCHECK_IS_ON() |
| 1015 |
| 1016 m_indexMap.clear(); |
| 1007 } | 1017 } |
| 1008 | 1018 |
| 1009 void IDBObjectStore::transactionFinished() { | 1019 void IDBObjectStore::revertMetadata( |
| 1020 RefPtr<IDBObjectStoreMetadata> oldMetadata) { |
| 1021 DCHECK(m_transaction->isVersionChange()); |
| 1010 DCHECK(!m_transaction->isActive()); | 1022 DCHECK(!m_transaction->isActive()); |
| 1023 DCHECK(oldMetadata.get()); |
| 1024 DCHECK(id() == oldMetadata->id); |
| 1011 | 1025 |
| 1012 // Break reference cycles. | 1026 for (auto& index : m_indexMap.values()) { |
| 1013 // TODO(jsbell): This can be removed c/o Oilpan. | 1027 const int64_t indexId = index->id(); |
| 1014 m_indexMap.clear(); | 1028 |
| 1015 m_createdIndexes.clear(); | 1029 if (index->isNewlyCreated(*oldMetadata)) { |
| 1030 // The index was created by this transaction. According to the spec, |
| 1031 // its metadata will remain as-is. |
| 1032 DCHECK(!oldMetadata->indexes.contains(indexId)); |
| 1033 index->markDeleted(); |
| 1034 continue; |
| 1035 } |
| 1036 |
| 1037 // The index was created in a previous transaction. We need to revert |
| 1038 // its metadata. The index might have been deleted, so we |
| 1039 // unconditionally reset the deletion marker. |
| 1040 DCHECK(oldMetadata->indexes.contains(indexId)); |
| 1041 RefPtr<IDBIndexMetadata> oldIndexMetadata = |
| 1042 oldMetadata->indexes.get(indexId); |
| 1043 index->revertMetadata(std::move(oldIndexMetadata)); |
| 1044 } |
| 1045 m_metadata = std::move(oldMetadata); |
| 1046 |
| 1047 // An object store's metadata will only get reverted if the index was in the |
| 1048 // database when the versionchange transaction started. |
| 1049 m_deleted = false; |
| 1016 } | 1050 } |
| 1017 | 1051 |
| 1018 void IDBObjectStore::indexRenamed(int64_t indexId, const String& newName) { | 1052 void IDBObjectStore::revertDeletedIndexMetadata(IDBIndex& deletedIndex) { |
| 1053 DCHECK(m_transaction->isVersionChange()); |
| 1054 DCHECK(!m_transaction->isActive()); |
| 1055 DCHECK(deletedIndex.objectStore() == this); |
| 1056 DCHECK(deletedIndex.isDeleted()); |
| 1057 |
| 1058 const int64_t indexId = deletedIndex.id(); |
| 1059 DCHECK(m_metadata->indexes.contains(indexId)) |
| 1060 << "The object store's metadata was not correctly reverted"; |
| 1061 RefPtr<IDBIndexMetadata> oldIndexMetadata = m_metadata->indexes.get(indexId); |
| 1062 deletedIndex.revertMetadata(std::move(oldIndexMetadata)); |
| 1063 } |
| 1064 |
| 1065 void IDBObjectStore::renameIndex(int64_t indexId, const String& newName) { |
| 1019 DCHECK(m_transaction->isVersionChange()); | 1066 DCHECK(m_transaction->isVersionChange()); |
| 1020 DCHECK(m_transaction->isActive()); | 1067 DCHECK(m_transaction->isActive()); |
| 1021 | 1068 |
| 1022 auto metadataIterator = m_metadata.indexes.find(indexId); | 1069 backendDB()->renameIndex(m_transaction->id(), id(), indexId, newName); |
| 1023 DCHECK_NE(metadataIterator, m_metadata.indexes.end()) << "Invalid indexId"; | 1070 |
| 1024 const String& oldName = metadataIterator->value.name; | 1071 auto metadataIterator = m_metadata->indexes.find(indexId); |
| 1072 DCHECK_NE(metadataIterator, m_metadata->indexes.end()) << "Invalid indexId"; |
| 1073 const String& oldName = metadataIterator->value->name; |
| 1025 | 1074 |
| 1026 DCHECK(m_indexMap.contains(oldName)) | 1075 DCHECK(m_indexMap.contains(oldName)) |
| 1027 << "The index had to be accessed in order to be renamed."; | 1076 << "The index had to be accessed in order to be renamed."; |
| 1028 DCHECK(!m_indexMap.contains(newName)); | 1077 DCHECK(!m_indexMap.contains(newName)); |
| 1029 m_indexMap.set(newName, m_indexMap.take(oldName)); | 1078 m_indexMap.set(newName, m_indexMap.take(oldName)); |
| 1030 | 1079 |
| 1031 metadataIterator->value.name = newName; | 1080 metadataIterator->value->name = newName; |
| 1032 } | 1081 } |
| 1033 | 1082 |
| 1034 int64_t IDBObjectStore::findIndexId(const String& name) const { | 1083 int64_t IDBObjectStore::findIndexId(const String& name) const { |
| 1035 for (const auto& it : metadata().indexes) { | 1084 for (const auto& it : metadata().indexes) { |
| 1036 if (it.value.name == name) { | 1085 if (it.value->name == name) { |
| 1037 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); | 1086 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); |
| 1038 return it.key; | 1087 return it.key; |
| 1039 } | 1088 } |
| 1040 } | 1089 } |
| 1041 return IDBIndexMetadata::InvalidId; | 1090 return IDBIndexMetadata::InvalidId; |
| 1042 } | 1091 } |
| 1043 | 1092 |
| 1044 WebIDBDatabase* IDBObjectStore::backendDB() const { | 1093 WebIDBDatabase* IDBObjectStore::backendDB() const { |
| 1045 return m_transaction->backendDB(); | 1094 return m_transaction->backendDB(); |
| 1046 } | 1095 } |
| 1047 | 1096 |
| 1048 } // namespace blink | 1097 } // namespace blink |
| OLD | NEW |