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

Side by Side Diff: content/browser/indexed_db/indexed_db_database.cc

Issue 2472213003: [IndexedDB] Refactoring to remove ref ptrs and host transaction ids. (Closed)
Patch Set: comments Created 4 years 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 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/indexed_db_database.h" 5 #include "content/browser/indexed_db/indexed_db_database.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include <limits> 9 #include <limits>
10 #include <set> 10 #include <set>
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 return KEY_PATH_TYPE_NONE; 63 return KEY_PATH_TYPE_NONE;
64 case blink::WebIDBKeyPathTypeString: 64 case blink::WebIDBKeyPathTypeString:
65 return KEY_PATH_TYPE_STRING; 65 return KEY_PATH_TYPE_STRING;
66 case blink::WebIDBKeyPathTypeArray: 66 case blink::WebIDBKeyPathTypeArray:
67 return KEY_PATH_TYPE_ARRAY; 67 return KEY_PATH_TYPE_ARRAY;
68 } 68 }
69 NOTREACHED(); 69 NOTREACHED();
70 return KEY_PATH_TYPE_NONE; 70 return KEY_PATH_TYPE_NONE;
71 } 71 }
72 72
73 // The database will be closed (IndexedDBFactory::ForceClose) during this call.
74 // This should NOT be used in an method scheduled as a transaction operation.
75 void ReportError(leveldb::Status status,
76 const url::Origin& origin,
77 IndexedDBFactory* factory,
78 const IndexedDBDatabaseError& error) {
79 DCHECK(!status.ok());
80 if (status.IsCorruption())
81 factory->HandleBackingStoreCorruption(origin, error);
82 else
83 factory->HandleBackingStoreFailure(origin);
84 }
85
73 } // namespace 86 } // namespace
74 87
75 // This represents what script calls an 'IDBOpenDBRequest' - either a database 88 // This represents what script calls an 'IDBOpenDBRequest' - either a database
76 // open or delete call. These may be blocked on other connections. After every 89 // open or delete call. These may be blocked on other connections. After every
77 // callback, the request must call IndexedDBDatabase::RequestComplete() or be 90 // callback, the request must call IndexedDBDatabase::RequestComplete() or be
78 // expecting a further callback. 91 // expecting a further callback.
79 class IndexedDBDatabase::ConnectionRequest { 92 class IndexedDBDatabase::ConnectionRequest {
80 public: 93 public:
81 explicit ConnectionRequest(scoped_refptr<IndexedDBDatabase> db) : db_(db) {} 94 explicit ConnectionRequest(scoped_refptr<IndexedDBDatabase> db) : db_(db) {}
82 95
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 return s; 470 return s;
458 if (success) 471 if (success)
459 return backing_store_->GetObjectStores(metadata_.id, 472 return backing_store_->GetObjectStores(metadata_.id,
460 &metadata_.object_stores); 473 &metadata_.object_stores);
461 474
462 return backing_store_->CreateIDBDatabaseMetaData( 475 return backing_store_->CreateIDBDatabaseMetaData(
463 metadata_.name, metadata_.version, &metadata_.id); 476 metadata_.name, metadata_.version, &metadata_.id);
464 } 477 }
465 478
466 IndexedDBDatabase::~IndexedDBDatabase() { 479 IndexedDBDatabase::~IndexedDBDatabase() {
467 DCHECK(transactions_.empty());
468 DCHECK(!active_request_); 480 DCHECK(!active_request_);
469 DCHECK(pending_requests_.empty()); 481 DCHECK(pending_requests_.empty());
470 } 482 }
471 483
472 size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const { 484 size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const {
473 return kMaxIDBMessageSizeInBytes; 485 return kMaxIDBMessageSizeInBytes;
474 } 486 }
475 487
476 std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( 488 std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection(
477 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 489 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
478 int child_process_id) { 490 int child_process_id) {
479 std::unique_ptr<IndexedDBConnection> connection( 491 std::unique_ptr<IndexedDBConnection> connection(
480 base::MakeUnique<IndexedDBConnection>(this, database_callbacks)); 492 base::MakeUnique<IndexedDBConnection>(child_process_id, this,
493 database_callbacks));
481 connections_.insert(connection.get()); 494 connections_.insert(connection.get());
482 backing_store_->GrantChildProcessPermissions(child_process_id); 495 backing_store_->GrantChildProcessPermissions(child_process_id);
483 return connection; 496 return connection;
484 } 497 }
485 498
486 IndexedDBTransaction* IndexedDBDatabase::GetTransaction(
487 int64_t transaction_id) const {
488 const auto& trans_iterator = transactions_.find(transaction_id);
489 if (trans_iterator == transactions_.end())
490 return NULL;
491 return trans_iterator->second;
492 }
493
494 bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const { 499 bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const {
495 if (!base::ContainsKey(metadata_.object_stores, object_store_id)) { 500 if (!base::ContainsKey(metadata_.object_stores, object_store_id)) {
496 DLOG(ERROR) << "Invalid object_store_id"; 501 DLOG(ERROR) << "Invalid object_store_id";
497 return false; 502 return false;
498 } 503 }
499 return true; 504 return true;
500 } 505 }
501 506
502 bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId( 507 bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(
503 int64_t object_store_id, 508 int64_t object_store_id,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 return false; 540 return false;
536 const IndexedDBObjectStoreMetadata& object_store_metadata = 541 const IndexedDBObjectStoreMetadata& object_store_metadata =
537 metadata_.object_stores.find(object_store_id)->second; 542 metadata_.object_stores.find(object_store_id)->second;
538 if (base::ContainsKey(object_store_metadata.indexes, index_id)) { 543 if (base::ContainsKey(object_store_metadata.indexes, index_id)) {
539 DLOG(ERROR) << "Invalid index_id"; 544 DLOG(ERROR) << "Invalid index_id";
540 return false; 545 return false;
541 } 546 }
542 return true; 547 return true;
543 } 548 }
544 549
545 void IndexedDBDatabase::CreateObjectStore(int64_t transaction_id, 550 void IndexedDBDatabase::CreateObjectStore(IndexedDBTransaction* transaction,
546 int64_t object_store_id, 551 int64_t object_store_id,
547 const base::string16& name, 552 const base::string16& name,
548 const IndexedDBKeyPath& key_path, 553 const IndexedDBKeyPath& key_path,
549 bool auto_increment) { 554 bool auto_increment) {
550 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id); 555 DCHECK(transaction);
551 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 556 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id",
552 if (!transaction) 557 transaction->id());
553 return;
554 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 558 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
555 559
556 if (base::ContainsKey(metadata_.object_stores, object_store_id)) { 560 if (base::ContainsKey(metadata_.object_stores, object_store_id)) {
557 DLOG(ERROR) << "Invalid object_store_id"; 561 DLOG(ERROR) << "Invalid object_store_id";
558 return; 562 return;
559 } 563 }
560 564
561 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType", 565 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType",
562 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); 566 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX);
563 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement", 567 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement",
(...skipping 14 matching lines...) Expand all
578 transaction->database()->id(), 582 transaction->database()->id(),
579 object_store_metadata.id, 583 object_store_metadata.id,
580 object_store_metadata.name, 584 object_store_metadata.name,
581 object_store_metadata.key_path, 585 object_store_metadata.key_path,
582 object_store_metadata.auto_increment); 586 object_store_metadata.auto_increment);
583 if (!s.ok()) { 587 if (!s.ok()) {
584 IndexedDBDatabaseError error( 588 IndexedDBDatabaseError error(
585 blink::WebIDBDatabaseExceptionUnknownError, 589 blink::WebIDBDatabaseExceptionUnknownError,
586 ASCIIToUTF16("Internal error creating object store '") + 590 ASCIIToUTF16("Internal error creating object store '") +
587 object_store_metadata.name + ASCIIToUTF16("'.")); 591 object_store_metadata.name + ASCIIToUTF16("'."));
588 transaction->Abort(error); 592 ReportError(s, origin(), factory_.get(), error);
589 if (s.IsCorruption())
590 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
591 return; 593 return;
592 } 594 }
593 595
594 AddObjectStore(object_store_metadata, object_store_id); 596 AddObjectStore(object_store_metadata, object_store_id);
595 transaction->ScheduleAbortTask( 597 transaction->ScheduleAbortTask(
596 base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, 598 base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation,
597 this, 599 this,
598 object_store_id)); 600 object_store_id));
599 } 601 }
600 602
601 void IndexedDBDatabase::DeleteObjectStore(int64_t transaction_id, 603 void IndexedDBDatabase::DeleteObjectStore(IndexedDBTransaction* transaction,
602 int64_t object_store_id) { 604 int64_t object_store_id) {
603 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id); 605 DCHECK(transaction);
604 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 606 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id",
605 if (!transaction) 607 transaction->id());
606 return;
607 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 608 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
608 609
609 if (!ValidateObjectStoreId(object_store_id)) 610 if (!ValidateObjectStoreId(object_store_id))
610 return; 611 return;
611 612
612 transaction->ScheduleTask( 613 transaction->ScheduleTask(
613 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, 614 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation,
614 this, 615 this,
615 object_store_id)); 616 object_store_id));
616 } 617 }
617 618
618 void IndexedDBDatabase::RenameObjectStore(int64_t transaction_id, 619 void IndexedDBDatabase::RenameObjectStore(IndexedDBTransaction* transaction,
619 int64_t object_store_id, 620 int64_t object_store_id,
620 const base::string16& new_name) { 621 const base::string16& new_name) {
621 IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id", transaction_id); 622 DCHECK(transaction);
622 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 623 IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id",
623 if (!transaction) 624 transaction->id());
624 return;
625 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 625 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
626 626
627 if (!ValidateObjectStoreId(object_store_id)) 627 if (!ValidateObjectStoreId(object_store_id))
628 return; 628 return;
629 629
630 // Store renaming is done synchronously, as it may be followed by 630 // Store renaming is done synchronously, as it may be followed by
631 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys 631 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys
632 // may follow. 632 // may follow.
633 const IndexedDBObjectStoreMetadata object_store_metadata = 633 const IndexedDBObjectStoreMetadata object_store_metadata =
634 metadata_.object_stores[object_store_id]; 634 metadata_.object_stores[object_store_id];
635 635
636 leveldb::Status s = 636 leveldb::Status s =
637 backing_store_->RenameObjectStore(transaction->BackingStoreTransaction(), 637 backing_store_->RenameObjectStore(transaction->BackingStoreTransaction(),
638 transaction->database()->id(), 638 transaction->database()->id(),
639 object_store_metadata.id, new_name); 639 object_store_metadata.id, new_name);
640 if (!s.ok()) { 640 if (!s.ok()) {
641 IndexedDBDatabaseError error( 641 IndexedDBDatabaseError error(
642 blink::WebIDBDatabaseExceptionUnknownError, 642 blink::WebIDBDatabaseExceptionUnknownError,
643 ASCIIToUTF16("Internal error renaming object store '") + 643 ASCIIToUTF16("Internal error renaming object store '") +
644 object_store_metadata.name + ASCIIToUTF16("' to '") + new_name + 644 object_store_metadata.name + ASCIIToUTF16("' to '") + new_name +
645 ASCIIToUTF16("'.")); 645 ASCIIToUTF16("'."));
646 transaction->Abort(error); 646 ReportError(s, origin(), factory_.get(), error);
647 if (s.IsCorruption())
648 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
649 return; 647 return;
650 } 648 }
651 649
652 transaction->ScheduleAbortTask( 650 transaction->ScheduleAbortTask(
653 base::Bind(&IndexedDBDatabase::RenameObjectStoreAbortOperation, 651 base::Bind(&IndexedDBDatabase::RenameObjectStoreAbortOperation,
654 this, 652 this,
655 object_store_id, 653 object_store_id,
656 object_store_metadata.name)); 654 object_store_metadata.name));
657 SetObjectStoreName(object_store_id, new_name); 655 SetObjectStoreName(object_store_id, new_name);
658 } 656 }
659 657
660 void IndexedDBDatabase::CreateIndex(int64_t transaction_id, 658 void IndexedDBDatabase::CreateIndex(IndexedDBTransaction* transaction,
661 int64_t object_store_id, 659 int64_t object_store_id,
662 int64_t index_id, 660 int64_t index_id,
663 const base::string16& name, 661 const base::string16& name,
664 const IndexedDBKeyPath& key_path, 662 const IndexedDBKeyPath& key_path,
665 bool unique, 663 bool unique,
666 bool multi_entry) { 664 bool multi_entry) {
667 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id); 665 DCHECK(transaction);
668 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 666 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction->id());
669 if (!transaction)
670 return;
671 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 667 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
672 668
673 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) 669 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id))
674 return; 670 return;
675 671
676 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType", 672 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType",
677 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); 673 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX);
678 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique); 674 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique);
679 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry", 675 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry",
680 multi_entry); 676 multi_entry);
(...skipping 26 matching lines...) Expand all
707 object_store_id, 703 object_store_id,
708 index_id)); 704 index_id));
709 } 705 }
710 706
711 void IndexedDBDatabase::CreateIndexAbortOperation(int64_t object_store_id, 707 void IndexedDBDatabase::CreateIndexAbortOperation(int64_t object_store_id,
712 int64_t index_id) { 708 int64_t index_id) {
713 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); 709 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation");
714 RemoveIndex(object_store_id, index_id); 710 RemoveIndex(object_store_id, index_id);
715 } 711 }
716 712
717 void IndexedDBDatabase::DeleteIndex(int64_t transaction_id, 713 void IndexedDBDatabase::DeleteIndex(IndexedDBTransaction* transaction,
718 int64_t object_store_id, 714 int64_t object_store_id,
719 int64_t index_id) { 715 int64_t index_id) {
720 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); 716 DCHECK(transaction);
721 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 717 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction->id());
722 if (!transaction)
723 return;
724 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 718 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
725 719
726 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 720 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id))
727 return; 721 return;
728 722
729 transaction->ScheduleTask( 723 transaction->ScheduleTask(
730 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, 724 base::Bind(&IndexedDBDatabase::DeleteIndexOperation,
731 this, 725 this,
732 object_store_id, 726 object_store_id,
733 index_id)); 727 index_id));
734 } 728 }
735 729
736 leveldb::Status IndexedDBDatabase::DeleteIndexOperation( 730 leveldb::Status IndexedDBDatabase::DeleteIndexOperation(
737 int64_t object_store_id, 731 int64_t object_store_id,
738 int64_t index_id, 732 int64_t index_id,
739 IndexedDBTransaction* transaction) { 733 IndexedDBTransaction* transaction) {
740 IDB_TRACE1( 734 IDB_TRACE1(
741 "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id()); 735 "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id());
742 736
743 const IndexedDBIndexMetadata index_metadata = 737 const IndexedDBIndexMetadata index_metadata =
744 metadata_.object_stores[object_store_id].indexes[index_id]; 738 metadata_.object_stores[object_store_id].indexes[index_id];
745 739
746 leveldb::Status s = 740 leveldb::Status s =
747 backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 741 backing_store_->DeleteIndex(transaction->BackingStoreTransaction(),
748 transaction->database()->id(), 742 transaction->database()->id(),
749 object_store_id, 743 object_store_id,
750 index_id); 744 index_id);
751 if (!s.ok()) { 745 if (!s.ok())
752 base::string16 error_string =
753 ASCIIToUTF16("Internal error deleting index '") +
754 index_metadata.name + ASCIIToUTF16("'.");
755 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
756 error_string);
757 transaction->Abort(error);
758 return s; 746 return s;
759 }
760 747
761 RemoveIndex(object_store_id, index_id); 748 RemoveIndex(object_store_id, index_id);
762 transaction->ScheduleAbortTask( 749 transaction->ScheduleAbortTask(
763 base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation, 750 base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation,
764 this, 751 this,
765 object_store_id, 752 object_store_id,
766 index_metadata)); 753 index_metadata));
767 return s; 754 return s;
768 } 755 }
769 756
770 void IndexedDBDatabase::DeleteIndexAbortOperation( 757 void IndexedDBDatabase::DeleteIndexAbortOperation(
771 int64_t object_store_id, 758 int64_t object_store_id,
772 const IndexedDBIndexMetadata& index_metadata) { 759 const IndexedDBIndexMetadata& index_metadata) {
773 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); 760 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation");
774 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); 761 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId);
775 } 762 }
776 763
777 void IndexedDBDatabase::RenameIndex(int64_t transaction_id, 764 void IndexedDBDatabase::RenameIndex(IndexedDBTransaction* transaction,
778 int64_t object_store_id, 765 int64_t object_store_id,
779 int64_t index_id, 766 int64_t index_id,
780 const base::string16& new_name) { 767 const base::string16& new_name) {
781 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction_id); 768 DCHECK(transaction);
782 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 769 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction->id());
783 if (!transaction)
784 return;
785 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 770 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
786 771
787 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 772 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id))
788 return; 773 return;
789 774
790 // Index renaming is done synchronously since preemptive 775 // Index renaming is done synchronously since preemptive
791 // OpenCursor/SetIndexKeys may follow. 776 // OpenCursor/SetIndexKeys may follow.
792 777
793 const IndexedDBIndexMetadata index_metadata = 778 const IndexedDBIndexMetadata index_metadata =
794 metadata_.object_stores[object_store_id].indexes[index_id]; 779 metadata_.object_stores[object_store_id].indexes[index_id];
795 780
796 leveldb::Status s = 781 leveldb::Status s =
797 backing_store_->RenameIndex(transaction->BackingStoreTransaction(), 782 backing_store_->RenameIndex(transaction->BackingStoreTransaction(),
798 transaction->database()->id(), 783 transaction->database()->id(),
799 object_store_id, 784 object_store_id,
800 index_id, 785 index_id,
801 new_name); 786 new_name);
802 if (!s.ok()) { 787 if (!s.ok()) {
803 base::string16 error_string = 788 base::string16 error_string =
804 ASCIIToUTF16("Internal error renaming index '") + 789 ASCIIToUTF16("Internal error renaming index '") +
805 index_metadata.name + ASCIIToUTF16("' to '") + new_name + 790 index_metadata.name + ASCIIToUTF16("' to '") + new_name +
806 ASCIIToUTF16("'."); 791 ASCIIToUTF16("'.");
807 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 792 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
808 error_string); 793 error_string);
809 transaction->Abort(error); 794 ReportError(s, origin(), factory_.get(), error);
810 if (s.IsCorruption())
811 factory_->HandleBackingStoreCorruption(origin(), error);
812 else
813 factory_->HandleBackingStoreFailure(origin());
814 return; 795 return;
815 } 796 }
816 797
817 transaction->ScheduleAbortTask( 798 transaction->ScheduleAbortTask(
818 base::Bind(&IndexedDBDatabase::RenameIndexAbortOperation, 799 base::Bind(&IndexedDBDatabase::RenameIndexAbortOperation,
819 this, 800 this,
820 object_store_id, 801 object_store_id,
821 index_id, 802 index_id,
822 index_metadata.name)); 803 index_metadata.name));
823 SetIndexName(object_store_id, index_id, new_name); 804 SetIndexName(object_store_id, index_id, new_name);
824 } 805 }
825 806
826 void IndexedDBDatabase::RenameIndexAbortOperation( 807 void IndexedDBDatabase::RenameIndexAbortOperation(
827 int64_t object_store_id, 808 int64_t object_store_id,
828 int64_t index_id, 809 int64_t index_id,
829 const base::string16& old_name) { 810 const base::string16& old_name) {
830 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation"); 811 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation");
831 SetIndexName(object_store_id, index_id, old_name); 812 SetIndexName(object_store_id, index_id, old_name);
832 } 813 }
833 814
834 void IndexedDBDatabase::Commit(int64_t transaction_id) { 815 void IndexedDBDatabase::Commit(IndexedDBTransaction* transaction) {
835 // The frontend suggests that we commit, but we may have previously initiated 816 // The frontend suggests that we commit, but we may have previously initiated
836 // an abort, and so have disposed of the transaction. on_abort has already 817 // an abort, and so have disposed of the transaction. on_abort has already
837 // been dispatched to the frontend, so it will find out about that 818 // been dispatched to the frontend, so it will find out about that
838 // asynchronously. 819 // asynchronously.
839 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
840 if (transaction) { 820 if (transaction) {
841 scoped_refptr<IndexedDBFactory> factory = factory_; 821 scoped_refptr<IndexedDBFactory> factory = factory_;
842 leveldb::Status result = transaction->Commit(); 822 leveldb::Status result = transaction->Commit();
843 if (!result.ok()) { 823 if (!result.ok()) {
844 if (result.IsCorruption()) { 824 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
845 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 825 base::ASCIIToUTF16(result.ToString()));
846 base::ASCIIToUTF16(result.ToString())); 826 ReportError(result, origin(), factory_.get(), error);
847 factory->HandleBackingStoreCorruption(origin(), error);
848 } else {
849 factory->HandleBackingStoreFailure(origin());
850 }
851 } 827 }
852 } 828 }
853 } 829 }
854 830
855 void IndexedDBDatabase::Abort(int64_t transaction_id) {
856 // If the transaction is unknown, then it has already been aborted by the
857 // backend before this call so it is safe to ignore it.
858 IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id);
859 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
860 if (transaction)
861 transaction->Abort();
862 }
863
864 void IndexedDBDatabase::Abort(int64_t transaction_id,
865 const IndexedDBDatabaseError& error) {
866 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id);
867 // If the transaction is unknown, then it has already been aborted by the
868 // backend before this call so it is safe to ignore it.
869 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
870 if (transaction)
871 transaction->Abort(error);
872 }
873
874 void IndexedDBDatabase::AddPendingObserver( 831 void IndexedDBDatabase::AddPendingObserver(
875 int64_t transaction_id, 832 IndexedDBTransaction* transaction,
876 int32_t observer_id, 833 int32_t observer_id,
877 const IndexedDBObserver::Options& options) { 834 const IndexedDBObserver::Options& options) {
878 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 835 DCHECK(transaction);
879 if (!transaction)
880 return;
881 transaction->AddPendingObserver(observer_id, options); 836 transaction->AddPendingObserver(observer_id, options);
882 } 837 }
883 838
884 void IndexedDBDatabase::RemovePendingObservers(
885 IndexedDBConnection* connection,
886 const std::vector<int32_t>& pending_observer_ids) {
887 for (const auto& it : transactions_) {
888 // Avoid call to RemovePendingObservers for transactions on other
889 // connections.
890 if (it.second->connection() == connection)
891 it.second->RemovePendingObservers(pending_observer_ids);
892 }
893 }
894
895 // TODO(palakj): Augment the function with IDBValue later. Issue 839 // TODO(palakj): Augment the function with IDBValue later. Issue
896 // crbug.com/609934. 840 // crbug.com/609934.
897 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, 841 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction,
898 int64_t object_store_id, 842 int64_t object_store_id,
899 blink::WebIDBOperationType type, 843 blink::WebIDBOperationType type,
900 const IndexedDBKeyRange& key_range) { 844 const IndexedDBKeyRange& key_range) {
901 for (auto* connection : connections_) { 845 for (auto* connection : connections_) {
902 bool recorded = false; 846 bool recorded = false;
903 for (const auto& observer : connection->active_observers()) { 847 for (const auto& observer : connection->active_observers()) {
904 if (!observer->IsRecordingType(type) || 848 if (!observer->IsRecordingType(type) ||
(...skipping 16 matching lines...) Expand all
921 865
922 void IndexedDBDatabase::SendObservations( 866 void IndexedDBDatabase::SendObservations(
923 std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> changes_map) { 867 std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> changes_map) {
924 for (auto* conn : connections_) { 868 for (auto* conn : connections_) {
925 auto it = changes_map.find(conn->id()); 869 auto it = changes_map.find(conn->id());
926 if (it != changes_map.end()) 870 if (it != changes_map.end())
927 conn->callbacks()->OnDatabaseChange(std::move(it->second)); 871 conn->callbacks()->OnDatabaseChange(std::move(it->second));
928 } 872 }
929 } 873 }
930 874
931 void IndexedDBDatabase::GetAll(int64_t transaction_id, 875 void IndexedDBDatabase::GetAll(IndexedDBTransaction* transaction,
932 int64_t object_store_id, 876 int64_t object_store_id,
933 int64_t index_id, 877 int64_t index_id,
934 std::unique_ptr<IndexedDBKeyRange> key_range, 878 std::unique_ptr<IndexedDBKeyRange> key_range,
935 bool key_only, 879 bool key_only,
936 int64_t max_count, 880 int64_t max_count,
937 scoped_refptr<IndexedDBCallbacks> callbacks) { 881 scoped_refptr<IndexedDBCallbacks> callbacks) {
938 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); 882 DCHECK(transaction);
939 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 883 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction->id());
940 if (!transaction)
941 return;
942 884
943 if (!ValidateObjectStoreId(object_store_id)) 885 if (!ValidateObjectStoreId(object_store_id))
944 return; 886 return;
945 887
946 transaction->ScheduleTask(base::Bind( 888 transaction->ScheduleTask(base::Bind(
947 &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id, 889 &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id,
948 base::Passed(&key_range), 890 base::Passed(&key_range),
949 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 891 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
950 max_count, callbacks)); 892 max_count, callbacks));
951 } 893 }
952 894
953 void IndexedDBDatabase::Get(int64_t transaction_id, 895 void IndexedDBDatabase::Get(IndexedDBTransaction* transaction,
954 int64_t object_store_id, 896 int64_t object_store_id,
955 int64_t index_id, 897 int64_t index_id,
956 std::unique_ptr<IndexedDBKeyRange> key_range, 898 std::unique_ptr<IndexedDBKeyRange> key_range,
957 bool key_only, 899 bool key_only,
958 scoped_refptr<IndexedDBCallbacks> callbacks) { 900 scoped_refptr<IndexedDBCallbacks> callbacks) {
959 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); 901 DCHECK(transaction);
960 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 902 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction->id());
961 if (!transaction)
962 return;
963 903
964 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 904 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
965 return; 905 return;
966 906
967 transaction->ScheduleTask(base::Bind( 907 transaction->ScheduleTask(base::Bind(
968 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id, 908 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id,
969 base::Passed(&key_range), 909 base::Passed(&key_range),
970 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 910 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
971 callbacks)); 911 callbacks));
972 } 912 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 backing_store_cursor = backing_store_->OpenIndexCursor( 958 backing_store_cursor = backing_store_->OpenIndexCursor(
1019 transaction->BackingStoreTransaction(), 959 transaction->BackingStoreTransaction(),
1020 id(), 960 id(),
1021 object_store_id, 961 object_store_id,
1022 index_id, 962 index_id,
1023 *key_range, 963 *key_range,
1024 blink::WebIDBCursorDirectionNext, 964 blink::WebIDBCursorDirectionNext,
1025 &s); 965 &s);
1026 } 966 }
1027 967
1028 if (!s.ok()) { 968 if (!s.ok())
1029 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1030 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1031 "Internal error deleting data in range");
1032 callbacks->OnError(error);
1033 return s; 969 return s;
1034 }
1035 970
1036 if (!backing_store_cursor) { 971 if (!backing_store_cursor) {
1037 // This means we've run out of data. 972 // This means we've run out of data.
1038 callbacks->OnSuccess(); 973 callbacks->OnSuccess();
1039 return s; 974 return s;
1040 } 975 }
1041 976
1042 key = &backing_store_cursor->key(); 977 key = &backing_store_cursor->key();
1043 } 978 }
1044 979
1045 std::unique_ptr<IndexedDBKey> primary_key; 980 std::unique_ptr<IndexedDBKey> primary_key;
1046 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 981 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
1047 // Object Store Retrieval Operation 982 // Object Store Retrieval Operation
1048 IndexedDBReturnValue value; 983 IndexedDBReturnValue value;
1049 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 984 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
1050 id(), 985 id(),
1051 object_store_id, 986 object_store_id,
1052 *key, 987 *key,
1053 &value); 988 &value);
1054 if (!s.ok()) { 989 if (!s.ok())
1055 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1056 "Internal error in GetRecord.");
1057 callbacks->OnError(error);
1058 return s; 990 return s;
1059 }
1060 991
1061 if (value.empty()) { 992 if (value.empty()) {
1062 callbacks->OnSuccess(); 993 callbacks->OnSuccess();
1063 return s; 994 return s;
1064 } 995 }
1065 996
1066 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 997 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1067 callbacks->OnSuccess(*key); 998 callbacks->OnSuccess(*key);
1068 return s; 999 return s;
1069 } 1000 }
1070 1001
1071 if (object_store_metadata.auto_increment && 1002 if (object_store_metadata.auto_increment &&
1072 !object_store_metadata.key_path.IsNull()) { 1003 !object_store_metadata.key_path.IsNull()) {
1073 value.primary_key = *key; 1004 value.primary_key = *key;
1074 value.key_path = object_store_metadata.key_path; 1005 value.key_path = object_store_metadata.key_path;
1075 } 1006 }
1076 1007
1077 callbacks->OnSuccess(&value); 1008 callbacks->OnSuccess(&value);
1078 return s; 1009 return s;
1079 } 1010 }
1080 1011
1081 // From here we are dealing only with indexes. 1012 // From here we are dealing only with indexes.
1082 s = backing_store_->GetPrimaryKeyViaIndex( 1013 s = backing_store_->GetPrimaryKeyViaIndex(
1083 transaction->BackingStoreTransaction(), 1014 transaction->BackingStoreTransaction(),
1084 id(), 1015 id(),
1085 object_store_id, 1016 object_store_id,
1086 index_id, 1017 index_id,
1087 *key, 1018 *key,
1088 &primary_key); 1019 &primary_key);
1089 if (!s.ok()) { 1020 if (!s.ok())
1090 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1091 "Internal error in GetPrimaryKeyViaIndex.");
1092 callbacks->OnError(error);
1093 return s; 1021 return s;
1094 } 1022
1095 if (!primary_key) { 1023 if (!primary_key) {
1096 callbacks->OnSuccess(); 1024 callbacks->OnSuccess();
1097 return s; 1025 return s;
1098 } 1026 }
1099 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1027 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1100 // Index Value Retrieval Operation 1028 // Index Value Retrieval Operation
1101 callbacks->OnSuccess(*primary_key); 1029 callbacks->OnSuccess(*primary_key);
1102 return s; 1030 return s;
1103 } 1031 }
1104 1032
1105 // Index Referenced Value Retrieval Operation 1033 // Index Referenced Value Retrieval Operation
1106 IndexedDBReturnValue value; 1034 IndexedDBReturnValue value;
1107 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 1035 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
1108 id(), 1036 id(),
1109 object_store_id, 1037 object_store_id,
1110 *primary_key, 1038 *primary_key,
1111 &value); 1039 &value);
1112 if (!s.ok()) { 1040 if (!s.ok())
1113 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1114 "Internal error in GetRecord.");
1115 callbacks->OnError(error);
1116 return s; 1041 return s;
1117 }
1118 1042
1119 if (value.empty()) { 1043 if (value.empty()) {
1120 callbacks->OnSuccess(); 1044 callbacks->OnSuccess();
1121 return s; 1045 return s;
1122 } 1046 }
1123 if (object_store_metadata.auto_increment && 1047 if (object_store_metadata.auto_increment &&
1124 !object_store_metadata.key_path.IsNull()) { 1048 !object_store_metadata.key_path.IsNull()) {
1125 value.primary_key = *primary_key; 1049 value.primary_key = *primary_key;
1126 value.key_path = object_store_metadata.key_path; 1050 value.key_path = object_store_metadata.key_path;
1127 } 1051 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 } else { 1097 } else {
1174 // Object Store: Referenced Value Retrieval Operation 1098 // Object Store: Referenced Value Retrieval Operation
1175 cursor = backing_store_->OpenIndexCursor( 1099 cursor = backing_store_->OpenIndexCursor(
1176 transaction->BackingStoreTransaction(), id(), object_store_id, 1100 transaction->BackingStoreTransaction(), id(), object_store_id,
1177 index_id, *key_range, blink::WebIDBCursorDirectionNext, &s); 1101 index_id, *key_range, blink::WebIDBCursorDirectionNext, &s);
1178 } 1102 }
1179 } 1103 }
1180 1104
1181 if (!s.ok()) { 1105 if (!s.ok()) {
1182 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1106 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1183 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1184 "Internal error in GetAllOperation");
1185 callbacks->OnError(error);
1186 return s; 1107 return s;
1187 } 1108 }
1188 1109
1189 std::vector<IndexedDBKey> found_keys; 1110 std::vector<IndexedDBKey> found_keys;
1190 std::vector<IndexedDBReturnValue> found_values; 1111 std::vector<IndexedDBReturnValue> found_values;
1191 if (!cursor) { 1112 if (!cursor) {
1192 // Doesn't matter if key or value array here - will be empty array when it 1113 // Doesn't matter if key or value array here - will be empty array when it
1193 // hits JavaScript. 1114 // hits JavaScript.
1194 callbacks->OnSuccessArray(&found_values); 1115 callbacks->OnSuccessArray(&found_values);
1195 return s; 1116 return s;
1196 } 1117 }
1197 1118
1198 bool did_first_seek = false; 1119 bool did_first_seek = false;
1199 bool generated_key = object_store_metadata.auto_increment && 1120 bool generated_key = object_store_metadata.auto_increment &&
1200 !object_store_metadata.key_path.IsNull(); 1121 !object_store_metadata.key_path.IsNull();
1201 1122
1202 size_t response_size = kMaxIDBMessageOverhead; 1123 size_t response_size = kMaxIDBMessageOverhead;
1203 int64_t num_found_items = 0; 1124 int64_t num_found_items = 0;
1204 while (num_found_items++ < max_count) { 1125 while (num_found_items++ < max_count) {
1205 bool cursor_valid; 1126 bool cursor_valid;
1206 if (did_first_seek) { 1127 if (did_first_seek) {
1207 cursor_valid = cursor->Continue(&s); 1128 cursor_valid = cursor->Continue(&s);
1208 } else { 1129 } else {
1209 cursor_valid = cursor->FirstSeek(&s); 1130 cursor_valid = cursor->FirstSeek(&s);
1210 did_first_seek = true; 1131 did_first_seek = true;
1211 } 1132 }
1212 if (!s.ok()) { 1133 if (!s.ok())
1213 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1214 "Internal error in GetAllOperation.");
1215 callbacks->OnError(error);
1216 return s; 1134 return s;
1217 }
1218 1135
1219 if (!cursor_valid) 1136 if (!cursor_valid)
1220 break; 1137 break;
1221 1138
1222 IndexedDBReturnValue return_value; 1139 IndexedDBReturnValue return_value;
1223 IndexedDBKey return_key; 1140 IndexedDBKey return_key;
1224 1141
1225 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1142 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1226 return_key = cursor->primary_key(); 1143 return_key = cursor->primary_key();
1227 } else { 1144 } else {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 std::unique_ptr<IndexedDBKey> key; 1220 std::unique_ptr<IndexedDBKey> key;
1304 blink::WebIDBPutMode put_mode; 1221 blink::WebIDBPutMode put_mode;
1305 scoped_refptr<IndexedDBCallbacks> callbacks; 1222 scoped_refptr<IndexedDBCallbacks> callbacks;
1306 std::vector<IndexedDBIndexKeys> index_keys; 1223 std::vector<IndexedDBIndexKeys> index_keys;
1307 1224
1308 private: 1225 private:
1309 DISALLOW_COPY_AND_ASSIGN(PutOperationParams); 1226 DISALLOW_COPY_AND_ASSIGN(PutOperationParams);
1310 }; 1227 };
1311 1228
1312 void IndexedDBDatabase::Put( 1229 void IndexedDBDatabase::Put(
1313 int64_t transaction_id, 1230 IndexedDBTransaction* transaction,
1314 int64_t object_store_id, 1231 int64_t object_store_id,
1315 IndexedDBValue* value, 1232 IndexedDBValue* value,
1316 std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles, 1233 std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles,
1317 std::unique_ptr<IndexedDBKey> key, 1234 std::unique_ptr<IndexedDBKey> key,
1318 blink::WebIDBPutMode put_mode, 1235 blink::WebIDBPutMode put_mode,
1319 scoped_refptr<IndexedDBCallbacks> callbacks, 1236 scoped_refptr<IndexedDBCallbacks> callbacks,
1320 const std::vector<IndexedDBIndexKeys>& index_keys) { 1237 const std::vector<IndexedDBIndexKeys>& index_keys) {
1321 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id); 1238 DCHECK(transaction);
1322 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1239 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction->id());
1323 if (!transaction)
1324 return;
1325 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1240 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1326 1241
1327 if (!ValidateObjectStoreId(object_store_id)) 1242 if (!ValidateObjectStoreId(object_store_id))
1328 return; 1243 return;
1329 1244
1330 DCHECK(key); 1245 DCHECK(key);
1331 DCHECK(value); 1246 DCHECK(value);
1332 std::unique_ptr<PutOperationParams> params( 1247 std::unique_ptr<PutOperationParams> params(
1333 base::MakeUnique<PutOperationParams>()); 1248 base::MakeUnique<PutOperationParams>());
1334 params->object_store_id = object_store_id; 1249 params->object_store_id = object_store_id;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 IndexedDBBackingStore::RecordIdentifier record_identifier; 1293 IndexedDBBackingStore::RecordIdentifier record_identifier;
1379 if (params->put_mode == blink::WebIDBPutModeAddOnly) { 1294 if (params->put_mode == blink::WebIDBPutModeAddOnly) {
1380 bool found = false; 1295 bool found = false;
1381 leveldb::Status s = backing_store_->KeyExistsInObjectStore( 1296 leveldb::Status s = backing_store_->KeyExistsInObjectStore(
1382 transaction->BackingStoreTransaction(), 1297 transaction->BackingStoreTransaction(),
1383 id(), 1298 id(),
1384 params->object_store_id, 1299 params->object_store_id,
1385 *key, 1300 *key,
1386 &record_identifier, 1301 &record_identifier,
1387 &found); 1302 &found);
1388 if (!s.ok()) { 1303 if (!s.ok())
1389 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1390 "Internal error checking key existence.");
1391 params->callbacks->OnError(error);
1392 return s; 1304 return s;
1393 }
1394 if (found) { 1305 if (found) {
1395 params->callbacks->OnError( 1306 params->callbacks->OnError(
1396 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 1307 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError,
1397 "Key already exists in the object store.")); 1308 "Key already exists in the object store."));
1398 return s; 1309 return s;
1399 } 1310 }
1400 } 1311 }
1401 1312
1402 std::vector<std::unique_ptr<IndexWriter>> index_writers; 1313 std::vector<std::unique_ptr<IndexWriter>> index_writers;
1403 base::string16 error_message; 1314 base::string16 error_message;
(...skipping 18 matching lines...) Expand all
1422 params->callbacks->OnError(IndexedDBDatabaseError( 1333 params->callbacks->OnError(IndexedDBDatabaseError(
1423 blink::WebIDBDatabaseExceptionConstraintError, error_message)); 1334 blink::WebIDBDatabaseExceptionConstraintError, error_message));
1424 return s; 1335 return s;
1425 } 1336 }
1426 1337
1427 // Before this point, don't do any mutation. After this point, rollback the 1338 // Before this point, don't do any mutation. After this point, rollback the
1428 // transaction in case of error. 1339 // transaction in case of error.
1429 s = backing_store_->PutRecord(transaction->BackingStoreTransaction(), id(), 1340 s = backing_store_->PutRecord(transaction->BackingStoreTransaction(), id(),
1430 params->object_store_id, *key, &params->value, 1341 params->object_store_id, *key, &params->value,
1431 &params->handles, &record_identifier); 1342 &params->handles, &record_identifier);
1432 if (!s.ok()) { 1343 if (!s.ok())
1433 IndexedDBDatabaseError error(
1434 blink::WebIDBDatabaseExceptionUnknownError,
1435 "Internal error: backing store error performing put/add.");
1436 params->callbacks->OnError(error);
1437 return s; 1344 return s;
1438 } 1345
1439 { 1346 {
1440 IDB_TRACE1("IndexedDBDatabase::PutOperation.UpdateIndexes", "txn.id", 1347 IDB_TRACE1("IndexedDBDatabase::PutOperation.UpdateIndexes", "txn.id",
1441 transaction->id()); 1348 transaction->id());
1442 for (const auto& writer : index_writers) { 1349 for (const auto& writer : index_writers) {
1443 writer->WriteIndexKeys(record_identifier, backing_store_.get(), 1350 writer->WriteIndexKeys(record_identifier, backing_store_.get(),
1444 transaction->BackingStoreTransaction(), id(), 1351 transaction->BackingStoreTransaction(), id(),
1445 params->object_store_id); 1352 params->object_store_id);
1446 } 1353 }
1447 } 1354 }
1448 1355
1449 if (object_store.auto_increment && 1356 if (object_store.auto_increment &&
1450 params->put_mode != blink::WebIDBPutModeCursorUpdate && 1357 params->put_mode != blink::WebIDBPutModeCursorUpdate &&
1451 key->type() == WebIDBKeyTypeNumber) { 1358 key->type() == WebIDBKeyTypeNumber) {
1452 IDB_TRACE1("IndexedDBDatabase::PutOperation.AutoIncrement", "txn.id", 1359 IDB_TRACE1("IndexedDBDatabase::PutOperation.AutoIncrement", "txn.id",
1453 transaction->id()); 1360 transaction->id());
1454 s = UpdateKeyGenerator(backing_store_.get(), transaction, id(), 1361 s = UpdateKeyGenerator(backing_store_.get(), transaction, id(),
1455 params->object_store_id, *key, !key_was_generated); 1362 params->object_store_id, *key, !key_was_generated);
1456 if (!s.ok()) { 1363 if (!s.ok())
1457 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1458 "Internal error updating key generator.");
1459 params->callbacks->OnError(error);
1460 return s; 1364 return s;
1461 }
1462 } 1365 }
1463 { 1366 {
1464 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id", 1367 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id",
1465 transaction->id()); 1368 transaction->id());
1466 params->callbacks->OnSuccess(*key); 1369 params->callbacks->OnSuccess(*key);
1467 } 1370 }
1468 FilterObservation(transaction, params->object_store_id, 1371 FilterObservation(transaction, params->object_store_id,
1469 params->put_mode == blink::WebIDBPutModeAddOnly 1372 params->put_mode == blink::WebIDBPutModeAddOnly
1470 ? blink::WebIDBAdd 1373 ? blink::WebIDBAdd
1471 : blink::WebIDBPut, 1374 : blink::WebIDBPut,
1472 IndexedDBKeyRange(*key)); 1375 IndexedDBKeyRange(*key));
1473 return s; 1376 return s;
1474 } 1377 }
1475 1378
1476 void IndexedDBDatabase::SetIndexKeys( 1379 void IndexedDBDatabase::SetIndexKeys(
1477 int64_t transaction_id, 1380 IndexedDBTransaction* transaction,
1478 int64_t object_store_id, 1381 int64_t object_store_id,
1479 std::unique_ptr<IndexedDBKey> primary_key, 1382 std::unique_ptr<IndexedDBKey> primary_key,
1480 const std::vector<IndexedDBIndexKeys>& index_keys) { 1383 const std::vector<IndexedDBIndexKeys>& index_keys) {
1481 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); 1384 DCHECK(transaction);
1482 1385 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction->id());
1483 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1484 if (!transaction)
1485 return;
1486 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 1386 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
1487 1387
1488 // TODO(alecflett): This method could be asynchronous, but we need to 1388 // TODO(alecflett): This method could be asynchronous, but we need to
1489 // evaluate if it's worth the extra complexity. 1389 // evaluate if it's worth the extra complexity.
1490 IndexedDBBackingStore::RecordIdentifier record_identifier; 1390 IndexedDBBackingStore::RecordIdentifier record_identifier;
1491 bool found = false; 1391 bool found = false;
1492 leveldb::Status s = backing_store_->KeyExistsInObjectStore( 1392 leveldb::Status s = backing_store_->KeyExistsInObjectStore(
1493 transaction->BackingStoreTransaction(), 1393 transaction->BackingStoreTransaction(),
1494 metadata_.id, 1394 metadata_.id,
1495 object_store_id, 1395 object_store_id,
1496 *primary_key, 1396 *primary_key,
1497 &record_identifier, 1397 &record_identifier,
1498 &found); 1398 &found);
1499 if (!s.ok()) { 1399 if (!s.ok()) {
1500 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1400 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1501 "Internal error setting index keys."); 1401 "Internal error setting index keys.");
1502 transaction->Abort(error); 1402 ReportError(s, origin(), factory_.get(), error);
1503 if (s.IsCorruption())
1504 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1505 return; 1403 return;
1506 } 1404 }
1507 if (!found) { 1405 if (!found) {
1508 transaction->Abort(IndexedDBDatabaseError( 1406 transaction->Abort(IndexedDBDatabaseError(
1509 blink::WebIDBDatabaseExceptionUnknownError, 1407 blink::WebIDBDatabaseExceptionUnknownError,
1510 "Internal error setting index keys for object store.")); 1408 "Internal error setting index keys for object store."));
1511 return; 1409 return;
1512 } 1410 }
1513 1411
1514 std::vector<std::unique_ptr<IndexWriter>> index_writers; 1412 std::vector<std::unique_ptr<IndexWriter>> index_writers;
(...skipping 25 matching lines...) Expand all
1540 return; 1438 return;
1541 } 1439 }
1542 1440
1543 for (const auto& writer : index_writers) { 1441 for (const auto& writer : index_writers) {
1544 writer->WriteIndexKeys(record_identifier, backing_store_.get(), 1442 writer->WriteIndexKeys(record_identifier, backing_store_.get(),
1545 transaction->BackingStoreTransaction(), id(), 1443 transaction->BackingStoreTransaction(), id(),
1546 object_store_id); 1444 object_store_id);
1547 } 1445 }
1548 } 1446 }
1549 1447
1550 void IndexedDBDatabase::SetIndexesReady(int64_t transaction_id, 1448 void IndexedDBDatabase::SetIndexesReady(IndexedDBTransaction* transaction,
1551 int64_t, 1449 int64_t,
1552 const std::vector<int64_t>& index_ids) { 1450 const std::vector<int64_t>& index_ids) {
1553 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1451 DCHECK(transaction);
1554 if (!transaction)
1555 return;
1556 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 1452 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
1557 1453
1558 transaction->ScheduleTask( 1454 transaction->ScheduleTask(
1559 blink::WebIDBTaskTypePreemptive, 1455 blink::WebIDBTaskTypePreemptive,
1560 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, 1456 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation,
1561 this, 1457 this,
1562 index_ids.size())); 1458 index_ids.size()));
1563 } 1459 }
1564 1460
1565 leveldb::Status IndexedDBDatabase::SetIndexesReadyOperation( 1461 leveldb::Status IndexedDBDatabase::SetIndexesReadyOperation(
(...skipping 12 matching lines...) Expand all
1578 blink::WebIDBCursorDirection direction; 1474 blink::WebIDBCursorDirection direction;
1579 indexed_db::CursorType cursor_type; 1475 indexed_db::CursorType cursor_type;
1580 blink::WebIDBTaskType task_type; 1476 blink::WebIDBTaskType task_type;
1581 scoped_refptr<IndexedDBCallbacks> callbacks; 1477 scoped_refptr<IndexedDBCallbacks> callbacks;
1582 1478
1583 private: 1479 private:
1584 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); 1480 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams);
1585 }; 1481 };
1586 1482
1587 void IndexedDBDatabase::OpenCursor( 1483 void IndexedDBDatabase::OpenCursor(
1588 int64_t transaction_id, 1484 IndexedDBTransaction* transaction,
1589 int64_t object_store_id, 1485 int64_t object_store_id,
1590 int64_t index_id, 1486 int64_t index_id,
1591 std::unique_ptr<IndexedDBKeyRange> key_range, 1487 std::unique_ptr<IndexedDBKeyRange> key_range,
1592 blink::WebIDBCursorDirection direction, 1488 blink::WebIDBCursorDirection direction,
1593 bool key_only, 1489 bool key_only,
1594 blink::WebIDBTaskType task_type, 1490 blink::WebIDBTaskType task_type,
1595 scoped_refptr<IndexedDBCallbacks> callbacks) { 1491 scoped_refptr<IndexedDBCallbacks> callbacks) {
1596 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id); 1492 DCHECK(transaction);
1597 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1493 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction->id());
1598 if (!transaction)
1599 return;
1600 1494
1601 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1495 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
1602 return; 1496 return;
1603 1497
1604 std::unique_ptr<OpenCursorOperationParams> params( 1498 std::unique_ptr<OpenCursorOperationParams> params(
1605 base::MakeUnique<OpenCursorOperationParams>()); 1499 base::MakeUnique<OpenCursorOperationParams>());
1606 params->object_store_id = object_store_id; 1500 params->object_store_id = object_store_id;
1607 params->index_id = index_id; 1501 params->index_id = index_id;
1608 params->key_range = std::move(key_range); 1502 params->key_range = std::move(key_range);
1609 params->direction = direction; 1503 params->direction = direction;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 params->object_store_id, 1561 params->object_store_id,
1668 params->index_id, 1562 params->index_id,
1669 *params->key_range, 1563 *params->key_range,
1670 params->direction, 1564 params->direction,
1671 &s); 1565 &s);
1672 } 1566 }
1673 } 1567 }
1674 1568
1675 if (!s.ok()) { 1569 if (!s.ok()) {
1676 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1570 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1677 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1678 "Internal error opening cursor operation");
1679 return s; 1571 return s;
1680 } 1572 }
1681 1573
1682 if (!backing_store_cursor) { 1574 if (!backing_store_cursor) {
1683 // Occurs when we've reached the end of cursor's data. 1575 // Occurs when we've reached the end of cursor's data.
1684 params->callbacks->OnSuccess(nullptr); 1576 params->callbacks->OnSuccess(nullptr);
1685 return s; 1577 return s;
1686 } 1578 }
1687 1579
1688 scoped_refptr<IndexedDBCursor> cursor = 1580 std::unique_ptr<IndexedDBCursor> cursor = base::MakeUnique<IndexedDBCursor>(
1689 new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type, 1581 std::move(backing_store_cursor), params->cursor_type, params->task_type,
1690 params->task_type, transaction); 1582 transaction);
1691 params->callbacks->OnSuccess( 1583 IndexedDBCursor* cursor_ptr = cursor.get();
1692 cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1584 transaction->RegisterOpenCursor(cursor_ptr);
1585 params->callbacks->OnSuccess(std::move(cursor), cursor_ptr->key(),
1586 cursor_ptr->primary_key(), cursor_ptr->Value());
1693 return s; 1587 return s;
1694 } 1588 }
1695 1589
1696 void IndexedDBDatabase::Count(int64_t transaction_id, 1590 void IndexedDBDatabase::Count(IndexedDBTransaction* transaction,
1697 int64_t object_store_id, 1591 int64_t object_store_id,
1698 int64_t index_id, 1592 int64_t index_id,
1699 std::unique_ptr<IndexedDBKeyRange> key_range, 1593 std::unique_ptr<IndexedDBKeyRange> key_range,
1700 scoped_refptr<IndexedDBCallbacks> callbacks) { 1594 scoped_refptr<IndexedDBCallbacks> callbacks) {
1701 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id); 1595 DCHECK(transaction);
1702 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1596 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction->id());
1703 if (!transaction)
1704 return;
1705 1597
1706 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1598 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
1707 return; 1599 return;
1708 1600
1709 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, 1601 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation,
1710 this, 1602 this,
1711 object_store_id, 1603 object_store_id,
1712 index_id, 1604 index_id,
1713 base::Passed(&key_range), 1605 base::Passed(&key_range),
1714 callbacks)); 1606 callbacks));
(...skipping 23 matching lines...) Expand all
1738 transaction->BackingStoreTransaction(), 1630 transaction->BackingStoreTransaction(),
1739 id(), 1631 id(),
1740 object_store_id, 1632 object_store_id,
1741 index_id, 1633 index_id,
1742 *key_range, 1634 *key_range,
1743 blink::WebIDBCursorDirectionNext, 1635 blink::WebIDBCursorDirectionNext,
1744 &s); 1636 &s);
1745 } 1637 }
1746 if (!s.ok()) { 1638 if (!s.ok()) {
1747 DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); 1639 DLOG(ERROR) << "Unable perform count operation: " << s.ToString();
1748 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1749 "Internal error performing count operation");
1750 return s; 1640 return s;
1751 } 1641 }
1752 if (!backing_store_cursor) { 1642 if (!backing_store_cursor) {
1753 callbacks->OnSuccess(count); 1643 callbacks->OnSuccess(count);
1754 return s; 1644 return s;
1755 } 1645 }
1756 1646
1757 do { 1647 do {
1758 if (!s.ok()) 1648 if (!s.ok())
1759 return s; 1649 return s;
1760 ++count; 1650 ++count;
1761 } while (backing_store_cursor->Continue(&s)); 1651 } while (backing_store_cursor->Continue(&s));
1762 1652
1763 callbacks->OnSuccess(count); 1653 callbacks->OnSuccess(count);
1764 return s; 1654 return s;
1765 } 1655 }
1766 1656
1767 void IndexedDBDatabase::DeleteRange( 1657 void IndexedDBDatabase::DeleteRange(
1768 int64_t transaction_id, 1658 IndexedDBTransaction* transaction,
1769 int64_t object_store_id, 1659 int64_t object_store_id,
1770 std::unique_ptr<IndexedDBKeyRange> key_range, 1660 std::unique_ptr<IndexedDBKeyRange> key_range,
1771 scoped_refptr<IndexedDBCallbacks> callbacks) { 1661 scoped_refptr<IndexedDBCallbacks> callbacks) {
1772 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); 1662 DCHECK(transaction);
1773 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1663 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction->id());
1774 if (!transaction)
1775 return;
1776 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1664 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1777 1665
1778 if (!ValidateObjectStoreId(object_store_id)) 1666 if (!ValidateObjectStoreId(object_store_id))
1779 return; 1667 return;
1780 1668
1781 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, 1669 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation,
1782 this, 1670 this,
1783 object_store_id, 1671 object_store_id,
1784 base::Passed(&key_range), 1672 base::Passed(&key_range),
1785 callbacks)); 1673 callbacks));
1786 } 1674 }
1787 1675
1788 leveldb::Status IndexedDBDatabase::DeleteRangeOperation( 1676 leveldb::Status IndexedDBDatabase::DeleteRangeOperation(
1789 int64_t object_store_id, 1677 int64_t object_store_id,
1790 std::unique_ptr<IndexedDBKeyRange> key_range, 1678 std::unique_ptr<IndexedDBKeyRange> key_range,
1791 scoped_refptr<IndexedDBCallbacks> callbacks, 1679 scoped_refptr<IndexedDBCallbacks> callbacks,
1792 IndexedDBTransaction* transaction) { 1680 IndexedDBTransaction* transaction) {
1793 IDB_TRACE1("IndexedDBDatabase::DeleteRangeOperation", "txn.id", 1681 IDB_TRACE1("IndexedDBDatabase::DeleteRangeOperation", "txn.id",
1794 transaction->id()); 1682 transaction->id());
1795 size_t delete_count = 0; 1683 size_t delete_count = 0;
1796 leveldb::Status s = 1684 leveldb::Status s =
1797 backing_store_->DeleteRange(transaction->BackingStoreTransaction(), id(), 1685 backing_store_->DeleteRange(transaction->BackingStoreTransaction(), id(),
1798 object_store_id, *key_range, &delete_count); 1686 object_store_id, *key_range, &delete_count);
1799 if (!s.ok()) { 1687 if (!s.ok())
1800 base::string16 error_string =
1801 ASCIIToUTF16("Internal error deleting data in range");
1802 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1803 error_string);
1804 transaction->Abort(error);
1805 return s; 1688 return s;
1806 }
1807 callbacks->OnSuccess(); 1689 callbacks->OnSuccess();
1808 FilterObservation(transaction, object_store_id, blink::WebIDBDelete, 1690 FilterObservation(transaction, object_store_id, blink::WebIDBDelete,
1809 *key_range); 1691 *key_range);
1810 return s; 1692 return s;
1811 } 1693 }
1812 1694
1813 void IndexedDBDatabase::Clear(int64_t transaction_id, 1695 void IndexedDBDatabase::Clear(IndexedDBTransaction* transaction,
1814 int64_t object_store_id, 1696 int64_t object_store_id,
1815 scoped_refptr<IndexedDBCallbacks> callbacks) { 1697 scoped_refptr<IndexedDBCallbacks> callbacks) {
1816 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); 1698 DCHECK(transaction);
1817 IndexedDBTransaction* transaction = GetTransaction(transaction_id); 1699 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction->id());
1818 if (!transaction)
1819 return;
1820 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1700 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1821 1701
1822 if (!ValidateObjectStoreId(object_store_id)) 1702 if (!ValidateObjectStoreId(object_store_id))
1823 return; 1703 return;
1824 1704
1825 transaction->ScheduleTask(base::Bind( 1705 transaction->ScheduleTask(base::Bind(
1826 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); 1706 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks));
1827 } 1707 }
1828 1708
1829 leveldb::Status IndexedDBDatabase::ClearOperation( 1709 leveldb::Status IndexedDBDatabase::ClearOperation(
1830 int64_t object_store_id, 1710 int64_t object_store_id,
1831 scoped_refptr<IndexedDBCallbacks> callbacks, 1711 scoped_refptr<IndexedDBCallbacks> callbacks,
1832 IndexedDBTransaction* transaction) { 1712 IndexedDBTransaction* transaction) {
1833 IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id()); 1713 IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id());
1834 leveldb::Status s = backing_store_->ClearObjectStore( 1714 leveldb::Status s = backing_store_->ClearObjectStore(
1835 transaction->BackingStoreTransaction(), id(), object_store_id); 1715 transaction->BackingStoreTransaction(), id(), object_store_id);
1836 if (!s.ok()) { 1716 if (!s.ok())
1837 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1838 "Internal error clearing object store");
1839 callbacks->OnError(error);
1840 return s; 1717 return s;
1841 }
1842 callbacks->OnSuccess(); 1718 callbacks->OnSuccess();
1843 1719
1844 FilterObservation(transaction, object_store_id, blink::WebIDBClear, 1720 FilterObservation(transaction, object_store_id, blink::WebIDBClear,
1845 IndexedDBKeyRange()); 1721 IndexedDBKeyRange());
1846 return s; 1722 return s;
1847 } 1723 }
1848 1724
1849 leveldb::Status IndexedDBDatabase::DeleteObjectStoreOperation( 1725 leveldb::Status IndexedDBDatabase::DeleteObjectStoreOperation(
1850 int64_t object_store_id, 1726 int64_t object_store_id,
1851 IndexedDBTransaction* transaction) { 1727 IndexedDBTransaction* transaction) {
1852 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation", 1728 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation",
1853 "txn.id", 1729 "txn.id",
1854 transaction->id()); 1730 transaction->id());
1855 1731
1856 const IndexedDBObjectStoreMetadata object_store_metadata = 1732 const IndexedDBObjectStoreMetadata object_store_metadata =
1857 metadata_.object_stores[object_store_id]; 1733 metadata_.object_stores[object_store_id];
1858 leveldb::Status s = 1734 leveldb::Status s =
1859 backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1735 backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(),
1860 transaction->database()->id(), 1736 transaction->database()->id(),
1861 object_store_id); 1737 object_store_id);
1862 if (!s.ok()) { 1738 if (!s.ok())
1863 base::string16 error_string =
1864 ASCIIToUTF16("Internal error deleting object store '") +
1865 object_store_metadata.name + ASCIIToUTF16("'.");
1866 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1867 error_string);
1868 transaction->Abort(error);
1869 return s; 1739 return s;
1870 }
1871 1740
1872 RemoveObjectStore(object_store_id); 1741 RemoveObjectStore(object_store_id);
1873 transaction->ScheduleAbortTask( 1742 transaction->ScheduleAbortTask(
1874 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, 1743 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation,
1875 this, 1744 this,
1876 object_store_metadata)); 1745 object_store_metadata));
1877 return s; 1746 return s;
1878 } 1747 }
1879 1748
1880 leveldb::Status IndexedDBDatabase::VersionChangeOperation( 1749 leveldb::Status IndexedDBDatabase::VersionChangeOperation(
(...skipping 12 matching lines...) Expand all
1893 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, 1762 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this,
1894 metadata_.version)); 1763 metadata_.version));
1895 metadata_.version = version; 1764 metadata_.version = version;
1896 1765
1897 active_request_->UpgradeTransactionStarted(old_version); 1766 active_request_->UpgradeTransactionStarted(old_version);
1898 return leveldb::Status::OK(); 1767 return leveldb::Status::OK();
1899 } 1768 }
1900 1769
1901 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, 1770 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
1902 bool committed) { 1771 bool committed) {
1903 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); 1772 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id",
1904 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1773 transaction->id());
1905 DCHECK_EQ(transactions_[transaction->id()], transaction); 1774 --transaction_count_;
1906 transactions_.erase(transaction->id()); 1775 DCHECK_GE(transaction_count_, 0);
1907 1776
1908 // This may be an unrelated transaction finishing while waiting for 1777 // This may be an unrelated transaction finishing while waiting for
1909 // connections to close, or the actual upgrade transaction from an active 1778 // connections to close, or the actual upgrade transaction from an active
1910 // request. Notify the active request if it's the latter. 1779 // request. Notify the active request if it's the latter.
1911 if (active_request_ && 1780 if (active_request_ &&
1912 transaction->mode() == blink::WebIDBTransactionModeVersionChange) { 1781 transaction->mode() == blink::WebIDBTransactionModeVersionChange) {
1913 active_request_->UpgradeTransactionFinished(committed); 1782 active_request_->UpgradeTransactionFinished(committed);
1914 } 1783 }
1915 } 1784 }
1916 1785
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 } while (!active_request_ && !pending_requests_.empty()); 1818 } while (!active_request_ && !pending_requests_.empty());
1950 } 1819 }
1951 1820
1952 IndexedDBTransaction* IndexedDBDatabase::CreateTransaction( 1821 IndexedDBTransaction* IndexedDBDatabase::CreateTransaction(
1953 int64_t transaction_id, 1822 int64_t transaction_id,
1954 IndexedDBConnection* connection, 1823 IndexedDBConnection* connection,
1955 const std::vector<int64_t>& object_store_ids, 1824 const std::vector<int64_t>& object_store_ids,
1956 blink::WebIDBTransactionMode mode) { 1825 blink::WebIDBTransactionMode mode) {
1957 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); 1826 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id);
1958 DCHECK(connections_.count(connection)); 1827 DCHECK(connections_.count(connection));
1959 DCHECK(transactions_.find(transaction_id) == transactions_.end());
1960 if (transactions_.find(transaction_id) != transactions_.end())
1961 return nullptr;
1962 1828
1963 UMA_HISTOGRAM_COUNTS_1000( 1829 UMA_HISTOGRAM_COUNTS_1000(
1964 "WebCore.IndexedDB.Database.OutstandingTransactionCount", 1830 "WebCore.IndexedDB.Database.OutstandingTransactionCount",
1965 transactions_.size()); 1831 transaction_count_);
1966 1832
1967 // The transaction will add itself to this database's coordinator, which 1833 IndexedDBTransaction* transaction = connection->CreateTransaction(
1968 // manages the lifetime of the object. 1834 transaction_id,
1969 IndexedDBTransaction* transaction = 1835 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode,
1970 IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( 1836 new IndexedDBBackingStore::Transaction(backing_store_.get()));
1971 transaction_id, connection->GetWeakPtr(),
1972 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()),
1973 mode, new IndexedDBBackingStore::Transaction(backing_store_.get()));
1974 TransactionCreated(transaction); 1837 TransactionCreated(transaction);
1975 return transaction; 1838 return transaction;
1976 } 1839 }
1977 1840
1978 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { 1841 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) {
1979 transactions_[transaction->id()] = transaction; 1842 transaction_count_++;
1843 transaction_coordinator_.DidCreateTransaction(transaction);
1980 } 1844 }
1981 1845
1982 void IndexedDBDatabase::OpenConnection( 1846 void IndexedDBDatabase::OpenConnection(
1983 std::unique_ptr<IndexedDBPendingConnection> connection) { 1847 std::unique_ptr<IndexedDBPendingConnection> connection) {
1984 AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection))); 1848 AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection)));
1985 } 1849 }
1986 1850
1987 void IndexedDBDatabase::DeleteDatabase( 1851 void IndexedDBDatabase::DeleteDatabase(
1988 scoped_refptr<IndexedDBCallbacks> callbacks) { 1852 scoped_refptr<IndexedDBCallbacks> callbacks) {
1989 AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks)); 1853 AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks));
(...skipping 19 matching lines...) Expand all
2009 DCHECK(connections_.count(connection)); 1873 DCHECK(connections_.count(connection));
2010 DCHECK(connection->IsConnected()); 1874 DCHECK(connection->IsConnected());
2011 DCHECK(connection->database() == this); 1875 DCHECK(connection->database() == this);
2012 1876
2013 IDB_TRACE("IndexedDBDatabase::Close"); 1877 IDB_TRACE("IndexedDBDatabase::Close");
2014 1878
2015 // Abort outstanding transactions from the closing connection. This can not 1879 // Abort outstanding transactions from the closing connection. This can not
2016 // happen if the close is requested by the connection itself as the 1880 // happen if the close is requested by the connection itself as the
2017 // front-end defers the close until all transactions are complete, but can 1881 // front-end defers the close until all transactions are complete, but can
2018 // occur on process termination or forced close. 1882 // occur on process termination or forced close.
2019 { 1883 connection->AbortAllTransactions(IndexedDBDatabaseError(
2020 auto transactions(transactions_); 1884 blink::WebIDBDatabaseExceptionUnknownError, "Connection is closing."));
2021 for (const auto& it : transactions) {
2022 if (it.second->callbacks() == connection->callbacks())
2023 it.second->Abort(
2024 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
2025 "Connection is closing."));
2026 }
2027 }
2028 1885
2029 // Abort transactions before removing the connection; aborting may complete 1886 // Abort transactions before removing the connection; aborting may complete
2030 // an upgrade, and thus allow the next open/delete requests to proceed. The 1887 // an upgrade, and thus allow the next open/delete requests to proceed. The
2031 // new active_request_ should see the old connection count until explicitly 1888 // new active_request_ should see the old connection count until explicitly
2032 // notified below. 1889 // notified below.
2033 connections_.erase(connection); 1890 connections_.erase(connection);
2034 1891
2035 // Notify the active request, which may need to do cleanup or proceed with 1892 // Notify the active request, which may need to do cleanup or proceed with
2036 // the operation. This may trigger other work, such as more connections or 1893 // the operation. This may trigger other work, such as more connections or
2037 // deletions, so |active_request_| itself may change. 1894 // deletions, so |active_request_| itself may change.
2038 if (active_request_) 1895 if (active_request_)
2039 active_request_->OnConnectionClosed(connection); 1896 active_request_->OnConnectionClosed(connection);
2040 1897
2041 // If there are no more connections (current, active, or pending), tell the 1898 // If there are no more connections (current, active, or pending), tell the
2042 // factory to clean us up. 1899 // factory to clean us up.
2043 if (connections_.empty() && !active_request_ && pending_requests_.empty()) { 1900 if (connections_.empty() && !active_request_ && pending_requests_.empty()) {
2044 DCHECK(transactions_.empty());
2045 backing_store_ = nullptr; 1901 backing_store_ = nullptr;
2046 factory_->ReleaseDatabase(identifier_, forced); 1902 factory_->ReleaseDatabase(identifier_, forced);
2047 } 1903 }
2048 } 1904 }
2049 1905
2050 void IndexedDBDatabase::CreateObjectStoreAbortOperation( 1906 void IndexedDBDatabase::CreateObjectStoreAbortOperation(
2051 int64_t object_store_id) { 1907 int64_t object_store_id) {
2052 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); 1908 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation");
2053 RemoveObjectStore(object_store_id); 1909 RemoveObjectStore(object_store_id);
2054 } 1910 }
(...skipping 11 matching lines...) Expand all
2066 IDB_TRACE("IndexedDBDatabase::RenameObjectStoreAbortOperation"); 1922 IDB_TRACE("IndexedDBDatabase::RenameObjectStoreAbortOperation");
2067 SetObjectStoreName(object_store_id, old_name); 1923 SetObjectStoreName(object_store_id, old_name);
2068 } 1924 }
2069 1925
2070 void IndexedDBDatabase::VersionChangeAbortOperation(int64_t previous_version) { 1926 void IndexedDBDatabase::VersionChangeAbortOperation(int64_t previous_version) {
2071 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 1927 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
2072 metadata_.version = previous_version; 1928 metadata_.version = previous_version;
2073 } 1929 }
2074 1930
2075 } // namespace content 1931 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698