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 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1013 if (!backing_store_success) { | 1013 if (!backing_store_success) { |
1014 callbacks_->OnError(IndexedDBDatabaseError( | 1014 callbacks_->OnError(IndexedDBDatabaseError( |
1015 WebKit::WebIDBDatabaseExceptionUnknownError, | 1015 WebKit::WebIDBDatabaseExceptionUnknownError, |
1016 "Internal error: backing store error performing put/add.")); | 1016 "Internal error: backing store error performing put/add.")); |
1017 return; | 1017 return; |
1018 } | 1018 } |
1019 | 1019 |
1020 for (size_t i = 0; i < index_writers.size(); ++i) { | 1020 for (size_t i = 0; i < index_writers.size(); ++i) { |
1021 IndexedDBObjectStoreImpl::IndexWriter* index_writer = index_writers[i]; | 1021 IndexedDBObjectStoreImpl::IndexWriter* index_writer = index_writers[i]; |
1022 index_writer->WriteIndexKeys(record_identifier, | 1022 index_writer->WriteIndexKeys(record_identifier, |
1023 backing_store_, | 1023 backing_store_.get(), |
1024 transaction->BackingStoreTransaction(), | 1024 transaction->BackingStoreTransaction(), |
1025 database_id_, | 1025 database_id_, |
1026 object_store_.id); | 1026 object_store_.id); |
1027 } | 1027 } |
1028 | 1028 |
1029 if (object_store_.auto_increment && | 1029 if (object_store_.auto_increment && |
1030 put_mode_ != IndexedDBDatabase::CURSOR_UPDATE && | 1030 put_mode_ != IndexedDBDatabase::CURSOR_UPDATE && |
1031 key->type() == WebIDBKey::NumberType) { | 1031 key->type() == WebIDBKey::NumberType) { |
1032 bool ok = UpdateKeyGenerator(backing_store_, | 1032 bool ok = UpdateKeyGenerator(backing_store_, |
1033 transaction, | 1033 transaction, |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 DCHECK(database_callbacks_set_.has(callbacks)); | 1513 DCHECK(database_callbacks_set_.has(callbacks)); |
1514 | 1514 |
1515 scoped_refptr<IndexedDBTransaction> transaction = | 1515 scoped_refptr<IndexedDBTransaction> transaction = |
1516 IndexedDBTransaction::Create( | 1516 IndexedDBTransaction::Create( |
1517 transaction_id, | 1517 transaction_id, |
1518 callbacks, | 1518 callbacks, |
1519 object_store_ids, | 1519 object_store_ids, |
1520 static_cast<indexed_db::TransactionMode>(mode), | 1520 static_cast<indexed_db::TransactionMode>(mode), |
1521 this); | 1521 this); |
1522 DCHECK(transactions_.find(transaction_id) == transactions_.end()); | 1522 DCHECK(transactions_.find(transaction_id) == transactions_.end()); |
1523 transactions_[transaction_id] = transaction; | 1523 transactions_[transaction_id] = transaction.get(); |
1524 } | 1524 } |
1525 | 1525 |
1526 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { | 1526 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { |
1527 return !pending_delete_calls_.empty() || | 1527 return !pending_delete_calls_.empty() || |
1528 running_version_change_transaction_ || | 1528 running_version_change_transaction_ || |
1529 pending_run_version_change_transaction_call_; | 1529 pending_run_version_change_transaction_call_; |
1530 } | 1530 } |
1531 | 1531 |
1532 void IndexedDBDatabase::OpenConnection( | 1532 void IndexedDBDatabase::OpenConnection( |
1533 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, | 1533 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1610 database_callbacks_set_.insert(database_callbacks); | 1610 database_callbacks_set_.insert(database_callbacks); |
1611 callbacks->OnSuccess(this, this->metadata()); | 1611 callbacks->OnSuccess(this, this->metadata()); |
1612 } | 1612 } |
1613 | 1613 |
1614 void IndexedDBDatabase::RunVersionChangeTransaction( | 1614 void IndexedDBDatabase::RunVersionChangeTransaction( |
1615 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, | 1615 scoped_refptr<IndexedDBCallbacksWrapper> callbacks, |
1616 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, | 1616 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> database_callbacks, |
1617 int64 transaction_id, | 1617 int64 transaction_id, |
1618 int64 requested_version) { | 1618 int64 requested_version) { |
1619 | 1619 |
1620 DCHECK(callbacks); | 1620 DCHECK(callbacks.get()); |
1621 DCHECK(database_callbacks_set_.has(database_callbacks)); | 1621 DCHECK(database_callbacks_set_.has(database_callbacks)); |
1622 if (ConnectionCount() > 1) { | 1622 if (ConnectionCount() > 1) { |
1623 // Front end ensures the event is not fired at connections that have | 1623 // Front end ensures the event is not fired at connections that have |
1624 // close_pending set. | 1624 // close_pending set. |
1625 for (DatabaseCallbacksSet::const_iterator it = | 1625 for (DatabaseCallbacksSet::const_iterator it = |
1626 database_callbacks_set_.begin(); | 1626 database_callbacks_set_.begin(); |
1627 it != database_callbacks_set_.end(); | 1627 it != database_callbacks_set_.end(); |
1628 ++it) { | 1628 ++it) { |
1629 if (*it != database_callbacks.get()) | 1629 if (it->get() != database_callbacks.get()) |
1630 (*it)->OnVersionChange(metadata_.int_version, requested_version); | 1630 (*it)->OnVersionChange(metadata_.int_version, requested_version); |
1631 } | 1631 } |
1632 // TODO(jsbell): Remove the call to on_blocked and instead wait | 1632 // TODO(jsbell): Remove the call to on_blocked and instead wait |
1633 // until the frontend tells us that all the "versionchange" events | 1633 // until the frontend tells us that all the "versionchange" events |
1634 // have been delivered. http://crbug.com/100123 | 1634 // have been delivered. http://crbug.com/100123 |
1635 callbacks->OnBlocked(metadata_.int_version); | 1635 callbacks->OnBlocked(metadata_.int_version); |
1636 | 1636 |
1637 DCHECK(!pending_run_version_change_transaction_call_); | 1637 DCHECK(!pending_run_version_change_transaction_call_); |
1638 pending_run_version_change_transaction_call_.reset(new PendingOpenCall( | 1638 pending_run_version_change_transaction_call_.reset(new PendingOpenCall( |
1639 callbacks, database_callbacks, transaction_id, requested_version)); | 1639 callbacks, database_callbacks, transaction_id, requested_version)); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 DeleteDatabaseFinal(callbacks); | 1692 DeleteDatabaseFinal(callbacks); |
1693 } | 1693 } |
1694 | 1694 |
1695 bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { | 1695 bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { |
1696 return !!ConnectionCount(); | 1696 return !!ConnectionCount(); |
1697 } | 1697 } |
1698 | 1698 |
1699 void IndexedDBDatabase::DeleteDatabaseFinal( | 1699 void IndexedDBDatabase::DeleteDatabaseFinal( |
1700 scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { | 1700 scoped_refptr<IndexedDBCallbacksWrapper> callbacks) { |
1701 DCHECK(!IsDeleteDatabaseBlocked()); | 1701 DCHECK(!IsDeleteDatabaseBlocked()); |
1702 DCHECK(backing_store_); | 1702 DCHECK(backing_store_.get()); |
1703 if (!backing_store_->DeleteDatabase(metadata_.name)) { | 1703 if (!backing_store_->DeleteDatabase(metadata_.name)) { |
1704 callbacks->OnError( | 1704 callbacks->OnError( |
1705 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, | 1705 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, |
1706 "Internal error deleting database.")); | 1706 "Internal error deleting database.")); |
1707 return; | 1707 return; |
1708 } | 1708 } |
1709 metadata_.version = kNoStringVersion; | 1709 metadata_.version = kNoStringVersion; |
1710 metadata_.id = kInvalidId; | 1710 metadata_.id = kInvalidId; |
1711 metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; | 1711 metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; |
1712 metadata_.object_stores.clear(); | 1712 metadata_.object_stores.clear(); |
1713 callbacks->OnSuccess(); | 1713 callbacks->OnSuccess(); |
1714 } | 1714 } |
1715 | 1715 |
1716 void IndexedDBDatabase::Close( | 1716 void IndexedDBDatabase::Close( |
1717 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks) { | 1717 scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks) { |
1718 DCHECK(callbacks); | 1718 DCHECK(callbacks.get()); |
1719 DCHECK(database_callbacks_set_.has(callbacks)); | 1719 DCHECK(database_callbacks_set_.has(callbacks)); |
1720 | 1720 |
1721 // Close outstanding transactions from the closing connection. This | 1721 // Close outstanding transactions from the closing connection. This |
1722 // can not happen if the close is requested by the connection itself | 1722 // can not happen if the close is requested by the connection itself |
1723 // as the front-end defers the close until all transactions are | 1723 // as the front-end defers the close until all transactions are |
1724 // complete, so something unusual has happened e.g. unexpected | 1724 // complete, so something unusual has happened e.g. unexpected |
1725 // process termination. | 1725 // process termination. |
1726 { | 1726 { |
1727 TransactionMap transactions(transactions_); | 1727 TransactionMap transactions(transactions_); |
1728 for (TransactionMap::const_iterator it = transactions.begin(), | 1728 for (TransactionMap::const_iterator it = transactions.begin(), |
1729 end = transactions.end(); | 1729 end = transactions.end(); |
1730 it != end; | 1730 it != end; |
1731 ++it) { | 1731 ++it) { |
1732 if (it->second->connection() == callbacks) | 1732 if (it->second->connection() == callbacks.get()) |
1733 it->second->Abort( | 1733 it->second->Abort( |
1734 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, | 1734 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, |
1735 "Connection is closing.")); | 1735 "Connection is closing.")); |
1736 } | 1736 } |
1737 } | 1737 } |
1738 | 1738 |
1739 database_callbacks_set_.erase(callbacks); | 1739 database_callbacks_set_.erase(callbacks); |
1740 if (pending_second_half_open_ && | 1740 if (pending_second_half_open_ && |
1741 pending_second_half_open_->DatabaseCallbacks() == callbacks) { | 1741 pending_second_half_open_->DatabaseCallbacks().get() == callbacks.get()) { |
1742 pending_second_half_open_->Callbacks()->OnError( | 1742 pending_second_half_open_->Callbacks()->OnError( |
1743 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionAbortError, | 1743 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionAbortError, |
1744 "The connection was closed.")); | 1744 "The connection was closed.")); |
1745 pending_second_half_open_.reset(); | 1745 pending_second_half_open_.reset(); |
1746 } | 1746 } |
1747 | 1747 |
1748 // process_pending_calls allows the inspector to process a pending open call | 1748 // process_pending_calls allows the inspector to process a pending open call |
1749 // and call close, reentering IndexedDBDatabase::close. Then the | 1749 // and call close, reentering IndexedDBDatabase::close. Then the |
1750 // backend would be removed both by the inspector closing its connection, and | 1750 // backend would be removed both by the inspector closing its connection, and |
1751 // by the connection that first called close. | 1751 // by the connection that first called close. |
1752 // To avoid that situation, don't proceed in case of reentrancy. | 1752 // To avoid that situation, don't proceed in case of reentrancy. |
1753 if (closing_connection_) | 1753 if (closing_connection_) |
1754 return; | 1754 return; |
1755 base::AutoReset<bool> ClosingConnection(&closing_connection_, true); | 1755 base::AutoReset<bool> ClosingConnection(&closing_connection_, true); |
1756 ProcessPendingCalls(); | 1756 ProcessPendingCalls(); |
1757 | 1757 |
1758 // TODO(jsbell): Add a test for the pending_open_calls_ cases below. | 1758 // TODO(jsbell): Add a test for the pending_open_calls_ cases below. |
1759 if (!ConnectionCount() && !pending_open_calls_.size() && | 1759 if (!ConnectionCount() && !pending_open_calls_.size() && |
1760 !pending_delete_calls_.size()) { | 1760 !pending_delete_calls_.size()) { |
1761 DCHECK(transactions_.empty()); | 1761 DCHECK(transactions_.empty()); |
1762 | 1762 |
1763 backing_store_ = NULL; | 1763 backing_store_ = NULL; |
1764 | 1764 |
1765 // This check should only be false in unit tests. | 1765 // This check should only be false in unit tests. |
1766 // TODO(jsbell): Assert factory_ || we're executing a unit test. | 1766 // TODO(jsbell): Assert factory_ || we're executing a unit test. |
1767 if (factory_) | 1767 if (factory_.get()) |
1768 factory_->RemoveIDBDatabaseBackend(identifier_); | 1768 factory_->RemoveIDBDatabaseBackend(identifier_); |
1769 } | 1769 } |
1770 } | 1770 } |
1771 | 1771 |
1772 void CreateObjectStoreAbortOperation::Perform( | 1772 void CreateObjectStoreAbortOperation::Perform( |
1773 IndexedDBTransaction* transaction) { | 1773 IndexedDBTransaction* transaction) { |
1774 IDB_TRACE("CreateObjectStoreAbortOperation"); | 1774 IDB_TRACE("CreateObjectStoreAbortOperation"); |
1775 DCHECK(!transaction); | 1775 DCHECK(!transaction); |
1776 database_->RemoveObjectStore(object_store_id_); | 1776 database_->RemoveObjectStore(object_store_id_); |
1777 } | 1777 } |
1778 | 1778 |
1779 void DeleteObjectStoreAbortOperation::Perform( | 1779 void DeleteObjectStoreAbortOperation::Perform( |
1780 IndexedDBTransaction* transaction) { | 1780 IndexedDBTransaction* transaction) { |
1781 IDB_TRACE("DeleteObjectStoreAbortOperation"); | 1781 IDB_TRACE("DeleteObjectStoreAbortOperation"); |
1782 DCHECK(!transaction); | 1782 DCHECK(!transaction); |
1783 database_->AddObjectStore(object_store_metadata_, | 1783 database_->AddObjectStore(object_store_metadata_, |
1784 IndexedDBObjectStoreMetadata::kInvalidId); | 1784 IndexedDBObjectStoreMetadata::kInvalidId); |
1785 } | 1785 } |
1786 | 1786 |
1787 void IndexedDBDatabase::VersionChangeAbortOperation::Perform( | 1787 void IndexedDBDatabase::VersionChangeAbortOperation::Perform( |
1788 IndexedDBTransaction* transaction) { | 1788 IndexedDBTransaction* transaction) { |
1789 IDB_TRACE("VersionChangeAbortOperation"); | 1789 IDB_TRACE("VersionChangeAbortOperation"); |
1790 DCHECK(!transaction); | 1790 DCHECK(!transaction); |
1791 database_->metadata_.version = previous_version_; | 1791 database_->metadata_.version = previous_version_; |
1792 database_->metadata_.int_version = previous_int_version_; | 1792 database_->metadata_.int_version = previous_int_version_; |
1793 } | 1793 } |
1794 | 1794 |
1795 } // namespace content | 1795 } // namespace content |
OLD | NEW |