| 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_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 224 |
| 225 if (db_data_version > latest_known_data_version) { | 225 if (db_data_version > latest_known_data_version) { |
| 226 *known = false; | 226 *known = false; |
| 227 return true; | 227 return true; |
| 228 } | 228 } |
| 229 | 229 |
| 230 *known = true; | 230 *known = true; |
| 231 return true; | 231 return true; |
| 232 } | 232 } |
| 233 | 233 |
| 234 WARN_UNUSED_RESULT static bool SetUpMetadata(LevelDBDatabase* db, | 234 WARN_UNUSED_RESULT static bool SetUpMetadata( |
| 235 const string16& origin) { | 235 LevelDBDatabase* db, |
| 236 const std::string& origin_identifier) { |
| 236 const uint32 latest_known_data_version = kWireVersion; | 237 const uint32 latest_known_data_version = kWireVersion; |
| 237 const std::vector<char> schema_version_key = SchemaVersionKey::Encode(); | 238 const std::vector<char> schema_version_key = SchemaVersionKey::Encode(); |
| 238 const std::vector<char> data_version_key = DataVersionKey::Encode(); | 239 const std::vector<char> data_version_key = DataVersionKey::Encode(); |
| 239 | 240 |
| 240 scoped_refptr<LevelDBTransaction> transaction = | 241 scoped_refptr<LevelDBTransaction> transaction = |
| 241 LevelDBTransaction::Create(db); | 242 LevelDBTransaction::Create(db); |
| 242 | 243 |
| 243 int64 db_schema_version = 0; | 244 int64 db_schema_version = 0; |
| 244 int64 db_data_version = 0; | 245 int64 db_data_version = 0; |
| 245 bool found = false; | 246 bool found = false; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 260 PutInt(transaction.get(), LevelDBSlice(data_version_key), db_data_version); | 261 PutInt(transaction.get(), LevelDBSlice(data_version_key), db_data_version); |
| 261 } else { | 262 } else { |
| 262 // Upgrade old backing store. | 263 // Upgrade old backing store. |
| 263 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); | 264 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); |
| 264 if (db_schema_version < 1) { | 265 if (db_schema_version < 1) { |
| 265 db_schema_version = 1; | 266 db_schema_version = 1; |
| 266 PutInt(transaction.get(), | 267 PutInt(transaction.get(), |
| 267 LevelDBSlice(schema_version_key), | 268 LevelDBSlice(schema_version_key), |
| 268 db_schema_version); | 269 db_schema_version); |
| 269 const std::vector<char> start_key = | 270 const std::vector<char> start_key = |
| 270 DatabaseNameKey::EncodeMinKeyForOrigin(origin); | 271 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); |
| 271 const std::vector<char> stop_key = | 272 const std::vector<char> stop_key = |
| 272 DatabaseNameKey::EncodeStopKeyForOrigin(origin); | 273 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); |
| 273 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); | 274 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); |
| 274 for (it->Seek(LevelDBSlice(start_key)); | 275 for (it->Seek(LevelDBSlice(start_key)); |
| 275 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; | 276 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; |
| 276 it->Next()) { | 277 it->Next()) { |
| 277 int64 database_id = 0; | 278 int64 database_id = 0; |
| 278 found = false; | 279 found = false; |
| 279 bool ok = GetInt(transaction.get(), it->Key(), &database_id, &found); | 280 bool ok = GetInt(transaction.get(), it->Key(), &database_id, &found); |
| 280 if (!ok) { | 281 if (!ok) { |
| 281 INTERNAL_READ_ERROR(SET_UP_METADATA); | 282 INTERNAL_READ_ERROR(SET_UP_METADATA); |
| 282 return false; | 283 return false; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 const base::FilePath& file_name, | 368 const base::FilePath& file_name, |
| 368 const LevelDBComparator* comparator, bool* is_disk_full) OVERRIDE { | 369 const LevelDBComparator* comparator, bool* is_disk_full) OVERRIDE { |
| 369 return LevelDBDatabase::Open(file_name, comparator, is_disk_full); | 370 return LevelDBDatabase::Open(file_name, comparator, is_disk_full); |
| 370 } | 371 } |
| 371 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE { | 372 virtual bool DestroyLevelDB(const base::FilePath& file_name) OVERRIDE { |
| 372 return LevelDBDatabase::Destroy(file_name); | 373 return LevelDBDatabase::Destroy(file_name); |
| 373 } | 374 } |
| 374 }; | 375 }; |
| 375 | 376 |
| 376 IndexedDBBackingStore::IndexedDBBackingStore( | 377 IndexedDBBackingStore::IndexedDBBackingStore( |
| 377 const string16& identifier, | 378 const std::string& identifier, |
| 378 scoped_ptr<LevelDBDatabase> db, | 379 scoped_ptr<LevelDBDatabase> db, |
| 379 scoped_ptr<LevelDBComparator> comparator) | 380 scoped_ptr<LevelDBComparator> comparator) |
| 380 : identifier_(identifier), | 381 : identifier_(identifier), |
| 381 db_(db.Pass()), | 382 db_(db.Pass()), |
| 382 comparator_(comparator.Pass()), | 383 comparator_(comparator.Pass()), |
| 383 weak_factory_(this) {} | 384 weak_factory_(this) {} |
| 384 | 385 |
| 385 IndexedDBBackingStore::~IndexedDBBackingStore() { | 386 IndexedDBBackingStore::~IndexedDBBackingStore() { |
| 386 // db_'s destructor uses comparator_. The order of destruction is important. | 387 // db_'s destructor uses comparator_. The order of destruction is important. |
| 387 db_.reset(); | 388 db_.reset(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 412 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, | 413 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, |
| 413 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, | 414 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, |
| 414 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED, | 415 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED, |
| 415 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, | 416 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, |
| 416 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_DISK_FULL, | 417 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_DISK_FULL, |
| 417 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, | 418 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, |
| 418 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 419 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 419 }; | 420 }; |
| 420 | 421 |
| 421 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( | 422 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( |
| 422 const string16& database_identifier, | 423 const std::string& origin_identifier, |
| 423 const base::FilePath& path_base, | 424 const base::FilePath& path_base, |
| 424 const string16& file_identifier) { | 425 const std::string& file_identifier) { |
| 425 DefaultLevelDBFactory leveldb_factory; | 426 DefaultLevelDBFactory leveldb_factory; |
| 426 return IndexedDBBackingStore::Open( | 427 return IndexedDBBackingStore::Open( |
| 427 database_identifier, path_base, file_identifier, &leveldb_factory); | 428 origin_identifier, path_base, file_identifier, &leveldb_factory); |
| 428 } | 429 } |
| 429 | 430 |
| 430 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( | 431 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( |
| 431 const string16& database_identifier, | 432 const std::string& origin_identifier, |
| 432 const base::FilePath& path_base, | 433 const base::FilePath& path_base, |
| 433 const string16& file_identifier, | 434 const std::string& file_identifier, |
| 434 LevelDBFactory* leveldb_factory) { | 435 LevelDBFactory* leveldb_factory) { |
| 435 IDB_TRACE("IndexedDBBackingStore::open"); | 436 IDB_TRACE("IndexedDBBackingStore::open"); |
| 436 DCHECK(!path_base.empty()); | 437 DCHECK(!path_base.empty()); |
| 437 | 438 |
| 438 scoped_ptr<LevelDBComparator> comparator(new Comparator()); | 439 scoped_ptr<LevelDBComparator> comparator(new Comparator()); |
| 439 scoped_ptr<LevelDBDatabase> db; | 440 scoped_ptr<LevelDBDatabase> db; |
| 440 | 441 |
| 441 if (!IsStringASCII(path_base.AsUTF8Unsafe())) { | 442 if (!IsStringASCII(path_base.AsUTF8Unsafe())) { |
| 442 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 443 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 443 1, | 444 1, |
| 444 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 445 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 445 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 446 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 446 base::HistogramBase::kUmaTargetedHistogramFlag) | 447 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 447 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII); | 448 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII); |
| 448 } | 449 } |
| 449 if (!file_util::CreateDirectory(path_base)) { | 450 if (!file_util::CreateDirectory(path_base)) { |
| 450 LOG(ERROR) << "Unable to create IndexedDB database path " | 451 LOG(ERROR) << "Unable to create IndexedDB database path " |
| 451 << path_base.AsUTF8Unsafe(); | 452 << path_base.AsUTF8Unsafe(); |
| 452 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 453 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 453 1, | 454 1, |
| 454 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 455 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 455 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 456 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 456 base::HistogramBase::kUmaTargetedHistogramFlag) | 457 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 457 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY); | 458 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY); |
| 458 return scoped_refptr<IndexedDBBackingStore>(); | 459 return scoped_refptr<IndexedDBBackingStore>(); |
| 459 } | 460 } |
| 460 | 461 |
| 461 // TODO(jsbell): Rework to use FilePath throughout. | 462 // TODO(jsbell): Rework to use FilePath throughout. |
| 462 base::FilePath identifier_path = base::FilePath::FromUTF8Unsafe( | 463 base::FilePath identifier_path = |
| 463 UTF16ToUTF8(database_identifier) + ".indexeddb.leveldb"); | 464 base::FilePath().AppendASCII(origin_identifier). |
| 465 AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); |
| 466 |
| 464 int limit = file_util::GetMaximumPathComponentLength(path_base); | 467 int limit = file_util::GetMaximumPathComponentLength(path_base); |
| 465 if (limit == -1) { | 468 if (limit == -1) { |
| 466 DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; | 469 DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; |
| 467 // In limited testing, ChromeOS returns 143, other OSes 255. | 470 // In limited testing, ChromeOS returns 143, other OSes 255. |
| 468 #if defined(OS_CHROMEOS) | 471 #if defined(OS_CHROMEOS) |
| 469 limit = 143; | 472 limit = 143; |
| 470 #else | 473 #else |
| 471 limit = 255; | 474 limit = 255; |
| 472 #endif | 475 #endif |
| 473 } | 476 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 594 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 592 base::HistogramBase::kUmaTargetedHistogramFlag) | 595 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 593 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR); | 596 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR); |
| 594 return scoped_refptr<IndexedDBBackingStore>(); | 597 return scoped_refptr<IndexedDBBackingStore>(); |
| 595 } | 598 } |
| 596 | 599 |
| 597 return Create(file_identifier, db.Pass(), comparator.Pass()); | 600 return Create(file_identifier, db.Pass(), comparator.Pass()); |
| 598 } | 601 } |
| 599 | 602 |
| 600 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 603 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
| 601 const string16& identifier) { | 604 const std::string& file_identifier) { |
| 602 DefaultLevelDBFactory leveldb_factory; | 605 DefaultLevelDBFactory leveldb_factory; |
| 603 return IndexedDBBackingStore::OpenInMemory(identifier, &leveldb_factory); | 606 return IndexedDBBackingStore::OpenInMemory(file_identifier, &leveldb_factory); |
| 604 } | 607 } |
| 605 | 608 |
| 606 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( | 609 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( |
| 607 const string16& identifier, | 610 const std::string& file_identifier, |
| 608 LevelDBFactory* leveldb_factory) { | 611 LevelDBFactory* leveldb_factory) { |
| 609 IDB_TRACE("IndexedDBBackingStore::open_in_memory"); | 612 IDB_TRACE("IndexedDBBackingStore::open_in_memory"); |
| 610 | 613 |
| 611 scoped_ptr<LevelDBComparator> comparator(new Comparator()); | 614 scoped_ptr<LevelDBComparator> comparator(new Comparator()); |
| 612 scoped_ptr<LevelDBDatabase> db = | 615 scoped_ptr<LevelDBDatabase> db = |
| 613 LevelDBDatabase::OpenInMemory(comparator.get()); | 616 LevelDBDatabase::OpenInMemory(comparator.get()); |
| 614 if (!db) { | 617 if (!db) { |
| 615 LOG(ERROR) << "LevelDBDatabase::open_in_memory failed."; | 618 LOG(ERROR) << "LevelDBDatabase::open_in_memory failed."; |
| 616 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 619 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 617 1, | 620 1, |
| 618 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 621 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 619 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 622 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 620 base::HistogramBase::kUmaTargetedHistogramFlag) | 623 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 621 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED); | 624 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_FAILED); |
| 622 return scoped_refptr<IndexedDBBackingStore>(); | 625 return scoped_refptr<IndexedDBBackingStore>(); |
| 623 } | 626 } |
| 624 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", | 627 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", |
| 625 1, | 628 1, |
| 626 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, | 629 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, |
| 627 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, | 630 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, |
| 628 base::HistogramBase::kUmaTargetedHistogramFlag) | 631 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 629 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS); | 632 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MEMORY_SUCCESS); |
| 630 | 633 |
| 631 return Create(identifier, db.Pass(), comparator.Pass()); | 634 return Create(file_identifier, db.Pass(), comparator.Pass()); |
| 632 } | 635 } |
| 633 | 636 |
| 634 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( | 637 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Create( |
| 635 const string16& identifier, | 638 const std::string& identifier, |
| 636 scoped_ptr<LevelDBDatabase> db, | 639 scoped_ptr<LevelDBDatabase> db, |
| 637 scoped_ptr<LevelDBComparator> comparator) { | 640 scoped_ptr<LevelDBComparator> comparator) { |
| 638 // TODO(jsbell): Handle comparator name changes. | 641 // TODO(jsbell): Handle comparator name changes. |
| 639 scoped_refptr<IndexedDBBackingStore> backing_store( | 642 scoped_refptr<IndexedDBBackingStore> backing_store( |
| 640 new IndexedDBBackingStore(identifier, db.Pass(), comparator.Pass())); | 643 new IndexedDBBackingStore(identifier, db.Pass(), comparator.Pass())); |
| 641 | 644 |
| 642 if (!SetUpMetadata(backing_store->db_.get(), identifier)) | 645 if (!SetUpMetadata(backing_store->db_.get(), identifier)) |
| 643 return scoped_refptr<IndexedDBBackingStore>(); | 646 return scoped_refptr<IndexedDBBackingStore>(); |
| 644 | 647 |
| 645 return backing_store; | 648 return backing_store; |
| (...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2634 } | 2637 } |
| 2635 | 2638 |
| 2636 void IndexedDBBackingStore::Transaction::Rollback() { | 2639 void IndexedDBBackingStore::Transaction::Rollback() { |
| 2637 IDB_TRACE("IndexedDBBackingStore::Transaction::rollback"); | 2640 IDB_TRACE("IndexedDBBackingStore::Transaction::rollback"); |
| 2638 DCHECK(transaction_.get()); | 2641 DCHECK(transaction_.get()); |
| 2639 transaction_->Rollback(); | 2642 transaction_->Rollback(); |
| 2640 transaction_ = NULL; | 2643 transaction_ = NULL; |
| 2641 } | 2644 } |
| 2642 | 2645 |
| 2643 } // namespace content | 2646 } // namespace content |
| OLD | NEW |