Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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, ¶ms->value, | 1356 params->object_store_id, *key, ¶ms->value, |
| 1431 ¶ms->handles, &record_identifier); | 1357 ¶ms->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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |