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

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

Powered by Google App Engine
This is Rietveld 408576698