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> |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 backing_stores_with_active_blobs_.erase(it); | 166 backing_stores_with_active_blobs_.erase(it); |
167 ReleaseBackingStore(origin, false /* immediate */); | 167 ReleaseBackingStore(origin, false /* immediate */); |
168 } | 168 } |
169 } | 169 } |
170 } | 170 } |
171 | 171 |
172 void IndexedDBFactoryImpl::GetDatabaseNames( | 172 void IndexedDBFactoryImpl::GetDatabaseNames( |
173 scoped_refptr<IndexedDBCallbacks> callbacks, | 173 scoped_refptr<IndexedDBCallbacks> callbacks, |
174 const Origin& origin, | 174 const Origin& origin, |
175 const base::FilePath& data_directory, | 175 const base::FilePath& data_directory, |
| 176 const IndexedDBDataFormatVersion& client_data_format_version, |
176 scoped_refptr<net::URLRequestContextGetter> request_context_getter) { | 177 scoped_refptr<net::URLRequestContextGetter> request_context_getter) { |
177 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); | 178 IDB_TRACE("IndexedDBFactoryImpl::GetDatabaseNames"); |
178 // TODO(dgrogan): Plumb data_loss back to script eventually? | 179 // TODO(dgrogan): Plumb data_loss back to script eventually? |
179 IndexedDBDataLossInfo data_loss_info; | 180 IndexedDBDataLossInfo data_loss_info; |
180 bool disk_full; | 181 bool disk_full; |
181 leveldb::Status s; | 182 leveldb::Status s; |
182 // TODO(cmumford): Handle this error | 183 // TODO(cmumford): Handle this error |
183 scoped_refptr<IndexedDBBackingStore> backing_store = | 184 scoped_refptr<IndexedDBBackingStore> backing_store = |
184 OpenBackingStore(origin, data_directory, request_context_getter, | 185 OpenBackingStore(origin, data_directory, client_data_format_version, |
185 &data_loss_info, &disk_full, &s); | 186 request_context_getter, &data_loss_info, &disk_full, &s); |
186 if (!backing_store.get()) { | 187 if (!backing_store.get()) { |
187 callbacks->OnError( | 188 callbacks->OnError( |
188 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 189 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
189 "Internal error opening backing store for " | 190 "Internal error opening backing store for " |
190 "indexedDB.webkitGetDatabaseNames.")); | 191 "indexedDB.webkitGetDatabaseNames.")); |
191 return; | 192 return; |
192 } | 193 } |
193 | 194 |
194 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); | 195 std::vector<base::string16> names = backing_store->GetDatabaseNames(&s); |
195 if (!s.ok()) { | 196 if (!s.ok()) { |
(...skipping 11 matching lines...) Expand all Loading... |
207 backing_store = NULL; | 208 backing_store = NULL; |
208 ReleaseBackingStore(origin, false /* immediate */); | 209 ReleaseBackingStore(origin, false /* immediate */); |
209 } | 210 } |
210 | 211 |
211 void IndexedDBFactoryImpl::DeleteDatabase( | 212 void IndexedDBFactoryImpl::DeleteDatabase( |
212 const base::string16& name, | 213 const base::string16& name, |
213 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 214 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
214 scoped_refptr<IndexedDBCallbacks> callbacks, | 215 scoped_refptr<IndexedDBCallbacks> callbacks, |
215 const Origin& origin, | 216 const Origin& origin, |
216 const base::FilePath& data_directory, | 217 const base::FilePath& data_directory, |
| 218 const IndexedDBDataFormatVersion& client_data_format_version, |
217 bool force_close) { | 219 bool force_close) { |
218 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); | 220 IDB_TRACE("IndexedDBFactoryImpl::DeleteDatabase"); |
219 IndexedDBDatabase::Identifier unique_identifier(origin, name); | 221 IndexedDBDatabase::Identifier unique_identifier(origin, name); |
220 const auto& it = database_map_.find(unique_identifier); | 222 const auto& it = database_map_.find(unique_identifier); |
221 if (it != database_map_.end()) { | 223 if (it != database_map_.end()) { |
222 // If there are any connections to the database, directly delete the | 224 // If there are any connections to the database, directly delete the |
223 // database. | 225 // database. |
224 it->second->DeleteDatabase(callbacks, force_close); | 226 it->second->DeleteDatabase(callbacks, force_close); |
225 return; | 227 return; |
226 } | 228 } |
227 | 229 |
228 // TODO(dgrogan): Plumb data_loss back to script eventually? | 230 // TODO(dgrogan): Plumb data_loss back to script eventually? |
229 IndexedDBDataLossInfo data_loss_info; | 231 IndexedDBDataLossInfo data_loss_info; |
230 bool disk_full = false; | 232 bool disk_full = false; |
231 leveldb::Status s; | 233 leveldb::Status s; |
232 scoped_refptr<IndexedDBBackingStore> backing_store = | 234 scoped_refptr<IndexedDBBackingStore> backing_store = |
233 OpenBackingStore(origin, data_directory, request_context_getter, | 235 OpenBackingStore(origin, data_directory, client_data_format_version, |
234 &data_loss_info, &disk_full, &s); | 236 request_context_getter, &data_loss_info, &disk_full, &s); |
235 if (!backing_store.get()) { | 237 if (!backing_store.get()) { |
236 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 238 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
237 ASCIIToUTF16( | 239 ASCIIToUTF16( |
238 "Internal error opening backing store " | 240 "Internal error opening backing store " |
239 "for indexedDB.deleteDatabase.")); | 241 "for indexedDB.deleteDatabase.")); |
240 callbacks->OnError(error); | 242 callbacks->OnError(error); |
241 if (s.IsCorruption()) { | 243 if (s.IsCorruption()) { |
242 HandleBackingStoreCorruption(origin, error); | 244 HandleBackingStoreCorruption(origin, error); |
243 } | 245 } |
244 return; | 246 return; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 const auto& it = backing_store_map_.find(origin); | 347 const auto& it = backing_store_map_.find(origin); |
346 if (it == backing_store_map_.end()) | 348 if (it == backing_store_map_.end()) |
347 return false; | 349 return false; |
348 return it->second->close_timer()->IsRunning(); | 350 return it->second->close_timer()->IsRunning(); |
349 } | 351 } |
350 | 352 |
351 scoped_refptr<IndexedDBBackingStore> | 353 scoped_refptr<IndexedDBBackingStore> |
352 IndexedDBFactoryImpl::OpenBackingStoreHelper( | 354 IndexedDBFactoryImpl::OpenBackingStoreHelper( |
353 const Origin& origin, | 355 const Origin& origin, |
354 const base::FilePath& data_directory, | 356 const base::FilePath& data_directory, |
| 357 const IndexedDBDataFormatVersion& data_format_version, |
355 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 358 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
356 IndexedDBDataLossInfo* data_loss_info, | 359 IndexedDBDataLossInfo* data_loss_info, |
357 bool* disk_full, | 360 bool* disk_full, |
358 bool first_time, | 361 bool first_time, |
359 leveldb::Status* status) { | 362 leveldb::Status* status) { |
360 return IndexedDBBackingStore::Open( | 363 return IndexedDBBackingStore::Open( |
361 this, origin, data_directory, request_context_getter, data_loss_info, | 364 this, origin, data_directory, data_format_version, request_context_getter, |
362 disk_full, context_->TaskRunner(), first_time, status); | 365 data_loss_info, disk_full, context_->TaskRunner(), first_time, status); |
363 } | 366 } |
364 | 367 |
365 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore( | 368 scoped_refptr<IndexedDBBackingStore> IndexedDBFactoryImpl::OpenBackingStore( |
366 const Origin& origin, | 369 const Origin& origin, |
367 const base::FilePath& data_directory, | 370 const base::FilePath& data_directory, |
| 371 const IndexedDBDataFormatVersion& data_format_version, |
368 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 372 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
369 IndexedDBDataLossInfo* data_loss_info, | 373 IndexedDBDataLossInfo* data_loss_info, |
370 bool* disk_full, | 374 bool* disk_full, |
371 leveldb::Status* status) { | 375 leveldb::Status* status) { |
372 const bool open_in_memory = data_directory.empty(); | 376 const bool open_in_memory = data_directory.empty(); |
373 | 377 |
374 const auto& it2 = backing_store_map_.find(origin); | 378 const auto& it2 = backing_store_map_.find(origin); |
375 if (it2 != backing_store_map_.end()) { | 379 if (it2 != backing_store_map_.end()) { |
376 it2->second->close_timer()->Stop(); | 380 scoped_refptr<IndexedDBBackingStore> backing_store = it2->second; |
377 return it2->second; | 381 if (backing_store->data_format_version() != data_format_version) { |
| 382 LOG(ERROR) << "IndexedDB backing store already open with a different " |
| 383 "data format version."; |
| 384 } |
| 385 backing_store->close_timer()->Stop(); |
| 386 return backing_store; |
378 } | 387 } |
379 | 388 |
380 scoped_refptr<IndexedDBBackingStore> backing_store; | 389 scoped_refptr<IndexedDBBackingStore> backing_store; |
381 bool first_time = false; | 390 bool first_time = false; |
382 if (open_in_memory) { | 391 if (open_in_memory) { |
383 backing_store = IndexedDBBackingStore::OpenInMemory( | 392 backing_store = IndexedDBBackingStore::OpenInMemory( |
384 origin, context_->TaskRunner(), status); | 393 origin, data_format_version, context_->TaskRunner(), status); |
385 } else { | 394 } else { |
386 first_time = !backends_opened_since_boot_.count(origin); | 395 first_time = !backends_opened_since_boot_.count(origin); |
387 | 396 |
388 backing_store = | 397 backing_store = OpenBackingStoreHelper( |
389 OpenBackingStoreHelper(origin, data_directory, request_context_getter, | 398 origin, data_directory, data_format_version, request_context_getter, |
390 data_loss_info, disk_full, first_time, status); | 399 data_loss_info, disk_full, first_time, status); |
391 } | 400 } |
392 | 401 |
393 if (backing_store.get()) { | 402 if (backing_store.get()) { |
394 if (first_time) | 403 if (first_time) |
395 backends_opened_since_boot_.insert(origin); | 404 backends_opened_since_boot_.insert(origin); |
396 backing_store_map_[origin] = backing_store; | 405 backing_store_map_[origin] = backing_store; |
397 // If an in-memory database, bind lifetime to this factory instance. | 406 // If an in-memory database, bind lifetime to this factory instance. |
398 if (open_in_memory) | 407 if (open_in_memory) |
399 session_only_backing_stores_.insert(backing_store); | 408 session_only_backing_stores_.insert(backing_store); |
400 | 409 |
401 // All backing stores associated with this factory should be of the same | 410 // All backing stores associated with this factory should be of the same |
402 // type. | 411 // type. |
403 DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory); | 412 DCHECK_NE(session_only_backing_stores_.empty(), open_in_memory); |
404 | 413 |
405 return backing_store; | 414 return backing_store; |
406 } | 415 } |
407 | 416 |
408 return 0; | 417 return 0; |
409 } | 418 } |
410 | 419 |
411 void IndexedDBFactoryImpl::Open( | 420 void IndexedDBFactoryImpl::Open( |
412 const base::string16& name, | 421 const base::string16& name, |
413 std::unique_ptr<IndexedDBPendingConnection> connection, | 422 std::unique_ptr<IndexedDBPendingConnection> connection, |
414 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 423 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
415 const Origin& origin, | 424 const Origin& origin, |
416 const base::FilePath& data_directory) { | 425 const base::FilePath& data_directory, |
| 426 const IndexedDBDataFormatVersion& client_data_format_version) { |
417 IDB_TRACE("IndexedDBFactoryImpl::Open"); | 427 IDB_TRACE("IndexedDBFactoryImpl::Open"); |
418 scoped_refptr<IndexedDBDatabase> database; | 428 scoped_refptr<IndexedDBDatabase> database; |
419 IndexedDBDatabase::Identifier unique_identifier(origin, name); | 429 IndexedDBDatabase::Identifier unique_identifier(origin, name); |
420 const auto& it = database_map_.find(unique_identifier); | 430 const auto& it = database_map_.find(unique_identifier); |
421 IndexedDBDataLossInfo data_loss_info; | 431 IndexedDBDataLossInfo data_loss_info; |
422 bool disk_full = false; | 432 bool disk_full = false; |
423 bool was_open = (it != database_map_.end()); | 433 bool was_open = (it != database_map_.end()); |
424 if (!was_open) { | 434 if (!was_open) { |
425 leveldb::Status s; | 435 leveldb::Status s; |
426 scoped_refptr<IndexedDBBackingStore> backing_store = | 436 scoped_refptr<IndexedDBBackingStore> backing_store = OpenBackingStore( |
427 OpenBackingStore(origin, data_directory, request_context_getter, | 437 origin, data_directory, client_data_format_version, |
428 &data_loss_info, &disk_full, &s); | 438 request_context_getter, &data_loss_info, &disk_full, &s); |
429 if (!backing_store.get()) { | 439 if (!backing_store.get()) { |
430 if (disk_full) { | 440 if (disk_full) { |
431 connection->callbacks->OnError(IndexedDBDatabaseError( | 441 connection->callbacks->OnError(IndexedDBDatabaseError( |
432 blink::WebIDBDatabaseExceptionQuotaError, | 442 blink::WebIDBDatabaseExceptionQuotaError, |
433 ASCIIToUTF16("Encountered full disk while opening " | 443 ASCIIToUTF16("Encountered full disk while opening " |
434 "backing store for indexedDB.open."))); | 444 "backing store for indexedDB.open."))); |
435 return; | 445 return; |
436 } | 446 } |
437 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, | 447 IndexedDBDatabaseError error(blink::WebIDBDatabaseExceptionUnknownError, |
438 ASCIIToUTF16( | 448 ASCIIToUTF16( |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 size_t count(0); | 495 size_t count(0); |
486 | 496 |
487 OriginDBs range = GetOpenDatabasesForOrigin(origin); | 497 OriginDBs range = GetOpenDatabasesForOrigin(origin); |
488 for (OriginDBMapIterator it = range.first; it != range.second; ++it) | 498 for (OriginDBMapIterator it = range.first; it != range.second; ++it) |
489 count += it->second->ConnectionCount(); | 499 count += it->second->ConnectionCount(); |
490 | 500 |
491 return count; | 501 return count; |
492 } | 502 } |
493 | 503 |
494 } // namespace content | 504 } // namespace content |
OLD | NEW |