data.set_is_active(input.is_active);
data.set_has_fetch_handler(input.has_fetch_handler);
data.set_last_update_check_time(input.last_update_check.ToInternalValue());
+ data.set_resources_total_size_bytes(input.resources_total_size_bytes);
std::string value;
bool success = data.SerializeToString(&value);
int64 version_id,
leveldb::WriteBatch* batch) {
DCHECK(batch);
+ DCHECK_GE(input.size_bytes, 0);
// Convert ResourceRecord to ServiceWorkerResourceRecord.
ServiceWorkerResourceRecord record;
record.set_resource_id(input.resource_id);
record.set_url(input.url.spec());
+ record.set_size_bytes(input.size_bytes);
std::string value;
bool success = record.SerializeToString(&value);
if (!scope_url.is_valid() ||
!script_url.is_valid() ||
scope_url.GetOrigin() != script_url.GetOrigin()) {
+ DLOG(ERROR) << "Scope URL '" << data.scope_url() << "' and/or script url '"
+ << data.script_url()
+ << "' are invalid or have mismatching origins.";
return ServiceWorkerDatabase::STATUS_ERROR_CORRUPTED;
}
out->has_fetch_handler = data.has_fetch_handler();
out->last_update_check =
base::Time::FromInternalValue(data.last_update_check_time());
+ out->resources_total_size_bytes = data.resources_total_size_bytes();
+
return ServiceWorkerDatabase::STATUS_OK;
}
// Convert ServiceWorkerResourceRecord to ResourceRecord.
out->resource_id = record.resource_id();
out->url = url;
+ out->size_bytes = record.size_bytes();
return ServiceWorkerDatabase::STATUS_OK;
}
return ServiceWorkerDatabase::STATUS_ERROR_FAILED;
}
-const char* StatusToString(ServiceWorkerDatabase::Status status) {
+} // namespace
+
+const char* ServiceWorkerDatabase::StatusToString(
+ ServiceWorkerDatabase::Status status) {
switch (status) {
case ServiceWorkerDatabase::STATUS_OK:
return "Database OK";
return "Database unknown error";
}
-} // namespace
-
ServiceWorkerDatabase::RegistrationData::RegistrationData()
: registration_id(kInvalidServiceWorkerRegistrationId),
version_id(kInvalidServiceWorkerVersionId),
is_active(false),
- has_fetch_handler(false) {
+ has_fetch_handler(false),
+ resources_total_size_bytes(0) {
}
ServiceWorkerDatabase::RegistrationData::~RegistrationData() {
ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteRegistration(
const RegistrationData& registration,
const std::vector<ResourceRecord>& resources,
- int64* deleted_version_id,
+ RegistrationData* old_registration,
std::vector<int64>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
- *deleted_version_id = kInvalidServiceWorkerVersionId;
+ DCHECK(old_registration);
Status status = LazyOpen(true);
+ old_registration->version_id = kInvalidServiceWorkerVersionId;
if (status != STATUS_OK)
return status;
BumpNextVersionIdIfNeeded(registration.version_id, &batch);
PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch);
+#if DCHECK_IS_ON
+ int64_t total_size_bytes = 0;
+ for (const auto& resource : resources) {
+ total_size_bytes += resource.size_bytes;
+ }
+ DCHECK_EQ(total_size_bytes, registration.resources_total_size_bytes)
+ << "The total size in the registration must match the cumulative "
+ << "sizes of the resources.";
+#endif
PutRegistrationDataToBatch(registration, &batch);
// Used for avoiding multiple writes for the same resource id or url.
}
// Retrieve a previous version to sweep purgeable resources.
- RegistrationData old_registration;
status = ReadRegistrationData(registration.registration_id,
registration.scope.GetOrigin(),
- &old_registration);
+ old_registration);
if (status != STATUS_OK && status != STATUS_ERROR_NOT_FOUND)
return status;
if (status == STATUS_OK) {
- DCHECK_LT(old_registration.version_id, registration.version_id);
- *deleted_version_id = old_registration.version_id;
+ DCHECK_LT(old_registration->version_id, registration.version_id);
status = DeleteResourceRecords(
- old_registration.version_id, newly_purgeable_resources, &batch);
+ old_registration->version_id, newly_purgeable_resources, &batch);
if (status != STATUS_OK)
return status;
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteRegistration(
int64 registration_id,
const GURL& origin,
- int64* version_id,
+ RegistrationData* deleted_version,
std::vector<int64>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
- *version_id = kInvalidServiceWorkerVersionId;
+ DCHECK(deleted_version);
+ deleted_version->version_id = kInvalidServiceWorkerVersionId;
Status status = LazyOpen(false);
if (IsNewOrNonexistentDatabase(status))
return STATUS_OK;
batch.Delete(CreateRegistrationKey(registration_id, origin));
// Delete resource records associated with the registration.
- for (std::vector<RegistrationData>::const_iterator itr =
- registrations.begin(); itr != registrations.end(); ++itr) {
- if (itr->registration_id == registration_id) {
- *version_id = itr->version_id;
+ for (const auto& registration : registrations) {
+ if (registration.registration_id == registration_id) {
+ *deleted_version = registration;
status = DeleteResourceRecords(
- itr->version_id, newly_purgeable_resources, &batch);
+ registration.version_id, newly_purgeable_resources, &batch);
if (status != STATUS_OK)
return status;
break;
return WriteBatch(&batch);
}
-ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigin(
- const GURL& origin,
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteAllDataForOrigins(
+ const std::set<GURL>& origins,
std::vector<int64>* newly_purgeable_resources) {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
Status status = LazyOpen(false);
return STATUS_OK;
if (status != STATUS_OK)
return status;
- if (!origin.is_valid())
- return STATUS_ERROR_FAILED;
-
leveldb::WriteBatch batch;
- // Delete from the unique origin list.
- batch.Delete(CreateUniqueOriginKey(origin));
+ for (const GURL& origin : origins) {
+ if (!origin.is_valid())
+ return STATUS_ERROR_FAILED;
- std::vector<RegistrationData> registrations;
- status = GetRegistrationsForOrigin(origin, ®istrations);
- if (status != STATUS_OK)
- return status;
+ // Delete from the unique origin list.
+ batch.Delete(CreateUniqueOriginKey(origin));
- // Delete registrations and resource records.
- for (std::vector<RegistrationData>::const_iterator itr =
- registrations.begin(); itr != registrations.end(); ++itr) {
- batch.Delete(CreateRegistrationKey(itr->registration_id, origin));
- status = DeleteResourceRecords(
- itr->version_id, newly_purgeable_resources, &batch);
+ std::vector<RegistrationData> registrations;
+ status = GetRegistrationsForOrigin(origin, ®istrations);
if (status != STATUS_OK)
return status;
+
+ // Delete registrations and resource records.
+ for (const RegistrationData& data : registrations) {
+ batch.Delete(CreateRegistrationKey(data.registration_id, origin));
+ status = DeleteResourceRecords(
+ data.version_id, newly_purgeable_resources, &batch);
+ if (status != STATUS_OK)
+ return status;
+ }
}
return WriteBatch(&batch);
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DestroyDatabase() {
DCHECK(sequence_checker_.CalledOnValidSequencedThread());
Disable(FROM_HERE, STATUS_OK);
+
+ leveldb::Options options;
+ if (path_.empty()) {
+ if (env_) {
+ options.env = env_.get();
+ } else {
+ // In-memory database not initialized.
+ return STATUS_OK;
+ }
+ }
+
return LevelDBStatusToStatus(
- leveldb::DestroyDB(path_.AsUTF8Unsafe(), leveldb::Options()));
+ leveldb::DestroyDB(path_.AsUTF8Unsafe(), options));
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::LazyOpen(