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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |