| 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 <memory> | 10 #include <memory> |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "base/stl_util.h" | 22 #include "base/stl_util.h" |
| 23 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 24 #include "base/strings/utf_string_conversions.h" | 24 #include "base/strings/utf_string_conversions.h" |
| 25 #include "content/browser/indexed_db/indexed_db_blob_info.h" | 25 #include "content/browser/indexed_db/indexed_db_blob_info.h" |
| 26 #include "content/browser/indexed_db/indexed_db_class_factory.h" | 26 #include "content/browser/indexed_db/indexed_db_class_factory.h" |
| 27 #include "content/browser/indexed_db/indexed_db_connection.h" | 27 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 28 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 28 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 29 #include "content/browser/indexed_db/indexed_db_cursor.h" | 29 #include "content/browser/indexed_db/indexed_db_cursor.h" |
| 30 #include "content/browser/indexed_db/indexed_db_factory.h" | 30 #include "content/browser/indexed_db/indexed_db_factory.h" |
| 31 #include "content/browser/indexed_db/indexed_db_index_writer.h" | 31 #include "content/browser/indexed_db/indexed_db_index_writer.h" |
| 32 #include "content/browser/indexed_db/indexed_db_observation.h" |
| 33 #include "content/browser/indexed_db/indexed_db_observer_changes.h" |
| 32 #include "content/browser/indexed_db/indexed_db_pending_connection.h" | 34 #include "content/browser/indexed_db/indexed_db_pending_connection.h" |
| 33 #include "content/browser/indexed_db/indexed_db_return_value.h" | 35 #include "content/browser/indexed_db/indexed_db_return_value.h" |
| 34 #include "content/browser/indexed_db/indexed_db_tracing.h" | 36 #include "content/browser/indexed_db/indexed_db_tracing.h" |
| 35 #include "content/browser/indexed_db/indexed_db_transaction.h" | 37 #include "content/browser/indexed_db/indexed_db_transaction.h" |
| 36 #include "content/browser/indexed_db/indexed_db_value.h" | 38 #include "content/browser/indexed_db/indexed_db_value.h" |
| 37 #include "content/common/indexed_db/indexed_db_constants.h" | 39 #include "content/common/indexed_db/indexed_db_constants.h" |
| 38 #include "content/common/indexed_db/indexed_db_key_path.h" | 40 #include "content/common/indexed_db/indexed_db_key_path.h" |
| 39 #include "content/common/indexed_db/indexed_db_key_range.h" | 41 #include "content/common/indexed_db/indexed_db_key_range.h" |
| 40 #include "content/public/common/content_switches.h" | 42 #include "content/public/common/content_switches.h" |
| 41 #include "storage/browser/blob/blob_data_handle.h" | 43 #include "storage/browser/blob/blob_data_handle.h" |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 void IndexedDBDatabase::Abort(int64_t transaction_id, | 536 void IndexedDBDatabase::Abort(int64_t transaction_id, |
| 535 const IndexedDBDatabaseError& error) { | 537 const IndexedDBDatabaseError& error) { |
| 536 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); | 538 IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); |
| 537 // If the transaction is unknown, then it has already been aborted by the | 539 // If the transaction is unknown, then it has already been aborted by the |
| 538 // backend before this call so it is safe to ignore it. | 540 // backend before this call so it is safe to ignore it. |
| 539 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 541 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 540 if (transaction) | 542 if (transaction) |
| 541 transaction->Abort(error); | 543 transaction->Abort(error); |
| 542 } | 544 } |
| 543 | 545 |
| 546 void IndexedDBDatabase::AddPendingObserver(int64_t transaction_id, |
| 547 int32_t observer_id, |
| 548 IndexedDBObserver::Options options) { |
| 549 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 550 if (!transaction) |
| 551 return; |
| 552 transaction->AddPendingObserver(observer_id, options); |
| 553 } |
| 554 |
| 555 void IndexedDBDatabase::RemovePendingObservers( |
| 556 IndexedDBConnection* connection, |
| 557 const std::vector<int32_t>& pending_observer_ids) { |
| 558 TransactionMap::iterator it; |
| 559 for (it = transactions_.begin(); it != transactions_.end(); it++) { |
| 560 // Avoid call to RemovePendingObservers for transactions on other |
| 561 // connections. |
| 562 if (it->second->connection() == connection) |
| 563 it->second->RemovePendingObservers(pending_observer_ids); |
| 564 } |
| 565 } |
| 566 |
| 567 // TODO(palakj): Augment the function with IDBValue later. Issue |
| 568 // crbug.com/609934. |
| 569 void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, |
| 570 int64_t object_store_id, |
| 571 blink::WebIDBOperationType type, |
| 572 const IndexedDBKeyRange& key_range) { |
| 573 for (const auto& connection : connections_) { |
| 574 bool recorded = false; |
| 575 for (const auto& observer : connection->active_observers()) { |
| 576 if (!observer->IsRecordingType(type) || |
| 577 !observer->IsRecordingObjectStore(object_store_id)) |
| 578 continue; |
| 579 if (!recorded) { |
| 580 if (type == blink::WebIDBClear) { |
| 581 transaction->AddObservation(connection->id(), |
| 582 base::WrapUnique(new IndexedDBObservation( |
| 583 object_store_id, type))); |
| 584 } else { |
| 585 transaction->AddObservation(connection->id(), |
| 586 base::WrapUnique(new IndexedDBObservation( |
| 587 object_store_id, type, key_range))); |
| 588 } |
| 589 recorded = true; |
| 590 } |
| 591 transaction->RecordObserverForLastObservation(connection->id(), |
| 592 observer->id()); |
| 593 } |
| 594 } |
| 595 } |
| 596 |
| 597 void IndexedDBDatabase::SendObservations( |
| 598 std::map<int32_t, std::unique_ptr<IndexedDBObserverChanges>> changes_map) { |
| 599 for (const auto& conn : connections_) { |
| 600 auto it = changes_map.find(conn->id()); |
| 601 if (it != changes_map.end()) |
| 602 conn->callbacks()->OnDatabaseChange(it->first, std::move(it->second)); |
| 603 } |
| 604 } |
| 605 |
| 544 void IndexedDBDatabase::GetAll(int64_t transaction_id, | 606 void IndexedDBDatabase::GetAll(int64_t transaction_id, |
| 545 int64_t object_store_id, | 607 int64_t object_store_id, |
| 546 int64_t index_id, | 608 int64_t index_id, |
| 547 std::unique_ptr<IndexedDBKeyRange> key_range, | 609 std::unique_ptr<IndexedDBKeyRange> key_range, |
| 548 bool key_only, | 610 bool key_only, |
| 549 int64_t max_count, | 611 int64_t max_count, |
| 550 scoped_refptr<IndexedDBCallbacks> callbacks) { | 612 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 551 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); | 613 IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); |
| 552 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 614 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 553 if (!transaction) | 615 if (!transaction) |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1088 if (s.IsCorruption()) | 1150 if (s.IsCorruption()) |
| 1089 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); | 1151 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); |
| 1090 return; | 1152 return; |
| 1091 } | 1153 } |
| 1092 } | 1154 } |
| 1093 { | 1155 { |
| 1094 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id", | 1156 IDB_TRACE1("IndexedDBDatabase::PutOperation.Callbacks", "txn.id", |
| 1095 transaction->id()); | 1157 transaction->id()); |
| 1096 params->callbacks->OnSuccess(*key); | 1158 params->callbacks->OnSuccess(*key); |
| 1097 } | 1159 } |
| 1160 FilterObservation(transaction, params->object_store_id, |
| 1161 params->put_mode == blink::WebIDBPutModeAddOnly |
| 1162 ? blink::WebIDBAdd |
| 1163 : blink::WebIDBPut, |
| 1164 IndexedDBKeyRange(*key)); |
| 1098 } | 1165 } |
| 1099 | 1166 |
| 1100 void IndexedDBDatabase::SetIndexKeys(int64_t transaction_id, | 1167 void IndexedDBDatabase::SetIndexKeys(int64_t transaction_id, |
| 1101 int64_t object_store_id, | 1168 int64_t object_store_id, |
| 1102 std::unique_ptr<IndexedDBKey> primary_key, | 1169 std::unique_ptr<IndexedDBKey> primary_key, |
| 1103 const std::vector<IndexKeys>& index_keys) { | 1170 const std::vector<IndexKeys>& index_keys) { |
| 1104 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); | 1171 IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); |
| 1105 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 1172 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 1106 if (!transaction) | 1173 if (!transaction) |
| 1107 return; | 1174 return; |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 if (s.IsCorruption()) { | 1498 if (s.IsCorruption()) { |
| 1432 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); | 1499 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); |
| 1433 } | 1500 } |
| 1434 return; | 1501 return; |
| 1435 } | 1502 } |
| 1436 if (experimental_web_platform_features_enabled_) { | 1503 if (experimental_web_platform_features_enabled_) { |
| 1437 callbacks->OnSuccess(base::checked_cast<int64_t>(delete_count)); | 1504 callbacks->OnSuccess(base::checked_cast<int64_t>(delete_count)); |
| 1438 } else { | 1505 } else { |
| 1439 callbacks->OnSuccess(); | 1506 callbacks->OnSuccess(); |
| 1440 } | 1507 } |
| 1508 FilterObservation(transaction, object_store_id, blink::WebIDBDelete, |
| 1509 *key_range); |
| 1441 } | 1510 } |
| 1442 | 1511 |
| 1443 void IndexedDBDatabase::Clear(int64_t transaction_id, | 1512 void IndexedDBDatabase::Clear(int64_t transaction_id, |
| 1444 int64_t object_store_id, | 1513 int64_t object_store_id, |
| 1445 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1514 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1446 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); | 1515 IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); |
| 1447 IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 1516 IndexedDBTransaction* transaction = GetTransaction(transaction_id); |
| 1448 if (!transaction) | 1517 if (!transaction) |
| 1449 return; | 1518 return; |
| 1450 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 1519 DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1466 if (!s.ok()) { | 1535 if (!s.ok()) { |
| 1467 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 1536 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
| 1468 "Internal error clearing object store"); | 1537 "Internal error clearing object store"); |
| 1469 callbacks->OnError(error); | 1538 callbacks->OnError(error); |
| 1470 if (s.IsCorruption()) { | 1539 if (s.IsCorruption()) { |
| 1471 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); | 1540 factory_->HandleBackingStoreCorruption(backing_store_->origin(), error); |
| 1472 } | 1541 } |
| 1473 return; | 1542 return; |
| 1474 } | 1543 } |
| 1475 callbacks->OnSuccess(); | 1544 callbacks->OnSuccess(); |
| 1545 |
| 1546 FilterObservation(transaction, object_store_id, blink::WebIDBClear, |
| 1547 IndexedDBKeyRange()); |
| 1476 } | 1548 } |
| 1477 | 1549 |
| 1478 void IndexedDBDatabase::DeleteObjectStoreOperation( | 1550 void IndexedDBDatabase::DeleteObjectStoreOperation( |
| 1479 int64_t object_store_id, | 1551 int64_t object_store_id, |
| 1480 IndexedDBTransaction* transaction) { | 1552 IndexedDBTransaction* transaction) { |
| 1481 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation", | 1553 IDB_TRACE1("IndexedDBDatabase::DeleteObjectStoreOperation", |
| 1482 "txn.id", | 1554 "txn.id", |
| 1483 transaction->id()); | 1555 transaction->id()); |
| 1484 | 1556 |
| 1485 const IndexedDBObjectStoreMetadata object_store_metadata = | 1557 const IndexedDBObjectStoreMetadata object_store_metadata = |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 if (transactions_.find(transaction_id) != transactions_.end()) | 1730 if (transactions_.find(transaction_id) != transactions_.end()) |
| 1659 return; | 1731 return; |
| 1660 | 1732 |
| 1661 UMA_HISTOGRAM_COUNTS_1000( | 1733 UMA_HISTOGRAM_COUNTS_1000( |
| 1662 "WebCore.IndexedDB.Database.OutstandingTransactionCount", | 1734 "WebCore.IndexedDB.Database.OutstandingTransactionCount", |
| 1663 transactions_.size()); | 1735 transactions_.size()); |
| 1664 | 1736 |
| 1665 // The transaction will add itself to this database's coordinator, which | 1737 // The transaction will add itself to this database's coordinator, which |
| 1666 // manages the lifetime of the object. | 1738 // manages the lifetime of the object. |
| 1667 TransactionCreated(IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( | 1739 TransactionCreated(IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( |
| 1668 transaction_id, connection->callbacks(), | 1740 transaction_id, connection->GetWeakPtr(), |
| 1669 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode, | 1741 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode, |
| 1670 this, new IndexedDBBackingStore::Transaction(backing_store_.get()))); | 1742 new IndexedDBBackingStore::Transaction(backing_store_.get()))); |
| 1671 } | 1743 } |
| 1672 | 1744 |
| 1673 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { | 1745 void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { |
| 1674 transactions_[transaction->id()] = transaction; | 1746 transactions_[transaction->id()] = transaction; |
| 1675 } | 1747 } |
| 1676 | 1748 |
| 1677 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { | 1749 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { |
| 1678 return !pending_delete_calls_.empty() || | 1750 return !pending_delete_calls_.empty() || |
| 1679 transaction_coordinator_.IsRunningVersionChangeTransaction() || | 1751 transaction_coordinator_.IsRunningVersionChangeTransaction() || |
| 1680 pending_run_version_change_transaction_call_; | 1752 pending_run_version_change_transaction_call_; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 | 1970 |
| 1899 connections_.erase(connection); | 1971 connections_.erase(connection); |
| 1900 | 1972 |
| 1901 // Abort outstanding transactions from the closing connection. This | 1973 // Abort outstanding transactions from the closing connection. This |
| 1902 // can not happen if the close is requested by the connection itself | 1974 // can not happen if the close is requested by the connection itself |
| 1903 // as the front-end defers the close until all transactions are | 1975 // as the front-end defers the close until all transactions are |
| 1904 // complete, but can occur on process termination or forced close. | 1976 // complete, but can occur on process termination or forced close. |
| 1905 { | 1977 { |
| 1906 TransactionMap transactions(transactions_); | 1978 TransactionMap transactions(transactions_); |
| 1907 for (const auto& it : transactions) { | 1979 for (const auto& it : transactions) { |
| 1908 if (it.second->connection() == connection->callbacks()) | 1980 if (it.second->callbacks() == connection->callbacks()) |
| 1909 it.second->Abort( | 1981 it.second->Abort( |
| 1910 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 1982 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
| 1911 "Connection is closing.")); | 1983 "Connection is closing.")); |
| 1912 } | 1984 } |
| 1913 } | 1985 } |
| 1914 | 1986 |
| 1915 if (pending_second_half_open_ && | 1987 if (pending_second_half_open_ && |
| 1916 pending_second_half_open_->connection() == connection) { | 1988 pending_second_half_open_->connection() == connection) { |
| 1917 pending_second_half_open_->callbacks()->OnError( | 1989 pending_second_half_open_->callbacks()->OnError( |
| 1918 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, | 1990 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1950 | 2022 |
| 1951 void IndexedDBDatabase::VersionChangeAbortOperation( | 2023 void IndexedDBDatabase::VersionChangeAbortOperation( |
| 1952 int64_t previous_version, | 2024 int64_t previous_version, |
| 1953 IndexedDBTransaction* transaction) { | 2025 IndexedDBTransaction* transaction) { |
| 1954 DCHECK(!transaction); | 2026 DCHECK(!transaction); |
| 1955 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); | 2027 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); |
| 1956 metadata_.version = previous_version; | 2028 metadata_.version = previous_version; |
| 1957 } | 2029 } |
| 1958 | 2030 |
| 1959 } // namespace content | 2031 } // namespace content |
| OLD | NEW |