| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/service_worker/service_worker_database.h" | 5 #include "content/browser/service_worker/service_worker_database.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/location.h" | 10 #include "base/location.h" |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 } | 233 } |
| 234 | 234 |
| 235 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { | 235 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { |
| 236 } | 236 } |
| 237 | 237 |
| 238 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) | 238 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) |
| 239 : path_(path), | 239 : path_(path), |
| 240 next_avail_registration_id_(0), | 240 next_avail_registration_id_(0), |
| 241 next_avail_resource_id_(0), | 241 next_avail_resource_id_(0), |
| 242 next_avail_version_id_(0), | 242 next_avail_version_id_(0), |
| 243 is_disabled_(false), | 243 state_(UNINITIALIZED) { |
| 244 was_corruption_detected_(false), | |
| 245 is_initialized_(false) { | |
| 246 sequence_checker_.DetachFromSequence(); | 244 sequence_checker_.DetachFromSequence(); |
| 247 } | 245 } |
| 248 | 246 |
| 249 ServiceWorkerDatabase::~ServiceWorkerDatabase() { | 247 ServiceWorkerDatabase::~ServiceWorkerDatabase() { |
| 250 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 248 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 251 db_.reset(); | 249 db_.reset(); |
| 252 } | 250 } |
| 253 | 251 |
| 254 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds( | 252 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds( |
| 255 int64* next_avail_registration_id, | 253 int64* next_avail_registration_id, |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 628 } | 626 } |
| 629 | 627 |
| 630 return WriteBatch(&batch); | 628 return WriteBatch(&batch); |
| 631 } | 629 } |
| 632 | 630 |
| 633 ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen( | 631 ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen( |
| 634 bool create_if_missing) { | 632 bool create_if_missing) { |
| 635 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 633 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 636 | 634 |
| 637 // Do not try to open a database if we tried and failed once. | 635 // Do not try to open a database if we tried and failed once. |
| 638 if (is_disabled_) | 636 if (state_ == DISABLED) |
| 639 return STATUS_ERROR_FAILED; | 637 return STATUS_ERROR_FAILED; |
| 640 if (IsOpen()) | 638 if (IsOpen()) |
| 641 return STATUS_OK; | 639 return STATUS_OK; |
| 642 | 640 |
| 643 // When |path_| is empty, open a database in-memory. | 641 // When |path_| is empty, open a database in-memory. |
| 644 bool use_in_memory_db = path_.empty(); | 642 bool use_in_memory_db = path_.empty(); |
| 645 | 643 |
| 646 if (!create_if_missing) { | 644 if (!create_if_missing) { |
| 647 // Avoid opening a database if it does not exist at the |path_|. | 645 // Avoid opening a database if it does not exist at the |path_|. |
| 648 if (use_in_memory_db || | 646 if (use_in_memory_db || |
| (...skipping 20 matching lines...) Expand all Loading... |
| 669 return LevelDBStatusToStatus(db_status); | 667 return LevelDBStatusToStatus(db_status); |
| 670 } | 668 } |
| 671 db_.reset(db); | 669 db_.reset(db); |
| 672 | 670 |
| 673 int64 db_version; | 671 int64 db_version; |
| 674 Status status = ReadDatabaseVersion(&db_version); | 672 Status status = ReadDatabaseVersion(&db_version); |
| 675 if (status != STATUS_OK) | 673 if (status != STATUS_OK) |
| 676 return status; | 674 return status; |
| 677 DCHECK_LE(0, db_version); | 675 DCHECK_LE(0, db_version); |
| 678 if (db_version > 0) | 676 if (db_version > 0) |
| 679 is_initialized_ = true; | 677 state_ = INITIALIZED; |
| 680 return STATUS_OK; | 678 return STATUS_OK; |
| 681 } | 679 } |
| 682 | 680 |
| 683 bool ServiceWorkerDatabase::IsNewOrNonexistentDatabase( | 681 bool ServiceWorkerDatabase::IsNewOrNonexistentDatabase( |
| 684 ServiceWorkerDatabase::Status status) { | 682 ServiceWorkerDatabase::Status status) { |
| 685 if (status == STATUS_ERROR_NOT_FOUND) | 683 if (status == STATUS_ERROR_NOT_FOUND) |
| 686 return true; | 684 return true; |
| 687 if (status == STATUS_OK && !is_initialized_) | 685 if (status == STATUS_OK && state_ == UNINITIALIZED) |
| 688 return true; | 686 return true; |
| 689 return false; | 687 return false; |
| 690 } | 688 } |
| 691 | 689 |
| 692 ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadNextAvailableId( | 690 ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadNextAvailableId( |
| 693 const char* id_key, | 691 const char* id_key, |
| 694 int64* next_avail_id) { | 692 int64* next_avail_id) { |
| 695 DCHECK(id_key); | 693 DCHECK(id_key); |
| 696 DCHECK(next_avail_id); | 694 DCHECK(next_avail_id); |
| 697 | 695 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 916 return STATUS_ERROR_CORRUPTED; | 914 return STATUS_ERROR_CORRUPTED; |
| 917 } | 915 } |
| 918 | 916 |
| 919 *db_version = parsed; | 917 *db_version = parsed; |
| 920 return STATUS_OK; | 918 return STATUS_OK; |
| 921 } | 919 } |
| 922 | 920 |
| 923 ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteBatch( | 921 ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteBatch( |
| 924 leveldb::WriteBatch* batch) { | 922 leveldb::WriteBatch* batch) { |
| 925 DCHECK(batch); | 923 DCHECK(batch); |
| 926 DCHECK(!is_disabled_); | 924 DCHECK_NE(DISABLED, state_); |
| 927 | 925 |
| 928 if (!is_initialized_) { | 926 if (state_ == UNINITIALIZED) { |
| 929 // Write the database schema version. | 927 // Write the database schema version. |
| 930 batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion)); | 928 batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion)); |
| 931 is_initialized_ = true; | 929 state_ = INITIALIZED; |
| 932 } | 930 } |
| 933 | 931 |
| 934 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch); | 932 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch); |
| 935 if (!status.ok()) | 933 if (!status.ok()) |
| 936 HandleError(FROM_HERE, status); | 934 HandleError(FROM_HERE, status); |
| 937 return LevelDBStatusToStatus(status); | 935 return LevelDBStatusToStatus(status); |
| 938 } | 936 } |
| 939 | 937 |
| 940 void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded( | 938 void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded( |
| 941 int64 used_id, leveldb::WriteBatch* batch) { | 939 int64 used_id, leveldb::WriteBatch* batch) { |
| 942 DCHECK(batch); | 940 DCHECK(batch); |
| 943 if (next_avail_registration_id_ <= used_id) { | 941 if (next_avail_registration_id_ <= used_id) { |
| 944 next_avail_registration_id_ = used_id + 1; | 942 next_avail_registration_id_ = used_id + 1; |
| 945 batch->Put(kNextRegIdKey, base::Int64ToString(next_avail_registration_id_)); | 943 batch->Put(kNextRegIdKey, base::Int64ToString(next_avail_registration_id_)); |
| 946 } | 944 } |
| 947 } | 945 } |
| 948 | 946 |
| 949 void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded( | 947 void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded( |
| 950 int64 used_id, leveldb::WriteBatch* batch) { | 948 int64 used_id, leveldb::WriteBatch* batch) { |
| 951 DCHECK(batch); | 949 DCHECK(batch); |
| 952 if (next_avail_version_id_ <= used_id) { | 950 if (next_avail_version_id_ <= used_id) { |
| 953 next_avail_version_id_ = used_id + 1; | 951 next_avail_version_id_ = used_id + 1; |
| 954 batch->Put(kNextVerIdKey, base::Int64ToString(next_avail_version_id_)); | 952 batch->Put(kNextVerIdKey, base::Int64ToString(next_avail_version_id_)); |
| 955 } | 953 } |
| 956 } | 954 } |
| 957 | 955 |
| 958 bool ServiceWorkerDatabase::IsOpen() { | 956 bool ServiceWorkerDatabase::IsOpen() { |
| 959 return db_.get() != NULL; | 957 return db_ != NULL; |
| 960 } | 958 } |
| 961 | 959 |
| 962 void ServiceWorkerDatabase::HandleError( | 960 void ServiceWorkerDatabase::HandleError( |
| 963 const tracked_objects::Location& from_here, | 961 const tracked_objects::Location& from_here, |
| 964 const leveldb::Status& status) { | 962 const leveldb::Status& status) { |
| 965 // TODO(nhiroki): Add an UMA histogram. | 963 // TODO(nhiroki): Add an UMA histogram. |
| 966 DLOG(ERROR) << "Failed at: " << from_here.ToString() | 964 DLOG(ERROR) << "Failed at: " << from_here.ToString() |
| 967 << " with error: " << status.ToString(); | 965 << " with error: " << status.ToString(); |
| 968 is_disabled_ = true; | 966 state_ = DISABLED; |
| 969 if (status.IsCorruption()) | |
| 970 was_corruption_detected_ = true; | |
| 971 db_.reset(); | 967 db_.reset(); |
| 972 } | 968 } |
| 973 | 969 |
| 974 } // namespace content | 970 } // namespace content |
| OLD | NEW |