OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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_connection.h" | 5 #include "content/browser/indexed_db/indexed_db_connection.h" |
6 | 6 |
| 7 #include <utility> |
| 8 |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
8 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "content/browser/indexed_db/database_factory_impl.h" |
| 12 #include "content/public/browser/indexed_db_context.h" |
| 13 #include "storage/browser/quota/quota_manager_proxy.h" |
| 14 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" |
| 15 |
| 16 using ::indexed_db::mojom::BlobInfoPtr; |
| 17 using ::indexed_db::mojom::CursorDirection; |
| 18 using ::indexed_db::mojom::KeyPtr; |
| 19 using ::indexed_db::mojom::KeyRangePtr; |
| 20 using ::indexed_db::mojom::PutMode; |
| 21 using ::indexed_db::mojom::TaskType; |
| 22 using ::indexed_db::mojom::TransactionMode; |
9 | 23 |
10 namespace content { | 24 namespace content { |
11 | 25 |
12 IndexedDBConnection::IndexedDBConnection( | 26 IndexedDBConnection::IndexedDBConnection( |
13 scoped_refptr<IndexedDBDatabase> database, | 27 scoped_refptr<IndexedDBDatabase> database, |
14 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks) | 28 scoped_refptr<IndexedDBChangeHandler> change_handler) |
15 : database_(database), callbacks_(callbacks), weak_factory_(this) {} | 29 : database_(database), |
| 30 change_handler_(change_handler), |
| 31 weak_factory_(this) { |
| 32 change_handler->SetConnection(GetWeakPtr()); |
| 33 } |
16 | 34 |
17 IndexedDBConnection::~IndexedDBConnection() {} | 35 IndexedDBConnection::~IndexedDBConnection() {} |
18 | 36 |
19 void IndexedDBConnection::set_id(int32_t id) { | 37 void IndexedDBConnection::set_id(int32_t id) { |
20 DCHECK_EQ(id_, kInvalidId); | 38 DCHECK_EQ(id_, kInvalidId); |
21 id_ = id; | 39 id_ = id; |
22 } | 40 } |
23 | 41 |
| 42 void IndexedDBConnection::ForceClose() { |
| 43 if (!change_handler_.get()) |
| 44 return; |
| 45 |
| 46 // IndexedDBDatabase::Close() can delete this instance. |
| 47 base::WeakPtr<IndexedDBConnection> this_obj = weak_factory_.GetWeakPtr(); |
| 48 scoped_refptr<IndexedDBChangeHandler> change_handler(change_handler_); |
| 49 database_->Close(this, true /* forced */); |
| 50 if (this_obj) { |
| 51 database_ = nullptr; |
| 52 change_handler_ = nullptr; |
| 53 active_observers_.clear(); |
| 54 } |
| 55 change_handler->OnForcedClose(); |
| 56 } |
| 57 |
| 58 bool IndexedDBConnection::IsConnected() { |
| 59 return database_.get() != NULL; |
| 60 } |
| 61 |
| 62 void IndexedDBConnection::CreateObjectStore(int64_t transaction_id, |
| 63 int64_t object_store_id, |
| 64 const std::string& name, |
| 65 const IndexedDBKeyPath& key_path, |
| 66 bool auto_increment) {} |
| 67 |
| 68 void IndexedDBConnection::DeleteObjectStore(int64_t transaction_id, |
| 69 int64_t object_store_id) {} |
| 70 |
| 71 void IndexedDBConnection::CreateTransaction(int64_t transaction_id, |
| 72 const std::vector<int64_t>& scope, |
| 73 TransactionMode transaction_mode) {} |
| 74 |
24 void IndexedDBConnection::Close() { | 75 void IndexedDBConnection::Close() { |
25 if (!callbacks_.get()) | 76 if (!change_handler_.get()) |
26 return; | 77 return; |
27 base::WeakPtr<IndexedDBConnection> this_obj = weak_factory_.GetWeakPtr(); | 78 base::WeakPtr<IndexedDBConnection> this_obj = weak_factory_.GetWeakPtr(); |
28 database_->Close(this, false /* forced */); | 79 database_->Close(this, false /* forced */); |
29 if (this_obj) { | 80 if (this_obj) { |
30 database_ = nullptr; | 81 database_ = nullptr; |
31 callbacks_ = nullptr; | 82 change_handler_ = nullptr; |
32 active_observers_.clear(); | 83 active_observers_.clear(); |
33 } | 84 } |
34 } | 85 } |
35 | 86 |
36 void IndexedDBConnection::ForceClose() { | |
37 if (!callbacks_.get()) | |
38 return; | |
39 | |
40 // IndexedDBDatabase::Close() can delete this instance. | |
41 base::WeakPtr<IndexedDBConnection> this_obj = weak_factory_.GetWeakPtr(); | |
42 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks(callbacks_); | |
43 database_->Close(this, true /* forced */); | |
44 if (this_obj) { | |
45 database_ = nullptr; | |
46 callbacks_ = nullptr; | |
47 active_observers_.clear(); | |
48 } | |
49 callbacks->OnForcedClose(); | |
50 } | |
51 | |
52 void IndexedDBConnection::VersionChangeIgnored() { | 87 void IndexedDBConnection::VersionChangeIgnored() { |
53 if (!database_.get()) | 88 if (!database_.get()) |
54 return; | 89 return; |
55 database_->VersionChangeIgnored(); | 90 database_->VersionChangeIgnored(); |
56 } | 91 } |
57 | 92 |
58 bool IndexedDBConnection::IsConnected() { | 93 void IndexedDBConnection::Abort(int64_t transaction_id) {} |
59 return database_.get() != NULL; | 94 |
| 95 void IndexedDBConnection::OnGotUsageAndQuotaForCommit( |
| 96 int64_t transaction_id, |
| 97 storage::QuotaStatusCode status, |
| 98 int64_t usage, |
| 99 int64_t quota) { |
| 100 DCHECK(context()->TaskRunner()->RunsTasksOnCurrentThread()); |
| 101 // May have disconnected while quota check was pending. |
| 102 if (!IsConnected()) |
| 103 return; |
| 104 // May have aborted while quota check was pending. |
| 105 if (!base::ContainsKey(transaction_id_to_size_, transaction_id)) |
| 106 return; |
| 107 int64_t transaction_size = transaction_id_to_size_[transaction_id]; |
| 108 |
| 109 if (status == storage::kQuotaStatusOk && usage + transaction_size <= quota) { |
| 110 database()->Commit(transaction_id); |
| 111 } else { |
| 112 database()->Abort( |
| 113 transaction_id, |
| 114 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionQuotaError)); |
| 115 } |
| 116 } |
| 117 |
| 118 void IndexedDBConnection::Commit(int64_t transaction_id) { |
| 119 if (!IsConnected()) |
| 120 return; |
| 121 |
| 122 // May have been aborted by back end before front-end could request commit. |
| 123 if (!base::ContainsKey(transaction_id_to_size_, transaction_id)) |
| 124 return; |
| 125 int64_t transaction_size = transaction_id_to_size_[transaction_id]; |
| 126 |
| 127 // Always allow empty or delete-only transactions. |
| 128 if (!transaction_size) { |
| 129 database()->Commit(transaction_id); |
| 130 return; |
| 131 } |
| 132 |
| 133 context()->quota_manager_proxy()->GetUsageAndQuota( |
| 134 context()->TaskRunner(), |
| 135 GURL(transaction_id_to_origin_[transaction_id].Serialize()), |
| 136 storage::kStorageTypeTemporary, |
| 137 base::Bind(&IndexedDBConnection::OnGotUsageAndQuotaForCommit, |
| 138 weak_factory_.GetWeakPtr(), transaction_id)); |
| 139 } |
| 140 |
| 141 void IndexedDBConnection::CreateIndex(int64_t transaction_id, |
| 142 int64_t object_store_id, |
| 143 int64_t index_id, |
| 144 const std::string& name, |
| 145 const IndexedDBKeyPath& key_path, |
| 146 bool unique, |
| 147 bool multi_entry) {} |
| 148 |
| 149 void IndexedDBConnection::DeleteIndex(int64_t transaction_id, |
| 150 int64_t object_store_id, |
| 151 int64_t index_id) {} |
| 152 |
| 153 void IndexedDBConnection::Get(int64_t transaction_id, |
| 154 int64_t object_store_id, |
| 155 int64_t index_id, |
| 156 KeyRangePtr key_range, |
| 157 bool key_only, |
| 158 const GetCallback& callback) { |
| 159 if (!IsConnected()) |
| 160 return; |
| 161 |
| 162 #if 0 |
| 163 connection->database()->Get( |
| 164 HostTransactionId(transaction_id), object_store_id, |
| 165 index_id, |
| 166 base::WrapUnique(new IndexedDBKeyRange(key_range)), |
| 167 params.key_only, callbacks); |
| 168 #endif |
| 169 #if 0 |
| 170 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread()); |
| 171 IndexedDBConnection* connection = |
| 172 parent_->GetOrTerminateProcess(&map_, params.ipc_database_id); |
| 173 if (!connection || !connection->IsConnected()) |
| 174 return; |
| 175 |
| 176 scoped_refptr<IndexedDBCallbacks> callbacks(new IndexedDBCallbacks( |
| 177 parent_, params.ipc_thread_id, params.ipc_callbacks_id)); |
| 178 connection->database()->Get( |
| 179 parent_->HostTransactionId(params.transaction_id), params.object_store_id, |
| 180 params.index_id, |
| 181 base::WrapUnique(new IndexedDBKeyRange(params.key_range)), |
| 182 params.key_only, callbacks); |
| 183 #endif |
| 184 |
| 185 // TODO(cmumford): Set the error data. |
| 186 content::IndexedDBDatabaseError error; |
| 187 // TODO(cmumford): Can we somehow use GetResult::From()? |
| 188 ::indexed_db::mojom::GetResultPtr result = |
| 189 ::indexed_db::mojom::GetResult::New(); |
| 190 result->set_error(error); |
| 191 callback.Run(std::move(result)); |
| 192 } |
| 193 |
| 194 void IndexedDBConnection::GetAll(int64_t transaction_id, |
| 195 int64_t object_store_id, |
| 196 int64_t index_id, |
| 197 KeyRangePtr key_range, |
| 198 int64_t max_count, |
| 199 bool key_only) {} |
| 200 |
| 201 void IndexedDBConnection::Put(int64_t transaction_id, |
| 202 int64_t object_store_id, |
| 203 const std::vector<int8_t>& value, |
| 204 std::vector<BlobInfoPtr> blob_info, |
| 205 KeyPtr key, |
| 206 PutMode put_mode, |
| 207 const std::vector<int64_t>& index_ids, |
| 208 std::vector<std::vector<KeyPtr>> index_keys) {} |
| 209 |
| 210 void IndexedDBConnection::DeleteRange(int64_t transaction_id, |
| 211 int64_t object_store_id, |
| 212 KeyRangePtr key_range) {} |
| 213 |
| 214 void IndexedDBConnection::Clear(int64_t transaction_id, |
| 215 int64_t object_store_id) {} |
| 216 |
| 217 void IndexedDBConnection::SetIndexKeys( |
| 218 int64_t transaction_id, |
| 219 int64_t object_store_id, |
| 220 KeyPtr primary_key, |
| 221 const std::vector<int64_t>& index_ids, |
| 222 std::vector<std::vector<KeyPtr>> index_keys) {} |
| 223 |
| 224 void IndexedDBConnection::SetIndexesReady( |
| 225 int64_t transaction_id, |
| 226 int64_t object_store_id, |
| 227 const std::vector<int64_t>& index_ids) {} |
| 228 |
| 229 void IndexedDBConnection::OpenCursor(int64_t transaction_id, |
| 230 int64_t object_store_id, |
| 231 int64_t index_id, |
| 232 KeyRangePtr key_range, |
| 233 CursorDirection direction, |
| 234 bool key_only, |
| 235 TaskType task_type) {} |
| 236 |
| 237 void IndexedDBConnection::Count(int64_t transaction_id, |
| 238 int64_t object_store_id, |
| 239 int64_t index_id, |
| 240 KeyRangePtr key_range) {} |
| 241 |
| 242 void IndexedDBConnection::AckReceivedBlobs( |
| 243 const std::vector<std::string>& uuids) {} |
| 244 |
| 245 void IndexedDBConnection::Bind(::indexed_db::mojom::DatabaseRequest request) { |
| 246 binding_.AddBinding(this, std::move(request)); |
60 } | 247 } |
61 | 248 |
62 // The observers begin listening to changes only once they are activated. | 249 // The observers begin listening to changes only once they are activated. |
63 void IndexedDBConnection::ActivatePendingObservers( | 250 void IndexedDBConnection::ActivatePendingObservers( |
64 std::vector<std::unique_ptr<IndexedDBObserver>> pending_observers) { | 251 std::vector<std::unique_ptr<IndexedDBObserver>> pending_observers) { |
65 for (auto& observer : pending_observers) { | 252 for (auto& observer : pending_observers) { |
66 active_observers_.push_back(std::move(observer)); | 253 active_observers_.push_back(std::move(observer)); |
67 } | 254 } |
68 pending_observers.clear(); | 255 pending_observers.clear(); |
69 } | 256 } |
70 | 257 |
71 void IndexedDBConnection::RemoveObservers( | 258 void IndexedDBConnection::RemoveObservers( |
72 const std::vector<int32_t>& observer_ids_to_remove) { | 259 const std::vector<int32_t>& observer_ids_to_remove) { |
73 std::vector<int32_t> pending_observer_ids; | 260 std::vector<int32_t> pending_observer_ids; |
74 for (int32_t id_to_remove : observer_ids_to_remove) { | 261 for (int32_t id_to_remove : observer_ids_to_remove) { |
75 const auto& it = std::find_if( | 262 const auto& it = std::find_if( |
76 active_observers_.begin(), active_observers_.end(), | 263 active_observers_.begin(), active_observers_.end(), |
77 [&id_to_remove](const std::unique_ptr<IndexedDBObserver>& o) { | 264 [&id_to_remove](const std::unique_ptr<IndexedDBObserver>& o) { |
78 return o->id() == id_to_remove; | 265 return o->id() == id_to_remove; |
79 }); | 266 }); |
80 if (it != active_observers_.end()) | 267 if (it != active_observers_.end()) |
81 active_observers_.erase(it); | 268 active_observers_.erase(it); |
82 else | 269 else |
83 pending_observer_ids.push_back(id_to_remove); | 270 pending_observer_ids.push_back(id_to_remove); |
84 } | 271 } |
85 if (!pending_observer_ids.empty()) | 272 if (!pending_observer_ids.empty()) |
86 database_->RemovePendingObservers(this, pending_observer_ids); | 273 database_->RemovePendingObservers(this, pending_observer_ids); |
87 } | 274 } |
88 | 275 |
| 276 void IndexedDBConnection::RegisterTransactionId(int64_t transaction_id, |
| 277 const url::Origin& origin) { |
| 278 transaction_id_to_size_[transaction_id] = 0; |
| 279 transaction_id_to_origin_[transaction_id] = origin; |
| 280 } |
| 281 |
| 282 void IndexedDBConnection::FinishTransaction(int64_t transaction_id, |
| 283 bool committed) { |
| 284 if (committed) |
| 285 context()->TransactionComplete(transaction_id_to_origin_[transaction_id]); |
| 286 transaction_id_to_origin_.erase(transaction_id); |
| 287 transaction_id_to_size_.erase(transaction_id); |
| 288 // TODO(cmumford): transaction_id_to_database_id_ is not currently being set. |
| 289 transaction_id_to_database_id_.erase(transaction_id); |
| 290 } |
| 291 |
| 292 IndexedDBContext* IndexedDBConnection::context() const { |
| 293 return database_->context(); |
| 294 } |
| 295 |
89 } // namespace content | 296 } // namespace content |
OLD | NEW |