| 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 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 | 90 |
| 91 // Called if a front-end signals that it is ignoring a "versionchange" | 91 // Called if a front-end signals that it is ignoring a "versionchange" |
| 92 // event. This should result in firing a "blocked" event at the request. | 92 // event. This should result in firing a "blocked" event at the request. |
| 93 virtual void OnVersionChangeIgnored() const = 0; | 93 virtual void OnVersionChangeIgnored() const = 0; |
| 94 | 94 |
| 95 // Called when a connection is closed; if it corresponds to this connection, | 95 // Called when a connection is closed; if it corresponds to this connection, |
| 96 // need to do cleanup. Otherwise, it may unblock further steps. | 96 // need to do cleanup. Otherwise, it may unblock further steps. |
| 97 virtual void OnConnectionClosed(IndexedDBConnection* connection) = 0; | 97 virtual void OnConnectionClosed(IndexedDBConnection* connection) = 0; |
| 98 | 98 |
| 99 // Called when the upgrade transaction has started executing. | 99 // Called when the upgrade transaction has started executing. |
| 100 virtual void UpgradeTransactionStarted(int64_t old_version) = 0; | 100 virtual void UpgradeTransactionStarted(int64_t old_version, |
| 101 IndexedDBTransaction* transaction) = 0; |
| 101 | 102 |
| 102 // Called when the upgrade transaction has finished. | 103 // Called when the upgrade transaction has finished. |
| 103 virtual void UpgradeTransactionFinished(bool committed) = 0; | 104 virtual void UpgradeTransactionFinished(bool committed) = 0; |
| 104 | 105 |
| 105 protected: | 106 protected: |
| 106 scoped_refptr<IndexedDBDatabase> db_; | 107 scoped_refptr<IndexedDBDatabase> db_; |
| 107 | 108 |
| 108 private: | 109 private: |
| 109 DISALLOW_COPY_AND_ASSIGN(ConnectionRequest); | 110 DISALLOW_COPY_AND_ASSIGN(ConnectionRequest); |
| 110 }; | 111 }; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 int64_t& new_version = pending_->version; | 150 int64_t& new_version = pending_->version; |
| 150 | 151 |
| 151 bool is_new_database = old_version == IndexedDBDatabaseMetadata::NO_VERSION; | 152 bool is_new_database = old_version == IndexedDBDatabaseMetadata::NO_VERSION; |
| 152 | 153 |
| 153 if (new_version == IndexedDBDatabaseMetadata::DEFAULT_VERSION) { | 154 if (new_version == IndexedDBDatabaseMetadata::DEFAULT_VERSION) { |
| 154 // For unit tests only - skip upgrade steps. (Calling from script with | 155 // For unit tests only - skip upgrade steps. (Calling from script with |
| 155 // DEFAULT_VERSION throws exception.) | 156 // DEFAULT_VERSION throws exception.) |
| 156 DCHECK(is_new_database); | 157 DCHECK(is_new_database); |
| 157 pending_->callbacks->OnSuccess( | 158 pending_->callbacks->OnSuccess( |
| 158 db_->CreateConnection(pending_->database_callbacks, | 159 db_->CreateConnection(pending_->database_callbacks, |
| 159 pending_->child_process_id), | 160 pending_->child_process_id, pending_->origin), |
| 160 db_->metadata_); | 161 db_->metadata_); |
| 161 db_->RequestComplete(this); | 162 db_->RequestComplete(this); |
| 162 return; | 163 return; |
| 163 } | 164 } |
| 164 | 165 |
| 165 if (!is_new_database && | 166 if (!is_new_database && |
| 166 (new_version == old_version || | 167 (new_version == old_version || |
| 167 new_version == IndexedDBDatabaseMetadata::NO_VERSION)) { | 168 new_version == IndexedDBDatabaseMetadata::NO_VERSION)) { |
| 168 pending_->callbacks->OnSuccess( | 169 pending_->callbacks->OnSuccess( |
| 169 db_->CreateConnection(pending_->database_callbacks, | 170 db_->CreateConnection(pending_->database_callbacks, |
| 170 pending_->child_process_id), | 171 pending_->child_process_id, pending_->origin), |
| 171 db_->metadata_); | 172 db_->metadata_); |
| 172 db_->RequestComplete(this); | 173 db_->RequestComplete(this); |
| 173 return; | 174 return; |
| 174 } | 175 } |
| 175 | 176 |
| 176 if (new_version == IndexedDBDatabaseMetadata::NO_VERSION) { | 177 if (new_version == IndexedDBDatabaseMetadata::NO_VERSION) { |
| 177 // If no version is specified and no database exists, upgrade the | 178 // If no version is specified and no database exists, upgrade the |
| 178 // database version to 1. | 179 // database version to 1. |
| 179 DCHECK(is_new_database); | 180 DCHECK(is_new_database); |
| 180 new_version = 1; | 181 new_version = 1; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 if (!db_->connections_.empty()) | 229 if (!db_->connections_.empty()) |
| 229 return; | 230 return; |
| 230 | 231 |
| 231 StartUpgrade(); | 232 StartUpgrade(); |
| 232 } | 233 } |
| 233 | 234 |
| 234 // Initiate the upgrade. The bulk of the work actually happens in | 235 // Initiate the upgrade. The bulk of the work actually happens in |
| 235 // IndexedDBDatabase::VersionChangeOperation in order to kick the | 236 // IndexedDBDatabase::VersionChangeOperation in order to kick the |
| 236 // transaction into the correct state. | 237 // transaction into the correct state. |
| 237 void StartUpgrade() { | 238 void StartUpgrade() { |
| 238 connection_ = db_->CreateConnection(pending_->database_callbacks, | 239 connection_ = |
| 239 pending_->child_process_id); | 240 db_->CreateConnection(pending_->database_callbacks, |
| 241 pending_->child_process_id, pending_->origin); |
| 240 DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL); | 242 DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL); |
| 241 | 243 |
| 242 std::vector<int64_t> object_store_ids; | 244 std::vector<int64_t> object_store_ids; |
| 243 IndexedDBTransaction* transaction = db_->CreateTransaction( | 245 IndexedDBTransaction* transaction = db_->CreateTransaction( |
| 244 pending_->transaction_id, connection_.get(), object_store_ids, | 246 pending_->transaction_id, connection_.get(), object_store_ids, |
| 245 blink::WebIDBTransactionModeVersionChange); | 247 blink::WebIDBTransactionModeVersionChange); |
| 246 | 248 |
| 247 DCHECK(db_->transaction_coordinator_.IsRunningVersionChangeTransaction()); | 249 DCHECK(db_->transaction_coordinator_.IsRunningVersionChangeTransaction()); |
| 248 transaction->ScheduleTask( | 250 transaction->ScheduleTask( |
| 249 base::Bind(&IndexedDBDatabase::VersionChangeOperation, db_, | 251 base::Bind(&IndexedDBDatabase::VersionChangeOperation, db_, |
| 250 pending_->version, pending_->callbacks)); | 252 pending_->version, pending_->callbacks)); |
| 251 } | 253 } |
| 252 | 254 |
| 253 // Called when the upgrade transaction has started executing. | 255 // Called when the upgrade transaction has started executing. |
| 254 void UpgradeTransactionStarted(int64_t old_version) override { | 256 void UpgradeTransactionStarted(int64_t old_version, |
| 257 IndexedDBTransaction* transaction) override { |
| 255 DCHECK(connection_); | 258 DCHECK(connection_); |
| 256 pending_->callbacks->OnUpgradeNeeded(old_version, std::move(connection_), | 259 pending_->callbacks->OnUpgradeNeeded(old_version, std::move(connection_), |
| 257 db_->metadata_, | 260 transaction, db_->metadata_, |
| 258 pending_->data_loss_info); | 261 pending_->data_loss_info); |
| 259 } | 262 } |
| 260 | 263 |
| 261 void UpgradeTransactionFinished(bool committed) override { | 264 void UpgradeTransactionFinished(bool committed) override { |
| 262 // Ownership of connection was already passed along in OnUpgradeNeeded. | 265 // Ownership of connection was already passed along in OnUpgradeNeeded. |
| 263 DCHECK(!connection_); | 266 DCHECK(!connection_); |
| 264 | 267 |
| 265 if (committed) { | 268 if (committed) { |
| 266 DCHECK_EQ(pending_->version, db_->metadata_.version); | 269 DCHECK_EQ(pending_->version, db_->metadata_.version); |
| 267 pending_->callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(), | 270 pending_->callbacks->OnSuccess(std::unique_ptr<IndexedDBConnection>(), |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 db_->metadata_.id = kInvalidId; | 342 db_->metadata_.id = kInvalidId; |
| 340 db_->metadata_.version = IndexedDBDatabaseMetadata::NO_VERSION; | 343 db_->metadata_.version = IndexedDBDatabaseMetadata::NO_VERSION; |
| 341 db_->metadata_.max_object_store_id = kInvalidId; | 344 db_->metadata_.max_object_store_id = kInvalidId; |
| 342 db_->metadata_.object_stores.clear(); | 345 db_->metadata_.object_stores.clear(); |
| 343 callbacks_->OnSuccess(old_version); | 346 callbacks_->OnSuccess(old_version); |
| 344 db_->factory_->DatabaseDeleted(db_->identifier_); | 347 db_->factory_->DatabaseDeleted(db_->identifier_); |
| 345 | 348 |
| 346 db_->RequestComplete(this); | 349 db_->RequestComplete(this); |
| 347 } | 350 } |
| 348 | 351 |
| 349 void UpgradeTransactionStarted(int64_t old_version) override { NOTREACHED(); } | 352 void UpgradeTransactionStarted(int64_t old_version, |
| 353 IndexedDBTransaction* transaction) override { |
| 354 NOTREACHED(); |
| 355 } |
| 350 | 356 |
| 351 void UpgradeTransactionFinished(bool committed) override { NOTREACHED(); } | 357 void UpgradeTransactionFinished(bool committed) override { NOTREACHED(); } |
| 352 | 358 |
| 353 private: | 359 private: |
| 354 scoped_refptr<IndexedDBCallbacks> callbacks_; | 360 scoped_refptr<IndexedDBCallbacks> callbacks_; |
| 355 | 361 |
| 356 DISALLOW_COPY_AND_ASSIGN(DeleteRequest); | 362 DISALLOW_COPY_AND_ASSIGN(DeleteRequest); |
| 357 }; | 363 }; |
| 358 | 364 |
| 359 scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( | 365 scoped_refptr<IndexedDBDatabase> IndexedDBDatabase::Create( |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 return s; | 467 return s; |
| 462 if (success) | 468 if (success) |
| 463 return backing_store_->GetObjectStores(metadata_.id, | 469 return backing_store_->GetObjectStores(metadata_.id, |
| 464 &metadata_.object_stores); | 470 &metadata_.object_stores); |
| 465 | 471 |
| 466 return backing_store_->CreateIDBDatabaseMetaData( | 472 return backing_store_->CreateIDBDatabaseMetaData( |
| 467 metadata_.name, metadata_.version, &metadata_.id); | 473 metadata_.name, metadata_.version, &metadata_.id); |
| 468 } | 474 } |
| 469 | 475 |
| 470 IndexedDBDatabase::~IndexedDBDatabase() { | 476 IndexedDBDatabase::~IndexedDBDatabase() { |
| 471 DCHECK(transactions_.empty()); | |
| 472 DCHECK(!active_request_); | 477 DCHECK(!active_request_); |
| 473 DCHECK(pending_requests_.empty()); | 478 DCHECK(pending_requests_.empty()); |
| 474 } | 479 } |
| 475 | 480 |
| 476 size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const { | 481 size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const { |
| 477 return kMaxIDBMessageSizeInBytes; | 482 return kMaxIDBMessageSizeInBytes; |
| 478 } | 483 } |
| 479 | 484 |
| 480 std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( | 485 std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( |
| 481 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 486 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
| 482 int child_process_id) { | 487 int child_process_id, |
| 488 const url::Origin& origin) { |
| 483 std::unique_ptr<IndexedDBConnection> connection( | 489 std::unique_ptr<IndexedDBConnection> connection( |
| 484 base::MakeUnique<IndexedDBConnection>(this, database_callbacks)); | 490 base::MakeUnique<IndexedDBConnection>(child_process_id, origin, this, |
| 491 database_callbacks)); |
| 485 connections_.insert(connection.get()); | 492 connections_.insert(connection.get()); |
| 486 backing_store_->GrantChildProcessPermissions(child_process_id); | 493 backing_store_->GrantChildProcessPermissions(child_process_id); |
| 487 return connection; | 494 return connection; |
| 488 } | 495 } |
| 489 | 496 |
| 490 IndexedDBTransaction* IndexedDBDatabase::GetTransaction( | |
| 491 int64_t transaction_id) const { | |
| 492 const auto& trans_iterator = transactions_.find(transaction_id); | |
| 493 if (trans_iterator == transactions_.end()) | |
| 494 return NULL; | |
| 495 return trans_iterator->second; | |
| 496 } | |
| 497 | |
| 498 bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const { | 497 bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const { |
| 499 if (!base::ContainsKey(metadata_.object_stores, object_store_id)) { | 498 if (!base::ContainsKey(metadata_.object_stores, object_store_id)) { |
| 500 DLOG(ERROR) << "Invalid object_store_id"; | 499 DLOG(ERROR) << "Invalid object_store_id"; |
| 501 return false; | 500 return false; |
| 502 } | 501 } |
| 503 return true; | 502 return true; |
| 504 } | 503 } |
| 505 | 504 |
| 506 bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId( | 505 bool IndexedDBDatabase::ValidateObjectStoreIdAndIndexId( |
| 507 int64_t object_store_id, | 506 int64_t object_store_id, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 return false; | 538 return false; |
| 540 const IndexedDBObjectStoreMetadata& object_store_metadata = | 539 const IndexedDBObjectStoreMetadata& object_store_metadata = |
| 541 metadata_.object_stores.find(object_store_id)->second; | 540 metadata_.object_stores.find(object_store_id)->second; |
| 542 if (base::ContainsKey(object_store_metadata.indexes, index_id)) { | 541 if (base::ContainsKey(object_store_metadata.indexes, index_id)) { |
| 543 DLOG(ERROR) << "Invalid index_id"; | 542 DLOG(ERROR) << "Invalid index_id"; |
| 544 return false; | 543 return false; |
| 545 } | 544 } |
| 546 return true; | 545 return true; |
| 547 } | 546 } |
| 548 | 547 |
| 549 void IndexedDBDatabase::CreateObjectStore(int64_t transaction_id, | 548 void IndexedDBDatabase::CreateObjectStore(IndexedDBTransaction* transaction, |
| 550 int64_t object_store_id, | 549 int64_t object_store_id, |
| 551 const base::string16& name, | 550 const base::string16& name, |
| 552 const IndexedDBKeyPath& key_path, | 551 const IndexedDBKeyPath& key_path, |
| 553 bool auto_increment) { | 552 bool auto_increment) { |
| 554 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id); | |
| 555 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 556 if (!transaction) | 553 if (!transaction) |
| 557 return; | 554 return; |
| 555 IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", |
| 556 transaction->id()); |
| 558 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 557 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 559 | 558 |
| 560 if (base::ContainsKey(metadata_.object_stores, object_store_id)) { | 559 if (base::ContainsKey(metadata_.object_stores, object_store_id)) { |
| 561 DLOG(ERROR) << "Invalid object_store_id"; | 560 DLOG(ERROR) << "Invalid object_store_id"; |
| 562 return; | 561 return; |
| 563 } | 562 } |
| 564 | 563 |
| 565 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType", | 564 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.ObjectStore.KeyPathType", |
| 566 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); | 565 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); |
| 567 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement", | 566 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.ObjectStore.AutoIncrement", |
| (...skipping 27 matching lines...) Expand all Loading... |
| 595 return; | 594 return; |
| 596 } | 595 } |
| 597 | 596 |
| 598 AddObjectStore(object_store_metadata, object_store_id); | 597 AddObjectStore(object_store_metadata, object_store_id); |
| 599 transaction->ScheduleAbortTask( | 598 transaction->ScheduleAbortTask( |
| 600 base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, | 599 base::Bind(&IndexedDBDatabase::CreateObjectStoreAbortOperation, |
| 601 this, | 600 this, |
| 602 object_store_id)); | 601 object_store_id)); |
| 603 } | 602 } |
| 604 | 603 |
| 605 void IndexedDBDatabase::DeleteObjectStore(int64_t transaction_id, | 604 void IndexedDBDatabase::DeleteObjectStore(IndexedDBTransaction* transaction, |
| 606 int64_t object_store_id) { | 605 int64_t object_store_id) { |
| 607 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id); | |
| 608 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 609 if (!transaction) | 606 if (!transaction) |
| 610 return; | 607 return; |
| 608 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", |
| 609 transaction->id()); |
| 611 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 610 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 612 | 611 |
| 613 if (!ValidateObjectStoreId(object_store_id)) | 612 if (!ValidateObjectStoreId(object_store_id)) |
| 614 return; | 613 return; |
| 615 | 614 |
| 616 transaction->ScheduleTask( | 615 transaction->ScheduleTask( |
| 617 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, | 616 base::Bind(&IndexedDBDatabase::DeleteObjectStoreOperation, |
| 618 this, | 617 this, |
| 619 object_store_id)); | 618 object_store_id)); |
| 620 } | 619 } |
| 621 | 620 |
| 622 void IndexedDBDatabase::RenameObjectStore(int64_t transaction_id, | 621 void IndexedDBDatabase::RenameObjectStore(IndexedDBTransaction* transaction, |
| 623 int64_t object_store_id, | 622 int64_t object_store_id, |
| 624 const base::string16& new_name) { | 623 const base::string16& new_name) { |
| 625 IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id", transaction_id); | |
| 626 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 627 if (!transaction) | 624 if (!transaction) |
| 628 return; | 625 return; |
| 626 IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id", |
| 627 transaction->id()); |
| 629 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 628 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 630 | 629 |
| 631 if (!ValidateObjectStoreId(object_store_id)) | 630 if (!ValidateObjectStoreId(object_store_id)) |
| 632 return; | 631 return; |
| 633 | 632 |
| 634 // Store renaming is done synchronously, as it may be followed by | 633 // Store renaming is done synchronously, as it may be followed by |
| 635 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys | 634 // index creation (also sync) since preemptive OpenCursor/SetIndexKeys |
| 636 // may follow. | 635 // may follow. |
| 637 const IndexedDBObjectStoreMetadata object_store_metadata = | 636 const IndexedDBObjectStoreMetadata object_store_metadata = |
| 638 metadata_.object_stores[object_store_id]; | 637 metadata_.object_stores[object_store_id]; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 654 } | 653 } |
| 655 | 654 |
| 656 transaction->ScheduleAbortTask( | 655 transaction->ScheduleAbortTask( |
| 657 base::Bind(&IndexedDBDatabase::RenameObjectStoreAbortOperation, | 656 base::Bind(&IndexedDBDatabase::RenameObjectStoreAbortOperation, |
| 658 this, | 657 this, |
| 659 object_store_id, | 658 object_store_id, |
| 660 object_store_metadata.name)); | 659 object_store_metadata.name)); |
| 661 SetObjectStoreName(object_store_id, new_name); | 660 SetObjectStoreName(object_store_id, new_name); |
| 662 } | 661 } |
| 663 | 662 |
| 664 void IndexedDBDatabase::CreateIndex(int64_t transaction_id, | 663 void IndexedDBDatabase::CreateIndex(IndexedDBTransaction* transaction, |
| 665 int64_t object_store_id, | 664 int64_t object_store_id, |
| 666 int64_t index_id, | 665 int64_t index_id, |
| 667 const base::string16& name, | 666 const base::string16& name, |
| 668 const IndexedDBKeyPath& key_path, | 667 const IndexedDBKeyPath& key_path, |
| 669 bool unique, | 668 bool unique, |
| 670 bool multi_entry) { | 669 bool multi_entry) { |
| 671 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id); | |
| 672 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 673 if (!transaction) | 670 if (!transaction) |
| 674 return; | 671 return; |
| 672 IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction->id()); |
| 675 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 673 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 676 | 674 |
| 677 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) | 675 if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) |
| 678 return; | 676 return; |
| 679 | 677 |
| 680 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType", | 678 UMA_HISTOGRAM_ENUMERATION("WebCore.IndexedDB.Schema.Index.KeyPathType", |
| 681 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); | 679 HistogramKeyPathType(key_path), KEY_PATH_TYPE_MAX); |
| 682 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique); | 680 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.Unique", unique); |
| 683 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry", | 681 UMA_HISTOGRAM_BOOLEAN("WebCore.IndexedDB.Schema.Index.MultiEntry", |
| 684 multi_entry); | 682 multi_entry); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 714 | 712 |
| 715 void IndexedDBDatabase::CreateIndexAbortOperation( | 713 void IndexedDBDatabase::CreateIndexAbortOperation( |
| 716 int64_t object_store_id, | 714 int64_t object_store_id, |
| 717 int64_t index_id, | 715 int64_t index_id, |
| 718 IndexedDBTransaction* transaction) { | 716 IndexedDBTransaction* transaction) { |
| 719 DCHECK(!transaction); | 717 DCHECK(!transaction); |
| 720 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); | 718 IDB_TRACE("IndexedDBDatabase::CreateIndexAbortOperation"); |
| 721 RemoveIndex(object_store_id, index_id); | 719 RemoveIndex(object_store_id, index_id); |
| 722 } | 720 } |
| 723 | 721 |
| 724 void IndexedDBDatabase::DeleteIndex(int64_t transaction_id, | 722 void IndexedDBDatabase::DeleteIndex(IndexedDBTransaction* transaction, |
| 725 int64_t object_store_id, | 723 int64_t object_store_id, |
| 726 int64_t index_id) { | 724 int64_t index_id) { |
| 727 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); | |
| 728 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 729 if (!transaction) | 725 if (!transaction) |
| 730 return; | 726 return; |
| 727 IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction->id()); |
| 731 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 728 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 732 | 729 |
| 733 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) | 730 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) |
| 734 return; | 731 return; |
| 735 | 732 |
| 736 transaction->ScheduleTask( | 733 transaction->ScheduleTask( |
| 737 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, | 734 base::Bind(&IndexedDBDatabase::DeleteIndexOperation, |
| 738 this, | 735 this, |
| 739 object_store_id, | 736 object_store_id, |
| 740 index_id)); | 737 index_id)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 | 774 |
| 778 void IndexedDBDatabase::DeleteIndexAbortOperation( | 775 void IndexedDBDatabase::DeleteIndexAbortOperation( |
| 779 int64_t object_store_id, | 776 int64_t object_store_id, |
| 780 const IndexedDBIndexMetadata& index_metadata, | 777 const IndexedDBIndexMetadata& index_metadata, |
| 781 IndexedDBTransaction* transaction) { | 778 IndexedDBTransaction* transaction) { |
| 782 DCHECK(!transaction); | 779 DCHECK(!transaction); |
| 783 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); | 780 IDB_TRACE("IndexedDBDatabase::DeleteIndexAbortOperation"); |
| 784 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); | 781 AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); |
| 785 } | 782 } |
| 786 | 783 |
| 787 void IndexedDBDatabase::RenameIndex(int64_t transaction_id, | 784 void IndexedDBDatabase::RenameIndex(IndexedDBTransaction* transaction, |
| 788 int64_t object_store_id, | 785 int64_t object_store_id, |
| 789 int64_t index_id, | 786 int64_t index_id, |
| 790 const base::string16& new_name) { | 787 const base::string16& new_name) { |
| 791 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction_id); | |
| 792 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 793 if (!transaction) | 788 if (!transaction) |
| 794 return; | 789 return; |
| 790 IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction->id()); |
| 795 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 791 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 796 | 792 |
| 797 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) | 793 if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) |
| 798 return; | 794 return; |
| 799 | 795 |
| 800 // Index renaming is done synchronously since preemptive | 796 // Index renaming is done synchronously since preemptive |
| 801 // OpenCursor/SetIndexKeys may follow. | 797 // OpenCursor/SetIndexKeys may follow. |
| 802 | 798 |
| 803 const IndexedDBIndexMetadata index_metadata = | 799 const IndexedDBIndexMetadata index_metadata = |
| 804 metadata_.object_stores[object_store_id].indexes[index_id]; | 800 metadata_.object_stores[object_store_id].indexes[index_id]; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 831 void IndexedDBDatabase::RenameIndexAbortOperation( | 827 void IndexedDBDatabase::RenameIndexAbortOperation( |
| 832 int64_t object_store_id, | 828 int64_t object_store_id, |
| 833 int64_t index_id, | 829 int64_t index_id, |
| 834 const base::string16& old_name, | 830 const base::string16& old_name, |
| 835 IndexedDBTransaction* transaction) { | 831 IndexedDBTransaction* transaction) { |
| 836 DCHECK(!transaction); | 832 DCHECK(!transaction); |
| 837 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation"); | 833 IDB_TRACE("IndexedDBDatabase::RenameIndexAbortOperation"); |
| 838 SetIndexName(object_store_id, index_id, old_name); | 834 SetIndexName(object_store_id, index_id, old_name); |
| 839 } | 835 } |
| 840 | 836 |
| 841 void IndexedDBDatabase::Commit(int64_t transaction_id) { | 837 void IndexedDBDatabase::Commit(IndexedDBTransaction* transaction) { |
| 842 // The frontend suggests that we commit, but we may have previously initiated | 838 // The frontend suggests that we commit, but we may have previously initiated |
| 843 // an abort, and so have disposed of the transaction. on_abort has already | 839 // an abort, and so have disposed of the transaction. on_abort has already |
| 844 // been dispatched to the frontend, so it will find out about that | 840 // been dispatched to the frontend, so it will find out about that |
| 845 // asynchronously. | 841 // asynchronously. |
| 846 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 847 if (transaction) { | 842 if (transaction) { |
| 848 scoped_refptr<IndexedDBFactory> factory = factory_; | 843 scoped_refptr<IndexedDBFactory> factory = factory_; |
| 849 leveldb::Status s = transaction->Commit(); | 844 leveldb::Status s = transaction->Commit(); |
| 850 if (s.IsCorruption()) { | 845 if (s.IsCorruption()) { |
| 851 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 846 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 852 "Internal error committing transaction."); | 847 "Internal error committing transaction."); |
| 853 factory->HandleBackingStoreCorruption(identifier_.first, error); | 848 factory->HandleBackingStoreCorruption(identifier_.first, error); |
| 854 } | 849 } |
| 855 } | 850 } |
| 856 } | 851 } |
| 857 | 852 |
| 858 void IndexedDBDatabase::Abort(int64_t transaction_id) { | |
| 859 // If the transaction is unknown, then it has already been aborted by the | |
| 860 // backend before this call so it is safe to ignore it. | |
| 861 IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id); | |
| 862 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 863 if (transaction) | |
| 864 transaction->Abort(); | |
| 865 } | |
| 866 | |
| 867 void IndexedDBDatabase::Abort(int64_t transaction_id, | |
| 868 const IndexedDBDatabaseError& error) { | |
| 869 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); | |
| 870 // If the transaction is unknown, then it has already been aborted by the | |
| 871 // backend before this call so it is safe to ignore it. | |
| 872 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 873 if (transaction) | |
| 874 transaction->Abort(error); | |
| 875 } | |
| 876 | |
| 877 void IndexedDBDatabase::AddPendingObserver( | 853 void IndexedDBDatabase::AddPendingObserver( |
| 878 int64_t transaction_id, | 854 IndexedDBTransaction* transaction, |
| 879 int32_t observer_id, | 855 int32_t observer_id, |
| 880 const IndexedDBObserver::Options& options) { | 856 const IndexedDBObserver::Options& options) { |
| 881 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 882 if (!transaction) | 857 if (!transaction) |
| 883 return; | 858 return; |
| 884 transaction->AddPendingObserver(observer_id, options); | 859 transaction->AddPendingObserver(observer_id, options); |
| 885 } | 860 } |
| 886 | 861 |
| 887 void IndexedDBDatabase::RemovePendingObservers( | |
| 888 IndexedDBConnection* connection, | |
| 889 const std::vector<int32_t>& pending_observer_ids) { | |
| 890 for (const auto& it : transactions_) { | |
| 891 // Avoid call to RemovePendingObservers for transactions on other | |
| 892 // connections. | |
| 893 if (it.second->connection() == connection) | |
| 894 it.second->RemovePendingObservers(pending_observer_ids); | |
| 895 } | |
| 896 } | |
| 897 | |
| 898 // TODO(palakj): Augment the function with IDBValue later. Issue | 862 // TODO(palakj): Augment the function with IDBValue later. Issue |
| 899 // crbug.com/609934. | 863 // crbug.com/609934. |
| 900 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, | 864 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, |
| 901 int64_t object_store_id, | 865 int64_t object_store_id, |
| 902 blink::WebIDBOperationType type, | 866 blink::WebIDBOperationType type, |
| 903 const IndexedDBKeyRange& key_range) { | 867 const IndexedDBKeyRange& key_range) { |
| 904 for (auto* connection : connections_) { | 868 for (auto* connection : connections_) { |
| 905 bool recorded = false; | 869 bool recorded = false; |
| 906 for (const auto& observer : connection->active_observers()) { | 870 for (const auto& observer : connection->active_observers()) { |
| 907 if (!observer->IsRecordingType(type) || | 871 if (!observer->IsRecordingType(type) || |
| (...skipping 19 matching lines...) Expand all Loading... |
| 927 | 891 |
| 928 void IndexedDBDatabase::SendObservations( | 892 void IndexedDBDatabase::SendObservations( |
| 929 std::map<int32_t, std::unique_ptr<IndexedDBObserverChanges>> changes_map) { | 893 std::map<int32_t, std::unique_ptr<IndexedDBObserverChanges>> changes_map) { |
| 930 for (auto* conn : connections_) { | 894 for (auto* conn : connections_) { |
| 931 auto it = changes_map.find(conn->id()); | 895 auto it = changes_map.find(conn->id()); |
| 932 if (it != changes_map.end()) | 896 if (it != changes_map.end()) |
| 933 conn->callbacks()->OnDatabaseChange(std::move(it->second)); | 897 conn->callbacks()->OnDatabaseChange(std::move(it->second)); |
| 934 } | 898 } |
| 935 } | 899 } |
| 936 | 900 |
| 937 void IndexedDBDatabase::GetAll(int64_t transaction_id, | 901 void IndexedDBDatabase::GetAll(IndexedDBTransaction* transaction, |
| 938 int64_t object_store_id, | 902 int64_t object_store_id, |
| 939 int64_t index_id, | 903 int64_t index_id, |
| 940 std::unique_ptr<IndexedDBKeyRange> key_range, | 904 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 941 bool key_only, | 905 bool key_only, |
| 942 int64_t max_count, | 906 int64_t max_count, |
| 943 scoped_refptr<IndexedDBCallbacks> callbacks) { | 907 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 944 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); | |
| 945 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 946 if (!transaction) | 908 if (!transaction) |
| 947 return; | 909 return; |
| 910 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction->id()); |
| 948 | 911 |
| 949 if (!ValidateObjectStoreId(object_store_id)) | 912 if (!ValidateObjectStoreId(object_store_id)) |
| 950 return; | 913 return; |
| 951 | 914 |
| 952 transaction->ScheduleTask(base::Bind( | 915 transaction->ScheduleTask(base::Bind( |
| 953 &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id, | 916 &IndexedDBDatabase::GetAllOperation, this, object_store_id, index_id, |
| 954 base::Passed(&key_range), | 917 base::Passed(&key_range), |
| 955 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, | 918 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, |
| 956 max_count, callbacks)); | 919 max_count, callbacks)); |
| 957 } | 920 } |
| 958 | 921 |
| 959 void IndexedDBDatabase::Get(int64_t transaction_id, | 922 void IndexedDBDatabase::Get(IndexedDBTransaction* transaction, |
| 960 int64_t object_store_id, | 923 int64_t object_store_id, |
| 961 int64_t index_id, | 924 int64_t index_id, |
| 962 std::unique_ptr<IndexedDBKeyRange> key_range, | 925 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 963 bool key_only, | 926 bool key_only, |
| 964 scoped_refptr<IndexedDBCallbacks> callbacks) { | 927 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 965 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); | |
| 966 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 967 if (!transaction) | 928 if (!transaction) |
| 968 return; | 929 return; |
| 930 IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction->id()); |
| 969 | 931 |
| 970 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 932 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) |
| 971 return; | 933 return; |
| 972 | 934 |
| 973 transaction->ScheduleTask(base::Bind( | 935 transaction->ScheduleTask(base::Bind( |
| 974 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id, | 936 &IndexedDBDatabase::GetOperation, this, object_store_id, index_id, |
| 975 base::Passed(&key_range), | 937 base::Passed(&key_range), |
| 976 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, | 938 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE, |
| 977 callbacks)); | 939 callbacks)); |
| 978 } | 940 } |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1319 std::unique_ptr<IndexedDBKey> key; | 1281 std::unique_ptr<IndexedDBKey> key; |
| 1320 blink::WebIDBPutMode put_mode; | 1282 blink::WebIDBPutMode put_mode; |
| 1321 scoped_refptr<IndexedDBCallbacks> callbacks; | 1283 scoped_refptr<IndexedDBCallbacks> callbacks; |
| 1322 std::vector<IndexKeys> index_keys; | 1284 std::vector<IndexKeys> index_keys; |
| 1323 | 1285 |
| 1324 private: | 1286 private: |
| 1325 DISALLOW_COPY_AND_ASSIGN(PutOperationParams); | 1287 DISALLOW_COPY_AND_ASSIGN(PutOperationParams); |
| 1326 }; | 1288 }; |
| 1327 | 1289 |
| 1328 void IndexedDBDatabase::Put( | 1290 void IndexedDBDatabase::Put( |
| 1329 int64_t transaction_id, | 1291 IndexedDBTransaction* transaction, |
| 1330 int64_t object_store_id, | 1292 int64_t object_store_id, |
| 1331 IndexedDBValue* value, | 1293 IndexedDBValue* value, |
| 1332 std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles, | 1294 std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles, |
| 1333 std::unique_ptr<IndexedDBKey> key, | 1295 std::unique_ptr<IndexedDBKey> key, |
| 1334 blink::WebIDBPutMode put_mode, | 1296 blink::WebIDBPutMode put_mode, |
| 1335 scoped_refptr<IndexedDBCallbacks> callbacks, | 1297 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1336 const std::vector<IndexKeys>& index_keys) { | 1298 const std::vector<IndexKeys>& index_keys) { |
| 1337 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id); | |
| 1338 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1339 if (!transaction) | 1299 if (!transaction) |
| 1340 return; | 1300 return; |
| 1301 IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction->id()); |
| 1341 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 1302 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
| 1342 | 1303 |
| 1343 if (!ValidateObjectStoreId(object_store_id)) | 1304 if (!ValidateObjectStoreId(object_store_id)) |
| 1344 return; | 1305 return; |
| 1345 | 1306 |
| 1346 DCHECK(key); | 1307 DCHECK(key); |
| 1347 DCHECK(value); | 1308 DCHECK(value); |
| 1348 std::unique_ptr<PutOperationParams> params( | 1309 std::unique_ptr<PutOperationParams> params( |
| 1349 base::MakeUnique<PutOperationParams>()); | 1310 base::MakeUnique<PutOperationParams>()); |
| 1350 params->object_store_id = object_store_id; | 1311 params->object_store_id = object_store_id; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1494 transaction->id()); | 1455 transaction->id()); |
| 1495 params->callbacks->OnSuccess(*key); | 1456 params->callbacks->OnSuccess(*key); |
| 1496 } | 1457 } |
| 1497 FilterObservation(transaction, params->object_store_id, | 1458 FilterObservation(transaction, params->object_store_id, |
| 1498 params->put_mode == blink::WebIDBPutModeAddOnly | 1459 params->put_mode == blink::WebIDBPutModeAddOnly |
| 1499 ? blink::WebIDBAdd | 1460 ? blink::WebIDBAdd |
| 1500 : blink::WebIDBPut, | 1461 : blink::WebIDBPut, |
| 1501 IndexedDBKeyRange(*key)); | 1462 IndexedDBKeyRange(*key)); |
| 1502 } | 1463 } |
| 1503 | 1464 |
| 1504 void IndexedDBDatabase::SetIndexKeys(int64_t transaction_id, | 1465 void IndexedDBDatabase::SetIndexKeys(IndexedDBTransaction* transaction, |
| 1505 int64_t object_store_id, | 1466 int64_t object_store_id, |
| 1506 std::unique_ptr<IndexedDBKey> primary_key, | 1467 std::unique_ptr<IndexedDBKey> primary_key, |
| 1507 const std::vector<IndexKeys>& index_keys) { | 1468 const std::vector<IndexKeys>& index_keys) { |
| 1508 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); | |
| 1509 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1510 if (!transaction) | 1469 if (!transaction) |
| 1511 return; | 1470 return; |
| 1471 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction->id()); |
| 1512 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 1472 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 1513 | 1473 |
| 1514 // TODO(alecflett): This method could be asynchronous, but we need to | 1474 // TODO(alecflett): This method could be asynchronous, but we need to |
| 1515 // evaluate if it's worth the extra complexity. | 1475 // evaluate if it's worth the extra complexity. |
| 1516 IndexedDBBackingStore::RecordIdentifier record_identifier; | 1476 IndexedDBBackingStore::RecordIdentifier record_identifier; |
| 1517 bool found = false; | 1477 bool found = false; |
| 1518 leveldb::Status s = backing_store_->KeyExistsInObjectStore( | 1478 leveldb::Status s = backing_store_->KeyExistsInObjectStore( |
| 1519 transaction->BackingStoreTransaction(), | 1479 transaction->BackingStoreTransaction(), |
| 1520 metadata_.id, | 1480 metadata_.id, |
| 1521 object_store_id, | 1481 object_store_id, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1566 return; | 1526 return; |
| 1567 } | 1527 } |
| 1568 | 1528 |
| 1569 for (const auto& writer : index_writers) { | 1529 for (const auto& writer : index_writers) { |
| 1570 writer->WriteIndexKeys(record_identifier, backing_store_.get(), | 1530 writer->WriteIndexKeys(record_identifier, backing_store_.get(), |
| 1571 transaction->BackingStoreTransaction(), id(), | 1531 transaction->BackingStoreTransaction(), id(), |
| 1572 object_store_id); | 1532 object_store_id); |
| 1573 } | 1533 } |
| 1574 } | 1534 } |
| 1575 | 1535 |
| 1576 void IndexedDBDatabase::SetIndexesReady(int64_t transaction_id, | 1536 void IndexedDBDatabase::SetIndexesReady(IndexedDBTransaction* transaction, |
| 1577 int64_t, | 1537 int64_t, |
| 1578 const std::vector<int64_t>& index_ids) { | 1538 const std::vector<int64_t>& index_ids) { |
| 1579 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1580 if (!transaction) | 1539 if (!transaction) |
| 1581 return; | 1540 return; |
| 1582 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 1541 DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); |
| 1583 | 1542 |
| 1584 transaction->ScheduleTask( | 1543 transaction->ScheduleTask( |
| 1585 blink::WebIDBTaskTypePreemptive, | 1544 blink::WebIDBTaskTypePreemptive, |
| 1586 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, | 1545 base::Bind(&IndexedDBDatabase::SetIndexesReadyOperation, |
| 1587 this, | 1546 this, |
| 1588 index_ids.size())); | 1547 index_ids.size())); |
| 1589 } | 1548 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1603 blink::WebIDBCursorDirection direction; | 1562 blink::WebIDBCursorDirection direction; |
| 1604 indexed_db::CursorType cursor_type; | 1563 indexed_db::CursorType cursor_type; |
| 1605 blink::WebIDBTaskType task_type; | 1564 blink::WebIDBTaskType task_type; |
| 1606 scoped_refptr<IndexedDBCallbacks> callbacks; | 1565 scoped_refptr<IndexedDBCallbacks> callbacks; |
| 1607 | 1566 |
| 1608 private: | 1567 private: |
| 1609 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); | 1568 DISALLOW_COPY_AND_ASSIGN(OpenCursorOperationParams); |
| 1610 }; | 1569 }; |
| 1611 | 1570 |
| 1612 void IndexedDBDatabase::OpenCursor( | 1571 void IndexedDBDatabase::OpenCursor( |
| 1613 int64_t transaction_id, | 1572 IndexedDBTransaction* transaction, |
| 1614 int64_t object_store_id, | 1573 int64_t object_store_id, |
| 1615 int64_t index_id, | 1574 int64_t index_id, |
| 1616 std::unique_ptr<IndexedDBKeyRange> key_range, | 1575 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 1617 blink::WebIDBCursorDirection direction, | 1576 blink::WebIDBCursorDirection direction, |
| 1618 bool key_only, | 1577 bool key_only, |
| 1619 blink::WebIDBTaskType task_type, | 1578 blink::WebIDBTaskType task_type, |
| 1620 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1579 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1621 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id); | |
| 1622 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1623 if (!transaction) | 1580 if (!transaction) |
| 1624 return; | 1581 return; |
| 1582 IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction->id()); |
| 1625 | 1583 |
| 1626 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 1584 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) |
| 1627 return; | 1585 return; |
| 1628 | 1586 |
| 1629 std::unique_ptr<OpenCursorOperationParams> params( | 1587 std::unique_ptr<OpenCursorOperationParams> params( |
| 1630 base::MakeUnique<OpenCursorOperationParams>()); | 1588 base::MakeUnique<OpenCursorOperationParams>()); |
| 1631 params->object_store_id = object_store_id; | 1589 params->object_store_id = object_store_id; |
| 1632 params->index_id = index_id; | 1590 params->index_id = index_id; |
| 1633 params->key_range = std::move(key_range); | 1591 params->key_range = std::move(key_range); |
| 1634 params->direction = direction; | 1592 params->direction = direction; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1705 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); | 1663 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); |
| 1706 } | 1664 } |
| 1707 } | 1665 } |
| 1708 | 1666 |
| 1709 if (!backing_store_cursor) { | 1667 if (!backing_store_cursor) { |
| 1710 // Why is Success being called? | 1668 // Why is Success being called? |
| 1711 params->callbacks->OnSuccess(nullptr); | 1669 params->callbacks->OnSuccess(nullptr); |
| 1712 return; | 1670 return; |
| 1713 } | 1671 } |
| 1714 | 1672 |
| 1715 scoped_refptr<IndexedDBCursor> cursor = | 1673 std::unique_ptr<IndexedDBCursor> cursor = base::MakeUnique<IndexedDBCursor>( |
| 1716 new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type, | 1674 std::move(backing_store_cursor), params->cursor_type, params->task_type, |
| 1717 params->task_type, transaction); | 1675 transaction); |
| 1718 params->callbacks->OnSuccess( | 1676 IndexedDBCursor* cursor_ptr = cursor.get(); |
| 1719 cursor, cursor->key(), cursor->primary_key(), cursor->Value()); | 1677 transaction->RegisterOpenCursor(cursor_ptr); |
| 1678 params->callbacks->OnSuccess(std::move(cursor), cursor_ptr->key(), |
| 1679 cursor_ptr->primary_key(), cursor_ptr->Value()); |
| 1720 } | 1680 } |
| 1721 | 1681 |
| 1722 void IndexedDBDatabase::Count(int64_t transaction_id, | 1682 void IndexedDBDatabase::Count(IndexedDBTransaction* transaction, |
| 1723 int64_t object_store_id, | 1683 int64_t object_store_id, |
| 1724 int64_t index_id, | 1684 int64_t index_id, |
| 1725 std::unique_ptr<IndexedDBKeyRange> key_range, | 1685 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 1726 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1686 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1727 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id); | |
| 1728 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1729 if (!transaction) | 1687 if (!transaction) |
| 1730 return; | 1688 return; |
| 1689 IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction->id()); |
| 1731 | 1690 |
| 1732 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 1691 if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) |
| 1733 return; | 1692 return; |
| 1734 | 1693 |
| 1735 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, | 1694 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::CountOperation, |
| 1736 this, | 1695 this, |
| 1737 object_store_id, | 1696 object_store_id, |
| 1738 index_id, | 1697 index_id, |
| 1739 base::Passed(&key_range), | 1698 base::Passed(&key_range), |
| 1740 callbacks)); | 1699 callbacks)); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 do { | 1744 do { |
| 1786 ++count; | 1745 ++count; |
| 1787 } while (backing_store_cursor->Continue(&s)); | 1746 } while (backing_store_cursor->Continue(&s)); |
| 1788 | 1747 |
| 1789 // TODO(cmumford): Check for database corruption. | 1748 // TODO(cmumford): Check for database corruption. |
| 1790 | 1749 |
| 1791 callbacks->OnSuccess(count); | 1750 callbacks->OnSuccess(count); |
| 1792 } | 1751 } |
| 1793 | 1752 |
| 1794 void IndexedDBDatabase::DeleteRange( | 1753 void IndexedDBDatabase::DeleteRange( |
| 1795 int64_t transaction_id, | 1754 IndexedDBTransaction* transaction, |
| 1796 int64_t object_store_id, | 1755 int64_t object_store_id, |
| 1797 std::unique_ptr<IndexedDBKeyRange> key_range, | 1756 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 1798 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1757 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1799 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); | |
| 1800 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1801 if (!transaction) | 1758 if (!transaction) |
| 1802 return; | 1759 return; |
| 1760 IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction->id()); |
| 1803 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 1761 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
| 1804 | 1762 |
| 1805 if (!ValidateObjectStoreId(object_store_id)) | 1763 if (!ValidateObjectStoreId(object_store_id)) |
| 1806 return; | 1764 return; |
| 1807 | 1765 |
| 1808 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, | 1766 transaction->ScheduleTask(base::Bind(&IndexedDBDatabase::DeleteRangeOperation, |
| 1809 this, | 1767 this, |
| 1810 object_store_id, | 1768 object_store_id, |
| 1811 base::Passed(&key_range), | 1769 base::Passed(&key_range), |
| 1812 callbacks)); | 1770 callbacks)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1832 if (s.IsCorruption()) { | 1790 if (s.IsCorruption()) { |
| 1833 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); | 1791 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); |
| 1834 } | 1792 } |
| 1835 return; | 1793 return; |
| 1836 } | 1794 } |
| 1837 callbacks->OnSuccess(); | 1795 callbacks->OnSuccess(); |
| 1838 FilterObservation(transaction, object_store_id, blink::WebIDBDelete, | 1796 FilterObservation(transaction, object_store_id, blink::WebIDBDelete, |
| 1839 *key_range); | 1797 *key_range); |
| 1840 } | 1798 } |
| 1841 | 1799 |
| 1842 void IndexedDBDatabase::Clear(int64_t transaction_id, | 1800 void IndexedDBDatabase::Clear(IndexedDBTransaction* transaction, |
| 1843 int64_t object_store_id, | 1801 int64_t object_store_id, |
| 1844 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1802 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1845 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); | |
| 1846 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | |
| 1847 if (!transaction) | 1803 if (!transaction) |
| 1848 return; | 1804 return; |
| 1805 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction->id()); |
| 1849 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 1806 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
| 1850 | 1807 |
| 1851 if (!ValidateObjectStoreId(object_store_id)) | 1808 if (!ValidateObjectStoreId(object_store_id)) |
| 1852 return; | 1809 return; |
| 1853 | 1810 |
| 1854 transaction->ScheduleTask(base::Bind( | 1811 transaction->ScheduleTask(base::Bind( |
| 1855 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); | 1812 &IndexedDBDatabase::ClearOperation, this, object_store_id, callbacks)); |
| 1856 } | 1813 } |
| 1857 | 1814 |
| 1858 void IndexedDBDatabase::ClearOperation( | 1815 void IndexedDBDatabase::ClearOperation( |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1928 callbacks->OnError(error); | 1885 callbacks->OnError(error); |
| 1929 transaction->Abort(error); | 1886 transaction->Abort(error); |
| 1930 return; | 1887 return; |
| 1931 } | 1888 } |
| 1932 | 1889 |
| 1933 transaction->ScheduleAbortTask( | 1890 transaction->ScheduleAbortTask( |
| 1934 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, | 1891 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, |
| 1935 metadata_.version)); | 1892 metadata_.version)); |
| 1936 metadata_.version = version; | 1893 metadata_.version = version; |
| 1937 | 1894 |
| 1938 active_request_->UpgradeTransactionStarted(old_version); | 1895 active_request_->UpgradeTransactionStarted(old_version, transaction); |
| 1939 } | 1896 } |
| 1940 | 1897 |
| 1941 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, | 1898 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, |
| 1942 bool committed) { | 1899 bool committed) { |
| 1943 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); | 1900 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", |
| 1944 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); | 1901 transaction->id()); |
| 1945 DCHECK_EQ(transactions_[transaction->id()], transaction); | 1902 --transaction_count_; |
| 1946 transactions_.erase(transaction->id()); | 1903 DCHECK_LE(0, transaction_count_); |
| 1947 | 1904 |
| 1948 // This may be an unrelated transaction finishing while waiting for | 1905 // This may be an unrelated transaction finishing while waiting for |
| 1949 // connections to close, or the actual upgrade transaction from an active | 1906 // connections to close, or the actual upgrade transaction from an active |
| 1950 // request. Notify the active request if it's the latter. | 1907 // request. Notify the active request if it's the latter. |
| 1951 if (active_request_ && | 1908 if (active_request_ && |
| 1952 transaction->mode() == blink::WebIDBTransactionModeVersionChange) { | 1909 transaction->mode() == blink::WebIDBTransactionModeVersionChange) { |
| 1953 active_request_->UpgradeTransactionFinished(committed); | 1910 active_request_->UpgradeTransactionFinished(committed); |
| 1954 } | 1911 } |
| 1955 } | 1912 } |
| 1956 | 1913 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1999 } while (!active_request_ && !pending_requests_.empty()); | 1956 } while (!active_request_ && !pending_requests_.empty()); |
| 2000 } | 1957 } |
| 2001 | 1958 |
| 2002 IndexedDBTransaction* IndexedDBDatabase::CreateTransaction( | 1959 IndexedDBTransaction* IndexedDBDatabase::CreateTransaction( |
| 2003 int64_t transaction_id, | 1960 int64_t transaction_id, |
| 2004 IndexedDBConnection* connection, | 1961 IndexedDBConnection* connection, |
| 2005 const std::vector<int64_t>& object_store_ids, | 1962 const std::vector<int64_t>& object_store_ids, |
| 2006 blink::WebIDBTransactionMode mode) { | 1963 blink::WebIDBTransactionMode mode) { |
| 2007 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); | 1964 IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); |
| 2008 DCHECK(connections_.count(connection)); | 1965 DCHECK(connections_.count(connection)); |
| 2009 DCHECK(transactions_.find(transaction_id) == transactions_.end()); | |
| 2010 if (transactions_.find(transaction_id) != transactions_.end()) | |
| 2011 return nullptr; | |
| 2012 | 1966 |
| 2013 UMA_HISTOGRAM_COUNTS_1000( | 1967 UMA_HISTOGRAM_COUNTS_1000( |
| 2014 "WebCore.IndexedDB.Database.OutstandingTransactionCount", | 1968 "WebCore.IndexedDB.Database.OutstandingTransactionCount", |
| 2015 transactions_.size()); | 1969 transaction_count_); |
| 2016 | 1970 |
| 2017 // The transaction will add itself to this database's coordinator, which | 1971 IndexedDBTransaction* transaction = connection->CreateTransaction( |
| 2018 // manages the lifetime of the object. | 1972 transaction_id, |
| 2019 IndexedDBTransaction* transaction = | 1973 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode, |
| 2020 IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( | 1974 new IndexedDBBackingStore::Transaction(backing_store_.get())); |
| 2021 transaction_id, connection->GetWeakPtr(), | |
| 2022 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), | |
| 2023 mode, new IndexedDBBackingStore::Transaction(backing_store_.get())); | |
| 2024 TransactionCreated(transaction); | 1975 TransactionCreated(transaction); |
| 2025 return transaction; | 1976 return transaction; |
| 2026 } | 1977 } |
| 2027 | 1978 |
| 2028 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { | 1979 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { |
| 2029 transactions_[transaction->id()] = transaction; | 1980 transaction_count_++; |
| 1981 transaction_coordinator_.DidCreateTransaction(transaction); |
| 2030 } | 1982 } |
| 2031 | 1983 |
| 2032 void IndexedDBDatabase::OpenConnection( | 1984 void IndexedDBDatabase::OpenConnection( |
| 2033 std::unique_ptr<IndexedDBPendingConnection> connection) { | 1985 std::unique_ptr<IndexedDBPendingConnection> connection) { |
| 2034 AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection))); | 1986 AppendRequest(base::MakeUnique<OpenRequest>(this, std::move(connection))); |
| 2035 } | 1987 } |
| 2036 | 1988 |
| 2037 void IndexedDBDatabase::DeleteDatabase( | 1989 void IndexedDBDatabase::DeleteDatabase( |
| 2038 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1990 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 2039 AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks)); | 1991 AppendRequest(base::MakeUnique<DeleteRequest>(this, callbacks)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2059 DCHECK(connections_.count(connection)); | 2011 DCHECK(connections_.count(connection)); |
| 2060 DCHECK(connection->IsConnected()); | 2012 DCHECK(connection->IsConnected()); |
| 2061 DCHECK(connection->database() == this); | 2013 DCHECK(connection->database() == this); |
| 2062 | 2014 |
| 2063 IDB_TRACE("IndexedDBDatabase::Close"); | 2015 IDB_TRACE("IndexedDBDatabase::Close"); |
| 2064 | 2016 |
| 2065 // Abort outstanding transactions from the closing connection. This can not | 2017 // Abort outstanding transactions from the closing connection. This can not |
| 2066 // happen if the close is requested by the connection itself as the | 2018 // happen if the close is requested by the connection itself as the |
| 2067 // front-end defers the close until all transactions are complete, but can | 2019 // front-end defers the close until all transactions are complete, but can |
| 2068 // occur on process termination or forced close. | 2020 // occur on process termination or forced close. |
| 2069 { | 2021 connection->AbortAllTransactions(IndexedDBDatabaseError( |
| 2070 auto transactions(transactions_); | 2022 blink::WebIDBDatabaseExceptionUnknownError, "Connection is closing.")); |
| 2071 for (const auto& it : transactions) { | |
| 2072 if (it.second->callbacks() == connection->callbacks()) | |
| 2073 it.second->Abort( | |
| 2074 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | |
| 2075 "Connection is closing.")); | |
| 2076 } | |
| 2077 } | |
| 2078 | 2023 |
| 2079 // Abort transactions before removing the connection; aborting may complete | 2024 // Abort transactions before removing the connection; aborting may complete |
| 2080 // an upgrade, and thus allow the next open/delete requests to proceed. The | 2025 // an upgrade, and thus allow the next open/delete requests to proceed. The |
| 2081 // new active_request_ should see the old connection count until explicitly | 2026 // new active_request_ should see the old connection count until explicitly |
| 2082 // notified below. | 2027 // notified below. |
| 2083 connections_.erase(connection); | 2028 connections_.erase(connection); |
| 2084 | 2029 |
| 2085 // Notify the active request, which may need to do cleanup or proceed with | 2030 // Notify the active request, which may need to do cleanup or proceed with |
| 2086 // the operation. This may trigger other work, such as more connections or | 2031 // the operation. This may trigger other work, such as more connections or |
| 2087 // deletions, so |active_request_| itself may change. | 2032 // deletions, so |active_request_| itself may change. |
| 2088 if (active_request_) | 2033 if (active_request_) |
| 2089 active_request_->OnConnectionClosed(connection); | 2034 active_request_->OnConnectionClosed(connection); |
| 2090 | 2035 |
| 2091 // If there are no more connections (current, active, or pending), tell the | 2036 // If there are no more connections (current, active, or pending), tell the |
| 2092 // factory to clean us up. | 2037 // factory to clean us up. |
| 2093 if (connections_.empty() && !active_request_ && pending_requests_.empty()) { | 2038 if (connections_.empty() && !active_request_ && pending_requests_.empty()) { |
| 2094 DCHECK(transactions_.empty()); | |
| 2095 backing_store_ = nullptr; | 2039 backing_store_ = nullptr; |
| 2096 factory_->ReleaseDatabase(identifier_, forced); | 2040 factory_->ReleaseDatabase(identifier_, forced); |
| 2097 } | 2041 } |
| 2098 } | 2042 } |
| 2099 | 2043 |
| 2100 void IndexedDBDatabase::CreateObjectStoreAbortOperation( | 2044 void IndexedDBDatabase::CreateObjectStoreAbortOperation( |
| 2101 int64_t object_store_id, | 2045 int64_t object_store_id, |
| 2102 IndexedDBTransaction* transaction) { | 2046 IndexedDBTransaction* transaction) { |
| 2103 DCHECK(!transaction); | 2047 DCHECK(!transaction); |
| 2104 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); | 2048 IDB_TRACE("IndexedDBDatabase::CreateObjectStoreAbortOperation"); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2125 | 2069 |
| 2126 void IndexedDBDatabase::VersionChangeAbortOperation( | 2070 void IndexedDBDatabase::VersionChangeAbortOperation( |
| 2127 int64_t previous_version, | 2071 int64_t previous_version, |
| 2128 IndexedDBTransaction* transaction) { | 2072 IndexedDBTransaction* transaction) { |
| 2129 DCHECK(!transaction); | 2073 DCHECK(!transaction); |
| 2130 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); | 2074 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); |
| 2131 metadata_.version = previous_version; | 2075 metadata_.version = previous_version; |
| 2132 } | 2076 } |
| 2133 | 2077 |
| 2134 } // namespace content | 2078 } // namespace content |
| OLD | NEW |