| 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 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionConstraintError, | 1025 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionConstraintError, |
| 1026 "Key already exists in the object store.")); | 1026 "Key already exists in the object store.")); |
| 1027 return; | 1027 return; |
| 1028 } | 1028 } |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 ScopedVector<IndexWriter> index_writers; | 1031 ScopedVector<IndexWriter> index_writers; |
| 1032 string16 error_message; | 1032 string16 error_message; |
| 1033 bool obeys_constraints = false; | 1033 bool obeys_constraints = false; |
| 1034 bool backing_store_success = MakeIndexWriters(transaction, | 1034 bool backing_store_success = MakeIndexWriters(transaction, |
| 1035 backing_store_.get(), | 1035 backing_store_, |
| 1036 database_id_, | 1036 database_id_, |
| 1037 object_store_, | 1037 object_store_, |
| 1038 *key, | 1038 *key, |
| 1039 key_was_generated, | 1039 key_was_generated, |
| 1040 index_ids_, | 1040 index_ids_, |
| 1041 index_keys_, | 1041 index_keys_, |
| 1042 &index_writers, | 1042 &index_writers, |
| 1043 &error_message, | 1043 &error_message, |
| 1044 &obeys_constraints); | 1044 &obeys_constraints); |
| 1045 if (!backing_store_success) { | 1045 if (!backing_store_success) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1066 if (!backing_store_success) { | 1066 if (!backing_store_success) { |
| 1067 callbacks_->OnError(IndexedDBDatabaseError( | 1067 callbacks_->OnError(IndexedDBDatabaseError( |
| 1068 WebKit::WebIDBDatabaseExceptionUnknownError, | 1068 WebKit::WebIDBDatabaseExceptionUnknownError, |
| 1069 "Internal error: backing store error performing put/add.")); | 1069 "Internal error: backing store error performing put/add.")); |
| 1070 return; | 1070 return; |
| 1071 } | 1071 } |
| 1072 | 1072 |
| 1073 for (size_t i = 0; i < index_writers.size(); ++i) { | 1073 for (size_t i = 0; i < index_writers.size(); ++i) { |
| 1074 IndexWriter* index_writer = index_writers[i]; | 1074 IndexWriter* index_writer = index_writers[i]; |
| 1075 index_writer->WriteIndexKeys(record_identifier, | 1075 index_writer->WriteIndexKeys(record_identifier, |
| 1076 backing_store_.get(), | 1076 backing_store_, |
| 1077 transaction->BackingStoreTransaction(), | 1077 transaction->BackingStoreTransaction(), |
| 1078 database_id_, | 1078 database_id_, |
| 1079 object_store_.id); | 1079 object_store_.id); |
| 1080 } | 1080 } |
| 1081 | 1081 |
| 1082 if (object_store_.auto_increment && | 1082 if (object_store_.auto_increment && |
| 1083 put_mode_ != IndexedDBDatabase::CURSOR_UPDATE && | 1083 put_mode_ != IndexedDBDatabase::CURSOR_UPDATE && |
| 1084 key->type() == WebIDBKey::NumberType) { | 1084 key->type() == WebIDBKey::NumberType) { |
| 1085 bool ok = UpdateKeyGenerator(backing_store_, | 1085 bool ok = UpdateKeyGenerator(backing_store_, |
| 1086 transaction, | 1086 transaction, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 } | 1138 } |
| 1139 | 1139 |
| 1140 ScopedVector<IndexWriter> index_writers; | 1140 ScopedVector<IndexWriter> index_writers; |
| 1141 string16 error_message; | 1141 string16 error_message; |
| 1142 bool obeys_constraints = false; | 1142 bool obeys_constraints = false; |
| 1143 DCHECK(metadata_.object_stores.find(object_store_id) != | 1143 DCHECK(metadata_.object_stores.find(object_store_id) != |
| 1144 metadata_.object_stores.end()); | 1144 metadata_.object_stores.end()); |
| 1145 const IndexedDBObjectStoreMetadata& object_store_metadata = | 1145 const IndexedDBObjectStoreMetadata& object_store_metadata = |
| 1146 metadata_.object_stores[object_store_id]; | 1146 metadata_.object_stores[object_store_id]; |
| 1147 bool backing_store_success = MakeIndexWriters(transaction, | 1147 bool backing_store_success = MakeIndexWriters(transaction, |
| 1148 store.get(), | 1148 store, |
| 1149 id(), | 1149 id(), |
| 1150 object_store_metadata, | 1150 object_store_metadata, |
| 1151 *primary_key, | 1151 *primary_key, |
| 1152 false, | 1152 false, |
| 1153 index_ids, | 1153 index_ids, |
| 1154 index_keys, | 1154 index_keys, |
| 1155 &index_writers, | 1155 &index_writers, |
| 1156 &error_message, | 1156 &error_message, |
| 1157 &obeys_constraints); | 1157 &obeys_constraints); |
| 1158 if (!backing_store_success) { | 1158 if (!backing_store_success) { |
| 1159 transaction->Abort(IndexedDBDatabaseError( | 1159 transaction->Abort(IndexedDBDatabaseError( |
| 1160 WebKit::WebIDBDatabaseExceptionUnknownError, | 1160 WebKit::WebIDBDatabaseExceptionUnknownError, |
| 1161 "Internal error: backing store error updating index keys.")); | 1161 "Internal error: backing store error updating index keys.")); |
| 1162 return; | 1162 return; |
| 1163 } | 1163 } |
| 1164 if (!obeys_constraints) { | 1164 if (!obeys_constraints) { |
| 1165 transaction->Abort(IndexedDBDatabaseError( | 1165 transaction->Abort(IndexedDBDatabaseError( |
| 1166 WebKit::WebIDBDatabaseExceptionConstraintError, error_message)); | 1166 WebKit::WebIDBDatabaseExceptionConstraintError, error_message)); |
| 1167 return; | 1167 return; |
| 1168 } | 1168 } |
| 1169 | 1169 |
| 1170 for (size_t i = 0; i < index_writers.size(); ++i) { | 1170 for (size_t i = 0; i < index_writers.size(); ++i) { |
| 1171 IndexWriter* index_writer = index_writers[i]; | 1171 IndexWriter* index_writer = index_writers[i]; |
| 1172 index_writer->WriteIndexKeys(record_identifier, | 1172 index_writer->WriteIndexKeys(record_identifier, |
| 1173 store.get(), | 1173 store, |
| 1174 transaction->BackingStoreTransaction(), | 1174 transaction->BackingStoreTransaction(), |
| 1175 id(), | 1175 id(), |
| 1176 object_store_id); | 1176 object_store_id); |
| 1177 } | 1177 } |
| 1178 } | 1178 } |
| 1179 | 1179 |
| 1180 void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, | 1180 void IndexedDBDatabase::SetIndexesReady(int64 transaction_id, |
| 1181 int64, | 1181 int64, |
| 1182 const std::vector<int64>& index_ids) { | 1182 const std::vector<int64>& index_ids) { |
| 1183 IDB_TRACE("IndexedDBDatabase::SetIndexesReady"); | 1183 IDB_TRACE("IndexedDBDatabase::SetIndexesReady"); |
| (...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 DCHECK(connections_.has(connection)); | 1562 DCHECK(connections_.has(connection)); |
| 1563 | 1563 |
| 1564 scoped_refptr<IndexedDBTransaction> transaction = | 1564 scoped_refptr<IndexedDBTransaction> transaction = |
| 1565 IndexedDBTransaction::Create( | 1565 IndexedDBTransaction::Create( |
| 1566 transaction_id, | 1566 transaction_id, |
| 1567 connection->callbacks(), | 1567 connection->callbacks(), |
| 1568 object_store_ids, | 1568 object_store_ids, |
| 1569 static_cast<indexed_db::TransactionMode>(mode), | 1569 static_cast<indexed_db::TransactionMode>(mode), |
| 1570 this); | 1570 this); |
| 1571 DCHECK(transactions_.find(transaction_id) == transactions_.end()); | 1571 DCHECK(transactions_.find(transaction_id) == transactions_.end()); |
| 1572 transactions_[transaction_id] = transaction.get(); | 1572 transactions_[transaction_id] = transaction; |
| 1573 } | 1573 } |
| 1574 | 1574 |
| 1575 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { | 1575 bool IndexedDBDatabase::IsOpenConnectionBlocked() const { |
| 1576 return !pending_delete_calls_.empty() || | 1576 return !pending_delete_calls_.empty() || |
| 1577 running_version_change_transaction_ || | 1577 running_version_change_transaction_ || |
| 1578 pending_run_version_change_transaction_call_; | 1578 pending_run_version_change_transaction_call_; |
| 1579 } | 1579 } |
| 1580 | 1580 |
| 1581 void IndexedDBDatabase::OpenConnection( | 1581 void IndexedDBDatabase::OpenConnection( |
| 1582 scoped_refptr<IndexedDBCallbacks> callbacks, | 1582 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1583 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 1583 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
| 1584 int64 transaction_id, | 1584 int64 transaction_id, |
| 1585 int64 version) { | 1585 int64 version) { |
| 1586 const WebKit::WebIDBCallbacks::DataLoss kDataLoss = | 1586 const WebKit::WebIDBCallbacks::DataLoss kDataLoss = |
| 1587 WebKit::WebIDBCallbacks::DataLossNone; | 1587 WebKit::WebIDBCallbacks::DataLossNone; |
| 1588 OpenConnection( | 1588 OpenConnection( |
| 1589 callbacks, database_callbacks, transaction_id, version, kDataLoss); | 1589 callbacks, database_callbacks, transaction_id, version, kDataLoss); |
| 1590 } | 1590 } |
| 1591 | 1591 |
| 1592 void IndexedDBDatabase::OpenConnection( | 1592 void IndexedDBDatabase::OpenConnection( |
| 1593 scoped_refptr<IndexedDBCallbacks> callbacks, | 1593 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1594 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 1594 scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, |
| 1595 int64 transaction_id, | 1595 int64 transaction_id, |
| 1596 int64 version, | 1596 int64 version, |
| 1597 WebKit::WebIDBCallbacks::DataLoss data_loss) { | 1597 WebKit::WebIDBCallbacks::DataLoss data_loss) { |
| 1598 DCHECK(backing_store_.get()); | 1598 DCHECK(backing_store_); |
| 1599 | 1599 |
| 1600 // TODO(jsbell): Should have a priority queue so that higher version | 1600 // TODO(jsbell): Should have a priority queue so that higher version |
| 1601 // requests are processed first. http://crbug.com/225850 | 1601 // requests are processed first. http://crbug.com/225850 |
| 1602 if (IsOpenConnectionBlocked()) { | 1602 if (IsOpenConnectionBlocked()) { |
| 1603 // The backing store only detects data loss when it is first opened. The | 1603 // The backing store only detects data loss when it is first opened. The |
| 1604 // presence of existing connections means we didn't even check for data loss | 1604 // presence of existing connections means we didn't even check for data loss |
| 1605 // so there'd better not be any. | 1605 // so there'd better not be any. |
| 1606 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); | 1606 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); |
| 1607 pending_open_calls_.push_back(new PendingOpenCall( | 1607 pending_open_calls_.push_back(new PendingOpenCall( |
| 1608 callbacks, database_callbacks, transaction_id, version)); | 1608 callbacks, database_callbacks, transaction_id, version)); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1679 callbacks->OnSuccess(connection.Pass(), this->metadata()); | 1679 callbacks->OnSuccess(connection.Pass(), this->metadata()); |
| 1680 } | 1680 } |
| 1681 | 1681 |
| 1682 void IndexedDBDatabase::RunVersionChangeTransaction( | 1682 void IndexedDBDatabase::RunVersionChangeTransaction( |
| 1683 scoped_refptr<IndexedDBCallbacks> callbacks, | 1683 scoped_refptr<IndexedDBCallbacks> callbacks, |
| 1684 scoped_ptr<IndexedDBConnection> connection, | 1684 scoped_ptr<IndexedDBConnection> connection, |
| 1685 int64 transaction_id, | 1685 int64 transaction_id, |
| 1686 int64 requested_version, | 1686 int64 requested_version, |
| 1687 WebKit::WebIDBCallbacks::DataLoss data_loss) { | 1687 WebKit::WebIDBCallbacks::DataLoss data_loss) { |
| 1688 | 1688 |
| 1689 DCHECK(callbacks.get()); | 1689 DCHECK(callbacks); |
| 1690 DCHECK(connections_.has(connection.get())); | 1690 DCHECK(connections_.has(connection.get())); |
| 1691 if (ConnectionCount() > 1) { | 1691 if (ConnectionCount() > 1) { |
| 1692 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); | 1692 DCHECK_NE(WebKit::WebIDBCallbacks::DataLossTotal, data_loss); |
| 1693 // Front end ensures the event is not fired at connections that have | 1693 // Front end ensures the event is not fired at connections that have |
| 1694 // close_pending set. | 1694 // close_pending set. |
| 1695 for (ConnectionSet::const_iterator it = connections_.begin(); | 1695 for (ConnectionSet::const_iterator it = connections_.begin(); |
| 1696 it != connections_.end(); | 1696 it != connections_.end(); |
| 1697 ++it) { | 1697 ++it) { |
| 1698 if (*it != connection.get()) { | 1698 if (*it != connection.get()) { |
| 1699 (*it)->callbacks()->OnVersionChange( | 1699 (*it)->callbacks()->OnVersionChange( |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1781 DeleteDatabaseFinal(callbacks); | 1781 DeleteDatabaseFinal(callbacks); |
| 1782 } | 1782 } |
| 1783 | 1783 |
| 1784 bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { | 1784 bool IndexedDBDatabase::IsDeleteDatabaseBlocked() const { |
| 1785 return !!ConnectionCount(); | 1785 return !!ConnectionCount(); |
| 1786 } | 1786 } |
| 1787 | 1787 |
| 1788 void IndexedDBDatabase::DeleteDatabaseFinal( | 1788 void IndexedDBDatabase::DeleteDatabaseFinal( |
| 1789 scoped_refptr<IndexedDBCallbacks> callbacks) { | 1789 scoped_refptr<IndexedDBCallbacks> callbacks) { |
| 1790 DCHECK(!IsDeleteDatabaseBlocked()); | 1790 DCHECK(!IsDeleteDatabaseBlocked()); |
| 1791 DCHECK(backing_store_.get()); | 1791 DCHECK(backing_store_); |
| 1792 if (!backing_store_->DeleteDatabase(metadata_.name)) { | 1792 if (!backing_store_->DeleteDatabase(metadata_.name)) { |
| 1793 callbacks->OnError( | 1793 callbacks->OnError( |
| 1794 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, | 1794 IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError, |
| 1795 "Internal error deleting database.")); | 1795 "Internal error deleting database.")); |
| 1796 return; | 1796 return; |
| 1797 } | 1797 } |
| 1798 metadata_.version = kNoStringVersion; | 1798 metadata_.version = kNoStringVersion; |
| 1799 metadata_.id = kInvalidId; | 1799 metadata_.id = kInvalidId; |
| 1800 metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; | 1800 metadata_.int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; |
| 1801 metadata_.object_stores.clear(); | 1801 metadata_.object_stores.clear(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1844 | 1844 |
| 1845 // TODO(jsbell): Add a test for the pending_open_calls_ cases below. | 1845 // TODO(jsbell): Add a test for the pending_open_calls_ cases below. |
| 1846 if (!ConnectionCount() && !pending_open_calls_.size() && | 1846 if (!ConnectionCount() && !pending_open_calls_.size() && |
| 1847 !pending_delete_calls_.size()) { | 1847 !pending_delete_calls_.size()) { |
| 1848 DCHECK(transactions_.empty()); | 1848 DCHECK(transactions_.empty()); |
| 1849 | 1849 |
| 1850 backing_store_ = NULL; | 1850 backing_store_ = NULL; |
| 1851 | 1851 |
| 1852 // factory_ should only be null in unit tests. | 1852 // factory_ should only be null in unit tests. |
| 1853 // TODO(jsbell): DCHECK(factory_ || !in_unit_tests) - somehow. | 1853 // TODO(jsbell): DCHECK(factory_ || !in_unit_tests) - somehow. |
| 1854 if (factory_.get()) | 1854 if (factory_) |
| 1855 factory_->RemoveIDBDatabaseBackend(identifier_); | 1855 factory_->RemoveIDBDatabaseBackend(identifier_); |
| 1856 } | 1856 } |
| 1857 } | 1857 } |
| 1858 | 1858 |
| 1859 void CreateObjectStoreAbortOperation::Perform( | 1859 void CreateObjectStoreAbortOperation::Perform( |
| 1860 IndexedDBTransaction* transaction) { | 1860 IndexedDBTransaction* transaction) { |
| 1861 IDB_TRACE("CreateObjectStoreAbortOperation"); | 1861 IDB_TRACE("CreateObjectStoreAbortOperation"); |
| 1862 DCHECK(!transaction); | 1862 DCHECK(!transaction); |
| 1863 database_->RemoveObjectStore(object_store_id_); | 1863 database_->RemoveObjectStore(object_store_id_); |
| 1864 } | 1864 } |
| 1865 | 1865 |
| 1866 void DeleteObjectStoreAbortOperation::Perform( | 1866 void DeleteObjectStoreAbortOperation::Perform( |
| 1867 IndexedDBTransaction* transaction) { | 1867 IndexedDBTransaction* transaction) { |
| 1868 IDB_TRACE("DeleteObjectStoreAbortOperation"); | 1868 IDB_TRACE("DeleteObjectStoreAbortOperation"); |
| 1869 DCHECK(!transaction); | 1869 DCHECK(!transaction); |
| 1870 database_->AddObjectStore(object_store_metadata_, | 1870 database_->AddObjectStore(object_store_metadata_, |
| 1871 IndexedDBObjectStoreMetadata::kInvalidId); | 1871 IndexedDBObjectStoreMetadata::kInvalidId); |
| 1872 } | 1872 } |
| 1873 | 1873 |
| 1874 void IndexedDBDatabase::VersionChangeAbortOperation::Perform( | 1874 void IndexedDBDatabase::VersionChangeAbortOperation::Perform( |
| 1875 IndexedDBTransaction* transaction) { | 1875 IndexedDBTransaction* transaction) { |
| 1876 IDB_TRACE("VersionChangeAbortOperation"); | 1876 IDB_TRACE("VersionChangeAbortOperation"); |
| 1877 DCHECK(!transaction); | 1877 DCHECK(!transaction); |
| 1878 database_->metadata_.version = previous_version_; | 1878 database_->metadata_.version = previous_version_; |
| 1879 database_->metadata_.int_version = previous_int_version_; | 1879 database_->metadata_.int_version = previous_int_version_; |
| 1880 } | 1880 } |
| 1881 | 1881 |
| 1882 } // namespace content | 1882 } // namespace content |
| OLD | NEW |