| 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 |