| 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 "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 // | 76 // |
| 77 // key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED" | 77 // key: "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED" |
| 78 // value: <empty> | 78 // value: <empty> |
| 79 // - This entry represents that the diskcache uses the Simple backend and | 79 // - This entry represents that the diskcache uses the Simple backend and |
| 80 // does not have to do diskcache migration (http://crbug.com/487482). | 80 // does not have to do diskcache migration (http://crbug.com/487482). |
| 81 // | 81 // |
| 82 // key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED" | 82 // key: "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED" |
| 83 // value: <empty> | 83 // value: <empty> |
| 84 // - This entry represents that the old BlockFile diskcache was deleted | 84 // - This entry represents that the old BlockFile diskcache was deleted |
| 85 // after diskcache migration (http://crbug.com/487482). | 85 // after diskcache migration (http://crbug.com/487482). |
| 86 // |
| 87 // Version 3 |
| 88 // |
| 89 // Deprecate |
| 90 // key: "INITDATA_NEXT_VERSION_ID" |
| 91 // value: <int64 'next_available_version_id'> |
| 92 // |
| 93 // Data type change |
| 94 // key: "RES:" + <std::string 'version_uuid'> + '\x00' + <int64 'resource_id'> |
| 95 // (ex. "RES:123456\x00654321") |
| 96 // value: <ServiceWorkerResourceRecord serialized as a string> |
| 86 namespace content { | 97 namespace content { |
| 87 | 98 |
| 88 namespace { | 99 namespace { |
| 89 | 100 |
| 90 const char kDatabaseVersionKey[] = "INITDATA_DB_VERSION"; | 101 const char kDatabaseVersionKey[] = "INITDATA_DB_VERSION"; |
| 91 const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID"; | 102 const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID"; |
| 92 const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID"; | 103 const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID"; |
| 93 const char kNextVerIdKey[] = "INITDATA_NEXT_VERSION_ID"; | |
| 94 const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:"; | 104 const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:"; |
| 95 const char kDiskCacheMigrationNotNeededKey[] = | 105 const char kDiskCacheMigrationNotNeededKey[] = |
| 96 "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"; | 106 "INITDATA_DISKCACHE_MIGRATION_NOT_NEEDED"; |
| 97 const char kOldDiskCacheDeletionNotNeededKey[] = | 107 const char kOldDiskCacheDeletionNotNeededKey[] = |
| 98 "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"; | 108 "INITDATA_OLD_DISKCACHE_DELETION_NOT_NEEDED"; |
| 99 | 109 |
| 100 const char kRegKeyPrefix[] = "REG:"; | 110 const char kRegKeyPrefix[] = "REG:"; |
| 101 const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:"; | 111 const char kRegUserDataKeyPrefix[] = "REG_USER_DATA:"; |
| 102 const char kRegHasUserDataKeyPrefix[] = "REG_HAS_USER_DATA:"; | 112 const char kRegHasUserDataKeyPrefix[] = "REG_HAS_USER_DATA:"; |
| 103 const char kRegIdToOriginKeyPrefix[] = "REGID_TO_ORIGIN:"; | 113 const char kRegIdToOriginKeyPrefix[] = "REGID_TO_ORIGIN:"; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 133 return base::StringPrintf("%s%s%c", kRegKeyPrefix, | 143 return base::StringPrintf("%s%s%c", kRegKeyPrefix, |
| 134 origin.GetOrigin().spec().c_str(), kKeySeparator); | 144 origin.GetOrigin().spec().c_str(), kKeySeparator); |
| 135 } | 145 } |
| 136 | 146 |
| 137 std::string CreateRegistrationKey(int64 registration_id, | 147 std::string CreateRegistrationKey(int64 registration_id, |
| 138 const GURL& origin) { | 148 const GURL& origin) { |
| 139 return CreateRegistrationKeyPrefix(origin) | 149 return CreateRegistrationKeyPrefix(origin) |
| 140 .append(base::Int64ToString(registration_id)); | 150 .append(base::Int64ToString(registration_id)); |
| 141 } | 151 } |
| 142 | 152 |
| 143 std::string CreateResourceRecordKeyPrefix(int64 version_id) { | 153 std::string CreateResourceRecordKeyPrefix(std::string version_uuid) { |
| 144 return base::StringPrintf("%s%s%c", | 154 return base::StringPrintf("%s%s%c", kResKeyPrefix, version_uuid.c_str(), |
| 145 kResKeyPrefix, | |
| 146 base::Int64ToString(version_id).c_str(), | |
| 147 kKeySeparator); | 155 kKeySeparator); |
| 148 } | 156 } |
| 149 | 157 |
| 150 std::string CreateResourceRecordKey(int64 version_id, | 158 std::string CreateResourceRecordKey(std::string version_uuid, |
| 151 int64 resource_id) { | 159 int64 resource_id) { |
| 152 return CreateResourceRecordKeyPrefix(version_id).append( | 160 return CreateResourceRecordKeyPrefix(version_uuid) |
| 153 base::Int64ToString(resource_id)); | 161 .append(base::Int64ToString(resource_id)); |
| 154 } | 162 } |
| 155 | 163 |
| 156 std::string CreateUniqueOriginKey(const GURL& origin) { | 164 std::string CreateUniqueOriginKey(const GURL& origin) { |
| 157 return base::StringPrintf("%s%s", kUniqueOriginKey, | 165 return base::StringPrintf("%s%s", kUniqueOriginKey, |
| 158 origin.GetOrigin().spec().c_str()); | 166 origin.GetOrigin().spec().c_str()); |
| 159 } | 167 } |
| 160 | 168 |
| 161 std::string CreateResourceIdKey(const char* key_prefix, int64 resource_id) { | 169 std::string CreateResourceIdKey(const char* key_prefix, int64 resource_id) { |
| 162 return base::StringPrintf( | 170 return base::StringPrintf( |
| 163 "%s%s", key_prefix, base::Int64ToString(resource_id).c_str()); | 171 "%s%s", key_prefix, base::Int64ToString(resource_id).c_str()); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 194 void PutRegistrationDataToBatch( | 202 void PutRegistrationDataToBatch( |
| 195 const ServiceWorkerDatabase::RegistrationData& input, | 203 const ServiceWorkerDatabase::RegistrationData& input, |
| 196 leveldb::WriteBatch* batch) { | 204 leveldb::WriteBatch* batch) { |
| 197 DCHECK(batch); | 205 DCHECK(batch); |
| 198 | 206 |
| 199 // Convert RegistrationData to ServiceWorkerRegistrationData. | 207 // Convert RegistrationData to ServiceWorkerRegistrationData. |
| 200 ServiceWorkerRegistrationData data; | 208 ServiceWorkerRegistrationData data; |
| 201 data.set_registration_id(input.registration_id); | 209 data.set_registration_id(input.registration_id); |
| 202 data.set_scope_url(input.scope.spec()); | 210 data.set_scope_url(input.scope.spec()); |
| 203 data.set_script_url(input.script.spec()); | 211 data.set_script_url(input.script.spec()); |
| 204 data.set_version_id(input.version_id); | 212 data.set_version_uuid(input.version_uuid); |
| 205 data.set_is_active(input.is_active); | 213 data.set_is_active(input.is_active); |
| 206 data.set_has_fetch_handler(input.has_fetch_handler); | 214 data.set_has_fetch_handler(input.has_fetch_handler); |
| 207 data.set_last_update_check_time(input.last_update_check.ToInternalValue()); | 215 data.set_last_update_check_time(input.last_update_check.ToInternalValue()); |
| 208 data.set_resources_total_size_bytes(input.resources_total_size_bytes); | 216 data.set_resources_total_size_bytes(input.resources_total_size_bytes); |
| 209 | 217 |
| 210 std::string value; | 218 std::string value; |
| 211 bool success = data.SerializeToString(&value); | 219 bool success = data.SerializeToString(&value); |
| 212 DCHECK(success); | 220 DCHECK(success); |
| 213 GURL origin = input.scope.GetOrigin(); | 221 GURL origin = input.scope.GetOrigin(); |
| 214 batch->Put(CreateRegistrationKey(data.registration_id(), origin), value); | 222 batch->Put(CreateRegistrationKey(data.registration_id(), origin), value); |
| 215 } | 223 } |
| 216 | 224 |
| 217 void PutResourceRecordToBatch( | 225 void PutResourceRecordToBatch( |
| 218 const ServiceWorkerDatabase::ResourceRecord& input, | 226 const ServiceWorkerDatabase::ResourceRecord& input, |
| 219 int64 version_id, | 227 std::string version_uuid, |
| 220 leveldb::WriteBatch* batch) { | 228 leveldb::WriteBatch* batch) { |
| 221 DCHECK(batch); | 229 DCHECK(batch); |
| 222 DCHECK_GE(input.size_bytes, 0); | 230 DCHECK_GE(input.size_bytes, 0); |
| 223 | 231 |
| 224 // Convert ResourceRecord to ServiceWorkerResourceRecord. | 232 // Convert ResourceRecord to ServiceWorkerResourceRecord. |
| 225 ServiceWorkerResourceRecord record; | 233 ServiceWorkerResourceRecord record; |
| 226 record.set_resource_id(input.resource_id); | 234 record.set_resource_id(input.resource_id); |
| 227 record.set_url(input.url.spec()); | 235 record.set_url(input.url.spec()); |
| 228 record.set_size_bytes(input.size_bytes); | 236 record.set_size_bytes(input.size_bytes); |
| 229 | 237 |
| 230 std::string value; | 238 std::string value; |
| 231 bool success = record.SerializeToString(&value); | 239 bool success = record.SerializeToString(&value); |
| 232 DCHECK(success); | 240 DCHECK(success); |
| 233 batch->Put(CreateResourceRecordKey(version_id, input.resource_id), value); | 241 batch->Put(CreateResourceRecordKey(version_uuid, input.resource_id), value); |
| 234 } | 242 } |
| 235 | 243 |
| 236 void PutUniqueOriginToBatch(const GURL& origin, | 244 void PutUniqueOriginToBatch(const GURL& origin, |
| 237 leveldb::WriteBatch* batch) { | 245 leveldb::WriteBatch* batch) { |
| 238 // Value should be empty. | 246 // Value should be empty. |
| 239 batch->Put(CreateUniqueOriginKey(origin), ""); | 247 batch->Put(CreateUniqueOriginKey(origin), ""); |
| 240 } | 248 } |
| 241 | 249 |
| 242 void PutPurgeableResourceIdToBatch(int64 resource_id, | 250 void PutPurgeableResourceIdToBatch(int64 resource_id, |
| 243 leveldb::WriteBatch* batch) { | 251 leveldb::WriteBatch* batch) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 DLOG(ERROR) << "Scope URL '" << data.scope_url() << "' and/or script url '" | 300 DLOG(ERROR) << "Scope URL '" << data.scope_url() << "' and/or script url '" |
| 293 << data.script_url() | 301 << data.script_url() |
| 294 << "' are invalid or have mismatching origins."; | 302 << "' are invalid or have mismatching origins."; |
| 295 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; | 303 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; |
| 296 } | 304 } |
| 297 | 305 |
| 298 // Convert ServiceWorkerRegistrationData to RegistrationData. | 306 // Convert ServiceWorkerRegistrationData to RegistrationData. |
| 299 out->registration_id = data.registration_id(); | 307 out->registration_id = data.registration_id(); |
| 300 out->scope = scope_url; | 308 out->scope = scope_url; |
| 301 out->script = script_url; | 309 out->script = script_url; |
| 302 out->version_id = data.version_id(); | 310 out->version_uuid = data.version_uuid(); |
| 303 out->is_active = data.is_active(); | 311 out->is_active = data.is_active(); |
| 304 out->has_fetch_handler = data.has_fetch_handler(); | 312 out->has_fetch_handler = data.has_fetch_handler(); |
| 305 out->last_update_check = | 313 out->last_update_check = |
| 306 base::Time::FromInternalValue(data.last_update_check_time()); | 314 base::Time::FromInternalValue(data.last_update_check_time()); |
| 307 out->resources_total_size_bytes = data.resources_total_size_bytes(); | 315 out->resources_total_size_bytes = data.resources_total_size_bytes(); |
| 308 | 316 |
| 309 return ServiceWorkerDatabase::STATUS_OK; | 317 return ServiceWorkerDatabase::STATUS_OK; |
| 310 } | 318 } |
| 311 | 319 |
| 312 ServiceWorkerDatabase::Status ParseResourceRecord( | 320 ServiceWorkerDatabase::Status ParseResourceRecord( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 case ServiceWorkerDatabase::STATUS_ERROR_MAX: | 376 case ServiceWorkerDatabase::STATUS_ERROR_MAX: |
| 369 NOTREACHED(); | 377 NOTREACHED(); |
| 370 return "Database unknown error"; | 378 return "Database unknown error"; |
| 371 } | 379 } |
| 372 NOTREACHED(); | 380 NOTREACHED(); |
| 373 return "Database unknown error"; | 381 return "Database unknown error"; |
| 374 } | 382 } |
| 375 | 383 |
| 376 ServiceWorkerDatabase::RegistrationData::RegistrationData() | 384 ServiceWorkerDatabase::RegistrationData::RegistrationData() |
| 377 : registration_id(kInvalidServiceWorkerRegistrationId), | 385 : registration_id(kInvalidServiceWorkerRegistrationId), |
| 378 version_id(kInvalidServiceWorkerVersionId), | 386 version_uuid(std::string()), |
| 379 is_active(false), | 387 is_active(false), |
| 380 has_fetch_handler(false), | 388 has_fetch_handler(false), |
| 381 resources_total_size_bytes(0) { | 389 resources_total_size_bytes(0) { |
| 382 } | 390 } |
| 383 | 391 |
| 384 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { | 392 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { |
| 385 } | 393 } |
| 386 | 394 |
| 387 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) | 395 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) |
| 388 : path_(path), | 396 : path_(path), |
| 389 next_avail_registration_id_(0), | 397 next_avail_registration_id_(0), |
| 390 next_avail_resource_id_(0), | 398 next_avail_resource_id_(0), |
| 391 next_avail_version_id_(0), | |
| 392 state_(UNINITIALIZED), | 399 state_(UNINITIALIZED), |
| 393 skip_writing_diskcache_migration_state_on_init_for_testing_(false) { | 400 skip_writing_diskcache_migration_state_on_init_for_testing_(false) { |
| 394 sequence_checker_.DetachFromSequence(); | 401 sequence_checker_.DetachFromSequence(); |
| 395 } | 402 } |
| 396 | 403 |
| 397 ServiceWorkerDatabase::~ServiceWorkerDatabase() { | 404 ServiceWorkerDatabase::~ServiceWorkerDatabase() { |
| 398 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 405 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 399 db_.reset(); | 406 db_.reset(); |
| 400 } | 407 } |
| 401 | 408 |
| 402 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds( | 409 ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetNextAvailableIds( |
| 403 int64* next_avail_registration_id, | 410 int64* next_avail_registration_id, |
| 404 int64* next_avail_version_id, | |
| 405 int64* next_avail_resource_id) { | 411 int64* next_avail_resource_id) { |
| 406 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 412 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 407 DCHECK(next_avail_registration_id); | 413 DCHECK(next_avail_registration_id); |
| 408 DCHECK(next_avail_version_id); | |
| 409 DCHECK(next_avail_resource_id); | 414 DCHECK(next_avail_resource_id); |
| 410 | 415 |
| 411 Status status = LazyOpen(false); | 416 Status status = LazyOpen(false); |
| 412 if (IsNewOrNonexistentDatabase(status)) { | 417 if (IsNewOrNonexistentDatabase(status)) { |
| 413 *next_avail_registration_id = 0; | 418 *next_avail_registration_id = 0; |
| 414 *next_avail_version_id = 0; | |
| 415 *next_avail_resource_id = 0; | 419 *next_avail_resource_id = 0; |
| 416 return STATUS_OK; | 420 return STATUS_OK; |
| 417 } | 421 } |
| 418 if (status != STATUS_OK) | 422 if (status != STATUS_OK) |
| 419 return status; | 423 return status; |
| 420 | 424 |
| 421 status = ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_); | 425 status = ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_); |
| 422 if (status != STATUS_OK) | 426 if (status != STATUS_OK) |
| 423 return status; | 427 return status; |
| 424 status = ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_); | |
| 425 if (status != STATUS_OK) | |
| 426 return status; | |
| 427 status = ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_); | 428 status = ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_); |
| 428 if (status != STATUS_OK) | 429 if (status != STATUS_OK) |
| 429 return status; | 430 return status; |
| 430 | 431 |
| 431 *next_avail_registration_id = next_avail_registration_id_; | 432 *next_avail_registration_id = next_avail_registration_id_; |
| 432 *next_avail_version_id = next_avail_version_id_; | |
| 433 *next_avail_resource_id = next_avail_resource_id_; | 433 *next_avail_resource_id = next_avail_resource_id_; |
| 434 return STATUS_OK; | 434 return STATUS_OK; |
| 435 } | 435 } |
| 436 | 436 |
| 437 ServiceWorkerDatabase::Status ServiceWorkerDatabase::IsDiskCacheMigrationNeeded( | 437 ServiceWorkerDatabase::Status ServiceWorkerDatabase::IsDiskCacheMigrationNeeded( |
| 438 bool* migration_needed) { | 438 bool* migration_needed) { |
| 439 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 439 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 440 | 440 |
| 441 Status status = LazyOpen(false); | 441 Status status = LazyOpen(false); |
| 442 if (IsNewOrNonexistentDatabase(status)) { | 442 if (IsNewOrNonexistentDatabase(status)) { |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 HandleReadResult(FROM_HERE, status); | 593 HandleReadResult(FROM_HERE, status); |
| 594 registrations->clear(); | 594 registrations->clear(); |
| 595 if (opt_resources_list) | 595 if (opt_resources_list) |
| 596 opt_resources_list->clear(); | 596 opt_resources_list->clear(); |
| 597 return status; | 597 return status; |
| 598 } | 598 } |
| 599 registrations->push_back(registration); | 599 registrations->push_back(registration); |
| 600 | 600 |
| 601 if (opt_resources_list) { | 601 if (opt_resources_list) { |
| 602 std::vector<ResourceRecord> resources; | 602 std::vector<ResourceRecord> resources; |
| 603 status = ReadResourceRecords(registration.version_id, &resources); | 603 status = ReadResourceRecords(registration.version_uuid, &resources); |
| 604 if (status != STATUS_OK) { | 604 if (status != STATUS_OK) { |
| 605 HandleReadResult(FROM_HERE, status); | 605 HandleReadResult(FROM_HERE, status); |
| 606 registrations->clear(); | 606 registrations->clear(); |
| 607 opt_resources_list->clear(); | 607 opt_resources_list->clear(); |
| 608 return status; | 608 return status; |
| 609 } | 609 } |
| 610 opt_resources_list->push_back(resources); | 610 opt_resources_list->push_back(resources); |
| 611 } | 611 } |
| 612 } | 612 } |
| 613 | 613 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 if (IsNewOrNonexistentDatabase(status)) | 665 if (IsNewOrNonexistentDatabase(status)) |
| 666 return STATUS_ERROR_NOT_FOUND; | 666 return STATUS_ERROR_NOT_FOUND; |
| 667 if (status != STATUS_OK) | 667 if (status != STATUS_OK) |
| 668 return status; | 668 return status; |
| 669 | 669 |
| 670 RegistrationData value; | 670 RegistrationData value; |
| 671 status = ReadRegistrationData(registration_id, origin, &value); | 671 status = ReadRegistrationData(registration_id, origin, &value); |
| 672 if (status != STATUS_OK) | 672 if (status != STATUS_OK) |
| 673 return status; | 673 return status; |
| 674 | 674 |
| 675 status = ReadResourceRecords(value.version_id, resources); | 675 status = ReadResourceRecords(value.version_uuid, resources); |
| 676 if (status != STATUS_OK) | 676 if (status != STATUS_OK) |
| 677 return status; | 677 return status; |
| 678 | 678 |
| 679 // ResourceRecord must contain the ServiceWorker's main script. | 679 // ResourceRecord must contain the ServiceWorker's main script. |
| 680 if (resources->empty()) | 680 if (resources->empty()) |
| 681 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; | 681 return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED; |
| 682 | 682 |
| 683 *registration = value; | 683 *registration = value; |
| 684 return STATUS_OK; | 684 return STATUS_OK; |
| 685 } | 685 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 | 720 |
| 721 ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration( | 721 ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration( |
| 722 const RegistrationData& registration, | 722 const RegistrationData& registration, |
| 723 const std::vector<ResourceRecord>& resources, | 723 const std::vector<ResourceRecord>& resources, |
| 724 RegistrationData* old_registration, | 724 RegistrationData* old_registration, |
| 725 std::vector<int64>* newly_purgeable_resources) { | 725 std::vector<int64>* newly_purgeable_resources) { |
| 726 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 726 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 727 DCHECK(old_registration); | 727 DCHECK(old_registration); |
| 728 DCHECK(!resources.empty()); | 728 DCHECK(!resources.empty()); |
| 729 Status status = LazyOpen(true); | 729 Status status = LazyOpen(true); |
| 730 old_registration->version_id = kInvalidServiceWorkerVersionId; | 730 old_registration->version_uuid = std::string(); |
| 731 if (status != STATUS_OK) | 731 if (status != STATUS_OK) |
| 732 return status; | 732 return status; |
| 733 | 733 |
| 734 leveldb::WriteBatch batch; | 734 leveldb::WriteBatch batch; |
| 735 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch); | 735 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch); |
| 736 BumpNextVersionIdIfNeeded(registration.version_id, &batch); | 736 // BumpNextVersionIdIfNeeded(registration.version_uuid, &batch); |
| 737 | 737 |
| 738 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch); | 738 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch); |
| 739 | 739 |
| 740 DCHECK_EQ(AccumulateResourceSizeInBytes(resources), | 740 DCHECK_EQ(AccumulateResourceSizeInBytes(resources), |
| 741 registration.resources_total_size_bytes) | 741 registration.resources_total_size_bytes) |
| 742 << "The total size in the registration must match the cumulative " | 742 << "The total size in the registration must match the cumulative " |
| 743 << "sizes of the resources."; | 743 << "sizes of the resources."; |
| 744 | 744 |
| 745 PutRegistrationDataToBatch(registration, &batch); | 745 PutRegistrationDataToBatch(registration, &batch); |
| 746 batch.Put(CreateRegistrationIdToOriginKey(registration.registration_id), | 746 batch.Put(CreateRegistrationIdToOriginKey(registration.registration_id), |
| 747 registration.scope.GetOrigin().spec()); | 747 registration.scope.GetOrigin().spec()); |
| 748 | 748 |
| 749 // Used for avoiding multiple writes for the same resource id or url. | 749 // Used for avoiding multiple writes for the same resource id or url. |
| 750 std::set<int64> pushed_resources; | 750 std::set<int64> pushed_resources; |
| 751 std::set<GURL> pushed_urls; | 751 std::set<GURL> pushed_urls; |
| 752 for (std::vector<ResourceRecord>::const_iterator itr = resources.begin(); | 752 for (std::vector<ResourceRecord>::const_iterator itr = resources.begin(); |
| 753 itr != resources.end(); ++itr) { | 753 itr != resources.end(); ++itr) { |
| 754 if (!itr->url.is_valid()) | 754 if (!itr->url.is_valid()) |
| 755 return STATUS_ERROR_FAILED; | 755 return STATUS_ERROR_FAILED; |
| 756 | 756 |
| 757 // Duplicated resource id or url should not exist. | 757 // Duplicated resource id or url should not exist. |
| 758 DCHECK(pushed_resources.insert(itr->resource_id).second); | 758 DCHECK(pushed_resources.insert(itr->resource_id).second); |
| 759 DCHECK(pushed_urls.insert(itr->url).second); | 759 DCHECK(pushed_urls.insert(itr->url).second); |
| 760 | 760 |
| 761 PutResourceRecordToBatch(*itr, registration.version_id, &batch); | 761 PutResourceRecordToBatch(*itr, registration.version_uuid, &batch); |
| 762 | 762 |
| 763 // Delete a resource from the uncommitted list. | 763 // Delete a resource from the uncommitted list. |
| 764 batch.Delete(CreateResourceIdKey( | 764 batch.Delete(CreateResourceIdKey( |
| 765 kUncommittedResIdKeyPrefix, itr->resource_id)); | 765 kUncommittedResIdKeyPrefix, itr->resource_id)); |
| 766 // Delete from the purgeable list in case this version was once deleted. | 766 // Delete from the purgeable list in case this version was once deleted. |
| 767 batch.Delete( | 767 batch.Delete( |
| 768 CreateResourceIdKey(kPurgeableResIdKeyPrefix, itr->resource_id)); | 768 CreateResourceIdKey(kPurgeableResIdKeyPrefix, itr->resource_id)); |
| 769 } | 769 } |
| 770 | 770 |
| 771 // Retrieve a previous version to sweep purgeable resources. | 771 // Retrieve a previous version to sweep purgeable resources. |
| 772 status = ReadRegistrationData(registration.registration_id, | 772 status = ReadRegistrationData(registration.registration_id, |
| 773 registration.scope.GetOrigin(), | 773 registration.scope.GetOrigin(), |
| 774 old_registration); | 774 old_registration); |
| 775 if (status != STATUS_OK && status != STATUS_ERROR_NOT_FOUND) | 775 if (status != STATUS_OK && status != STATUS_ERROR_NOT_FOUND) |
| 776 return status; | 776 return status; |
| 777 if (status == STATUS_OK) { | 777 if (status == STATUS_OK) { |
| 778 DCHECK_LT(old_registration->version_id, registration.version_id); | 778 DCHECK_NE(old_registration->version_uuid, registration.version_uuid); |
| 779 status = DeleteResourceRecords( | 779 status = DeleteResourceRecords(old_registration->version_uuid, |
| 780 old_registration->version_id, newly_purgeable_resources, &batch); | 780 newly_purgeable_resources, &batch); |
| 781 if (status != STATUS_OK) | 781 if (status != STATUS_OK) |
| 782 return status; | 782 return status; |
| 783 | 783 |
| 784 // Currently resource sharing across versions and registrations is not | 784 // Currently resource sharing across versions and registrations is not |
| 785 // supported, so resource ids should not be overlapped between | 785 // supported, so resource ids should not be overlapped between |
| 786 // |registration| and |old_registration|. | 786 // |registration| and |old_registration|. |
| 787 std::set<int64> deleted_resources(newly_purgeable_resources->begin(), | 787 std::set<int64> deleted_resources(newly_purgeable_resources->begin(), |
| 788 newly_purgeable_resources->end()); | 788 newly_purgeable_resources->end()); |
| 789 DCHECK(base::STLSetIntersection<std::set<int64> >( | 789 DCHECK(base::STLSetIntersection<std::set<int64> >( |
| 790 pushed_resources, deleted_resources).empty()); | 790 pushed_resources, deleted_resources).empty()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 return WriteBatch(&batch); | 842 return WriteBatch(&batch); |
| 843 } | 843 } |
| 844 | 844 |
| 845 ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration( | 845 ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration( |
| 846 int64 registration_id, | 846 int64 registration_id, |
| 847 const GURL& origin, | 847 const GURL& origin, |
| 848 RegistrationData* deleted_version, | 848 RegistrationData* deleted_version, |
| 849 std::vector<int64>* newly_purgeable_resources) { | 849 std::vector<int64>* newly_purgeable_resources) { |
| 850 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); | 850 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); |
| 851 DCHECK(deleted_version); | 851 DCHECK(deleted_version); |
| 852 deleted_version->version_id = kInvalidServiceWorkerVersionId; | 852 deleted_version->version_uuid = std::string(); |
| 853 Status status = LazyOpen(false); | 853 Status status = LazyOpen(false); |
| 854 if (IsNewOrNonexistentDatabase(status)) | 854 if (IsNewOrNonexistentDatabase(status)) |
| 855 return STATUS_OK; | 855 return STATUS_OK; |
| 856 if (status != STATUS_OK) | 856 if (status != STATUS_OK) |
| 857 return status; | 857 return status; |
| 858 if (!origin.is_valid()) | 858 if (!origin.is_valid()) |
| 859 return STATUS_ERROR_FAILED; | 859 return STATUS_ERROR_FAILED; |
| 860 | 860 |
| 861 leveldb::WriteBatch batch; | 861 leveldb::WriteBatch batch; |
| 862 | 862 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 874 } | 874 } |
| 875 | 875 |
| 876 // Delete a registration specified by |registration_id|. | 876 // Delete a registration specified by |registration_id|. |
| 877 batch.Delete(CreateRegistrationKey(registration_id, origin)); | 877 batch.Delete(CreateRegistrationKey(registration_id, origin)); |
| 878 batch.Delete(CreateRegistrationIdToOriginKey(registration_id)); | 878 batch.Delete(CreateRegistrationIdToOriginKey(registration_id)); |
| 879 | 879 |
| 880 // Delete resource records and user data associated with the registration. | 880 // Delete resource records and user data associated with the registration. |
| 881 for (const auto& registration : registrations) { | 881 for (const auto& registration : registrations) { |
| 882 if (registration.registration_id == registration_id) { | 882 if (registration.registration_id == registration_id) { |
| 883 *deleted_version = registration; | 883 *deleted_version = registration; |
| 884 status = DeleteResourceRecords( | 884 status = DeleteResourceRecords(registration.version_uuid, |
| 885 registration.version_id, newly_purgeable_resources, &batch); | 885 newly_purgeable_resources, &batch); |
| 886 if (status != STATUS_OK) | 886 if (status != STATUS_OK) |
| 887 return status; | 887 return status; |
| 888 | 888 |
| 889 status = DeleteUserDataForRegistration(registration_id, &batch); | 889 status = DeleteUserDataForRegistration(registration_id, &batch); |
| 890 if (status != STATUS_OK) | 890 if (status != STATUS_OK) |
| 891 return status; | 891 return status; |
| 892 break; | 892 break; |
| 893 } | 893 } |
| 894 } | 894 } |
| 895 | 895 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 std::vector<RegistrationData> registrations; | 1083 std::vector<RegistrationData> registrations; |
| 1084 status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); | 1084 status = GetRegistrationsForOrigin(origin, ®istrations, nullptr); |
| 1085 if (status != STATUS_OK) | 1085 if (status != STATUS_OK) |
| 1086 return status; | 1086 return status; |
| 1087 | 1087 |
| 1088 // Delete registrations, resource records and user data. | 1088 // Delete registrations, resource records and user data. |
| 1089 for (const RegistrationData& data : registrations) { | 1089 for (const RegistrationData& data : registrations) { |
| 1090 batch.Delete(CreateRegistrationKey(data.registration_id, origin)); | 1090 batch.Delete(CreateRegistrationKey(data.registration_id, origin)); |
| 1091 batch.Delete(CreateRegistrationIdToOriginKey(data.registration_id)); | 1091 batch.Delete(CreateRegistrationIdToOriginKey(data.registration_id)); |
| 1092 | 1092 |
| 1093 status = DeleteResourceRecords( | 1093 status = DeleteResourceRecords(data.version_uuid, |
| 1094 data.version_id, newly_purgeable_resources, &batch); | 1094 newly_purgeable_resources, &batch); |
| 1095 if (status != STATUS_OK) | 1095 if (status != STATUS_OK) |
| 1096 return status; | 1096 return status; |
| 1097 | 1097 |
| 1098 status = DeleteUserDataForRegistration(data.registration_id, &batch); | 1098 status = DeleteUserDataForRegistration(data.registration_id, &batch); |
| 1099 if (status != STATUS_OK) | 1099 if (status != STATUS_OK) |
| 1100 return status; | 1100 return status; |
| 1101 } | 1101 } |
| 1102 } | 1102 } |
| 1103 | 1103 |
| 1104 return WriteBatch(&batch); | 1104 return WriteBatch(&batch); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 status == STATUS_ERROR_NOT_FOUND ? STATUS_OK : status); | 1281 status == STATUS_ERROR_NOT_FOUND ? STATUS_OK : status); |
| 1282 return status; | 1282 return status; |
| 1283 } | 1283 } |
| 1284 | 1284 |
| 1285 status = ParseRegistrationData(value, registration); | 1285 status = ParseRegistrationData(value, registration); |
| 1286 HandleReadResult(FROM_HERE, status); | 1286 HandleReadResult(FROM_HERE, status); |
| 1287 return status; | 1287 return status; |
| 1288 } | 1288 } |
| 1289 | 1289 |
| 1290 ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceRecords( | 1290 ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceRecords( |
| 1291 int64 version_id, | 1291 std::string version_uuid, |
| 1292 std::vector<ResourceRecord>* resources) { | 1292 std::vector<ResourceRecord>* resources) { |
| 1293 DCHECK(resources->empty()); | 1293 DCHECK(resources->empty()); |
| 1294 | 1294 |
| 1295 Status status = STATUS_OK; | 1295 Status status = STATUS_OK; |
| 1296 const std::string prefix = CreateResourceRecordKeyPrefix(version_id); | 1296 const std::string prefix = CreateResourceRecordKeyPrefix(version_uuid); |
| 1297 | 1297 |
| 1298 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); | 1298 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
| 1299 for (itr->Seek(prefix); itr->Valid(); itr->Next()) { | 1299 for (itr->Seek(prefix); itr->Valid(); itr->Next()) { |
| 1300 Status status = LevelDBStatusToStatus(itr->status()); | 1300 Status status = LevelDBStatusToStatus(itr->status()); |
| 1301 if (status != STATUS_OK) { | 1301 if (status != STATUS_OK) { |
| 1302 HandleReadResult(FROM_HERE, status); | 1302 HandleReadResult(FROM_HERE, status); |
| 1303 resources->clear(); | 1303 resources->clear(); |
| 1304 return status; | 1304 return status; |
| 1305 } | 1305 } |
| 1306 | 1306 |
| 1307 if (!RemovePrefix(itr->key().ToString(), prefix, NULL)) | 1307 if (!RemovePrefix(itr->key().ToString(), prefix, NULL)) |
| 1308 break; | 1308 break; |
| 1309 | 1309 |
| 1310 ResourceRecord resource; | 1310 ResourceRecord resource; |
| 1311 status = ParseResourceRecord(itr->value().ToString(), &resource); | 1311 status = ParseResourceRecord(itr->value().ToString(), &resource); |
| 1312 if (status != STATUS_OK) { | 1312 if (status != STATUS_OK) { |
| 1313 HandleReadResult(FROM_HERE, status); | 1313 HandleReadResult(FROM_HERE, status); |
| 1314 resources->clear(); | 1314 resources->clear(); |
| 1315 return status; | 1315 return status; |
| 1316 } | 1316 } |
| 1317 resources->push_back(resource); | 1317 resources->push_back(resource); |
| 1318 } | 1318 } |
| 1319 | 1319 |
| 1320 HandleReadResult(FROM_HERE, status); | 1320 HandleReadResult(FROM_HERE, status); |
| 1321 return status; | 1321 return status; |
| 1322 } | 1322 } |
| 1323 | 1323 |
| 1324 ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords( | 1324 ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords( |
| 1325 int64 version_id, | 1325 std::string version_uuid, |
| 1326 std::vector<int64>* newly_purgeable_resources, | 1326 std::vector<int64>* newly_purgeable_resources, |
| 1327 leveldb::WriteBatch* batch) { | 1327 leveldb::WriteBatch* batch) { |
| 1328 DCHECK(batch); | 1328 DCHECK(batch); |
| 1329 | 1329 |
| 1330 Status status = STATUS_OK; | 1330 Status status = STATUS_OK; |
| 1331 const std::string prefix = CreateResourceRecordKeyPrefix(version_id); | 1331 const std::string prefix = CreateResourceRecordKeyPrefix(version_uuid); |
| 1332 | 1332 |
| 1333 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); | 1333 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); |
| 1334 for (itr->Seek(prefix); itr->Valid(); itr->Next()) { | 1334 for (itr->Seek(prefix); itr->Valid(); itr->Next()) { |
| 1335 status = LevelDBStatusToStatus(itr->status()); | 1335 status = LevelDBStatusToStatus(itr->status()); |
| 1336 if (status != STATUS_OK) { | 1336 if (status != STATUS_OK) { |
| 1337 HandleReadResult(FROM_HERE, status); | 1337 HandleReadResult(FROM_HERE, status); |
| 1338 return status; | 1338 return status; |
| 1339 } | 1339 } |
| 1340 | 1340 |
| 1341 const std::string key = itr->key().ToString(); | 1341 const std::string key = itr->key().ToString(); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 | 1544 |
| 1545 void ServiceWorkerDatabase::BumpNextResourceIdIfNeeded( | 1545 void ServiceWorkerDatabase::BumpNextResourceIdIfNeeded( |
| 1546 int64 used_id, leveldb::WriteBatch* batch) { | 1546 int64 used_id, leveldb::WriteBatch* batch) { |
| 1547 DCHECK(batch); | 1547 DCHECK(batch); |
| 1548 if (next_avail_resource_id_ <= used_id) { | 1548 if (next_avail_resource_id_ <= used_id) { |
| 1549 next_avail_resource_id_ = used_id + 1; | 1549 next_avail_resource_id_ = used_id + 1; |
| 1550 batch->Put(kNextResIdKey, base::Int64ToString(next_avail_resource_id_)); | 1550 batch->Put(kNextResIdKey, base::Int64ToString(next_avail_resource_id_)); |
| 1551 } | 1551 } |
| 1552 } | 1552 } |
| 1553 | 1553 |
| 1554 void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded( | |
| 1555 int64 used_id, leveldb::WriteBatch* batch) { | |
| 1556 DCHECK(batch); | |
| 1557 if (next_avail_version_id_ <= used_id) { | |
| 1558 next_avail_version_id_ = used_id + 1; | |
| 1559 batch->Put(kNextVerIdKey, base::Int64ToString(next_avail_version_id_)); | |
| 1560 } | |
| 1561 } | |
| 1562 | |
| 1563 bool ServiceWorkerDatabase::IsOpen() { | 1554 bool ServiceWorkerDatabase::IsOpen() { |
| 1564 return db_ != NULL; | 1555 return db_ != NULL; |
| 1565 } | 1556 } |
| 1566 | 1557 |
| 1567 void ServiceWorkerDatabase::Disable( | 1558 void ServiceWorkerDatabase::Disable( |
| 1568 const tracked_objects::Location& from_here, | 1559 const tracked_objects::Location& from_here, |
| 1569 Status status) { | 1560 Status status) { |
| 1570 if (status != STATUS_OK) { | 1561 if (status != STATUS_OK) { |
| 1571 DLOG(ERROR) << "Failed at: " << from_here.ToString() | 1562 DLOG(ERROR) << "Failed at: " << from_here.ToString() |
| 1572 << " with error: " << StatusToString(status); | 1563 << " with error: " << StatusToString(status); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1598 if (status != STATUS_OK) | 1589 if (status != STATUS_OK) |
| 1599 Disable(from_here, status); | 1590 Disable(from_here, status); |
| 1600 ServiceWorkerMetrics::CountWriteDatabaseResult(status); | 1591 ServiceWorkerMetrics::CountWriteDatabaseResult(status); |
| 1601 } | 1592 } |
| 1602 | 1593 |
| 1603 bool ServiceWorkerDatabase::IsDatabaseInMemory() const { | 1594 bool ServiceWorkerDatabase::IsDatabaseInMemory() const { |
| 1604 return path_.empty(); | 1595 return path_.empty(); |
| 1605 } | 1596 } |
| 1606 | 1597 |
| 1607 } // namespace content | 1598 } // namespace content |
| OLD | NEW |