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 |