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

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: rebase 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
83 virtual ~ConnectionRequest() {} 96 virtual ~ConnectionRequest() {}
84 97
85 // Called when the request makes it to the front of the queue. 98 // Called when the request makes it to the front of the queue.
86 virtual void Perform() = 0; 99 virtual void Perform() = 0;
87 100
88 // Called if a front-end signals that it is ignoring a "versionchange" 101 // Called if a front-end signals that it is ignoring a "versionchange"
89 // event. This should result in firing a "blocked" event at the request. 102 // event. This should result in firing a "blocked" event at the request.
90 virtual void OnVersionChangeIgnored() const = 0; 103 virtual void OnVersionChangeIgnored() const = 0;
91 104
92 // Called when a connection is closed; if it corresponds to this connection, 105 // Called when a connection is closed; if it corresponds to this connection,
93 // need to do cleanup. Otherwise, it may unblock further steps. 106 // need to do cleanup. Otherwise, it may unblock further steps.
94 virtual void OnConnectionClosed(IndexedDBConnection* connection) = 0; 107 virtual void OnConnectionClosed(IndexedDBConnection* connection) = 0;
95 108
96 // Called when the upgrade transaction has started executing. 109 // Called when the upgrade transaction has started executing.
97 virtual void UpgradeTransactionStarted(int64_t old_version) = 0; 110 virtual void UpgradeTransactionStarted(int64_t old_version,
111 IndexedDBTransaction* transaction) = 0;
98 112
99 // Called when the upgrade transaction has finished. 113 // Called when the upgrade transaction has finished.
100 virtual void UpgradeTransactionFinished(bool committed) = 0; 114 virtual void UpgradeTransactionFinished(bool committed) = 0;
101 115
102 protected: 116 protected:
103 scoped_refptr<IndexedDBDatabase> db_; 117 scoped_refptr<IndexedDBDatabase> db_;
104 118
105 private: 119 private:
106 DISALLOW_COPY_AND_ASSIGN(ConnectionRequest); 120 DISALLOW_COPY_AND_ASSIGN(ConnectionRequest);
107 }; 121 };
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 pending_->transaction_id, connection_.get(), object_store_ids, 255 pending_->transaction_id, connection_.get(), object_store_ids,
242 blink::WebIDBTransactionModeVersionChange); 256 blink::WebIDBTransactionModeVersionChange);
243 257
244 DCHECK(db_->transaction_coordinator_.IsRunningVersionChangeTransaction()); 258 DCHECK(db_->transaction_coordinator_.IsRunningVersionChangeTransaction());
245 transaction->ScheduleTask( 259 transaction->ScheduleTask(
246 base::Bind(&IndexedDBDatabase::VersionChangeOperation, db_, 260 base::Bind(&IndexedDBDatabase::VersionChangeOperation, db_,
247 pending_->version, pending_->callbacks)); 261 pending_->version, pending_->callbacks));
248 } 262 }
249 263
250 // Called when the upgrade transaction has started executing. 264 // Called when the upgrade transaction has started executing.
251 void UpgradeTransactionStarted(int64_t old_version) override { 265 void UpgradeTransactionStarted(int64_t old_version,
266 IndexedDBTransaction* transaction) override {
252 DCHECK(connection_); 267 DCHECK(connection_);
253 pending_->callbacks->OnUpgradeNeeded(old_version, std::move(connection_), 268 pending_->callbacks->OnUpgradeNeeded(old_version, std::move(connection_),
254 db_->metadata_, 269 transaction, db_->metadata_,
255 pending_->data_loss_info); 270 pending_->data_loss_info);
256 } 271 }
257 272
258 void UpgradeTransactionFinished(bool committed) override { 273 void UpgradeTransactionFinished(bool committed) override {
259 // Ownership of connection was already passed along in OnUpgradeNeeded. 274 // Ownership of connection was already passed along in OnUpgradeNeeded.
260 DCHECK(!connection_); 275 DCHECK(!connection_);
261 276
262 if (committed) { 277 if (committed) {
263 DCHECK_EQ(pending_->version, db_->metadata_.version); 278 DCHECK_EQ(pending_->version, db_->metadata_.version);
264 pending_->callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(), 279 pending_->callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 db_->metadata_.id = kInvalidId; 351 db_->metadata_.id = kInvalidId;
337 db_->metadata_.version = IndexedDBDatabaseMetadata::NO_VERSION; 352 db_->metadata_.version = IndexedDBDatabaseMetadata::NO_VERSION;
338 db_->metadata_.max_object_store_id = kInvalidId; 353 db_->metadata_.max_object_store_id = kInvalidId;
339 db_->metadata_.object_stores.clear(); 354 db_->metadata_.object_stores.clear();
340 callbacks_->OnSuccess(old_version); 355 callbacks_->OnSuccess(old_version);
341 db_->factory_->DatabaseDeleted(db_->identifier_); 356 db_->factory_->DatabaseDeleted(db_->identifier_);
342 357
343 db_->RequestComplete(this); 358 db_->RequestComplete(this);
344 } 359 }
345 360
346 void UpgradeTransactionStarted(int64_t old_version) override { NOTREACHED(); } 361 void UpgradeTransactionStarted(int64_t old_version,
362 IndexedDBTransaction* transaction) override {
363 NOTREACHED();
364 }
347 365
348 void UpgradeTransactionFinished(bool committed) override { NOTREACHED(); } 366 void UpgradeTransactionFinished(bool committed) override { NOTREACHED(); }
349 367
350 private: 368 private:
351 scoped_refptr<IndexedDBCallbacks> callbacks_; 369 scoped_refptr<IndexedDBCallbacks> callbacks_;
352 370
353 DISALLOW_COPY_AND_ASSIGN(DeleteRequest); 371 DISALLOW_COPY_AND_ASSIGN(DeleteRequest);
354 }; 372 };
355 373
356 std::tuple<scoped_refptr<IndexedDBDatabase>, leveldb::Status> 374 std::tuple<scoped_refptr<IndexedDBDatabase>, leveldb::Status>
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 return s; 475 return s;
458 if (success) 476 if (success)
459 return backing_store_->GetObjectStores(metadata_.id, 477 return backing_store_->GetObjectStores(metadata_.id,
460 &metadata_.object_stores); 478 &metadata_.object_stores);
461 479
462 return backing_store_->CreateIDBDatabaseMetaData( 480 return backing_store_->CreateIDBDatabaseMetaData(
463 metadata_.name, metadata_.version, &metadata_.id); 481 metadata_.name, metadata_.version, &metadata_.id);
464 } 482 }
465 483
466 IndexedDBDatabase::~IndexedDBDatabase() { 484 IndexedDBDatabase::~IndexedDBDatabase() {
467 DCHECK(transactions_.empty());
468 DCHECK(!active_request_); 485 DCHECK(!active_request_);
469 DCHECK(pending_requests_.empty()); 486 DCHECK(pending_requests_.empty());
470 } 487 }
471 488
472 size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const { 489 size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const {
473 return kMaxIDBMessageSizeInBytes; 490 return kMaxIDBMessageSizeInBytes;
474 } 491 }
475 492
476 std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( 493 std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection(
477 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, 494 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks,
478 int child_process_id) { 495 int child_process_id) {
479 std::unique_ptr<IndexedDBConnection> connection( 496 std::unique_ptr<IndexedDBConnection> connection(
480 base::MakeUnique<IndexedDBConnection>(this, database_callbacks)); 497 base::MakeUnique<IndexedDBConnection>(child_process_id, this,
498 database_callbacks));
481 connections_.insert(connection.get()); 499 connections_.insert(connection.get());
482 backing_store_->GrantChildProcessPermissions(child_process_id); 500 backing_store_->GrantChildProcessPermissions(child_process_id);
483 return connection; 501 return connection;
484 } 502 }
485 503
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 { 504 bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const {
495 if (!base::ContainsKey(metadata_.object_stores, object_store_id)) { 505 if (!base::ContainsKey(metadata_.object_stores, object_store_id)) {
496 DLOG(ERROR) << "Invalid object_store_id"; 506 DLOG(ERROR) << "Invalid object_store_id";
497 return false; 507 return false;
498 } 508 }
499 return true; 509 return true;
500 } 510 }
501 511
502 bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId( 512 bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId(
503 int64_t object_store_id, 513 int64_t object_store_id,
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 return false; 545 return false;
536 const IndexedDBObjectStoreMetadata& object_store_metadata = 546 const IndexedDBObjectStoreMetadata& object_store_metadata =
537 metadata_.object_stores.find(object_store_id)->second; 547 metadata_.object_stores.find(object_store_id)->second;
538 if (base::ContainsKey(object_store_metadata.indexes, index_id)) { 548 if (base::ContainsKey(object_store_metadata.indexes, index_id)) {
539 DLOG(ERROR) << "Invalid index_id"; 549 DLOG(ERROR) << "Invalid index_id";
540 return false; 550 return false;
541 } 551 }
542 return true; 552 return true;
543 } 553 }
544 554
545 void IndexedDBDatabase::CreateObjectStore(int64_t transaction_id, 555 void IndexedDBDatabase::CreateObjectStore(IndexedDBTransaction* transaction,
546 int64_t object_store_id, 556 int64_t object_store_id,
547 const base::string16& name, 557 const base::string16& name,
548 const IndexedDBKeyPath& key_path, 558 const IndexedDBKeyPath& key_path,
549 bool auto_increment) { 559 bool auto_increment) {
550 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id);
551 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
552 if (!transaction) 560 if (!transaction)
553 return; 561 return;
562 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id",
563 transaction->id());
554 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 564 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
555 565
556 if (base::ContainsKey(metadata_.object_stores, object_store_id)) { 566 if (base::ContainsKey(metadata_.object_stores, object_store_id)) {
557 DLOG(ERROR) << "Invalid object_store_id"; 567 DLOG(ERROR) << "Invalid object_store_id";
558 return; 568 return;
559 } 569 }
560 570
561 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType", 571 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType",
562 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); 572 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX);
563 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement", 573 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement",
(...skipping 14 matching lines...) Expand all
578 transaction->database()->id(), 588 transaction->database()->id(),
579 object_store_metadata.id, 589 object_store_metadata.id,
580 object_store_metadata.name, 590 object_store_metadata.name,
581 object_store_metadata.key_path, 591 object_store_metadata.key_path,
582 object_store_metadata.auto_increment); 592 object_store_metadata.auto_increment);
583 if (!s.ok()) { 593 if (!s.ok()) {
584 IndexedDBDatabaseError error( 594 IndexedDBDatabaseError error(
585 blink::WebIDBDatabaseExceptionUnknownError, 595 blink::WebIDBDatabaseExceptionUnknownError,
586 ASCIIToUTF16("Internal error creating object store '") + 596 ASCIIToUTF16("Internal error creating object store '") +
587 object_store_metadata.name + ASCIIToUTF16("'.")); 597 object_store_metadata.name + ASCIIToUTF16("'."));
588 transaction->Abort(error); 598 ReportError(s, origin(), factory_.get(), error);
589 if (s.IsCorruption())
590 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
591 return; 599 return;
592 } 600 }
593 601
594 AddObjectStore(object_store_metadata, object_store_id); 602 AddObjectStore(object_store_metadata, object_store_id);
595 transaction->ScheduleAbortTask( 603 transaction->ScheduleAbortTask(
596 base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, 604 base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation,
597 this, 605 this,
598 object_store_id)); 606 object_store_id));
599 } 607 }
600 608
601 void IndexedDBDatabase::DeleteObjectStore(int64_t transaction_id, 609 void IndexedDBDatabase::DeleteObjectStore(IndexedDBTransaction* transaction,
602 int64_t object_store_id) { 610 int64_t object_store_id) {
603 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id);
604 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
605 if (!transaction) 611 if (!transaction)
606 return; 612 return;
613 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id",
614 transaction->id());
607 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 615 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
608 616
609 if (!ValidateObjectStoreId(object_store_id)) 617 if (!ValidateObjectStoreId(object_store_id))
610 return; 618 return;
611 619
612 transaction->ScheduleTask( 620 transaction->ScheduleTask(
613 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, 621 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation,
614 this, 622 this,
615 object_store_id)); 623 object_store_id));
616 } 624 }
617 625
618 void IndexedDBDatabase::RenameObjectStore(int64_t transaction_id, 626 void IndexedDBDatabase::RenameObjectStore(IndexedDBTransaction* transaction,
619 int64_t object_store_id, 627 int64_t object_store_id,
620 const base::string16& new_name) { 628 const base::string16& new_name) {
621 IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id", transaction_id);
622 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
623 if (!transaction) 629 if (!transaction)
624 return; 630 return;
631 IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id",
632 transaction->id());
625 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 633 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
626 634
627 if (!ValidateObjectStoreId(object_store_id)) 635 if (!ValidateObjectStoreId(object_store_id))
628 return; 636 return;
629 637
630 // Store renaming is done synchronously, as it may be followed by 638 // Store renaming is done synchronously, as it may be followed by
631 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys 639 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys
632 // may follow. 640 // may follow.
633 const IndexedDBObjectStoreMetadata object_store_metadata = 641 const IndexedDBObjectStoreMetadata object_store_metadata =
634 metadata_.object_stores[object_store_id]; 642 metadata_.object_stores[object_store_id];
635 643
636 leveldb::Status s = 644 leveldb::Status s =
637 backing_store_->RenameObjectStore(transaction->BackingStoreTransaction(), 645 backing_store_->RenameObjectStore(transaction->BackingStoreTransaction(),
638 transaction->database()->id(), 646 transaction->database()->id(),
639 object_store_metadata.id, new_name); 647 object_store_metadata.id, new_name);
640 if (!s.ok()) { 648 if (!s.ok()) {
641 IndexedDBDatabaseError error( 649 IndexedDBDatabaseError error(
642 blink::WebIDBDatabaseExceptionUnknownError, 650 blink::WebIDBDatabaseExceptionUnknownError,
643 ASCIIToUTF16("Internal error renaming object store '") + 651 ASCIIToUTF16("Internal error renaming object store '") +
644 object_store_metadata.name + ASCIIToUTF16("' to '") + new_name + 652 object_store_metadata.name + ASCIIToUTF16("' to '") + new_name +
645 ASCIIToUTF16("'.")); 653 ASCIIToUTF16("'."));
646 transaction->Abort(error); 654 ReportError(s, origin(), factory_.get(), error);
647 if (s.IsCorruption())
648 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
649 return; 655 return;
650 } 656 }
651 657
652 transaction->ScheduleAbortTask( 658 transaction->ScheduleAbortTask(
653 base::Bind(&IndexedDBDatabase::RenameObjectStoreAbortOperation, 659 base::Bind(&IndexedDBDatabase::RenameObjectStoreAbortOperation,
654 this, 660 this,
655 object_store_id, 661 object_store_id,
656 object_store_metadata.name)); 662 object_store_metadata.name));
657 SetObjectStoreName(object_store_id, new_name); 663 SetObjectStoreName(object_store_id, new_name);
658 } 664 }
659 665
660 void IndexedDBDatabase::CreateIndex(int64_t transaction_id, 666 void IndexedDBDatabase::CreateIndex(IndexedDBTransaction* transaction,
661 int64_t object_store_id, 667 int64_t object_store_id,
662 int64_t index_id, 668 int64_t index_id,
663 const base::string16& name, 669 const base::string16& name,
664 const IndexedDBKeyPath& key_path, 670 const IndexedDBKeyPath& key_path,
665 bool unique, 671 bool unique,
666 bool multi_entry) { 672 bool multi_entry) {
667 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id);
668 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
669 if (!transaction) 673 if (!transaction)
670 return; 674 return;
675 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction->id());
671 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 676 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
672 677
673 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) 678 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id))
674 return; 679 return;
675 680
676 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType", 681 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType",
677 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); 682 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX);
678 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique); 683 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique);
679 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry", 684 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry",
680 multi_entry); 685 multi_entry);
(...skipping 26 matching lines...) Expand all
707 object_store_id, 712 object_store_id,
708 index_id)); 713 index_id));
709 } 714 }
710 715
711 void IndexedDBDatabase::CreateIndexAbortOperation(int64_t object_store_id, 716 void IndexedDBDatabase::CreateIndexAbortOperation(int64_t object_store_id,
712 int64_t index_id) { 717 int64_t index_id) {
713 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); 718 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation");
714 RemoveIndex(object_store_id, index_id); 719 RemoveIndex(object_store_id, index_id);
715 } 720 }
716 721
717 void IndexedDBDatabase::DeleteIndex(int64_t transaction_id, 722 void IndexedDBDatabase::DeleteIndex(IndexedDBTransaction* transaction,
718 int64_t object_store_id, 723 int64_t object_store_id,
719 int64_t index_id) { 724 int64_t index_id) {
720 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id);
721 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
722 if (!transaction) 725 if (!transaction)
723 return; 726 return;
727 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction->id());
724 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 728 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
725 729
726 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 730 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id))
727 return; 731 return;
728 732
729 transaction->ScheduleTask( 733 transaction->ScheduleTask(
730 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, 734 base::Bind(&IndexedDBDatabase::DeleteIndexOperation,
731 this, 735 this,
732 object_store_id, 736 object_store_id,
733 index_id)); 737 index_id));
734 } 738 }
735 739
736 leveldb::Status IndexedDBDatabase::DeleteIndexOperation( 740 leveldb::Status IndexedDBDatabase::DeleteIndexOperation(
737 int64_t object_store_id, 741 int64_t object_store_id,
738 int64_t index_id, 742 int64_t index_id,
739 IndexedDBTransaction* transaction) { 743 IndexedDBTransaction* transaction) {
740 IDB_TRACE1( 744 IDB_TRACE1(
741 "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id()); 745 "IndexedDBDatabase::DeleteIndexOperation", "txn.id", transaction->id());
742 746
743 const IndexedDBIndexMetadata index_metadata = 747 const IndexedDBIndexMetadata index_metadata =
744 metadata_.object_stores[object_store_id].indexes[index_id]; 748 metadata_.object_stores[object_store_id].indexes[index_id];
745 749
746 leveldb::Status s = 750 leveldb::Status s =
747 backing_store_->DeleteIndex(transaction->BackingStoreTransaction(), 751 backing_store_->DeleteIndex(transaction->BackingStoreTransaction(),
748 transaction->database()->id(), 752 transaction->database()->id(),
749 object_store_id, 753 object_store_id,
750 index_id); 754 index_id);
751 if (!s.ok()) { 755 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; 756 return s;
759 }
760 757
761 RemoveIndex(object_store_id, index_id); 758 RemoveIndex(object_store_id, index_id);
762 transaction->ScheduleAbortTask( 759 transaction->ScheduleAbortTask(
763 base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation, 760 base::Bind(&IndexedDBDatabase::DeleteIndexAbortOperation,
764 this, 761 this,
765 object_store_id, 762 object_store_id,
766 index_metadata)); 763 index_metadata));
767 return s; 764 return s;
768 } 765 }
769 766
770 void IndexedDBDatabase::DeleteIndexAbortOperation( 767 void IndexedDBDatabase::DeleteIndexAbortOperation(
771 int64_t object_store_id, 768 int64_t object_store_id,
772 const IndexedDBIndexMetadata& index_metadata) { 769 const IndexedDBIndexMetadata& index_metadata) {
773 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); 770 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation");
774 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); 771 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId);
775 } 772 }
776 773
777 void IndexedDBDatabase::RenameIndex(int64_t transaction_id, 774 void IndexedDBDatabase::RenameIndex(IndexedDBTransaction* transaction,
778 int64_t object_store_id, 775 int64_t object_store_id,
779 int64_t index_id, 776 int64_t index_id,
780 const base::string16& new_name) { 777 const base::string16& new_name) {
781 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction_id);
782 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
783 if (!transaction) 778 if (!transaction)
784 return; 779 return;
780 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction->id());
785 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 781 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
786 782
787 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) 783 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id))
788 return; 784 return;
789 785
790 // Index renaming is done synchronously since preemptive 786 // Index renaming is done synchronously since preemptive
791 // OpenCursor/SetIndexKeys may follow. 787 // OpenCursor/SetIndexKeys may follow.
792 788
793 const IndexedDBIndexMetadata index_metadata = 789 const IndexedDBIndexMetadata index_metadata =
794 metadata_.object_stores[object_store_id].indexes[index_id]; 790 metadata_.object_stores[object_store_id].indexes[index_id];
795 791
796 leveldb::Status s = 792 leveldb::Status s =
797 backing_store_->RenameIndex(transaction->BackingStoreTransaction(), 793 backing_store_->RenameIndex(transaction->BackingStoreTransaction(),
798 transaction->database()->id(), 794 transaction->database()->id(),
799 object_store_id, 795 object_store_id,
800 index_id, 796 index_id,
801 new_name); 797 new_name);
802 if (!s.ok()) { 798 if (!s.ok()) {
803 base::string16 error_string = 799 base::string16 error_string =
804 ASCIIToUTF16("Internal error renaming index '") + 800 ASCIIToUTF16("Internal error renaming index '") +
805 index_metadata.name + ASCIIToUTF16("' to '") + new_name + 801 index_metadata.name + ASCIIToUTF16("' to '") + new_name +
806 ASCIIToUTF16("'."); 802 ASCIIToUTF16("'.");
807 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 803 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
808 error_string); 804 error_string);
809 transaction->Abort(error); 805 ReportError(s, origin(), factory_.get(), error);
810 if (s.IsCorruption())
811 factory_->HandleBackingStoreCorruption(origin(), error);
812 else
813 factory_->HandleBackingStoreFailure(origin());
814 return; 806 return;
815 } 807 }
816 808
817 transaction->ScheduleAbortTask( 809 transaction->ScheduleAbortTask(
818 base::Bind(&IndexedDBDatabase::RenameIndexAbortOperation, 810 base::Bind(&IndexedDBDatabase::RenameIndexAbortOperation,
819 this, 811 this,
820 object_store_id, 812 object_store_id,
821 index_id, 813 index_id,
822 index_metadata.name)); 814 index_metadata.name));
823 SetIndexName(object_store_id, index_id, new_name); 815 SetIndexName(object_store_id, index_id, new_name);
824 } 816 }
825 817
826 void IndexedDBDatabase::RenameIndexAbortOperation( 818 void IndexedDBDatabase::RenameIndexAbortOperation(
827 int64_t object_store_id, 819 int64_t object_store_id,
828 int64_t index_id, 820 int64_t index_id,
829 const base::string16& old_name) { 821 const base::string16& old_name) {
830 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation"); 822 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation");
831 SetIndexName(object_store_id, index_id, old_name); 823 SetIndexName(object_store_id, index_id, old_name);
832 } 824 }
833 825
834 void IndexedDBDatabase::Commit(int64_t transaction_id) { 826 void IndexedDBDatabase::Commit(IndexedDBTransaction* transaction) {
835 // The frontend suggests that we commit, but we may have previously initiated 827 // 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 828 // 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 829 // been dispatched to the frontend, so it will find out about that
838 // asynchronously. 830 // asynchronously.
839 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
840 if (transaction) { 831 if (transaction) {
841 scoped_refptr<IndexedDBFactory> factory = factory_; 832 scoped_refptr<IndexedDBFactory> factory = factory_;
842 leveldb::Status result = transaction->Commit(); 833 leveldb::Status result = transaction->Commit();
843 if (!result.ok()) { 834 if (!result.ok()) {
844 if (result.IsCorruption()) { 835 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
845 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 836 base::ASCIIToUTF16(result.ToString()));
846 base::ASCIIToUTF16(result.ToString())); 837 ReportError(result, origin(), factory_.get(), error);
847 factory->HandleBackingStoreCorruption(origin(), error);
848 } else {
849 factory->HandleBackingStoreFailure(origin());
850 }
851 } 838 }
852 } 839 }
853 } 840 }
854 841
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( 842 void IndexedDBDatabase::AddPendingObserver(
875 int64_t transaction_id, 843 IndexedDBTransaction* transaction,
876 int32_t observer_id, 844 int32_t observer_id,
877 const IndexedDBObserver::Options& options) { 845 const IndexedDBObserver::Options& options) {
878 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
cmumford 2016/12/01 19:14:51 It looks like callers (like IDBThreadHelper) alrea
dmurph 2016/12/01 21:12:23 I'll do DCHECKs everywhere. It's a safe assumption
879 if (!transaction) 846 if (!transaction)
880 return; 847 return;
881 transaction->AddPendingObserver(observer_id, options); 848 transaction->AddPendingObserver(observer_id, options);
882 } 849 }
883 850
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 851 // TODO(palakj): Augment the function with IDBValue later. Issue
896 // crbug.com/609934. 852 // crbug.com/609934.
897 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, 853 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction,
898 int64_t object_store_id, 854 int64_t object_store_id,
899 blink::WebIDBOperationType type, 855 blink::WebIDBOperationType type,
900 const IndexedDBKeyRange& key_range) { 856 const IndexedDBKeyRange& key_range) {
901 for (auto* connection : connections_) { 857 for (auto* connection : connections_) {
902 bool recorded = false; 858 bool recorded = false;
903 for (const auto& observer : connection->active_observers()) { 859 for (const auto& observer : connection->active_observers()) {
904 if (!observer->IsRecordingType(type) || 860 if (!observer->IsRecordingType(type) ||
(...skipping 16 matching lines...) Expand all
921 877
922 void IndexedDBDatabase::SendObservations( 878 void IndexedDBDatabase::SendObservations(
923 std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> changes_map) { 879 std::map<int32_t, ::indexed_db::mojom::ObserverChangesPtr> changes_map) {
924 for (auto* conn : connections_) { 880 for (auto* conn : connections_) {
925 auto it = changes_map.find(conn->id()); 881 auto it = changes_map.find(conn->id());
926 if (it != changes_map.end()) 882 if (it != changes_map.end())
927 conn->callbacks()->OnDatabaseChange(std::move(it->second)); 883 conn->callbacks()->OnDatabaseChange(std::move(it->second));
928 } 884 }
929 } 885 }
930 886
931 void IndexedDBDatabase::GetAll(int64_t transaction_id, 887 void IndexedDBDatabase::GetAll(IndexedDBTransaction* transaction,
932 int64_t object_store_id, 888 int64_t object_store_id,
933 int64_t index_id, 889 int64_t index_id,
934 std::unique_ptr<IndexedDBKeyRange> key_range, 890 std::unique_ptr<IndexedDBKeyRange> key_range,
935 bool key_only, 891 bool key_only,
936 int64_t max_count, 892 int64_t max_count,
937 scoped_refptr<IndexedDBCallbacks> callbacks) { 893 scoped_refptr<IndexedDBCallbacks> callbacks) {
938 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id);
939 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
940 if (!transaction) 894 if (!transaction)
941 return; 895 return;
896 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction->id());
942 897
943 if (!ValidateObjectStoreId(object_store_id)) 898 if (!ValidateObjectStoreId(object_store_id))
944 return; 899 return;
945 900
946 transaction->ScheduleTask(base::Bind( 901 transaction->ScheduleTask(base::Bind(
947 &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id, 902 &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id,
948 base::Passed(&key_range), 903 base::Passed(&key_range),
949 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 904 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
950 max_count, callbacks)); 905 max_count, callbacks));
951 } 906 }
952 907
953 void IndexedDBDatabase::Get(int64_t transaction_id, 908 void IndexedDBDatabase::Get(IndexedDBTransaction* transaction,
954 int64_t object_store_id, 909 int64_t object_store_id,
955 int64_t index_id, 910 int64_t index_id,
956 std::unique_ptr<IndexedDBKeyRange> key_range, 911 std::unique_ptr<IndexedDBKeyRange> key_range,
957 bool key_only, 912 bool key_only,
958 scoped_refptr<IndexedDBCallbacks> callbacks) { 913 scoped_refptr<IndexedDBCallbacks> callbacks) {
959 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id);
960 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
961 if (!transaction) 914 if (!transaction)
962 return; 915 return;
916 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction->id());
963 917
964 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 918 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
965 return; 919 return;
966 920
967 transaction->ScheduleTask(base::Bind( 921 transaction->ScheduleTask(base::Bind(
968 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id, 922 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id,
969 base::Passed(&key_range), 923 base::Passed(&key_range),
970 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, 924 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
971 callbacks)); 925 callbacks));
972 } 926 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 backing_store_cursor = backing_store_->OpenIndexCursor( 972 backing_store_cursor = backing_store_->OpenIndexCursor(
1019 transaction->BackingStoreTransaction(), 973 transaction->BackingStoreTransaction(),
1020 id(), 974 id(),
1021 object_store_id, 975 object_store_id,
1022 index_id, 976 index_id,
1023 *key_range, 977 *key_range,
1024 blink::WebIDBCursorDirectionNext, 978 blink::WebIDBCursorDirectionNext,
1025 &s); 979 &s);
1026 } 980 }
1027 981
1028 if (!s.ok()) { 982 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; 983 return s;
1034 }
1035 984
1036 if (!backing_store_cursor) { 985 if (!backing_store_cursor) {
1037 // This means we've run out of data. 986 // This means we've run out of data.
1038 callbacks->OnSuccess(); 987 callbacks->OnSuccess();
1039 return s; 988 return s;
1040 } 989 }
1041 990
1042 key = &backing_store_cursor->key(); 991 key = &backing_store_cursor->key();
1043 } 992 }
1044 993
1045 std::unique_ptr<IndexedDBKey> primary_key; 994 std::unique_ptr<IndexedDBKey> primary_key;
1046 if (index_id == IndexedDBIndexMetadata::kInvalidId) { 995 if (index_id == IndexedDBIndexMetadata::kInvalidId) {
1047 // Object Store Retrieval Operation 996 // Object Store Retrieval Operation
1048 IndexedDBReturnValue value; 997 IndexedDBReturnValue value;
1049 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 998 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
1050 id(), 999 id(),
1051 object_store_id, 1000 object_store_id,
1052 *key, 1001 *key,
1053 &value); 1002 &value);
1054 if (!s.ok()) { 1003 if (!s.ok())
1055 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1056 "Internal error in GetRecord.");
1057 callbacks->OnError(error);
1058 return s; 1004 return s;
1059 }
1060 1005
1061 if (value.empty()) { 1006 if (value.empty()) {
1062 callbacks->OnSuccess(); 1007 callbacks->OnSuccess();
1063 return s; 1008 return s;
1064 } 1009 }
1065 1010
1066 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1011 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1067 callbacks->OnSuccess(*key); 1012 callbacks->OnSuccess(*key);
1068 return s; 1013 return s;
1069 } 1014 }
1070 1015
1071 if (object_store_metadata.auto_increment && 1016 if (object_store_metadata.auto_increment &&
1072 !object_store_metadata.key_path.IsNull()) { 1017 !object_store_metadata.key_path.IsNull()) {
1073 value.primary_key = *key; 1018 value.primary_key = *key;
1074 value.key_path = object_store_metadata.key_path; 1019 value.key_path = object_store_metadata.key_path;
1075 } 1020 }
1076 1021
1077 callbacks->OnSuccess(&value); 1022 callbacks->OnSuccess(&value);
1078 return s; 1023 return s;
1079 } 1024 }
1080 1025
1081 // From here we are dealing only with indexes. 1026 // From here we are dealing only with indexes.
1082 s = backing_store_->GetPrimaryKeyViaIndex( 1027 s = backing_store_->GetPrimaryKeyViaIndex(
1083 transaction->BackingStoreTransaction(), 1028 transaction->BackingStoreTransaction(),
1084 id(), 1029 id(),
1085 object_store_id, 1030 object_store_id,
1086 index_id, 1031 index_id,
1087 *key, 1032 *key,
1088 &primary_key); 1033 &primary_key);
1089 if (!s.ok()) { 1034 if (!s.ok())
1090 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1091 "Internal error in GetPrimaryKeyViaIndex.");
1092 callbacks->OnError(error);
1093 return s; 1035 return s;
1094 } 1036
1095 if (!primary_key) { 1037 if (!primary_key) {
1096 callbacks->OnSuccess(); 1038 callbacks->OnSuccess();
1097 return s; 1039 return s;
1098 } 1040 }
1099 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1041 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1100 // Index Value Retrieval Operation 1042 // Index Value Retrieval Operation
1101 callbacks->OnSuccess(*primary_key); 1043 callbacks->OnSuccess(*primary_key);
1102 return s; 1044 return s;
1103 } 1045 }
1104 1046
1105 // Index Referenced Value Retrieval Operation 1047 // Index Referenced Value Retrieval Operation
1106 IndexedDBReturnValue value; 1048 IndexedDBReturnValue value;
1107 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(), 1049 s = backing_store_->GetRecord(transaction->BackingStoreTransaction(),
1108 id(), 1050 id(),
1109 object_store_id, 1051 object_store_id,
1110 *primary_key, 1052 *primary_key,
1111 &value); 1053 &value);
1112 if (!s.ok()) { 1054 if (!s.ok())
1113 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1114 "Internal error in GetRecord.");
1115 callbacks->OnError(error);
1116 return s; 1055 return s;
1117 }
1118 1056
1119 if (value.empty()) { 1057 if (value.empty()) {
1120 callbacks->OnSuccess(); 1058 callbacks->OnSuccess();
1121 return s; 1059 return s;
1122 } 1060 }
1123 if (object_store_metadata.auto_increment && 1061 if (object_store_metadata.auto_increment &&
1124 !object_store_metadata.key_path.IsNull()) { 1062 !object_store_metadata.key_path.IsNull()) {
1125 value.primary_key = *primary_key; 1063 value.primary_key = *primary_key;
1126 value.key_path = object_store_metadata.key_path; 1064 value.key_path = object_store_metadata.key_path;
1127 } 1065 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 } else { 1111 } else {
1174 // Object Store: Referenced Value Retrieval Operation 1112 // Object Store: Referenced Value Retrieval Operation
1175 cursor = backing_store_->OpenIndexCursor( 1113 cursor = backing_store_->OpenIndexCursor(
1176 transaction->BackingStoreTransaction(), id(), object_store_id, 1114 transaction->BackingStoreTransaction(), id(), object_store_id,
1177 index_id, *key_range, blink::WebIDBCursorDirectionNext, &s); 1115 index_id, *key_range, blink::WebIDBCursorDirectionNext, &s);
1178 } 1116 }
1179 } 1117 }
1180 1118
1181 if (!s.ok()) { 1119 if (!s.ok()) {
1182 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1120 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; 1121 return s;
1187 } 1122 }
1188 1123
1189 std::vector<IndexedDBKey> found_keys; 1124 std::vector<IndexedDBKey> found_keys;
1190 std::vector<IndexedDBReturnValue> found_values; 1125 std::vector<IndexedDBReturnValue> found_values;
1191 if (!cursor) { 1126 if (!cursor) {
1192 // Doesn't matter if key or value array here - will be empty array when it 1127 // Doesn't matter if key or value array here - will be empty array when it
1193 // hits JavaScript. 1128 // hits JavaScript.
1194 callbacks->OnSuccessArray(&found_values); 1129 callbacks->OnSuccessArray(&found_values);
1195 return s; 1130 return s;
1196 } 1131 }
1197 1132
1198 bool did_first_seek = false; 1133 bool did_first_seek = false;
1199 bool generated_key = object_store_metadata.auto_increment && 1134 bool generated_key = object_store_metadata.auto_increment &&
1200 !object_store_metadata.key_path.IsNull(); 1135 !object_store_metadata.key_path.IsNull();
1201 1136
1202 size_t response_size = kMaxIDBMessageOverhead; 1137 size_t response_size = kMaxIDBMessageOverhead;
1203 int64_t num_found_items = 0; 1138 int64_t num_found_items = 0;
1204 while (num_found_items++ < max_count) { 1139 while (num_found_items++ < max_count) {
1205 bool cursor_valid; 1140 bool cursor_valid;
1206 if (did_first_seek) { 1141 if (did_first_seek) {
1207 cursor_valid = cursor->Continue(&s); 1142 cursor_valid = cursor->Continue(&s);
1208 } else { 1143 } else {
1209 cursor_valid = cursor->FirstSeek(&s); 1144 cursor_valid = cursor->FirstSeek(&s);
1210 did_first_seek = true; 1145 did_first_seek = true;
1211 } 1146 }
1212 if (!s.ok()) { 1147 if (!s.ok())
1213 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1214 "Internal error in GetAllOperation.");
1215 callbacks->OnError(error);
1216 return s; 1148 return s;
1217 }
1218 1149
1219 if (!cursor_valid) 1150 if (!cursor_valid)
1220 break; 1151 break;
1221 1152
1222 IndexedDBReturnValue return_value; 1153 IndexedDBReturnValue return_value;
1223 IndexedDBKey return_key; 1154 IndexedDBKey return_key;
1224 1155
1225 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) { 1156 if (cursor_type == indexed_db::CURSOR_KEY_ONLY) {
1226 return_key = cursor->primary_key(); 1157 return_key = cursor->primary_key();
1227 } else { 1158 } else {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 std::unique_ptr<IndexedDBKey> key; 1234 std::unique_ptr<IndexedDBKey> key;
1304 blink::WebIDBPutMode put_mode; 1235 blink::WebIDBPutMode put_mode;
1305 scoped_refptr<IndexedDBCallbacks> callbacks; 1236 scoped_refptr<IndexedDBCallbacks> callbacks;
1306 std::vector<IndexedDBIndexKeys> index_keys; 1237 std::vector<IndexedDBIndexKeys> index_keys;
1307 1238
1308 private: 1239 private:
1309 DISALLOW_COPY_AND_ASSIGN(PutOperationParams); 1240 DISALLOW_COPY_AND_ASSIGN(PutOperationParams);
1310 }; 1241 };
1311 1242
1312 void IndexedDBDatabase::Put( 1243 void IndexedDBDatabase::Put(
1313 int64_t transaction_id, 1244 IndexedDBTransaction* transaction,
1314 int64_t object_store_id, 1245 int64_t object_store_id,
1315 IndexedDBValue* value, 1246 IndexedDBValue* value,
1316 std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles, 1247 std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles,
1317 std::unique_ptr<IndexedDBKey> key, 1248 std::unique_ptr<IndexedDBKey> key,
1318 blink::WebIDBPutMode put_mode, 1249 blink::WebIDBPutMode put_mode,
1319 scoped_refptr<IndexedDBCallbacks> callbacks, 1250 scoped_refptr<IndexedDBCallbacks> callbacks,
1320 const std::vector<IndexedDBIndexKeys>& index_keys) { 1251 const std::vector<IndexedDBIndexKeys>& index_keys) {
1321 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id);
1322 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1323 if (!transaction) 1252 if (!transaction)
1324 return; 1253 return;
1254 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction->id());
1325 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1255 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1326 1256
1327 if (!ValidateObjectStoreId(object_store_id)) 1257 if (!ValidateObjectStoreId(object_store_id))
1328 return; 1258 return;
1329 1259
1330 DCHECK(key); 1260 DCHECK(key);
1331 DCHECK(value); 1261 DCHECK(value);
1332 std::unique_ptr<PutOperationParams> params( 1262 std::unique_ptr<PutOperationParams> params(
1333 base::MakeUnique<PutOperationParams>()); 1263 base::MakeUnique<PutOperationParams>());
1334 params->object_store_id = object_store_id; 1264 params->object_store_id = object_store_id;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1378 IndexedDBBackingStore::RecordIdentifier record_identifier; 1308 IndexedDBBackingStore::RecordIdentifier record_identifier;
1379 if (params->put_mode == blink::WebIDBPutModeAddOnly) { 1309 if (params->put_mode == blink::WebIDBPutModeAddOnly) {
1380 bool found = false; 1310 bool found = false;
1381 leveldb::Status s = backing_store_->KeyExistsInObjectStore( 1311 leveldb::Status s = backing_store_->KeyExistsInObjectStore(
1382 transaction->BackingStoreTransaction(), 1312 transaction->BackingStoreTransaction(),
1383 id(), 1313 id(),
1384 params->object_store_id, 1314 params->object_store_id,
1385 *key, 1315 *key,
1386 &record_identifier, 1316 &record_identifier,
1387 &found); 1317 &found);
1388 if (!s.ok()) { 1318 if (!s.ok())
1389 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1390 "Internal error checking key existence.");
1391 params->callbacks->OnError(error);
1392 return s; 1319 return s;
1393 }
1394 if (found) { 1320 if (found) {
1395 params->callbacks->OnError( 1321 params->callbacks->OnError(
1396 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError, 1322 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionConstraintError,
1397 "Key already exists in the object store.")); 1323 "Key already exists in the object store."));
1398 return s; 1324 return s;
1399 } 1325 }
1400 } 1326 }
1401 1327
1402 std::vector<std::unique_ptr<IndexWriter>> index_writers; 1328 std::vector<std::unique_ptr<IndexWriter>> index_writers;
1403 base::string16 error_message; 1329 base::string16 error_message;
(...skipping 18 matching lines...) Expand all
1422 params->callbacks->OnError(IndexedDBDatabaseError( 1348 params->callbacks->OnError(IndexedDBDatabaseError(
1423 blink::WebIDBDatabaseExceptionConstraintError, error_message)); 1349 blink::WebIDBDatabaseExceptionConstraintError, error_message));
1424 return s; 1350 return s;
1425 } 1351 }
1426 1352
1427 // Before this point, don't do any mutation. After this point, rollback the 1353 // Before this point, don't do any mutation. After this point, rollback the
1428 // transaction in case of error. 1354 // transaction in case of error.
1429 s = backing_store_->PutRecord(transaction->BackingStoreTransaction(), id(), 1355 s = backing_store_->PutRecord(transaction->BackingStoreTransaction(), id(),
1430 params->object_store_id, *key, &params->value, 1356 params->object_store_id, *key, &params->value,
1431 &params->handles, &record_identifier); 1357 &params->handles, &record_identifier);
1432 if (!s.ok()) { 1358 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; 1359 return s;
1438 } 1360
1439 { 1361 {
1440 IDB_TRACE1("IndexedDBDatabase::PutOperation.UpdateIndexes", "txn.id", 1362 IDB_TRACE1("IndexedDBDatabase::PutOperation.UpdateIndexes", "txn.id",
1441 transaction->id()); 1363 transaction->id());
1442 for (const auto& writer : index_writers) { 1364 for (const auto& writer : index_writers) {
1443 writer->WriteIndexKeys(record_identifier, backing_store_.get(), 1365 writer->WriteIndexKeys(record_identifier, backing_store_.get(),
1444 transaction->BackingStoreTransaction(), id(), 1366 transaction->BackingStoreTransaction(), id(),
1445 params->object_store_id); 1367 params->object_store_id);
1446 } 1368 }
1447 } 1369 }
1448 1370
1449 if (object_store.auto_increment && 1371 if (object_store.auto_increment &&
1450 params->put_mode != blink::WebIDBPutModeCursorUpdate && 1372 params->put_mode != blink::WebIDBPutModeCursorUpdate &&
1451 key->type() == WebIDBKeyTypeNumber) { 1373 key->type() == WebIDBKeyTypeNumber) {
1452 IDB_TRACE1("IndexedDBDatabase::PutOperation.AutoIncrement", "txn.id", 1374 IDB_TRACE1("IndexedDBDatabase::PutOperation.AutoIncrement", "txn.id",
1453 transaction->id()); 1375 transaction->id());
1454 s = UpdateKeyGenerator(backing_store_.get(), transaction, id(), 1376 s = UpdateKeyGenerator(backing_store_.get(), transaction, id(),
1455 params->object_store_id, *key, !key_was_generated); 1377 params->object_store_id, *key, !key_was_generated);
1456 if (!s.ok()) { 1378 if (!s.ok())
1457 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1458 "Internal error updating key generator.");
1459 params->callbacks->OnError(error);
1460 return s; 1379 return s;
1461 }
1462 } 1380 }
1463 { 1381 {
1464 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id", 1382 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id",
1465 transaction->id()); 1383 transaction->id());
1466 params->callbacks->OnSuccess(*key); 1384 params->callbacks->OnSuccess(*key);
1467 } 1385 }
1468 FilterObservation(transaction, params->object_store_id, 1386 FilterObservation(transaction, params->object_store_id,
1469 params->put_mode == blink::WebIDBPutModeAddOnly 1387 params->put_mode == blink::WebIDBPutModeAddOnly
1470 ? blink::WebIDBAdd 1388 ? blink::WebIDBAdd
1471 : blink::WebIDBPut, 1389 : blink::WebIDBPut,
1472 IndexedDBKeyRange(*key)); 1390 IndexedDBKeyRange(*key));
1473 return s; 1391 return s;
1474 } 1392 }
1475 1393
1476 void IndexedDBDatabase::SetIndexKeys( 1394 void IndexedDBDatabase::SetIndexKeys(
1477 int64_t transaction_id, 1395 IndexedDBTransaction* transaction,
1478 int64_t object_store_id, 1396 int64_t object_store_id,
1479 std::unique_ptr<IndexedDBKey> primary_key, 1397 std::unique_ptr<IndexedDBKey> primary_key,
1480 const std::vector<IndexedDBIndexKeys>& index_keys) { 1398 const std::vector<IndexedDBIndexKeys>& index_keys) {
1481 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id);
1482
1483 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1484 if (!transaction) 1399 if (!transaction)
1485 return; 1400 return;
1401 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction->id());
1486 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 1402 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
1487 1403
1488 // TODO(alecflett): This method could be asynchronous, but we need to 1404 // TODO(alecflett): This method could be asynchronous, but we need to
1489 // evaluate if it's worth the extra complexity. 1405 // evaluate if it's worth the extra complexity.
1490 IndexedDBBackingStore::RecordIdentifier record_identifier; 1406 IndexedDBBackingStore::RecordIdentifier record_identifier;
1491 bool found = false; 1407 bool found = false;
1492 leveldb::Status s = backing_store_->KeyExistsInObjectStore( 1408 leveldb::Status s = backing_store_->KeyExistsInObjectStore(
1493 transaction->BackingStoreTransaction(), 1409 transaction->BackingStoreTransaction(),
1494 metadata_.id, 1410 metadata_.id,
1495 object_store_id, 1411 object_store_id,
1496 *primary_key, 1412 *primary_key,
1497 &record_identifier, 1413 &record_identifier,
1498 &found); 1414 &found);
1499 if (!s.ok()) { 1415 if (!s.ok()) {
1500 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, 1416 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1501 "Internal error setting index keys."); 1417 "Internal error setting index keys.");
1502 transaction->Abort(error); 1418 ReportError(s, origin(), factory_.get(), error);
cmumford 2016/12/01 19:14:51 Why can't we still use backing_store_->origin()?
dmurph 2016/12/01 21:12:23 ... aren't they the same? Which would you rather m
cmumford 2016/12/01 22:25:45 If the other callers to ReportError have no origin
1503 if (s.IsCorruption())
1504 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error);
1505 return; 1419 return;
1506 } 1420 }
1507 if (!found) { 1421 if (!found) {
1508 transaction->Abort(IndexedDBDatabaseError( 1422 transaction->Abort(IndexedDBDatabaseError(
1509 blink::WebIDBDatabaseExceptionUnknownError, 1423 blink::WebIDBDatabaseExceptionUnknownError,
1510 "Internal error setting index keys for object store.")); 1424 "Internal error setting index keys for object store."));
1511 return; 1425 return;
1512 } 1426 }
1513 1427
1514 std::vector<std::unique_ptr<IndexWriter>> index_writers; 1428 std::vector<std::unique_ptr<IndexWriter>> index_writers;
(...skipping 25 matching lines...) Expand all
1540 return; 1454 return;
1541 } 1455 }
1542 1456
1543 for (const auto& writer : index_writers) { 1457 for (const auto& writer : index_writers) {
1544 writer->WriteIndexKeys(record_identifier, backing_store_.get(), 1458 writer->WriteIndexKeys(record_identifier, backing_store_.get(),
1545 transaction->BackingStoreTransaction(), id(), 1459 transaction->BackingStoreTransaction(), id(),
1546 object_store_id); 1460 object_store_id);
1547 } 1461 }
1548 } 1462 }
1549 1463
1550 void IndexedDBDatabase::SetIndexesReady(int64_t transaction_id, 1464 void IndexedDBDatabase::SetIndexesReady(IndexedDBTransaction* transaction,
1551 int64_t, 1465 int64_t,
1552 const std::vector<int64_t>& index_ids) { 1466 const std::vector<int64_t>& index_ids) {
1553 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1554 if (!transaction) 1467 if (!transaction)
1555 return; 1468 return;
1556 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); 1469 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange);
1557 1470
1558 transaction->ScheduleTask( 1471 transaction->ScheduleTask(
1559 blink::WebIDBTaskTypePreemptive, 1472 blink::WebIDBTaskTypePreemptive,
1560 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, 1473 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation,
1561 this, 1474 this,
1562 index_ids.size())); 1475 index_ids.size()));
1563 } 1476 }
(...skipping 14 matching lines...) Expand all
1578 blink::WebIDBCursorDirection direction; 1491 blink::WebIDBCursorDirection direction;
1579 indexed_db::CursorType cursor_type; 1492 indexed_db::CursorType cursor_type;
1580 blink::WebIDBTaskType task_type; 1493 blink::WebIDBTaskType task_type;
1581 scoped_refptr<IndexedDBCallbacks> callbacks; 1494 scoped_refptr<IndexedDBCallbacks> callbacks;
1582 1495
1583 private: 1496 private:
1584 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); 1497 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams);
1585 }; 1498 };
1586 1499
1587 void IndexedDBDatabase::OpenCursor( 1500 void IndexedDBDatabase::OpenCursor(
1588 int64_t transaction_id, 1501 IndexedDBTransaction* transaction,
1589 int64_t object_store_id, 1502 int64_t object_store_id,
1590 int64_t index_id, 1503 int64_t index_id,
1591 std::unique_ptr<IndexedDBKeyRange> key_range, 1504 std::unique_ptr<IndexedDBKeyRange> key_range,
1592 blink::WebIDBCursorDirection direction, 1505 blink::WebIDBCursorDirection direction,
1593 bool key_only, 1506 bool key_only,
1594 blink::WebIDBTaskType task_type, 1507 blink::WebIDBTaskType task_type,
1595 scoped_refptr<IndexedDBCallbacks> callbacks) { 1508 scoped_refptr<IndexedDBCallbacks> callbacks) {
1596 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id);
1597 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1598 if (!transaction) 1509 if (!transaction)
1599 return; 1510 return;
1511 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction->id());
1600 1512
1601 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1513 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
1602 return; 1514 return;
1603 1515
1604 std::unique_ptr<OpenCursorOperationParams> params( 1516 std::unique_ptr<OpenCursorOperationParams> params(
1605 base::MakeUnique<OpenCursorOperationParams>()); 1517 base::MakeUnique<OpenCursorOperationParams>());
1606 params->object_store_id = object_store_id; 1518 params->object_store_id = object_store_id;
1607 params->index_id = index_id; 1519 params->index_id = index_id;
1608 params->key_range = std::move(key_range); 1520 params->key_range = std::move(key_range);
1609 params->direction = direction; 1521 params->direction = direction;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 params->object_store_id, 1579 params->object_store_id,
1668 params->index_id, 1580 params->index_id,
1669 *params->key_range, 1581 *params->key_range,
1670 params->direction, 1582 params->direction,
1671 &s); 1583 &s);
1672 } 1584 }
1673 } 1585 }
1674 1586
1675 if (!s.ok()) { 1587 if (!s.ok()) {
1676 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString(); 1588 DLOG(ERROR) << "Unable to open cursor operation: " << s.ToString();
1677 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1678 "Internal error opening cursor operation");
1679 return s; 1589 return s;
1680 } 1590 }
1681 1591
1682 if (!backing_store_cursor) { 1592 if (!backing_store_cursor) {
1683 // Occurs when we've reached the end of cursor's data. 1593 // Occurs when we've reached the end of cursor's data.
1684 params->callbacks->OnSuccess(nullptr); 1594 params->callbacks->OnSuccess(nullptr);
1685 return s; 1595 return s;
1686 } 1596 }
1687 1597
1688 scoped_refptr<IndexedDBCursor> cursor = 1598 std::unique_ptr<IndexedDBCursor> cursor = base::MakeUnique<IndexedDBCursor>(
1689 new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type, 1599 std::move(backing_store_cursor), params->cursor_type, params->task_type,
1690 params->task_type, transaction); 1600 transaction);
1691 params->callbacks->OnSuccess( 1601 IndexedDBCursor* cursor_ptr = cursor.get();
1692 cursor, cursor->key(), cursor->primary_key(), cursor->Value()); 1602 transaction->RegisterOpenCursor(cursor_ptr);
1603 params->callbacks->OnSuccess(std::move(cursor), cursor_ptr->key(),
1604 cursor_ptr->primary_key(), cursor_ptr->Value());
1693 return s; 1605 return s;
1694 } 1606 }
1695 1607
1696 void IndexedDBDatabase::Count(int64_t transaction_id, 1608 void IndexedDBDatabase::Count(IndexedDBTransaction* transaction,
1697 int64_t object_store_id, 1609 int64_t object_store_id,
1698 int64_t index_id, 1610 int64_t index_id,
1699 std::unique_ptr<IndexedDBKeyRange> key_range, 1611 std::unique_ptr<IndexedDBKeyRange> key_range,
1700 scoped_refptr<IndexedDBCallbacks> callbacks) { 1612 scoped_refptr<IndexedDBCallbacks> callbacks) {
1701 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id);
1702 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1703 if (!transaction) 1613 if (!transaction)
1704 return; 1614 return;
1615 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction->id());
1705 1616
1706 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) 1617 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id))
1707 return; 1618 return;
1708 1619
1709 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, 1620 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation,
1710 this, 1621 this,
1711 object_store_id, 1622 object_store_id,
1712 index_id, 1623 index_id,
1713 base::Passed(&key_range), 1624 base::Passed(&key_range),
1714 callbacks)); 1625 callbacks));
(...skipping 23 matching lines...) Expand all
1738 transaction->BackingStoreTransaction(), 1649 transaction->BackingStoreTransaction(),
1739 id(), 1650 id(),
1740 object_store_id, 1651 object_store_id,
1741 index_id, 1652 index_id,
1742 *key_range, 1653 *key_range,
1743 blink::WebIDBCursorDirectionNext, 1654 blink::WebIDBCursorDirectionNext,
1744 &s); 1655 &s);
1745 } 1656 }
1746 if (!s.ok()) { 1657 if (!s.ok()) {
1747 DLOG(ERROR) << "Unable perform count operation: " << s.ToString(); 1658 DLOG(ERROR) << "Unable perform count operation: " << s.ToString();
1748 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1749 "Internal error performing count operation");
1750 return s; 1659 return s;
1751 } 1660 }
1752 if (!backing_store_cursor) { 1661 if (!backing_store_cursor) {
1753 callbacks->OnSuccess(count); 1662 callbacks->OnSuccess(count);
1754 return s; 1663 return s;
1755 } 1664 }
1756 1665
1757 do { 1666 do {
1758 if (!s.ok()) 1667 if (!s.ok())
1759 return s; 1668 return s;
1760 ++count; 1669 ++count;
1761 } while (backing_store_cursor->Continue(&s)); 1670 } while (backing_store_cursor->Continue(&s));
1762 1671
1763 callbacks->OnSuccess(count); 1672 callbacks->OnSuccess(count);
1764 return s; 1673 return s;
1765 } 1674 }
1766 1675
1767 void IndexedDBDatabase::DeleteRange( 1676 void IndexedDBDatabase::DeleteRange(
1768 int64_t transaction_id, 1677 IndexedDBTransaction* transaction,
1769 int64_t object_store_id, 1678 int64_t object_store_id,
1770 std::unique_ptr<IndexedDBKeyRange> key_range, 1679 std::unique_ptr<IndexedDBKeyRange> key_range,
1771 scoped_refptr<IndexedDBCallbacks> callbacks) { 1680 scoped_refptr<IndexedDBCallbacks> callbacks) {
1772 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id);
1773 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1774 if (!transaction) 1681 if (!transaction)
1775 return; 1682 return;
1683 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction->id());
1776 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1684 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1777 1685
1778 if (!ValidateObjectStoreId(object_store_id)) 1686 if (!ValidateObjectStoreId(object_store_id))
1779 return; 1687 return;
1780 1688
1781 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, 1689 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation,
1782 this, 1690 this,
1783 object_store_id, 1691 object_store_id,
1784 base::Passed(&key_range), 1692 base::Passed(&key_range),
1785 callbacks)); 1693 callbacks));
1786 } 1694 }
1787 1695
1788 leveldb::Status IndexedDBDatabase::DeleteRangeOperation( 1696 leveldb::Status IndexedDBDatabase::DeleteRangeOperation(
1789 int64_t object_store_id, 1697 int64_t object_store_id,
1790 std::unique_ptr<IndexedDBKeyRange> key_range, 1698 std::unique_ptr<IndexedDBKeyRange> key_range,
1791 scoped_refptr<IndexedDBCallbacks> callbacks, 1699 scoped_refptr<IndexedDBCallbacks> callbacks,
1792 IndexedDBTransaction* transaction) { 1700 IndexedDBTransaction* transaction) {
1793 IDB_TRACE1("IndexedDBDatabase::DeleteRangeOperation", "txn.id", 1701 IDB_TRACE1("IndexedDBDatabase::DeleteRangeOperation", "txn.id",
1794 transaction->id()); 1702 transaction->id());
1795 size_t delete_count = 0; 1703 size_t delete_count = 0;
1796 leveldb::Status s = 1704 leveldb::Status s =
1797 backing_store_->DeleteRange(transaction->BackingStoreTransaction(), id(), 1705 backing_store_->DeleteRange(transaction->BackingStoreTransaction(), id(),
1798 object_store_id, *key_range, &delete_count); 1706 object_store_id, *key_range, &delete_count);
1799 if (!s.ok()) { 1707 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; 1708 return s;
1806 }
1807 callbacks->OnSuccess(); 1709 callbacks->OnSuccess();
1808 FilterObservation(transaction, object_store_id, blink::WebIDBDelete, 1710 FilterObservation(transaction, object_store_id, blink::WebIDBDelete,
1809 *key_range); 1711 *key_range);
1810 return s; 1712 return s;
1811 } 1713 }
1812 1714
1813 void IndexedDBDatabase::Clear(int64_t transaction_id, 1715 void IndexedDBDatabase::Clear(IndexedDBTransaction* transaction,
1814 int64_t object_store_id, 1716 int64_t object_store_id,
1815 scoped_refptr<IndexedDBCallbacks> callbacks) { 1717 scoped_refptr<IndexedDBCallbacks> callbacks) {
1816 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id);
1817 IndexedDBTransaction* transaction = GetTransaction(transaction_id);
1818 if (!transaction) 1718 if (!transaction)
1819 return; 1719 return;
1720 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction->id());
1820 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); 1721 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly);
1821 1722
1822 if (!ValidateObjectStoreId(object_store_id)) 1723 if (!ValidateObjectStoreId(object_store_id))
1823 return; 1724 return;
1824 1725
1825 transaction->ScheduleTask(base::Bind( 1726 transaction->ScheduleTask(base::Bind(
1826 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); 1727 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks));
1827 } 1728 }
1828 1729
1829 leveldb::Status IndexedDBDatabase::ClearOperation( 1730 leveldb::Status IndexedDBDatabase::ClearOperation(
1830 int64_t object_store_id, 1731 int64_t object_store_id,
1831 scoped_refptr<IndexedDBCallbacks> callbacks, 1732 scoped_refptr<IndexedDBCallbacks> callbacks,
1832 IndexedDBTransaction* transaction) { 1733 IndexedDBTransaction* transaction) {
1833 IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id()); 1734 IDB_TRACE1("IndexedDBDatabase::ClearOperation", "txn.id", transaction->id());
1834 leveldb::Status s = backing_store_->ClearObjectStore( 1735 leveldb::Status s = backing_store_->ClearObjectStore(
1835 transaction->BackingStoreTransaction(), id(), object_store_id); 1736 transaction->BackingStoreTransaction(), id(), object_store_id);
1836 if (!s.ok()) { 1737 if (!s.ok())
1837 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError,
1838 "Internal error clearing object store");
1839 callbacks->OnError(error);
1840 return s; 1738 return s;
1841 }
1842 callbacks->OnSuccess(); 1739 callbacks->OnSuccess();
1843 1740
1844 FilterObservation(transaction, object_store_id, blink::WebIDBClear, 1741 FilterObservation(transaction, object_store_id, blink::WebIDBClear,
1845 IndexedDBKeyRange()); 1742 IndexedDBKeyRange());
1846 return s; 1743 return s;
1847 } 1744 }
1848 1745
1849 leveldb::Status IndexedDBDatabase::DeleteObjectStoreOperation( 1746 leveldb::Status IndexedDBDatabase::DeleteObjectStoreOperation(
1850 int64_t object_store_id, 1747 int64_t object_store_id,
1851 IndexedDBTransaction* transaction) { 1748 IndexedDBTransaction* transaction) {
1852 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation", 1749 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation",
1853 "txn.id", 1750 "txn.id",
1854 transaction->id()); 1751 transaction->id());
1855 1752
1856 const IndexedDBObjectStoreMetadata object_store_metadata = 1753 const IndexedDBObjectStoreMetadata object_store_metadata =
1857 metadata_.object_stores[object_store_id]; 1754 metadata_.object_stores[object_store_id];
1858 leveldb::Status s = 1755 leveldb::Status s =
1859 backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(), 1756 backing_store_->DeleteObjectStore(transaction->BackingStoreTransaction(),
1860 transaction->database()->id(), 1757 transaction->database()->id(),
1861 object_store_id); 1758 object_store_id);
1862 if (!s.ok()) { 1759 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; 1760 return s;
1870 }
1871 1761
1872 RemoveObjectStore(object_store_id); 1762 RemoveObjectStore(object_store_id);
1873 transaction->ScheduleAbortTask( 1763 transaction->ScheduleAbortTask(
1874 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, 1764 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation,
1875 this, 1765 this,
1876 object_store_metadata)); 1766 object_store_metadata));
1877 return s; 1767 return s;
1878 } 1768 }
1879 1769
1880 leveldb::Status IndexedDBDatabase::VersionChangeOperation( 1770 leveldb::Status IndexedDBDatabase::VersionChangeOperation(
1881 int64_t version, 1771 int64_t version,
1882 scoped_refptr<IndexedDBCallbacks> callbacks, 1772 scoped_refptr<IndexedDBCallbacks> callbacks,
1883 IndexedDBTransaction* transaction) { 1773 IndexedDBTransaction* transaction) {
1884 IDB_TRACE1( 1774 IDB_TRACE1(
1885 "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id()); 1775 "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id());
1886 int64_t old_version = metadata_.version; 1776 int64_t old_version = metadata_.version;
1887 DCHECK_GT(version, old_version); 1777 DCHECK_GT(version, old_version);
1888 1778
1889 backing_store_->UpdateIDBDatabaseIntVersion( 1779 backing_store_->UpdateIDBDatabaseIntVersion(
1890 transaction->BackingStoreTransaction(), id(), version); 1780 transaction->BackingStoreTransaction(), id(), version);
1891 1781
1892 transaction->ScheduleAbortTask( 1782 transaction->ScheduleAbortTask(
1893 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, 1783 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this,
1894 metadata_.version)); 1784 metadata_.version));
1895 metadata_.version = version; 1785 metadata_.version = version;
1896 1786
1897 active_request_->UpgradeTransactionStarted(old_version); 1787 active_request_->UpgradeTransactionStarted(old_version, transaction);
1898 return leveldb::Status::OK(); 1788 return leveldb::Status::OK();
1899 } 1789 }
1900 1790
1901 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, 1791 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction,
1902 bool committed) { 1792 bool committed) {
1903 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); 1793 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id",
1904 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); 1794 transaction->id());
1905 DCHECK_EQ(transactions_[transaction->id()], transaction); 1795 --transaction_count_;
1906 transactions_.erase(transaction->id()); 1796 DCHECK_GE(transaction_count_, 0);
1907 1797
1908 // This may be an unrelated transaction finishing while waiting for 1798 // This may be an unrelated transaction finishing while waiting for
1909 // connections to close, or the actual upgrade transaction from an active 1799 // connections to close, or the actual upgrade transaction from an active
1910 // request. Notify the active request if it's the latter. 1800 // request. Notify the active request if it's the latter.
1911 if (active_request_ && 1801 if (active_request_ &&
1912 transaction->mode() == blink::WebIDBTransactionModeVersionChange) { 1802 transaction->mode() == blink::WebIDBTransactionModeVersionChange) {
1913 active_request_->UpgradeTransactionFinished(committed); 1803 active_request_->UpgradeTransactionFinished(committed);
1914 } 1804 }
1915 } 1805 }
1916 1806
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 } while (!active_request_ && !pending_requests_.empty()); 1839 } while (!active_request_ && !pending_requests_.empty());
1950 } 1840 }
1951 1841
1952 IndexedDBTransaction* IndexedDBDatabase::CreateTransaction( 1842 IndexedDBTransaction* IndexedDBDatabase::CreateTransaction(
1953 int64_t transaction_id, 1843 int64_t transaction_id,
1954 IndexedDBConnection* connection, 1844 IndexedDBConnection* connection,
1955 const std::vector<int64_t>& object_store_ids, 1845 const std::vector<int64_t>& object_store_ids,
1956 blink::WebIDBTransactionMode mode) { 1846 blink::WebIDBTransactionMode mode) {
1957 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); 1847 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id);
1958 DCHECK(connections_.count(connection)); 1848 DCHECK(connections_.count(connection));
1959 DCHECK(transactions_.find(transaction_id) == transactions_.end());
1960 if (transactions_.find(transaction_id) != transactions_.end())
1961 return nullptr;
1962 1849
1963 UMA_HISTOGRAM_COUNTS_1000( 1850 UMA_HISTOGRAM_COUNTS_1000(
1964 "WebCore.IndexedDB.Database.OutstandingTransactionCount", 1851 "WebCore.IndexedDB.Database.OutstandingTransactionCount",
1965 transactions_.size()); 1852 transaction_count_);
1966 1853
1967 // The transaction will add itself to this database's coordinator, which 1854 IndexedDBTransaction* transaction = connection->CreateTransaction(
1968 // manages the lifetime of the object. 1855 transaction_id,
1969 IndexedDBTransaction* transaction = 1856 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode,
1970 IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( 1857 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); 1858 TransactionCreated(transaction);
1975 return transaction; 1859 return transaction;
1976 } 1860 }
1977 1861
1978 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { 1862 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) {
1979 transactions_[transaction->id()] = transaction; 1863 transaction_count_++;
1864 transaction_coordinator_.DidCreateTransaction(transaction);
1980 } 1865 }
1981 1866
1982 void IndexedDBDatabase::OpenConnection( 1867 void IndexedDBDatabase::OpenConnection(
1983 std::unique_ptr<IndexedDBPendingConnection> connection) { 1868 std::unique_ptr<IndexedDBPendingConnection> connection) {
1984 AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection))); 1869 AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection)));
1985 } 1870 }
1986 1871
1987 void IndexedDBDatabase::DeleteDatabase( 1872 void IndexedDBDatabase::DeleteDatabase(
1988 scoped_refptr<IndexedDBCallbacks> callbacks) { 1873 scoped_refptr<IndexedDBCallbacks> callbacks) {
1989 AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks)); 1874 AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks));
(...skipping 19 matching lines...) Expand all
2009 DCHECK(connections_.count(connection)); 1894 DCHECK(connections_.count(connection));
2010 DCHECK(connection->IsConnected()); 1895 DCHECK(connection->IsConnected());
2011 DCHECK(connection->database() == this); 1896 DCHECK(connection->database() == this);
2012 1897
2013 IDB_TRACE("IndexedDBDatabase::Close"); 1898 IDB_TRACE("IndexedDBDatabase::Close");
2014 1899
2015 // Abort outstanding transactions from the closing connection. This can not 1900 // Abort outstanding transactions from the closing connection. This can not
2016 // happen if the close is requested by the connection itself as the 1901 // 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 1902 // front-end defers the close until all transactions are complete, but can
2018 // occur on process termination or forced close. 1903 // occur on process termination or forced close.
2019 { 1904 connection->AbortAllTransactions(IndexedDBDatabaseError(
2020 auto transactions(transactions_); 1905 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 1906
2029 // Abort transactions before removing the connection; aborting may complete 1907 // Abort transactions before removing the connection; aborting may complete
2030 // an upgrade, and thus allow the next open/delete requests to proceed. The 1908 // 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 1909 // new active_request_ should see the old connection count until explicitly
2032 // notified below. 1910 // notified below.
2033 connections_.erase(connection); 1911 connections_.erase(connection);
2034 1912
2035 // Notify the active request, which may need to do cleanup or proceed with 1913 // 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 1914 // the operation. This may trigger other work, such as more connections or
2037 // deletions, so |active_request_| itself may change. 1915 // deletions, so |active_request_| itself may change.
2038 if (active_request_) 1916 if (active_request_)
2039 active_request_->OnConnectionClosed(connection); 1917 active_request_->OnConnectionClosed(connection);
2040 1918
2041 // If there are no more connections (current, active, or pending), tell the 1919 // If there are no more connections (current, active, or pending), tell the
2042 // factory to clean us up. 1920 // factory to clean us up.
2043 if (connections_.empty() && !active_request_ && pending_requests_.empty()) { 1921 if (connections_.empty() && !active_request_ && pending_requests_.empty()) {
2044 DCHECK(transactions_.empty());
2045 backing_store_ = nullptr; 1922 backing_store_ = nullptr;
2046 factory_->ReleaseDatabase(identifier_, forced); 1923 factory_->ReleaseDatabase(identifier_, forced);
2047 } 1924 }
2048 } 1925 }
2049 1926
2050 void IndexedDBDatabase::CreateObjectStoreAbortOperation( 1927 void IndexedDBDatabase::CreateObjectStoreAbortOperation(
2051 int64_t object_store_id) { 1928 int64_t object_store_id) {
2052 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); 1929 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation");
2053 RemoveObjectStore(object_store_id); 1930 RemoveObjectStore(object_store_id);
2054 } 1931 }
(...skipping 11 matching lines...) Expand all
2066 IDB_TRACE("IndexedDBDatabase::RenameObjectStoreAbortOperation"); 1943 IDB_TRACE("IndexedDBDatabase::RenameObjectStoreAbortOperation");
2067 SetObjectStoreName(object_store_id, old_name); 1944 SetObjectStoreName(object_store_id, old_name);
2068 } 1945 }
2069 1946
2070 void IndexedDBDatabase::VersionChangeAbortOperation(int64_t previous_version) { 1947 void IndexedDBDatabase::VersionChangeAbortOperation(int64_t previous_version) {
2071 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); 1948 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation");
2072 metadata_.version = previous_version; 1949 metadata_.version = previous_version;
2073 } 1950 }
2074 1951
2075 } // namespace content 1952 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698