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_factory_impl.h" | 5 #include "content/browser/indexed_db/indexed_db_factory_impl.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
15 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 15 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
16 #include "content/browser/indexed_db/indexed_db_context_impl.h" | 16 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
17 #include "content/browser/indexed_db/indexed_db_database_error.h" | 17 #include "content/browser/indexed_db/indexed_db_database_error.h" |
| 18 #include "content/browser/indexed_db/indexed_db_pending_connection.h" |
| 19 #include "content/browser/indexed_db/indexed_db_pending_delete.h" |
18 #include "content/browser/indexed_db/indexed_db_tracing.h" | 20 #include "content/browser/indexed_db/indexed_db_tracing.h" |
19 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" | 21 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" |
| 22 #include "net/url_request/url_request_context_getter.h" |
20 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" | 23 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" |
21 #include "third_party/leveldatabase/env_chromium.h" | 24 #include "third_party/leveldatabase/env_chromium.h" |
22 | 25 |
23 using base::ASCIIToUTF16; | 26 using base::ASCIIToUTF16; |
24 using url::Origin; | 27 using url::Origin; |
25 | 28 |
26 namespace content { | 29 namespace content { |
27 | 30 |
28 const int64_t kBackingStoreGracePeriodMs = 2000; | 31 const int64_t kBackingStoreGracePeriodMs = 2000; |
29 | 32 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } else { | 165 } else { |
163 const auto& it = backing_stores_with_active_blobs_.find(origin); | 166 const auto& it = backing_stores_with_active_blobs_.find(origin); |
164 if (it != backing_stores_with_active_blobs_.end()) { | 167 if (it != backing_stores_with_active_blobs_.end()) { |
165 backing_stores_with_active_blobs_.erase(it); | 168 backing_stores_with_active_blobs_.erase(it); |
166 ReleaseBackingStore(origin, false /* immediate */); | 169 ReleaseBackingStore(origin, false /* immediate */); |
167 } | 170 } |
168 } | 171 } |
169 } | 172 } |
170 | 173 |
171 void IndexedDBFactoryImpl::GetDatabaseNames( | 174 void IndexedDBFactoryImpl::GetDatabaseNames( |
172 scoped_refptr<IndexedDBCallbacks> callbacks, | |
173 const Origin& origin, | 175 const Origin& origin, |
174 const base::FilePath& data_directory, | 176 const base::FilePath& data_directory, |
175 scoped_refptr<net::URLRequestContextGetter> request_context_getter) { | 177 scoped_refptr<net::URLRequestContextGetter> request_context_getter) { |
176 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); | 178 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); |
177 // TODO(dgrogan): Plumb data_loss back to script eventually? | 179 // TODO(dgrogan): Plumb data_loss back to script eventually? |
178 IndexedDBDataLossInfo data_loss_info; | 180 IndexedDBDataLossInfo data_loss_info; |
179 bool disk_full; | 181 bool disk_full; |
180 leveldb::Status s; | 182 leveldb::Status s; |
181 // TODO(cmumford): Handle this error | 183 // TODO(cmumford): Handle this error |
182 scoped_refptr<IndexedDBBackingStore> backing_store = | 184 scoped_refptr<IndexedDBBackingStore> backing_store = |
183 OpenBackingStore(origin, data_directory, request_context_getter, | 185 OpenBackingStore(origin, data_directory, request_context_getter, |
184 &data_loss_info, &disk_full, &s); | 186 &data_loss_info, &disk_full, &s); |
185 if (!backing_store.get()) { | 187 if (!backing_store.get()) { |
| 188 #ifdef CJM_NEED_CALLBACK |
186 callbacks->OnError( | 189 callbacks->OnError( |
187 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 190 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
188 "Internal error opening backing store for " | 191 "Internal error opening backing store for " |
189 "indexedDB.webkitGetDatabaseNames.")); | 192 "indexedDB.webkitGetDatabaseNames.")); |
| 193 #endif |
190 return; | 194 return; |
191 } | 195 } |
192 | 196 |
193 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); | 197 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); |
194 if (!s.ok()) { | 198 if (!s.ok()) { |
195 DLOG(ERROR) << "Internal error getting database names"; | 199 DLOG(ERROR) << "Internal error getting database names"; |
196 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 200 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
197 "Internal error opening backing store for " | 201 "Internal error opening backing store for " |
198 "indexedDB.webkitGetDatabaseNames."); | 202 "indexedDB.webkitGetDatabaseNames."); |
| 203 #ifdef CJM_NEED_CALLBACK |
199 callbacks->OnError(error); | 204 callbacks->OnError(error); |
| 205 #endif |
200 backing_store = NULL; | 206 backing_store = NULL; |
201 if (s.IsCorruption()) | 207 if (s.IsCorruption()) |
202 HandleBackingStoreCorruption(origin, error); | 208 HandleBackingStoreCorruption(origin, error); |
203 return; | 209 return; |
204 } | 210 } |
| 211 #ifdef CJM_NEED_CALLBACK |
205 callbacks->OnSuccess(names); | 212 callbacks->OnSuccess(names); |
| 213 #endif |
206 backing_store = NULL; | 214 backing_store = NULL; |
207 ReleaseBackingStore(origin, false /* immediate */); | 215 ReleaseBackingStore(origin, false /* immediate */); |
208 } | 216 } |
209 | 217 |
210 void IndexedDBFactoryImpl::DeleteDatabase( | 218 void IndexedDBFactoryImpl::DeleteDatabase( |
211 const base::string16& name, | 219 const base::string16& name, |
212 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 220 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
213 scoped_refptr<IndexedDBCallbacks> callbacks, | 221 std::unique_ptr<IndexedDBPendingDelete> pending_delete, |
214 const Origin& origin, | 222 const Origin& origin, |
215 const base::FilePath& data_directory) { | 223 const base::FilePath& data_directory) { |
216 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); | 224 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); |
217 IndexedDBDatabase::Identifier unique_identifier(origin, name); | 225 IndexedDBDatabase::Identifier unique_identifier(origin, name); |
218 const auto& it = database_map_.find(unique_identifier); | 226 const auto& it = database_map_.find(unique_identifier); |
219 if (it != database_map_.end()) { | 227 if (it != database_map_.end()) { |
220 // If there are any connections to the database, directly delete the | 228 // If there are any connections to the database, directly delete the |
221 // database. | 229 // database. |
222 it->second->DeleteDatabase(callbacks); | 230 it->second->DeleteDatabase(std::move(pending_delete)); |
223 return; | 231 return; |
224 } | 232 } |
225 | 233 |
226 // TODO(dgrogan): Plumb data_loss back to script eventually? | 234 // TODO(dgrogan): Plumb data_loss back to script eventually? |
227 IndexedDBDataLossInfo data_loss_info; | 235 IndexedDBDataLossInfo data_loss_info; |
228 bool disk_full = false; | 236 bool disk_full = false; |
229 leveldb::Status s; | 237 leveldb::Status s; |
230 scoped_refptr<IndexedDBBackingStore> backing_store = | 238 scoped_refptr<IndexedDBBackingStore> backing_store = |
231 OpenBackingStore(origin, data_directory, request_context_getter, | 239 OpenBackingStore(origin, data_directory, request_context_getter, |
232 &data_loss_info, &disk_full, &s); | 240 &data_loss_info, &disk_full, &s); |
233 if (!backing_store.get()) { | 241 if (!backing_store.get()) { |
234 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 242 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
235 ASCIIToUTF16( | 243 ASCIIToUTF16( |
236 "Internal error opening backing store " | 244 "Internal error opening backing store " |
237 "for indexedDB.deleteDatabase.")); | 245 "for indexedDB.deleteDatabase.")); |
238 callbacks->OnError(error); | 246 pending_delete->OnError(error); |
239 if (s.IsCorruption()) { | 247 if (s.IsCorruption()) { |
240 HandleBackingStoreCorruption(origin, error); | 248 HandleBackingStoreCorruption(origin, error); |
241 } | 249 } |
242 return; | 250 return; |
243 } | 251 } |
244 | 252 |
245 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); | 253 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); |
246 if (!s.ok()) { | 254 if (!s.ok()) { |
247 DLOG(ERROR) << "Internal error getting database names"; | 255 DLOG(ERROR) << "Internal error getting database names"; |
248 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 256 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
249 "Internal error opening backing store for " | 257 "Internal error opening backing store for " |
250 "indexedDB.deleteDatabase."); | 258 "indexedDB.deleteDatabase."); |
251 callbacks->OnError(error); | 259 pending_delete->OnError(error); |
252 backing_store = NULL; | 260 backing_store = NULL; |
253 if (s.IsCorruption()) | 261 if (s.IsCorruption()) |
254 HandleBackingStoreCorruption(origin, error); | 262 HandleBackingStoreCorruption(origin, error); |
255 return; | 263 return; |
256 } | 264 } |
257 if (!base::ContainsValue(names, name)) { | 265 if (!base::ContainsValue(names, name)) { |
| 266 #ifdef CJM_NEED_CALLBACK |
258 const int64_t version = 0; | 267 const int64_t version = 0; |
259 callbacks->OnSuccess(version); | 268 pending_delete->OnSuccess(version); |
| 269 #endif |
260 backing_store = NULL; | 270 backing_store = NULL; |
261 ReleaseBackingStore(origin, false /* immediate */); | 271 ReleaseBackingStore(origin, false /* immediate */); |
262 return; | 272 return; |
263 } | 273 } |
264 | 274 |
265 scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create( | 275 scoped_refptr<IndexedDBDatabase> database = IndexedDBDatabase::Create( |
266 name, backing_store.get(), this, unique_identifier, &s); | 276 name, backing_store.get(), this, unique_identifier, &s); |
267 if (!database.get()) { | 277 if (!database.get()) { |
268 IndexedDBDatabaseError error( | 278 IndexedDBDatabaseError error( |
269 blink::WebIDBDatabaseExceptionUnknownError, | 279 blink::WebIDBDatabaseExceptionUnknownError, |
270 ASCIIToUTF16( | 280 ASCIIToUTF16( |
271 "Internal error creating database backend for " | 281 "Internal error creating database backend for " |
272 "indexedDB.deleteDatabase.")); | 282 "indexedDB.deleteDatabase.")); |
273 callbacks->OnError(error); | 283 pending_delete->OnError(error); |
274 if (s.IsCorruption()) { | 284 if (s.IsCorruption()) { |
275 backing_store = NULL; | 285 backing_store = NULL; |
276 HandleBackingStoreCorruption(origin, error); | 286 HandleBackingStoreCorruption(origin, error); |
277 } | 287 } |
278 return; | 288 return; |
279 } | 289 } |
280 | 290 |
281 database_map_[unique_identifier] = database.get(); | 291 database_map_[unique_identifier] = database.get(); |
282 origin_dbs_.insert(std::make_pair(origin, database.get())); | 292 origin_dbs_.insert(std::make_pair(origin, database.get())); |
283 database->DeleteDatabase(callbacks); | 293 database->DeleteDatabase(std::move(pending_delete)); |
284 RemoveDatabaseFromMaps(unique_identifier); | 294 RemoveDatabaseFromMaps(unique_identifier); |
285 database = NULL; | 295 database = NULL; |
286 backing_store = NULL; | 296 backing_store = NULL; |
287 ReleaseBackingStore(origin, false /* immediate */); | 297 ReleaseBackingStore(origin, false /* immediate */); |
288 } | 298 } |
289 | 299 |
290 void IndexedDBFactoryImpl::DatabaseDeleted( | 300 void IndexedDBFactoryImpl::DatabaseDeleted( |
291 const IndexedDBDatabase::Identifier& identifier) { | 301 const IndexedDBDatabase::Identifier& identifier) { |
292 // NULL after ContextDestroyed() called, and in some unit tests. | 302 // NULL after ContextDestroyed() called, and in some unit tests. |
293 if (!context_) | 303 if (!context_) |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 IndexedDBDataLossInfo data_loss_info; | 422 IndexedDBDataLossInfo data_loss_info; |
413 bool disk_full = false; | 423 bool disk_full = false; |
414 bool was_open = (it != database_map_.end()); | 424 bool was_open = (it != database_map_.end()); |
415 if (!was_open) { | 425 if (!was_open) { |
416 leveldb::Status s; | 426 leveldb::Status s; |
417 scoped_refptr<IndexedDBBackingStore> backing_store = | 427 scoped_refptr<IndexedDBBackingStore> backing_store = |
418 OpenBackingStore(origin, data_directory, request_context_getter, | 428 OpenBackingStore(origin, data_directory, request_context_getter, |
419 &data_loss_info, &disk_full, &s); | 429 &data_loss_info, &disk_full, &s); |
420 if (!backing_store.get()) { | 430 if (!backing_store.get()) { |
421 if (disk_full) { | 431 if (disk_full) { |
422 connection->callbacks->OnError(IndexedDBDatabaseError( | 432 connection->OnError(IndexedDBDatabaseError( |
423 blink::WebIDBDatabaseExceptionQuotaError, | 433 blink::WebIDBDatabaseExceptionQuotaError, |
424 ASCIIToUTF16("Encountered full disk while opening " | 434 ASCIIToUTF16("Encountered full disk while opening " |
425 "backing store for indexedDB.open."))); | 435 "backing store for indexedDB.open."))); |
426 return; | 436 return; |
427 } | 437 } |
428 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 438 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
429 ASCIIToUTF16( | 439 ASCIIToUTF16( |
430 "Internal error opening backing store" | 440 "Internal error opening backing store" |
431 " for indexedDB.open.")); | 441 " for indexedDB.open.")); |
432 connection->callbacks->OnError(error); | 442 connection->OnError(error); |
433 if (s.IsCorruption()) { | 443 if (s.IsCorruption()) { |
434 HandleBackingStoreCorruption(origin, error); | 444 HandleBackingStoreCorruption(origin, error); |
435 } | 445 } |
436 return; | 446 return; |
437 } | 447 } |
438 | 448 |
439 database = IndexedDBDatabase::Create( | 449 database = IndexedDBDatabase::Create( |
440 name, backing_store.get(), this, unique_identifier, &s); | 450 name, backing_store.get(), this, unique_identifier, &s); |
441 if (!database.get()) { | 451 if (!database.get()) { |
442 DLOG(ERROR) << "Unable to create the database"; | 452 DLOG(ERROR) << "Unable to create the database"; |
443 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 453 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
444 ASCIIToUTF16( | 454 ASCIIToUTF16( |
445 "Internal error creating " | 455 "Internal error creating " |
446 "database backend for " | 456 "database backend for " |
447 "indexedDB.open.")); | 457 "indexedDB.open.")); |
448 connection->callbacks->OnError(error); | 458 connection->OnError(error); |
449 if (s.IsCorruption()) { | 459 if (s.IsCorruption()) { |
450 backing_store = NULL; // Closes the LevelDB so that it can be deleted | 460 backing_store = NULL; // Closes the LevelDB so that it can be deleted |
451 HandleBackingStoreCorruption(origin, error); | 461 HandleBackingStoreCorruption(origin, error); |
452 } | 462 } |
453 return; | 463 return; |
454 } | 464 } |
455 } else { | 465 } else { |
456 database = it->second; | 466 database = it->second; |
457 } | 467 } |
458 | 468 |
459 connection->data_loss_info = data_loss_info; | 469 connection->SetDataLossInfo(data_loss_info); |
460 | 470 |
461 database->OpenConnection(std::move(connection)); | 471 database->OpenConnection(std::move(connection)); |
462 | 472 |
463 if (!was_open && database->ConnectionCount() > 0) { | 473 if (!was_open && database->ConnectionCount() > 0) { |
464 database_map_[unique_identifier] = database.get(); | 474 database_map_[unique_identifier] = database.get(); |
465 origin_dbs_.insert(std::make_pair(origin, database.get())); | 475 origin_dbs_.insert(std::make_pair(origin, database.get())); |
466 } | 476 } |
467 } | 477 } |
468 | 478 |
469 std::pair<IndexedDBFactoryImpl::OriginDBMapIterator, | 479 std::pair<IndexedDBFactoryImpl::OriginDBMapIterator, |
470 IndexedDBFactoryImpl::OriginDBMapIterator> | 480 IndexedDBFactoryImpl::OriginDBMapIterator> |
471 IndexedDBFactoryImpl::GetOpenDatabasesForOrigin(const Origin& origin) const { | 481 IndexedDBFactoryImpl::GetOpenDatabasesForOrigin(const Origin& origin) const { |
472 return origin_dbs_.equal_range(origin); | 482 return origin_dbs_.equal_range(origin); |
473 } | 483 } |
474 | 484 |
475 size_t IndexedDBFactoryImpl::GetConnectionCount(const Origin& origin) const { | 485 size_t IndexedDBFactoryImpl::GetConnectionCount(const Origin& origin) const { |
476 size_t count(0); | 486 size_t count(0); |
477 | 487 |
478 OriginDBs range = GetOpenDatabasesForOrigin(origin); | 488 OriginDBs range = GetOpenDatabasesForOrigin(origin); |
479 for (OriginDBMapIterator it = range.first; it != range.second; ++it) | 489 for (OriginDBMapIterator it = range.first; it != range.second; ++it) |
480 count += it->second->ConnectionCount(); | 490 count += it->second->ConnectionCount(); |
481 | 491 |
482 return count; | 492 return count; |
483 } | 493 } |
484 | 494 |
| 495 IndexedDBContext* IndexedDBFactoryImpl::context() const { |
| 496 return context_; |
| 497 } |
| 498 |
485 } // namespace content | 499 } // namespace content |
OLD | NEW |