Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBObjectStore.cpp

Issue 2314933005: Align IndexedDB metadata rollback on transaction abort to spec. (Closed)
Patch Set: Rebased. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h" 48 #include "public/platform/modules/indexeddb/WebIDBKeyRange.h"
49 #include <memory> 49 #include <memory>
50 #include <v8.h> 50 #include <v8.h>
51 51
52 using blink::WebBlobInfo; 52 using blink::WebBlobInfo;
53 using blink::WebIDBCallbacks; 53 using blink::WebIDBCallbacks;
54 using blink::WebIDBCursor; 54 using blink::WebIDBCursor;
55 using blink::WebIDBDatabase; 55 using blink::WebIDBDatabase;
56 using blink::WebVector; 56 using blink::WebVector;
57 57
58
jsbell 2016/09/26 22:23:40 Nit: remove extra blank line
pwnall 2016/09/27 00:12:19 Done.
58 namespace blink { 59 namespace blink {
59 60
60 namespace { 61 namespace {
61 62
62 using IndexKeys = HeapVector<Member<IDBKey>>; 63 using IndexKeys = HeapVector<Member<IDBKey>>;
63
64 } 64 }
65 65
66 IDBObjectStore::IDBObjectStore(const IDBObjectStoreMetadata& metadata, IDBTransa ction* transaction) 66 IDBObjectStore::IDBObjectStore(RefPtr<IDBObjectStoreMetadata> metadata, IDBTrans action* transaction)
67 : m_metadata(metadata) 67 : m_metadata(std::move(metadata))
68 , m_transaction(transaction) 68 , m_transaction(transaction)
69 { 69 {
70 DCHECK(m_transaction); 70 DCHECK(m_transaction);
71 DCHECK(m_metadata.get());
71 } 72 }
72 73
73 DEFINE_TRACE(IDBObjectStore) 74 DEFINE_TRACE(IDBObjectStore)
74 { 75 {
75 visitor->trace(m_transaction); 76 visitor->trace(m_transaction);
76 visitor->trace(m_indexMap); 77 visitor->trace(m_indexMap);
77 visitor->trace(m_createdIndexes);
78 } 78 }
79 79
80 void IDBObjectStore::setName(const String& name, ExceptionState& exceptionState) 80 void IDBObjectStore::setName(const String& name, ExceptionState& exceptionState)
81 { 81 {
82 if (!RuntimeEnabledFeatures::indexedDBExperimentalEnabled()) 82 if (!RuntimeEnabledFeatures::indexedDBExperimentalEnabled())
83 return; 83 return;
84 84
85 IDB_TRACE("IDBObjectStore::setName"); 85 IDB_TRACE("IDBObjectStore::setName");
86 if (!m_transaction->isVersionChange()) { 86 if (!m_transaction->isVersionChange()) {
87 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); 87 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage);
(...skipping 16 matching lines...) Expand all
104 return; 104 return;
105 if (m_transaction->db()->containsObjectStore(name)) { 105 if (m_transaction->db()->containsObjectStore(name)) {
106 exceptionState.throwDOMException(ConstraintError, IDBDatabase::objectSto reNameTakenErrorMessage); 106 exceptionState.throwDOMException(ConstraintError, IDBDatabase::objectSto reNameTakenErrorMessage);
107 return; 107 return;
108 } 108 }
109 if (!backendDB()) { 109 if (!backendDB()) {
110 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); 110 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage);
111 return; 111 return;
112 } 112 }
113 113
114 backendDB()->renameObjectStore(m_transaction->id(), id(), name); 114 m_transaction->db()->renameObjectStore(id(), name);
115 m_transaction->objectStoreRenamed(m_metadata.name, name);
116 m_metadata.name = name;
117
118 // The name inside the database's version of the object store metadata is us ed by IDBDatabase.objectStoreNames().
119 // If the transaction is aborted, this name will be reverted when the metada ta is overwritten with the previousMetadata in IDBTransaction.
120 m_transaction->db()->objectStoreRenamed(id(), name);
121 } 115 }
122 116
123 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const 117 ScriptValue IDBObjectStore::keyPath(ScriptState* scriptState) const
124 { 118 {
125 return ScriptValue::from(scriptState, metadata().keyPath); 119 return ScriptValue::from(scriptState, metadata().keyPath);
126 } 120 }
127 121
128 DOMStringList* IDBObjectStore::indexNames() const 122 DOMStringList* IDBObjectStore::indexNames() const
129 { 123 {
130 IDB_TRACE("IDBObjectStore::indexNames"); 124 IDB_TRACE("IDBObjectStore::indexNames");
131 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB); 125 DOMStringList* indexNames = DOMStringList::create(DOMStringList::IndexedDB);
132 for (const auto& it : metadata().indexes) 126 for (const auto& it : metadata().indexes)
133 indexNames->append(it.value.name); 127 indexNames->append(it.value->name);
134 indexNames->sort(); 128 indexNames->sort();
135 return indexNames; 129 return indexNames;
136 } 130 }
137 131
138 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, const ScriptValue& key , ExceptionState& exceptionState) 132 IDBRequest* IDBObjectStore::get(ScriptState* scriptState, const ScriptValue& key , ExceptionState& exceptionState)
139 { 133 {
140 IDB_TRACE("IDBObjectStore::get"); 134 IDB_TRACE("IDBObjectStore::get");
141 if (isDeleted()) { 135 if (isDeleted()) {
142 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); 136 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage);
143 return nullptr; 137 return nullptr;
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); 399 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage);
406 return nullptr; 400 return nullptr;
407 } 401 }
408 402
409 Vector<int64_t> indexIds; 403 Vector<int64_t> indexIds;
410 HeapVector<IndexKeys> indexKeys; 404 HeapVector<IndexKeys> indexKeys;
411 for (const auto& it : metadata().indexes) { 405 for (const auto& it : metadata().indexes) {
412 if (clone.isEmpty()) 406 if (clone.isEmpty())
413 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo); 407 clone = deserializeScriptValue(scriptState, serializedValue.get(), & blobInfo);
414 IndexKeys keys; 408 IndexKeys keys;
415 generateIndexKeysForValue(scriptState->isolate(), it.value, clone, &keys ); 409 generateIndexKeysForValue(scriptState->isolate(), *it.value, clone, &key s);
416 indexIds.append(it.key); 410 indexIds.append(it.key);
417 indexKeys.append(keys); 411 indexKeys.append(keys);
418 } 412 }
419 413
420 IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction. get()); 414 IDBRequest* request = IDBRequest::create(scriptState, source, m_transaction. get());
421 Vector<char> wireBytes; 415 Vector<char> wireBytes;
422 serializedValue->toWireBytes(wireBytes); 416 serializedValue->toWireBytes(wireBytes);
423 RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes); 417 RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(wireBytes);
424 418
425 backendDB()->put(m_transaction->id(), id(), WebData(valueBuffer), blobInfo, key, static_cast<WebIDBPutMode>(putMode), WebIDBCallbacksImpl::create(request).r elease(), indexIds, indexKeys); 419 backendDB()->put(m_transaction->id(), id(), WebData(valueBuffer), blobInfo, key, static_cast<WebIDBPutMode>(putMode), WebIDBCallbacksImpl::create(request).r elease(), indexIds, indexKeys);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 } 487 }
494 488
495 namespace { 489 namespace {
496 // This class creates the index keys for a given index by extracting 490 // This class creates the index keys for a given index by extracting
497 // them from the SerializedScriptValue, for all the existing values in 491 // them from the SerializedScriptValue, for all the existing values in
498 // the objectStore. It only needs to be kept alive by virtue of being 492 // the objectStore. It only needs to be kept alive by virtue of being
499 // a listener on an IDBRequest object, in the same way that JavaScript 493 // a listener on an IDBRequest object, in the same way that JavaScript
500 // cursor success handlers are kept alive. 494 // cursor success handlers are kept alive.
501 class IndexPopulator final : public EventListener { 495 class IndexPopulator final : public EventListener {
502 public: 496 public:
503 static IndexPopulator* create(ScriptState* scriptState, IDBDatabase* databas e, int64_t transactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMe tadata) 497 static IndexPopulator* create(ScriptState* scriptState, IDBDatabase* databas e, int64_t transactionId, int64_t objectStoreId, RefPtr<const IDBIndexMetadata> indexMetadata)
504 { 498 {
505 return new IndexPopulator(scriptState, database, transactionId, objectSt oreId, indexMetadata); 499 return new IndexPopulator(scriptState, database, transactionId, objectSt oreId, std::move(indexMetadata));
506 } 500 }
507 501
508 bool operator==(const EventListener& other) const override 502 bool operator==(const EventListener& other) const override
509 { 503 {
510 return this == &other; 504 return this == &other;
511 } 505 }
512 506
513 DEFINE_INLINE_VIRTUAL_TRACE() 507 DEFINE_INLINE_VIRTUAL_TRACE()
514 { 508 {
515 visitor->trace(m_database); 509 visitor->trace(m_database);
516 EventListener::trace(visitor); 510 EventListener::trace(visitor);
517 } 511 }
518 512
519 private: 513 private:
520 IndexPopulator(ScriptState* scriptState, IDBDatabase* database, int64_t tran sactionId, int64_t objectStoreId, const IDBIndexMetadata& indexMetadata) 514 IndexPopulator(ScriptState* scriptState, IDBDatabase* database, int64_t tran sactionId, int64_t objectStoreId, RefPtr<const IDBIndexMetadata> indexMetadata)
521 : EventListener(CPPEventListenerType) 515 : EventListener(CPPEventListenerType)
522 , m_scriptState(scriptState) 516 , m_scriptState(scriptState)
523 , m_database(database) 517 , m_database(database)
524 , m_transactionId(transactionId) 518 , m_transactionId(transactionId)
525 , m_objectStoreId(objectStoreId) 519 , m_objectStoreId(objectStoreId)
526 , m_indexMetadata(indexMetadata) 520 , m_indexMetadata(std::move(indexMetadata))
527 { 521 {
522 DCHECK(m_indexMetadata.get());
528 } 523 }
529 524
530 const IDBIndexMetadata& indexMetadata() const { return m_indexMetadata; } 525 const IDBIndexMetadata& indexMetadata() const { return *m_indexMetadata; }
531 526
532 void handleEvent(ExecutionContext* executionContext, Event* event) override 527 void handleEvent(ExecutionContext* executionContext, Event* event) override
533 { 528 {
534 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext); 529 DCHECK_EQ(m_scriptState->getExecutionContext(), executionContext);
535 DCHECK_EQ(event->type(), EventTypeNames::success); 530 DCHECK_EQ(event->type(), EventTypeNames::success);
536 EventTarget* target = event->target(); 531 EventTarget* target = event->target();
537 IDBRequest* request = static_cast<IDBRequest*>(target); 532 IDBRequest* request = static_cast<IDBRequest*>(target);
538 533
539 if (!m_database->backend()) // If database is stopped? 534 if (!m_database->backend()) // If database is stopped?
540 return; 535 return;
(...skipping 24 matching lines...) Expand all
565 m_database->backend()->setIndexesReady(m_transactionId, m_objectStor eId, indexIds); 560 m_database->backend()->setIndexesReady(m_transactionId, m_objectStor eId, indexIds);
566 m_database.clear(); 561 m_database.clear();
567 } 562 }
568 563
569 } 564 }
570 565
571 RefPtr<ScriptState> m_scriptState; 566 RefPtr<ScriptState> m_scriptState;
572 Member<IDBDatabase> m_database; 567 Member<IDBDatabase> m_database;
573 const int64_t m_transactionId; 568 const int64_t m_transactionId;
574 const int64_t m_objectStoreId; 569 const int64_t m_objectStoreId;
575 const IDBIndexMetadata m_indexMetadata; 570 RefPtr<const IDBIndexMetadata> m_indexMetadata;
576 }; 571 };
577 } // namespace 572 } // namespace
578 573
579 IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, const String& na me, const IDBKeyPath& keyPath, const IDBIndexParameters& options, ExceptionState & exceptionState) 574 IDBIndex* IDBObjectStore::createIndex(ScriptState* scriptState, const String& na me, const IDBKeyPath& keyPath, const IDBIndexParameters& options, ExceptionState & exceptionState)
580 { 575 {
581 IDB_TRACE("IDBObjectStore::createIndex"); 576 IDB_TRACE("IDBObjectStore::createIndex");
582 if (!m_transaction->isVersionChange()) { 577 if (!m_transaction->isVersionChange()) {
583 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); 578 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage);
584 return nullptr; 579 return nullptr;
585 } 580 }
(...skipping 19 matching lines...) Expand all
605 } 600 }
606 if (keyPath.getType() == IDBKeyPath::ArrayType && options.multiEntry()) { 601 if (keyPath.getType() == IDBKeyPath::ArrayType && options.multiEntry()) {
607 exceptionState.throwDOMException(InvalidAccessError, "The keyPath argume nt was an array and the multiEntry option is true."); 602 exceptionState.throwDOMException(InvalidAccessError, "The keyPath argume nt was an array and the multiEntry option is true.");
608 return nullptr; 603 return nullptr;
609 } 604 }
610 if (!backendDB()) { 605 if (!backendDB()) {
611 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); 606 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage);
612 return nullptr; 607 return nullptr;
613 } 608 }
614 609
615 int64_t indexId = m_metadata.maxIndexId + 1; 610 int64_t indexId = m_metadata->maxIndexId + 1;
616 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId); 611 DCHECK_NE(indexId, IDBIndexMetadata::InvalidId);
617 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry()); 612 backendDB()->createIndex(m_transaction->id(), id(), indexId, name, keyPath, options.unique(), options.multiEntry());
618 613
619 ++m_metadata.maxIndexId; 614 ++m_metadata->maxIndexId;
620 615
621 IDBIndexMetadata indexMetadata(name, indexId, keyPath, options.unique(), opt ions.multiEntry()); 616 RefPtr<IDBIndexMetadata> indexMetadata = adoptRef(new IDBIndexMetadata(
617 name, indexId, keyPath, options.unique(), options.multiEntry()));
622 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; 618 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ;
623 m_indexMap.set(name, index); 619 m_indexMap.set(name, index);
624 m_createdIndexes.add(index); 620 m_metadata->indexes.set(indexId, indexMetadata);
625 m_metadata.indexes.set(indexId, indexMetadata);
626 m_transaction->db()->indexCreated(id(), indexMetadata);
627 621
628 DCHECK(!exceptionState.hadException()); 622 DCHECK(!exceptionState.hadException());
629 if (exceptionState.hadException()) 623 if (exceptionState.hadException())
630 return nullptr; 624 return nullptr;
631 625
632 IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDire ctionNext, WebIDBTaskTypePreemptive); 626 IDBRequest* indexRequest = openCursor(scriptState, nullptr, WebIDBCursorDire ctionNext, WebIDBTaskTypePreemptive);
633 indexRequest->preventPropagation(); 627 indexRequest->preventPropagation();
634 628
635 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction. 629 // This is kept alive by being the success handler of the request, which is in turn kept alive by the owning transaction.
636 IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transac tion()->db(), m_transaction->id(), id(), indexMetadata); 630 IndexPopulator* indexPopulator = IndexPopulator::create(scriptState, transac tion()->db(), m_transaction->id(), id(), std::move(indexMetadata));
637 indexRequest->setOnsuccess(indexPopulator); 631 indexRequest->setOnsuccess(indexPopulator);
638 return index; 632 return index;
639 } 633 }
640 634
641 IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionSta te) 635 IDBIndex* IDBObjectStore::index(const String& name, ExceptionState& exceptionSta te)
642 { 636 {
643 IDB_TRACE("IDBObjectStore::index"); 637 IDB_TRACE("IDBObjectStore::index");
644 if (isDeleted()) { 638 if (isDeleted()) {
645 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); 639 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage);
646 return nullptr; 640 return nullptr;
647 } 641 }
648 if (m_transaction->isFinished() || m_transaction->isFinishing()) { 642 if (m_transaction->isFinished() || m_transaction->isFinishing()) {
649 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage); 643 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transac tionFinishedErrorMessage);
650 return nullptr; 644 return nullptr;
651 } 645 }
652 646
653 IDBIndexMap::iterator it = m_indexMap.find(name); 647 IDBIndexMap::iterator it = m_indexMap.find(name);
654 if (it != m_indexMap.end()) 648 if (it != m_indexMap.end())
655 return it->value; 649 return it->value;
656 650
657 int64_t indexId = findIndexId(name); 651 int64_t indexId = findIndexId(name);
658 if (indexId == IDBIndexMetadata::InvalidId) { 652 if (indexId == IDBIndexMetadata::InvalidId) {
659 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); 653 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage);
660 return nullptr; 654 return nullptr;
661 } 655 }
662 656
663 DCHECK(metadata().indexes.contains(indexId)); 657 DCHECK(metadata().indexes.contains(indexId));
664 const IDBIndexMetadata& indexMetadata = metadata().indexes.get(indexId); 658 RefPtr<IDBIndexMetadata> indexMetadata = metadata().indexes.get(indexId);
665 IDBIndex* index = IDBIndex::create(indexMetadata, this, m_transaction.get()) ; 659 DCHECK(indexMetadata.get());
660 IDBIndex* index = IDBIndex::create(std::move(indexMetadata), this, m_transac tion.get());
666 m_indexMap.set(name, index); 661 m_indexMap.set(name, index);
667 return index; 662 return index;
668 } 663 }
669 664
670 void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionSt ate) 665 void IDBObjectStore::deleteIndex(const String& name, ExceptionState& exceptionSt ate)
671 { 666 {
672 IDB_TRACE("IDBObjectStore::deleteIndex"); 667 IDB_TRACE("IDBObjectStore::deleteIndex");
673 if (!m_transaction->isVersionChange()) { 668 if (!m_transaction->isVersionChange()) {
674 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage); 669 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::notVers ionChangeTransactionErrorMessage);
675 return; 670 return;
(...skipping 15 matching lines...) Expand all
691 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage); 686 exceptionState.throwDOMException(NotFoundError, IDBDatabase::noSuchIndex ErrorMessage);
692 return; 687 return;
693 } 688 }
694 if (!backendDB()) { 689 if (!backendDB()) {
695 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage); 690 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::databas eClosedErrorMessage);
696 return; 691 return;
697 } 692 }
698 693
699 backendDB()->deleteIndex(m_transaction->id(), id(), indexId); 694 backendDB()->deleteIndex(m_transaction->id(), id(), indexId);
700 695
701 m_metadata.indexes.remove(indexId); 696 m_metadata->indexes.remove(indexId);
702 m_transaction->db()->indexDeleted(id(), indexId);
703 IDBIndexMap::iterator it = m_indexMap.find(name); 697 IDBIndexMap::iterator it = m_indexMap.find(name);
704 if (it != m_indexMap.end()) { 698 if (it != m_indexMap.end()) {
699 m_transaction->indexDeleted(it->value);
705 it->value->markDeleted(); 700 it->value->markDeleted();
706 m_indexMap.remove(name); 701 m_indexMap.remove(name);
707 } 702 }
708 } 703 }
709 704
710 IDBRequest* IDBObjectStore::openCursor(ScriptState* scriptState, const ScriptVal ue& range, const String& directionString, ExceptionState& exceptionState) 705 IDBRequest* IDBObjectStore::openCursor(ScriptState* scriptState, const ScriptVal ue& range, const String& directionString, ExceptionState& exceptionState)
711 { 706 {
712 IDB_TRACE("IDBObjectStore::openCursor"); 707 IDB_TRACE("IDBObjectStore::openCursor");
713 if (isDeleted()) { 708 if (isDeleted()) {
714 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage); 709 exceptionState.throwDOMException(InvalidStateError, IDBDatabase::objectS toreDeletedErrorMessage);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 } 799 }
805 800
806 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get()); 801 IDBRequest* request = IDBRequest::create(scriptState, IDBAny::create(this), m_transaction.get());
807 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, k eyRange, WebIDBCallbacksImpl::create(request).release()); 802 backendDB()->count(m_transaction->id(), id(), IDBIndexMetadata::InvalidId, k eyRange, WebIDBCallbacksImpl::create(request).release());
808 return request; 803 return request;
809 } 804 }
810 805
811 void IDBObjectStore::markDeleted() 806 void IDBObjectStore::markDeleted()
812 { 807 {
813 DCHECK(m_transaction->isVersionChange()) << "An object store got deleted out side a versionchange transaction."; 808 DCHECK(m_transaction->isVersionChange()) << "An object store got deleted out side a versionchange transaction.";
809
814 m_deleted = true; 810 m_deleted = true;
811 m_metadata->indexes.clear();
812
813 for (auto& it : m_indexMap) {
814 IDBIndex* index = it.value;
815 index->markDeleted();
816 }
815 } 817 }
816 818
817 void IDBObjectStore::abort() 819 void IDBObjectStore::clearIndexCache()
818 { 820 {
819 for (auto& index : m_createdIndexes) 821 DCHECK(!m_transaction->isActive() || (isDeleted() && id() > m_transaction->o ldMaxObjectStoreId()));
820 index->markDeleted(); 822
823 // There is no harm in having clearIndexCache() happen multiple times for
824 // the same object. We assert that it is called once to uncover potential
825 // object store accounting bugs.
826 #if DCHECK_IS_ON()
827 DCHECK(!m_clearIndexCacheCalled);
828 m_clearIndexCacheCalled = true;
829 #endif // DCHECK_IS_ON()
830
831 m_indexMap.clear();
821 } 832 }
822 833
823 void IDBObjectStore::transactionFinished() 834 void IDBObjectStore::revertMetadata(RefPtr<IDBObjectStoreMetadata> oldMetadata)
824 { 835 {
836 DCHECK(m_transaction->isVersionChange());
825 DCHECK(!m_transaction->isActive()); 837 DCHECK(!m_transaction->isActive());
838 DCHECK(oldMetadata.get());
839 DCHECK(id() == oldMetadata->id);
826 840
827 // Break reference cycles. 841 // Index IDs are allocated sequentially, so we can tell if an index was
828 // TODO(jsbell): This can be removed c/o Oilpan. 842 // created in this transaction by comparing its ID with the object store's
829 m_indexMap.clear(); 843 // maximum index ID at the time when the transaction was started.
830 m_createdIndexes.clear(); 844 const int64_t oldMaxIndexId = oldMetadata->maxIndexId;
845 for (auto& it : m_indexMap) {
846 IDBIndex* index = it.value;
847 const int64_t indexId = index->id();
848
849 if (indexId > oldMaxIndexId) {
850 // The index was created by this transaction. According to the spec,
851 // its metadata will remain as-is. We just need to look up the
jsbell 2016/09/26 22:23:40 You can drop the second sentence here ("We just ne
pwnall 2016/09/27 00:12:19 Done. Thanks, that's a very good point!
852 // index's IDBIndex instance, and mark it as deleted.
853 DCHECK(!oldMetadata->indexes.contains(indexId));
854 index->markDeleted();
855 continue;
856 }
857
858 // The index was created in a previous transaction. We need to revert
859 // its metadata. The index might have been deleted, so we
860 // unconditionally reset the deletion marker. We could find out if the
jsbell 2016/09/26 22:23:40 I think you can drop the alternative here ("We cou
pwnall 2016/09/27 00:12:19 Done. Sure, as long as one of us remembers why I w
861 // index was deleted by looking up the index ID in the store's metadata,
862 // but that would be more work than the unconditional reset.
863 DCHECK(oldMetadata->indexes.contains(indexId));
864 RefPtr<IDBIndexMetadata> oldIndexMetadata = oldMetadata->indexes.get(ind exId);
865 index->revertMetadata(std::move(oldIndexMetadata));
866 }
867 m_metadata = std::move(oldMetadata);
868
869 // An object store's metadata will only get reverted if the index was in the
870 // database when the versionchange transaction started.
871 m_deleted = false;
831 } 872 }
832 873
833 void IDBObjectStore::indexRenamed(int64_t indexId, const String& newName) 874 void IDBObjectStore::revertDeletedIndexMetadata(IDBIndex& deletedIndex)
875 {
876 DCHECK(m_transaction->isVersionChange());
877 DCHECK(!m_transaction->isActive());
878 DCHECK(deletedIndex.objectStore() == this);
879 DCHECK(deletedIndex.isDeleted());
880
881 const int64_t indexId = deletedIndex.id();
882 DCHECK(m_metadata->indexes.contains(indexId)) << "The object store's metadat a was not correctly reverted";
883 RefPtr<IDBIndexMetadata> oldIndexMetadata = m_metadata->indexes.get(indexId) ;
884 deletedIndex.revertMetadata(std::move(oldIndexMetadata));
885 }
886
887 void IDBObjectStore::renameIndex(int64_t indexId, const String& newName)
834 { 888 {
835 DCHECK(m_transaction->isVersionChange()); 889 DCHECK(m_transaction->isVersionChange());
836 DCHECK(m_transaction->isActive()); 890 DCHECK(m_transaction->isActive());
837 891
838 auto metadataIterator = m_metadata.indexes.find(indexId); 892 auto metadataIterator = m_metadata->indexes.find(indexId);
839 DCHECK_NE(metadataIterator, m_metadata.indexes.end()) << "Invalid indexId"; 893 DCHECK_NE(metadataIterator, m_metadata->indexes.end()) << "Invalid indexId";
840 const String& oldName = metadataIterator->value.name; 894 const String& oldName = metadataIterator->value->name;
841 895
842 DCHECK(m_indexMap.contains(oldName)) << "The index had to be accessed in ord er to be renamed."; 896 DCHECK(m_indexMap.contains(oldName)) << "The index had to be accessed in ord er to be renamed.";
843 DCHECK(!m_indexMap.contains(newName)); 897 DCHECK(!m_indexMap.contains(newName));
844 m_indexMap.set(newName, m_indexMap.take(oldName)); 898 m_indexMap.set(newName, m_indexMap.take(oldName));
845 899
846 metadataIterator->value.name = newName; 900 metadataIterator->value->name = newName;
847 } 901 }
848 902
849 int64_t IDBObjectStore::findIndexId(const String& name) const 903 int64_t IDBObjectStore::findIndexId(const String& name) const
850 { 904 {
851 for (const auto& it : metadata().indexes) { 905 for (const auto& it : metadata().indexes) {
852 if (it.value.name == name) { 906 if (it.value->name == name) {
853 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId); 907 DCHECK_NE(it.key, IDBIndexMetadata::InvalidId);
854 return it.key; 908 return it.key;
855 } 909 }
856 } 910 }
857 return IDBIndexMetadata::InvalidId; 911 return IDBIndexMetadata::InvalidId;
858 } 912 }
859 913
860 WebIDBDatabase* IDBObjectStore::backendDB() const 914 WebIDBDatabase* IDBObjectStore::backendDB() const
861 { 915 {
862 return m_transaction->backendDB(); 916 return m_transaction->backendDB();
863 } 917 }
864 918
865 } // namespace blink 919 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698