Chromium Code Reviews| 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 |