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_open_request_observer.h" |
32 #include "content/browser/indexed_db/indexed_db_pending_connection.h" | 33 #include "content/browser/indexed_db/indexed_db_pending_connection.h" |
33 #include "content/browser/indexed_db/indexed_db_return_value.h" | 34 #include "content/browser/indexed_db/indexed_db_return_value.h" |
34 #include "content/browser/indexed_db/indexed_db_tracing.h" | 35 #include "content/browser/indexed_db/indexed_db_tracing.h" |
35 #include "content/browser/indexed_db/indexed_db_transaction.h" | 36 #include "content/browser/indexed_db/indexed_db_transaction.h" |
36 #include "content/browser/indexed_db/indexed_db_value.h" | 37 #include "content/browser/indexed_db/indexed_db_value.h" |
37 #include "content/common/indexed_db/indexed_db_constants.h" | 38 #include "content/common/indexed_db/indexed_db_constants.h" |
38 #include "content/common/indexed_db/indexed_db_key_path.h" | 39 #include "content/common/indexed_db/indexed_db_key_path.h" |
39 #include "content/common/indexed_db/indexed_db_key_range.h" | 40 #include "content/common/indexed_db/indexed_db_key_range.h" |
40 #include "content/public/common/content_switches.h" | 41 #include "content/public/common/content_switches.h" |
41 #include "storage/browser/blob/blob_data_handle.h" | 42 #include "storage/browser/blob/blob_data_handle.h" |
(...skipping 29 matching lines...) Expand all Loading... |
71 case blink::WebIDBKeyPathTypeArray: | 72 case blink::WebIDBKeyPathTypeArray: |
72 return KEY_PATH_TYPE_ARRAY; | 73 return KEY_PATH_TYPE_ARRAY; |
73 } | 74 } |
74 NOTREACHED(); | 75 NOTREACHED(); |
75 return KEY_PATH_TYPE_NONE; | 76 return KEY_PATH_TYPE_NONE; |
76 } | 77 } |
77 | 78 |
78 } // namespace | 79 } // namespace |
79 | 80 |
80 // PendingUpgradeCall has a std::unique_ptr<IndexedDBConnection> because it owns | 81 // PendingUpgradeCall has a std::unique_ptr<IndexedDBConnection> because it owns |
81 // the | 82 // the in-progress connection. |
82 // in-progress connection. | |
83 class IndexedDBDatabase::PendingUpgradeCall { | 83 class IndexedDBDatabase::PendingUpgradeCall { |
84 public: | 84 public: |
85 PendingUpgradeCall(scoped_refptr<IndexedDBCallbacks> callbacks, | 85 PendingUpgradeCall(const IndexedDBPendingConnection& pending_connection, |
86 std::unique_ptr<IndexedDBConnection> connection, | 86 std::unique_ptr<IndexedDBConnection> connection) |
87 int64_t transaction_id, | 87 : pending_connection_(pending_connection), |
88 int64_t version) | 88 connection_(std::move(connection)) {} |
89 : callbacks_(callbacks), | 89 const IndexedDBPendingConnection& pending_connection() const { |
90 connection_(std::move(connection)), | 90 return pending_connection_; |
91 version_(version), | 91 } |
92 transaction_id_(transaction_id) {} | 92 void OnBlocked(int64_t old_version) { |
93 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } | 93 pending_connection_.OnBlocked(old_version); |
| 94 } |
94 // Takes ownership of the connection object. | 95 // Takes ownership of the connection object. |
95 std::unique_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT { | 96 std::unique_ptr<IndexedDBConnection> ReleaseConnection() WARN_UNUSED_RESULT { |
96 return std::move(connection_); | 97 return std::move(connection_); |
97 } | 98 } |
98 int64_t version() const { return version_; } | 99 int64_t version() const { return pending_connection_.version(); } |
99 int64_t transaction_id() const { return transaction_id_; } | |
100 | 100 |
101 private: | 101 private: |
102 scoped_refptr<IndexedDBCallbacks> callbacks_; | 102 IndexedDBPendingConnection pending_connection_; |
103 std::unique_ptr<IndexedDBConnection> connection_; | 103 std::unique_ptr<IndexedDBConnection> connection_; |
104 int64_t version_; | |
105 const int64_t transaction_id_; | |
106 }; | 104 }; |
107 | 105 |
108 // PendingSuccessCall has a IndexedDBConnection* because the connection is now | 106 // PendingSuccessCall has a IndexedDBConnection* because the connection is now |
109 // owned elsewhere, but we need to cancel the success call if that connection | 107 // owned elsewhere, but we need to cancel the success call if that connection |
110 // closes before it is sent. | 108 // closes before it is sent. |
111 class IndexedDBDatabase::PendingSuccessCall { | 109 class IndexedDBDatabase::PendingSuccessCall { |
112 public: | 110 public: |
113 PendingSuccessCall(scoped_refptr<IndexedDBCallbacks> callbacks, | 111 PendingSuccessCall(const IndexedDBPendingConnection& pending_connection, |
114 IndexedDBConnection* connection, | 112 IndexedDBConnection* connection) |
115 int64_t version) | 113 : pending_connection_(pending_connection), connection_(connection) {} |
116 : callbacks_(callbacks), connection_(connection), version_(version) {} | 114 void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, |
117 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } | 115 const IndexedDBDatabaseMetadata& metadata) const { |
| 116 // TODO(cmumford): Need to pass in the OpenResultCallback. |
| 117 } |
| 118 void OnError(const IndexedDBDatabaseError& error) const { |
| 119 // TODO(cmumford): Need to pass in the OpenResultCallback. |
| 120 } |
118 IndexedDBConnection* connection() const { return connection_; } | 121 IndexedDBConnection* connection() const { return connection_; } |
119 int64_t version() const { return version_; } | 122 int64_t version() const { return pending_connection_.version(); } |
120 | 123 |
121 private: | 124 private: |
122 scoped_refptr<IndexedDBCallbacks> callbacks_; | 125 IndexedDBPendingConnection pending_connection_; |
123 IndexedDBConnection* connection_; | 126 IndexedDBConnection* connection_; |
124 int64_t version_; | |
125 }; | 127 }; |
126 | 128 |
127 class IndexedDBDatabase::PendingDeleteCall { | 129 class IndexedDBDatabase::PendingDeleteCall { |
128 public: | 130 public: |
129 explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) | 131 explicit PendingDeleteCall(scoped_refptr<IndexedDBCallbacks> callbacks) |
130 : callbacks_(callbacks) {} | 132 : callbacks_(callbacks) {} |
131 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } | 133 scoped_refptr<IndexedDBCallbacks> callbacks() const { return callbacks_; } |
132 | 134 |
133 private: | 135 private: |
134 scoped_refptr<IndexedDBCallbacks> callbacks_; | 136 scoped_refptr<IndexedDBCallbacks> callbacks_; |
(...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1522 } | 1524 } |
1523 | 1525 |
1524 RemoveObjectStore(object_store_id); | 1526 RemoveObjectStore(object_store_id); |
1525 transaction->ScheduleAbortTask( | 1527 transaction->ScheduleAbortTask( |
1526 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, | 1528 base::Bind(&IndexedDBDatabase::DeleteObjectStoreAbortOperation, |
1527 this, | 1529 this, |
1528 object_store_metadata)); | 1530 object_store_metadata)); |
1529 } | 1531 } |
1530 | 1532 |
1531 void IndexedDBDatabase::VersionChangeOperation( | 1533 void IndexedDBDatabase::VersionChangeOperation( |
1532 int64_t version, | 1534 const IndexedDBPendingConnection& pending_connection, |
1533 scoped_refptr<IndexedDBCallbacks> callbacks, | |
1534 std::unique_ptr<IndexedDBConnection> connection, | 1535 std::unique_ptr<IndexedDBConnection> connection, |
1535 IndexedDBTransaction* transaction) { | 1536 IndexedDBTransaction* transaction) { |
1536 IDB_TRACE1( | 1537 IDB_TRACE1( |
1537 "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id()); | 1538 "IndexedDBDatabase::VersionChangeOperation", "txn.id", transaction->id()); |
1538 int64_t old_version = metadata_.version; | 1539 int64_t old_version = metadata_.version; |
1539 DCHECK_GT(version, old_version); | 1540 DCHECK_GT(pending_connection.version(), old_version); |
1540 | 1541 |
1541 if (!backing_store_->UpdateIDBDatabaseIntVersion( | 1542 if (!backing_store_->UpdateIDBDatabaseIntVersion( |
1542 transaction->BackingStoreTransaction(), id(), version)) { | 1543 transaction->BackingStoreTransaction(), id(), |
| 1544 pending_connection.version())) { |
1543 IndexedDBDatabaseError error( | 1545 IndexedDBDatabaseError error( |
1544 blink::WebIDBDatabaseExceptionUnknownError, | 1546 blink::WebIDBDatabaseExceptionUnknownError, |
1545 ASCIIToUTF16( | 1547 ASCIIToUTF16( |
1546 "Internal error writing data to stable storage when " | 1548 "Internal error writing data to stable storage when " |
1547 "updating version.")); | 1549 "updating version.")); |
1548 callbacks->OnError(error); | 1550 pending_connection.OnError(error); |
1549 transaction->Abort(error); | 1551 transaction->Abort(error); |
1550 return; | 1552 return; |
1551 } | 1553 } |
1552 | 1554 |
1553 transaction->ScheduleAbortTask( | 1555 transaction->ScheduleAbortTask( |
1554 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, | 1556 base::Bind(&IndexedDBDatabase::VersionChangeAbortOperation, this, |
1555 metadata_.version)); | 1557 metadata_.version)); |
1556 metadata_.version = version; | 1558 metadata_.version = pending_connection.version(); |
1557 | 1559 |
1558 DCHECK(!pending_second_half_open_); | 1560 DCHECK(!pending_second_half_open_); |
1559 pending_second_half_open_.reset( | 1561 pending_second_half_open_.reset( |
1560 new PendingSuccessCall(callbacks, connection.get(), version)); | 1562 new PendingSuccessCall(pending_connection, connection.get())); |
1561 callbacks->OnUpgradeNeeded(old_version, std::move(connection), metadata()); | 1563 pending_connection.open_observer()->OnUpgradeNeeded( |
| 1564 old_version, connection.get(), metadata()); |
1562 } | 1565 } |
1563 | 1566 |
1564 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, | 1567 void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, |
1565 bool committed) { | 1568 bool committed) { |
1566 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); | 1569 IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); |
1567 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); | 1570 DCHECK(transactions_.find(transaction->id()) != transactions_.end()); |
1568 DCHECK_EQ(transactions_[transaction->id()], transaction); | 1571 DCHECK_EQ(transactions_[transaction->id()], transaction); |
1569 transactions_.erase(transaction->id()); | 1572 transactions_.erase(transaction->id()); |
1570 | 1573 |
1571 if (transaction->mode() == blink::WebIDBTransactionModeVersionChange) { | 1574 if (transaction->mode() == blink::WebIDBTransactionModeVersionChange) { |
1572 if (pending_second_half_open_) { | 1575 if (pending_second_half_open_) { |
1573 if (committed) { | 1576 if (committed) { |
1574 DCHECK_EQ(pending_second_half_open_->version(), metadata_.version); | 1577 DCHECK_EQ(pending_second_half_open_->version(), metadata_.version); |
1575 DCHECK(metadata_.id != kInvalidId); | 1578 DCHECK(metadata_.id != kInvalidId); |
1576 | 1579 |
1577 // Connection was already minted for OnUpgradeNeeded callback. | 1580 // Connection was already minted for OnUpgradeNeeded callback. |
1578 std::unique_ptr<IndexedDBConnection> connection; | 1581 std::unique_ptr<IndexedDBConnection> connection; |
1579 pending_second_half_open_->callbacks()->OnSuccess(std::move(connection), | 1582 pending_second_half_open_->OnSuccess(std::move(connection), |
1580 this->metadata()); | 1583 this->metadata()); |
1581 } else { | 1584 } else { |
1582 pending_second_half_open_->callbacks()->OnError( | 1585 pending_second_half_open_->OnError( |
1583 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, | 1586 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, |
1584 "Version change transaction was aborted in " | 1587 "Version change transaction was aborted in " |
1585 "upgradeneeded event handler.")); | 1588 "upgradeneeded event handler.")); |
1586 } | 1589 } |
1587 pending_second_half_open_.reset(); | 1590 pending_second_half_open_.reset(); |
1588 } | 1591 } |
1589 | 1592 |
1590 // Connection queue is now unblocked. | 1593 // Connection queue is now unblocked. |
1591 ProcessPendingCalls(); | 1594 ProcessPendingCalls(); |
1592 } | 1595 } |
(...skipping 30 matching lines...) Expand all Loading... |
1623 size_t IndexedDBDatabase::PendingDeleteCount() const { | 1626 size_t IndexedDBDatabase::PendingDeleteCount() const { |
1624 return pending_delete_calls_.size(); | 1627 return pending_delete_calls_.size(); |
1625 } | 1628 } |
1626 | 1629 |
1627 void IndexedDBDatabase::ProcessPendingCalls() { | 1630 void IndexedDBDatabase::ProcessPendingCalls() { |
1628 if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { | 1631 if (pending_run_version_change_transaction_call_ && ConnectionCount() == 1) { |
1629 DCHECK(pending_run_version_change_transaction_call_->version() > | 1632 DCHECK(pending_run_version_change_transaction_call_->version() > |
1630 metadata_.version); | 1633 metadata_.version); |
1631 std::unique_ptr<PendingUpgradeCall> pending_call = | 1634 std::unique_ptr<PendingUpgradeCall> pending_call = |
1632 std::move(pending_run_version_change_transaction_call_); | 1635 std::move(pending_run_version_change_transaction_call_); |
1633 RunVersionChangeTransactionFinal(pending_call->callbacks(), | 1636 RunVersionChangeTransactionFinal(pending_call->pending_connection(), |
1634 pending_call->ReleaseConnection(), | 1637 pending_call->ReleaseConnection()); |
1635 pending_call->transaction_id(), | |
1636 pending_call->version()); | |
1637 DCHECK_EQ(1u, ConnectionCount()); | 1638 DCHECK_EQ(1u, ConnectionCount()); |
1638 // Fall through would be a no-op, since transaction must complete | 1639 // Fall through would be a no-op, since transaction must complete |
1639 // asynchronously. | 1640 // asynchronously. |
1640 DCHECK(IsUpgradeRunning()); | 1641 DCHECK(IsUpgradeRunning()); |
1641 DCHECK(IsDeleteDatabaseBlocked()); | 1642 DCHECK(IsDeleteDatabaseBlocked()); |
1642 DCHECK(IsOpenConnectionBlocked()); | 1643 DCHECK(IsOpenConnectionBlocked()); |
1643 return; | 1644 return; |
1644 } | 1645 } |
1645 | 1646 |
1646 if (IsUpgradeRunning()) { | 1647 if (IsUpgradeRunning()) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 | 1729 |
1729 bool IndexedDBDatabase::IsUpgradePendingOrRunning() const { | 1730 bool IndexedDBDatabase::IsUpgradePendingOrRunning() const { |
1730 return pending_run_version_change_transaction_call_ || IsUpgradeRunning(); | 1731 return pending_run_version_change_transaction_call_ || IsUpgradeRunning(); |
1731 } | 1732 } |
1732 | 1733 |
1733 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { | 1734 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { |
1734 return IsUpgradePendingOrRunning() || !blocked_delete_calls_.empty(); | 1735 return IsUpgradePendingOrRunning() || !blocked_delete_calls_.empty(); |
1735 } | 1736 } |
1736 | 1737 |
1737 void IndexedDBDatabase::OpenConnection( | 1738 void IndexedDBDatabase::OpenConnection( |
1738 const IndexedDBPendingConnection& connection) { | 1739 const IndexedDBPendingConnection& requested_connection) { |
1739 DCHECK(backing_store_.get()); | 1740 DCHECK(backing_store_.get()); |
1740 | 1741 |
| 1742 IndexedDBPendingConnection pending_connection(requested_connection); |
| 1743 |
1741 if (IsOpenConnectionBlocked()) { | 1744 if (IsOpenConnectionBlocked()) { |
1742 // The backing store only detects data loss when it is first opened. The | 1745 // The backing store only detects data loss when it is first opened. The |
1743 // presence of existing connections means we didn't even check for data loss | 1746 // presence of existing connections means we didn't even check for data loss |
1744 // so there'd better not be any. | 1747 // so there'd better not be any. |
1745 DCHECK_NE(blink::WebIDBDataLossTotal, connection.callbacks->data_loss()); | 1748 DCHECK_NE(blink::WebIDBDataLossTotal, requested_connection.data_loss()); |
1746 pending_open_calls_.push(connection); | 1749 pending_open_calls_.push(requested_connection); |
1747 return; | 1750 return; |
1748 } | 1751 } |
1749 | 1752 |
1750 if (metadata_.id == kInvalidId) { | 1753 if (metadata_.id == kInvalidId) { |
1751 // The database was deleted then immediately re-opened; OpenInternal() | 1754 // The database was deleted then immediately re-opened; OpenInternal() |
1752 // recreates it in the backing store. | 1755 // recreates it in the backing store. |
1753 if (OpenInternal().ok()) { | 1756 if (OpenInternal().ok()) { |
1754 DCHECK_EQ(IndexedDBDatabaseMetadata::NO_VERSION, metadata_.version); | 1757 DCHECK_EQ(IndexedDBDatabaseMetadata::NO_VERSION, metadata_.version); |
1755 } else { | 1758 } else { |
1756 base::string16 message; | 1759 base::string16 message; |
1757 if (connection.version == IndexedDBDatabaseMetadata::NO_VERSION) { | 1760 if (pending_connection.version() == |
| 1761 IndexedDBDatabaseMetadata::NO_VERSION) { |
1758 message = ASCIIToUTF16( | 1762 message = ASCIIToUTF16( |
1759 "Internal error opening database with no version specified."); | 1763 "Internal error opening database with no version specified."); |
1760 } else { | 1764 } else { |
1761 message = | 1765 message = |
1762 ASCIIToUTF16("Internal error opening database with version ") + | 1766 ASCIIToUTF16("Internal error opening database with version ") + |
1763 Int64ToString16(connection.version); | 1767 Int64ToString16(pending_connection.version()); |
1764 } | 1768 } |
1765 connection.callbacks->OnError(IndexedDBDatabaseError( | 1769 pending_connection.OnError(IndexedDBDatabaseError( |
1766 blink::WebIDBDatabaseExceptionUnknownError, message)); | 1770 blink::WebIDBDatabaseExceptionUnknownError, message)); |
1767 return; | 1771 return; |
1768 } | 1772 } |
1769 } | 1773 } |
1770 | 1774 |
1771 // We infer that the database didn't exist from its lack of either type of | 1775 // We infer that the database didn't exist from its lack of either type of |
1772 // version. | 1776 // version. |
1773 bool is_new_database = | 1777 bool is_new_database = |
1774 metadata_.version == IndexedDBDatabaseMetadata::NO_VERSION; | 1778 metadata_.version == IndexedDBDatabaseMetadata::NO_VERSION; |
1775 | 1779 |
1776 if (connection.version == IndexedDBDatabaseMetadata::DEFAULT_VERSION) { | 1780 if (pending_connection.version() == |
| 1781 IndexedDBDatabaseMetadata::DEFAULT_VERSION) { |
1777 // For unit tests only - skip upgrade steps. Calling from script with | 1782 // For unit tests only - skip upgrade steps. Calling from script with |
1778 // DEFAULT_VERSION throws exception. | 1783 // DEFAULT_VERSION throws exception. |
1779 // TODO(jsbell): DCHECK that not in unit tests. | 1784 // TODO(jsbell): DCHECK that not in unit tests. |
1780 DCHECK(is_new_database); | 1785 DCHECK(is_new_database); |
1781 connection.callbacks->OnSuccess( | 1786 pending_connection.OnSuccess( |
1782 CreateConnection(connection.database_callbacks, | 1787 CreateConnection(pending_connection.database_callbacks(), |
1783 connection.child_process_id), | 1788 pending_connection.child_process_id()), |
1784 this->metadata()); | 1789 this->metadata()); |
1785 return; | 1790 return; |
1786 } | 1791 } |
1787 | 1792 |
1788 // We may need to change the version. | 1793 // We may need to change the version. |
1789 int64_t local_version = connection.version; | 1794 if (pending_connection.version() == IndexedDBDatabaseMetadata::NO_VERSION) { |
1790 if (local_version == IndexedDBDatabaseMetadata::NO_VERSION) { | |
1791 if (!is_new_database) { | 1795 if (!is_new_database) { |
1792 connection.callbacks->OnSuccess( | 1796 pending_connection.OnSuccess( |
1793 CreateConnection(connection.database_callbacks, | 1797 CreateConnection(pending_connection.database_callbacks(), |
1794 connection.child_process_id), | 1798 pending_connection.child_process_id()), |
1795 this->metadata()); | 1799 this->metadata()); |
1796 return; | 1800 return; |
1797 } | 1801 } |
1798 // Spec says: If no version is specified and no database exists, set | 1802 // Spec says: If no version is specified and no database exists, set |
1799 // database version to 1. | 1803 // database version to 1. |
1800 local_version = 1; | 1804 pending_connection.SetVersion(1); |
1801 } | 1805 } |
1802 | 1806 |
1803 if (local_version > metadata_.version) { | 1807 if (pending_connection.version() > metadata_.version) { |
1804 RunVersionChangeTransaction(connection.callbacks, | 1808 RunVersionChangeTransaction( |
1805 CreateConnection(connection.database_callbacks, | 1809 pending_connection, |
1806 connection.child_process_id), | 1810 CreateConnection(pending_connection.database_callbacks(), |
1807 connection.transaction_id, | 1811 pending_connection.child_process_id())); |
1808 local_version); | |
1809 return; | 1812 return; |
1810 } | 1813 } |
1811 if (local_version < metadata_.version) { | 1814 if (pending_connection.version() < metadata_.version) { |
1812 connection.callbacks->OnError(IndexedDBDatabaseError( | 1815 pending_connection.OnError(IndexedDBDatabaseError( |
1813 blink::WebIDBDatabaseExceptionVersionError, | 1816 blink::WebIDBDatabaseExceptionVersionError, |
1814 ASCIIToUTF16("The requested version (") + | 1817 ASCIIToUTF16("The requested version (") + |
1815 Int64ToString16(local_version) + | 1818 Int64ToString16(pending_connection.version()) + |
1816 ASCIIToUTF16(") is less than the existing version (") + | 1819 ASCIIToUTF16(") is less than the existing version (") + |
1817 Int64ToString16(metadata_.version) + ASCIIToUTF16(")."))); | 1820 Int64ToString16(metadata_.version) + ASCIIToUTF16(")."))); |
1818 return; | 1821 return; |
1819 } | 1822 } |
1820 DCHECK_EQ(local_version, metadata_.version); | 1823 DCHECK_EQ(pending_connection.version(), metadata_.version); |
1821 connection.callbacks->OnSuccess( | 1824 pending_connection.OnSuccess( |
1822 CreateConnection(connection.database_callbacks, | 1825 CreateConnection(pending_connection.database_callbacks(), |
1823 connection.child_process_id), | 1826 pending_connection.child_process_id()), |
1824 this->metadata()); | 1827 this->metadata()); |
1825 } | 1828 } |
1826 | 1829 |
1827 void IndexedDBDatabase::RunVersionChangeTransaction( | 1830 void IndexedDBDatabase::RunVersionChangeTransaction( |
1828 scoped_refptr<IndexedDBCallbacks> callbacks, | 1831 const IndexedDBPendingConnection& pending_connection, |
1829 std::unique_ptr<IndexedDBConnection> connection, | 1832 std::unique_ptr<IndexedDBConnection> connection) { |
1830 int64_t transaction_id, | |
1831 int64_t requested_version) { | |
1832 DCHECK(callbacks.get()); | |
1833 DCHECK(connections_.count(connection.get())); | 1833 DCHECK(connections_.count(connection.get())); |
1834 if (ConnectionCount() > 1) { | 1834 if (ConnectionCount() > 1) { |
1835 DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss()); | 1835 // TODO(cmumford): Replace this check? |
| 1836 // DCHECK_NE(blink::WebIDBDataLossTotal, callbacks->data_loss()); |
1836 // Front end ensures the event is not fired at connections that have | 1837 // Front end ensures the event is not fired at connections that have |
1837 // close_pending set. | 1838 // close_pending set. |
1838 for (const auto* iter : connections_) { | 1839 for (const auto* iter : connections_) { |
1839 if (iter != connection.get()) { | 1840 if (iter != connection.get()) { |
1840 iter->callbacks()->OnVersionChange(metadata_.version, | 1841 iter->callbacks()->OnVersionChange(metadata_.version, |
1841 requested_version); | 1842 pending_connection.version()); |
1842 } | 1843 } |
1843 } | 1844 } |
1844 // OnBlocked will be fired at the request when one of the other | 1845 // OnBlocked will be fired at the request when one of the other |
1845 // connections acks that the OnVersionChange was ignored. | 1846 // connections acks that the OnVersionChange was ignored. |
1846 | 1847 |
1847 DCHECK(!pending_run_version_change_transaction_call_); | 1848 DCHECK(!pending_run_version_change_transaction_call_); |
1848 pending_run_version_change_transaction_call_.reset(new PendingUpgradeCall( | 1849 pending_run_version_change_transaction_call_.reset( |
1849 callbacks, std::move(connection), transaction_id, requested_version)); | 1850 new PendingUpgradeCall(pending_connection, std::move(connection))); |
1850 return; | 1851 return; |
1851 } | 1852 } |
1852 RunVersionChangeTransactionFinal(callbacks, std::move(connection), | 1853 RunVersionChangeTransactionFinal(pending_connection, std::move(connection)); |
1853 transaction_id, requested_version); | |
1854 } | 1854 } |
1855 | 1855 |
1856 void IndexedDBDatabase::RunVersionChangeTransactionFinal( | 1856 void IndexedDBDatabase::RunVersionChangeTransactionFinal( |
1857 scoped_refptr<IndexedDBCallbacks> callbacks, | 1857 const IndexedDBPendingConnection& pending_connection, |
1858 std::unique_ptr<IndexedDBConnection> connection, | 1858 std::unique_ptr<IndexedDBConnection> connection) { |
1859 int64_t transaction_id, | |
1860 int64_t requested_version) { | |
1861 std::vector<int64_t> object_store_ids; | 1859 std::vector<int64_t> object_store_ids; |
1862 CreateTransaction(transaction_id, | 1860 CreateTransaction(pending_connection.transaction_id(), connection.get(), |
1863 connection.get(), | |
1864 object_store_ids, | 1861 object_store_ids, |
1865 blink::WebIDBTransactionModeVersionChange); | 1862 blink::WebIDBTransactionModeVersionChange); |
1866 | 1863 |
1867 DCHECK(transaction_coordinator_.IsRunningVersionChangeTransaction()); | 1864 DCHECK(transaction_coordinator_.IsRunningVersionChangeTransaction()); |
1868 transactions_[transaction_id]->ScheduleTask( | 1865 transactions_[pending_connection.transaction_id()]->ScheduleTask( |
1869 base::Bind(&IndexedDBDatabase::VersionChangeOperation, | 1866 base::Bind(&IndexedDBDatabase::VersionChangeOperation, this, |
1870 this, | 1867 pending_connection, base::Passed(&connection))); |
1871 requested_version, | |
1872 callbacks, | |
1873 base::Passed(&connection))); | |
1874 DCHECK(!pending_second_half_open_); | 1868 DCHECK(!pending_second_half_open_); |
1875 } | 1869 } |
1876 | 1870 |
1877 void IndexedDBDatabase::DeleteDatabase( | 1871 void IndexedDBDatabase::DeleteDatabase( |
1878 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1872 scoped_refptr<IndexedDBCallbacks> callbacks) { |
1879 // If there's a running upgrade, the delete calls should be deferred so that | 1873 // If there's a running upgrade, the delete calls should be deferred so that |
1880 // "versionchange" is seen after "success" fires. | 1874 // "versionchange" is seen after "success" fires. |
1881 if (IsUpgradeRunning()) { | 1875 if (IsUpgradeRunning()) { |
1882 pending_delete_calls_.push_back( | 1876 pending_delete_calls_.push_back( |
1883 std::unique_ptr<PendingDeleteCall>(new PendingDeleteCall(callbacks))); | 1877 std::unique_ptr<PendingDeleteCall>(new PendingDeleteCall(callbacks))); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1930 } | 1924 } |
1931 | 1925 |
1932 void IndexedDBDatabase::ForceClose() { | 1926 void IndexedDBDatabase::ForceClose() { |
1933 // IndexedDBConnection::ForceClose() may delete this database, so hold ref. | 1927 // IndexedDBConnection::ForceClose() may delete this database, so hold ref. |
1934 scoped_refptr<IndexedDBDatabase> protect(this); | 1928 scoped_refptr<IndexedDBDatabase> protect(this); |
1935 ConnectionSet::const_iterator it = connections_.begin(); | 1929 ConnectionSet::const_iterator it = connections_.begin(); |
1936 while (it != connections_.end()) { | 1930 while (it != connections_.end()) { |
1937 IndexedDBConnection* connection = *it++; | 1931 IndexedDBConnection* connection = *it++; |
1938 connection->ForceClose(); | 1932 connection->ForceClose(); |
1939 } | 1933 } |
| 1934 |
1940 DCHECK(connections_.empty()); | 1935 DCHECK(connections_.empty()); |
1941 } | 1936 } |
1942 | 1937 |
1943 void IndexedDBDatabase::VersionChangeIgnored() { | 1938 void IndexedDBDatabase::VersionChangeIgnored() { |
1944 if (pending_run_version_change_transaction_call_) { | 1939 if (pending_run_version_change_transaction_call_) { |
1945 pending_run_version_change_transaction_call_->callbacks()->OnBlocked( | 1940 pending_run_version_change_transaction_call_->OnBlocked( |
1946 metadata_.version); | 1941 metadata_.version); |
1947 } | 1942 } |
1948 | 1943 |
1949 for (const auto& pending_delete_call : blocked_delete_calls_) | 1944 for (const auto& pending_delete_call : blocked_delete_calls_) |
1950 pending_delete_call->callbacks()->OnBlocked(metadata_.version); | 1945 pending_delete_call->callbacks()->OnBlocked(metadata_.version); |
1951 } | 1946 } |
1952 | 1947 |
1953 void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { | 1948 void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { |
1954 DCHECK(connections_.count(connection)); | 1949 DCHECK(connections_.count(connection)); |
1955 DCHECK(connection->IsConnected()); | 1950 DCHECK(connection->IsConnected()); |
(...skipping 12 matching lines...) Expand all Loading... |
1968 for (const auto& it : transactions) { | 1963 for (const auto& it : transactions) { |
1969 if (it.second->callbacks() == connection->callbacks()) | 1964 if (it.second->callbacks() == connection->callbacks()) |
1970 it.second->Abort( | 1965 it.second->Abort( |
1971 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 1966 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
1972 "Connection is closing.")); | 1967 "Connection is closing.")); |
1973 } | 1968 } |
1974 } | 1969 } |
1975 | 1970 |
1976 if (pending_second_half_open_ && | 1971 if (pending_second_half_open_ && |
1977 pending_second_half_open_->connection() == connection) { | 1972 pending_second_half_open_->connection() == connection) { |
1978 pending_second_half_open_->callbacks()->OnError( | 1973 pending_second_half_open_->OnError( |
1979 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, | 1974 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionAbortError, |
1980 "The connection was closed.")); | 1975 "The connection was closed.")); |
1981 pending_second_half_open_.reset(); | 1976 pending_second_half_open_.reset(); |
1982 } | 1977 } |
1983 | 1978 |
1984 ProcessPendingCalls(); | 1979 ProcessPendingCalls(); |
1985 | 1980 |
1986 // TODO(jsbell): Add a test for the pending_open_calls_ cases below. | 1981 // TODO(jsbell): Add a test for the pending_open_calls_ cases below. |
1987 if (!ConnectionCount() && pending_open_calls_.empty() && | 1982 if (!ConnectionCount() && pending_open_calls_.empty() && |
1988 blocked_delete_calls_.empty()) { | 1983 blocked_delete_calls_.empty()) { |
(...skipping 22 matching lines...) Expand all Loading... |
2011 | 2006 |
2012 void IndexedDBDatabase::VersionChangeAbortOperation( | 2007 void IndexedDBDatabase::VersionChangeAbortOperation( |
2013 int64_t previous_version, | 2008 int64_t previous_version, |
2014 IndexedDBTransaction* transaction) { | 2009 IndexedDBTransaction* transaction) { |
2015 DCHECK(!transaction); | 2010 DCHECK(!transaction); |
2016 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); | 2011 IDB_TRACE("IndexedDBDatabase::VersionChangeAbortOperation"); |
2017 metadata_.version = previous_version; | 2012 metadata_.version = previous_version; |
2018 } | 2013 } |
2019 | 2014 |
2020 } // namespace content | 2015 } // namespace content |
OLD | NEW |