Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: content/browser/service_worker/service_worker_database.cc

Issue 248803003: ServiceWorker: Store registration data in ServiceWorkerDatabase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix win build Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "base/strings/stringprintf.h"
16 #include "content/browser/service_worker/service_worker_database.pb.h"
13 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h" 17 #include "third_party/leveldatabase/src/helpers/memenv/memenv.h"
14 #include "third_party/leveldatabase/src/include/leveldb/db.h" 18 #include "third_party/leveldatabase/src/include/leveldb/db.h"
15 #include "third_party/leveldatabase/src/include/leveldb/env.h" 19 #include "third_party/leveldatabase/src/include/leveldb/env.h"
16 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 20 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
17 21
18 // LevelDB database schema 22 // LevelDB database schema
19 // ======================= 23 // =======================
20 // 24 //
21 // NOTE 25 // NOTE
22 // - int64 value is serialized as a string by base::Int64ToString(). 26 // - int64 value is serialized as a string by base::Int64ToString().
27 // - GURL value is serialized as a string by GURL::spec().
23 // 28 //
24 // Version 1 (in sorted order) 29 // Version 1 (in sorted order)
25 // key: "DB_VERSION" 30 // key: "INITDATA_DB_VERSION"
26 // value: "1" 31 // value: "1"
27 // 32 //
28 // key: "NEXT_REGISTRATION_ID" 33 // key: "INITDATA_NEXT_REGISTRATION_ID"
29 // value: <int64 'next_available_registration_id'> 34 // value: <int64 'next_available_registration_id'>
30 // 35 //
31 // key: "NEXT_RESOURCE_ID" 36 // key: "INITDATA_NEXT_RESOURCE_ID"
32 // value: <int64 'next_available_resource_id'> 37 // value: <int64 'next_available_resource_id'>
33 // 38 //
34 // key: "NEXT_VERSION_ID" 39 // key: "INITDATA_NEXT_VERSION_ID"
35 // value: <int64 'next_available_version_id'> 40 // value: <int64 'next_available_version_id'>
41 //
42 // key: "INITDATA_UNIQUE_ORIGIN:" + <GURL 'origin'>
43 // value: <empty>
44 //
45 // key: "REG:" + <GURL 'origin'> + '\x00' + <int64 'registration_id'>
46 // (ex. "REG:http://example.com\x00123456")
47 // value: <ServiceWorkerRegistrationData serialized as a string>
36 48
37 namespace content { 49 namespace content {
38 50
39 namespace { 51 namespace {
40 52
41 const char kDatabaseVersionKey[] = "DB_VERSION"; 53 const char kDatabaseVersionKey[] = "INITDATA_DB_VERSION";
42 const char kNextRegIdKey[] = "NEXT_REGISTRATION_ID"; 54 const char kNextRegIdKey[] = "INITDATA_NEXT_REGISTRATION_ID";
43 const char kNextResIdKey[] = "NEXT_RESOURCE_ID"; 55 const char kNextResIdKey[] = "INITDATA_NEXT_RESOURCE_ID";
44 const char kNextVerIdKey[] = "NEXT_VERSION_ID"; 56 const char kNextVerIdKey[] = "INITDATA_NEXT_VERSION_ID";
57 const char kUniqueOriginKey[] = "INITDATA_UNIQUE_ORIGIN:";
58
59 const char kRegKeyPrefix[] = "REG:";
60 const char kKeySeparator = '\x00';
45 61
46 const int64 kCurrentSchemaVersion = 1; 62 const int64 kCurrentSchemaVersion = 1;
47 63
64 bool RemovePrefix(const std::string& str,
65 const std::string& prefix,
66 std::string* out) {
67 if (!StartsWithASCII(str, prefix, true))
68 return false;
69 if (out)
70 *out = str.substr(prefix.size());
71 return true;
72 }
73
74 std::string CreateRegistrationKey(int64 registration_id,
75 const GURL& origin) {
76 return base::StringPrintf("%s%s%c%s",
77 kRegKeyPrefix,
78 origin.spec().c_str(),
79 kKeySeparator,
80 base::Int64ToString(registration_id).c_str());
81 }
82
83 std::string CreateUniqueOriginKey(const GURL& origin) {
84 return base::StringPrintf("%s%s", kUniqueOriginKey, origin.spec().c_str());
85 }
86
87 void PutRegistrationDataToBatch(
88 const ServiceWorkerDatabase::RegistrationData& input,
89 leveldb::WriteBatch* batch) {
90 DCHECK(batch);
91
92 // Convert RegistrationData to ServiceWorkerRegistrationData.
93 ServiceWorkerRegistrationData data;
94 data.set_registration_id(input.registration_id);
95 data.set_scope_url(input.scope.spec());
96 data.set_script_url(input.script.spec());
97 data.set_version_id(input.version_id);
98 data.set_is_active(input.is_active);
99 data.set_has_fetch_handler(input.has_fetch_handler);
100 data.set_last_update_check_time(input.last_update_check.ToInternalValue());
101
102 std::string value;
103 bool success = data.SerializeToString(&value);
104 DCHECK(success);
105 GURL origin = input.scope.GetOrigin();
106 batch->Put(CreateRegistrationKey(data.registration_id(), origin), value);
107 }
108
109 void PutUniqueOriginToBatch(const GURL& origin,
110 leveldb::WriteBatch* batch) {
111 // Value should be empty.
112 batch->Put(CreateUniqueOriginKey(origin), "");
113 }
114
115 bool ParseRegistrationData(
116 const std::string& serialized,
117 ServiceWorkerDatabase::RegistrationData* out) {
118 DCHECK(out);
119 ServiceWorkerRegistrationData data;
120 if (!data.ParseFromString(serialized))
121 return false;
122
123 GURL scope_url(data.scope_url());
124 GURL script_url(data.script_url());
125 if (scope_url.GetOrigin() != script_url.GetOrigin())
126 return false;
127
128 // Convert ServiceWorkerRegistrationData to RegistrationData.
129 out->registration_id = data.registration_id();
130 out->scope = scope_url;
131 out->script = script_url;
132 out->version_id = data.version_id();
133 out->is_active = data.is_active();
134 out->has_fetch_handler = data.has_fetch_handler();
135 out->last_update_check =
136 base::Time::FromInternalValue(data.last_update_check_time());
137 return true;
138 }
139
48 } // namespace 140 } // namespace
49 141
50 ServiceWorkerDatabase::RegistrationData::RegistrationData() 142 ServiceWorkerDatabase::RegistrationData::RegistrationData()
51 : registration_id(-1), 143 : registration_id(-1),
52 version_id(-1), 144 version_id(-1),
53 is_active(false), 145 is_active(false),
54 has_fetch_handler(false) { 146 has_fetch_handler(false) {
55 } 147 }
56 148
57 ServiceWorkerDatabase::RegistrationData::~RegistrationData() { 149 ServiceWorkerDatabase::RegistrationData::~RegistrationData() {
58 } 150 }
59 151
60 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path) 152 ServiceWorkerDatabase::ServiceWorkerDatabase(const base::FilePath& path)
61 : path_(path), 153 : path_(path),
154 next_avail_registration_id_(0),
155 next_avail_resource_id_(0),
156 next_avail_version_id_(0),
62 is_disabled_(false), 157 is_disabled_(false),
63 was_corruption_detected_(false) { 158 was_corruption_detected_(false) {
64 } 159 }
65 160
66 ServiceWorkerDatabase::~ServiceWorkerDatabase() { 161 ServiceWorkerDatabase::~ServiceWorkerDatabase() {
67 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 162 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
68 db_.reset(); 163 db_.reset();
69 } 164 }
70 165
71 bool ServiceWorkerDatabase::GetNextAvailableIds( 166 bool ServiceWorkerDatabase::GetNextAvailableIds(
72 int64* next_avail_registration_id, 167 int64* next_avail_registration_id,
73 int64* next_avail_version_id, 168 int64* next_avail_version_id,
74 int64* next_avail_resource_id) { 169 int64* next_avail_resource_id) {
75 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 170 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
76 DCHECK(next_avail_registration_id); 171 DCHECK(next_avail_registration_id);
77 DCHECK(next_avail_version_id); 172 DCHECK(next_avail_version_id);
78 DCHECK(next_avail_resource_id); 173 DCHECK(next_avail_resource_id);
79 174
80 if (!LazyOpen(false) || is_disabled_) 175 if (!LazyOpen(false) || is_disabled_)
81 return false; 176 return false;
82 177
83 int64 reg_id = -1; 178 if (!ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_) ||
84 int64 ver_id = -1; 179 !ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_) ||
85 int64 res_id = -1; 180 !ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_)) {
181 return false;
182 }
86 183
87 if (!ReadNextAvailableId(kNextRegIdKey, &reg_id) || 184 *next_avail_registration_id = next_avail_registration_id_;
88 !ReadNextAvailableId(kNextVerIdKey, &ver_id) || 185 *next_avail_version_id = next_avail_version_id_;
89 !ReadNextAvailableId(kNextResIdKey, &res_id)) 186 *next_avail_resource_id = next_avail_resource_id_;
187 return true;
188 }
189
190 bool ServiceWorkerDatabase::GetOriginsWithRegistrations(
191 std::set<GURL>* origins) {
192 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
193 DCHECK(origins);
194
195 if (!LazyOpen(false) || is_disabled_)
90 return false; 196 return false;
91 197
92 *next_avail_registration_id = reg_id; 198 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
93 *next_avail_version_id = ver_id; 199 for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) {
94 *next_avail_resource_id = res_id; 200 if (!itr->status().ok()) {
201 HandleError(FROM_HERE, itr->status());
202 origins->clear();
203 return false;
204 }
205
206 std::string origin;
207 if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin))
208 break;
209 origins->insert(GURL(origin));
210 }
95 return true; 211 return true;
96 } 212 }
97 213
214 bool ServiceWorkerDatabase::GetRegistrationsForOrigin(
215 const GURL& origin,
216 std::vector<RegistrationData>* registrations) {
217 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
218 DCHECK(registrations);
219
220 if (!LazyOpen(false) || is_disabled_)
221 return false;
222
223 // Create a key prefix for registrations.
224 std::string prefix = base::StringPrintf(
225 "%s%s%c", kRegKeyPrefix, origin.spec().c_str(), kKeySeparator);
226
227 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
228 for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
229 if (!itr->status().ok()) {
230 HandleError(FROM_HERE, itr->status());
231 registrations->clear();
232 return false;
233 }
234
235 if (!RemovePrefix(itr->key().ToString(), prefix, NULL))
236 break;
237
238 RegistrationData registration;
239 if (!ParseRegistrationData(itr->value().ToString(), &registration)) {
240 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
241 registrations->clear();
242 return false;
243 }
244 registrations->push_back(registration);
245 }
246 return true;
247 }
248
249 bool ServiceWorkerDatabase::ReadRegistration(
250 int64 registration_id,
251 const GURL& origin,
252 RegistrationData* registration,
253 std::vector<ResourceRecord>* resources) {
254 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
255 DCHECK(registration);
256 DCHECK(resources);
257
258 if (!LazyOpen(false) || is_disabled_)
259 return false;
260
261 RegistrationData value;
262 if (!ReadRegistrationData(registration_id, origin, &value))
263 return false;
264
265 // TODO(nhiroki): Read ResourceRecords tied with this registration.
266
267 *registration = value;
268 return true;
269 }
270
271 bool ServiceWorkerDatabase::WriteRegistration(
272 const RegistrationData& registration,
273 const std::vector<ResourceRecord>& resources) {
274 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
275 if (!LazyOpen(true) || is_disabled_)
276 return false;
277
278 leveldb::WriteBatch batch;
279 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch);
280 BumpNextVersionIdIfNeeded(registration.version_id, &batch);
281
282 // TODO(nhiroki): Skip to add the origin into the unique origin list if it
283 // has already been added.
284 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch);
285
286 PutRegistrationDataToBatch(registration, &batch);
287
288 // TODO(nhiroki): Write |resources| into the database.
289 return WriteBatch(&batch);
290 }
291
292 bool ServiceWorkerDatabase::UpdateVersionToActive(int64 registration_id,
293 const GURL& origin) {
294 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
295 if (!LazyOpen(false) || is_disabled_)
296 return false;
297
298 RegistrationData registration;
299 if (!ReadRegistrationData(registration_id, origin, &registration))
300 return false;
301
302 registration.is_active = true;
303
304 leveldb::WriteBatch batch;
305 PutRegistrationDataToBatch(registration, &batch);
306 return WriteBatch(&batch);
307 }
308
309 bool ServiceWorkerDatabase::UpdateLastCheckTime(int64 registration_id,
310 const GURL& origin,
311 const base::Time& time) {
312 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
313 if (!LazyOpen(false) || is_disabled_)
314 return false;
315
316 RegistrationData registration;
317 if (!ReadRegistrationData(registration_id, origin, &registration))
318 return false;
319
320 registration.last_update_check = time;
321
322 leveldb::WriteBatch batch;
323 PutRegistrationDataToBatch(registration, &batch);
324 return WriteBatch(&batch);
325 }
326
327 bool ServiceWorkerDatabase::DeleteRegistration(int64 registration_id,
328 const GURL& origin) {
329 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
330 if (!LazyOpen(false) || is_disabled_)
331 return false;
332
333 leveldb::WriteBatch batch;
334
335 // Remove |origin| from unique origins if a registration specified by
336 // |registration_id| is the only one for |origin|.
337 // TODO(nhiroki): Check the uniqueness by more efficient way.
338 std::vector<RegistrationData> registrations;
339 if (!GetRegistrationsForOrigin(origin, &registrations))
340 return false;
341 if (registrations.size() == 1 &&
342 registrations[0].registration_id == registration_id) {
343 batch.Delete(CreateUniqueOriginKey(origin));
344 }
345
346 batch.Delete(CreateRegistrationKey(registration_id, origin));
347
348 // TODO(nhiroki): Delete ResourceRecords tied with this registration.
349 return WriteBatch(&batch);
350 }
351
98 bool ServiceWorkerDatabase::LazyOpen(bool create_if_needed) { 352 bool ServiceWorkerDatabase::LazyOpen(bool create_if_needed) {
99 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 353 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
100 if (IsOpen()) 354 if (IsOpen())
101 return true; 355 return true;
102 356
103 // Do not try to open a database if we tried and failed once. 357 // Do not try to open a database if we tried and failed once.
104 if (is_disabled_) 358 if (is_disabled_)
105 return false; 359 return false;
106 360
107 // When |path_| is empty, open a database in-memory. 361 // When |path_| is empty, open a database in-memory.
(...skipping 19 matching lines...) Expand all
127 leveldb::Status status = 381 leveldb::Status status =
128 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db); 382 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db);
129 if (!status.ok()) { 383 if (!status.ok()) {
130 DCHECK(!db); 384 DCHECK(!db);
131 // TODO(nhiroki): Should we retry to open the database? 385 // TODO(nhiroki): Should we retry to open the database?
132 HandleError(FROM_HERE, status); 386 HandleError(FROM_HERE, status);
133 return false; 387 return false;
134 } 388 }
135 db_.reset(db); 389 db_.reset(db);
136 390
137 if (IsEmpty() && !PopulateInitialData()) { 391 int64 db_version;
138 DLOG(ERROR) << "Failed to populate the database."; 392 if (!ReadDatabaseVersion(&db_version))
139 db_.reset();
140 return false; 393 return false;
141 } 394 if (db_version > 0)
395 is_initialized_ = true;
142 return true; 396 return true;
143 } 397 }
144 398
145 bool ServiceWorkerDatabase::PopulateInitialData() {
146 leveldb::WriteBatch batch;
147 batch.Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion));
148 batch.Put(kNextRegIdKey, base::Int64ToString(0));
149 batch.Put(kNextResIdKey, base::Int64ToString(0));
150 batch.Put(kNextVerIdKey, base::Int64ToString(0));
151 return WriteBatch(&batch);
152 }
153
154 bool ServiceWorkerDatabase::ReadNextAvailableId( 399 bool ServiceWorkerDatabase::ReadNextAvailableId(
155 const char* id_key, int64* next_avail_id) { 400 const char* id_key, int64* next_avail_id) {
156 DCHECK(id_key); 401 DCHECK(id_key);
157 DCHECK(next_avail_id); 402 DCHECK(next_avail_id);
158 403
159 std::string value; 404 std::string value;
160 leveldb::Status status = db_->Get(leveldb::ReadOptions(), id_key, &value); 405 leveldb::Status status = db_->Get(leveldb::ReadOptions(), id_key, &value);
406 if (status.IsNotFound()) {
407 // Nobody has gotten the next resource id for |id_key|.
408 *next_avail_id = 0;
409 return true;
410 }
411
161 if (!status.ok()) { 412 if (!status.ok()) {
162 HandleError(FROM_HERE, status); 413 HandleError(FROM_HERE, status);
163 return false; 414 return false;
164 } 415 }
165 416
166 int64 parsed; 417 int64 parsed;
167 if (!base::StringToInt64(value, &parsed)) { 418 if (!base::StringToInt64(value, &parsed)) {
168 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse")); 419 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
169 return false; 420 return false;
170 } 421 }
171 422
172 *next_avail_id = parsed; 423 *next_avail_id = parsed;
173 return true; 424 return true;
174 } 425 }
175 426
427 bool ServiceWorkerDatabase::ReadRegistrationData(
428 int64 registration_id,
429 const GURL& origin,
430 RegistrationData* registration) {
431 DCHECK(registration);
432
433 std::string key = CreateRegistrationKey(registration_id, origin);
434
435 std::string value;
436 leveldb::Status status = db_->Get(leveldb::ReadOptions(), key, &value);
437 if (!status.ok()) {
438 if (!status.IsNotFound())
439 HandleError(FROM_HERE, status);
440 return false;
441 }
442
443 RegistrationData parsed;
444 if (!ParseRegistrationData(value, &parsed)) {
445 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
446 return false;
447 }
448
449 *registration = parsed;
450 return true;
451 }
452
453 bool ServiceWorkerDatabase::ReadDatabaseVersion(int64* db_version) {
454 std::string value;
455 leveldb::Status status =
456 db_->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value);
457 if (status.IsNotFound()) {
458 // The database hasn't been initialized yet.
459 *db_version = 0;
460 return true;
461 }
462 if (!status.ok()) {
463 HandleError(FROM_HERE, status);
464 return false;
465 }
466
467 int64 parsed;
468 if (!base::StringToInt64(value, &parsed)) {
469 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
470 return false;
471 }
472
473 const int kFirstValidVersion = 1;
474 if (parsed < kFirstValidVersion || kCurrentSchemaVersion < parsed) {
475 HandleError(FROM_HERE, leveldb::Status::Corruption("invalid DB version"));
476 return false;
477 }
478
479 *db_version = parsed;
480 return true;
481 }
482
176 bool ServiceWorkerDatabase::WriteBatch(leveldb::WriteBatch* batch) { 483 bool ServiceWorkerDatabase::WriteBatch(leveldb::WriteBatch* batch) {
177 DCHECK(batch); 484 DCHECK(batch);
178 DCHECK(!is_disabled_); 485 DCHECK(!is_disabled_);
486
487 if (!is_initialized_) {
488 // Write the database schema version.
489 batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion));
490 is_initialized_ = true;
491 }
492
179 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch); 493 leveldb::Status status = db_->Write(leveldb::WriteOptions(), batch);
180 if (!status.ok()) { 494 if (!status.ok()) {
181 HandleError(FROM_HERE, status); 495 HandleError(FROM_HERE, status);
182 return false; 496 return false;
183 } 497 }
184 return true; 498 return true;
185 } 499 }
186 500
501 void ServiceWorkerDatabase::BumpNextRegistrationIdIfNeeded(
502 int64 used_id, leveldb::WriteBatch* batch) {
503 DCHECK(batch);
504 if (next_avail_registration_id_ <= used_id) {
505 next_avail_registration_id_ = used_id + 1;
506 batch->Put(kNextRegIdKey, base::Int64ToString(next_avail_registration_id_));
507 }
508 }
509
510 void ServiceWorkerDatabase::BumpNextVersionIdIfNeeded(
511 int64 used_id, leveldb::WriteBatch* batch) {
512 DCHECK(batch);
513 if (next_avail_version_id_ <= used_id) {
514 next_avail_version_id_ = used_id + 1;
515 batch->Put(kNextVerIdKey, base::Int64ToString(next_avail_version_id_));
516 }
517 }
518
187 bool ServiceWorkerDatabase::IsOpen() { 519 bool ServiceWorkerDatabase::IsOpen() {
188 return db_.get() != NULL; 520 return db_.get() != NULL;
189 } 521 }
190 522
191 bool ServiceWorkerDatabase::IsEmpty() {
192 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
193 itr->SeekToFirst();
194 // TODO(nhiroki): Handle an error.
195 DCHECK(itr->status().ok());
196 return !itr->Valid();
197 }
198
199 void ServiceWorkerDatabase::HandleError( 523 void ServiceWorkerDatabase::HandleError(
200 const tracked_objects::Location& from_here, 524 const tracked_objects::Location& from_here,
201 const leveldb::Status& status) { 525 const leveldb::Status& status) {
202 // TODO(nhiroki): Add an UMA histogram. 526 // TODO(nhiroki): Add an UMA histogram.
203 DLOG(ERROR) << "Failed at: " << from_here.ToString() 527 DLOG(ERROR) << "Failed at: " << from_here.ToString()
204 << " with error: " << status.ToString(); 528 << " with error: " << status.ToString();
205 is_disabled_ = true; 529 is_disabled_ = true;
206 if (status.IsCorruption()) 530 if (status.IsCorruption())
207 was_corruption_detected_ = true; 531 was_corruption_detected_ = true;
208 db_.reset(); 532 db_.reset();
209 } 533 }
210 534
211 } // namespace content 535 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_database.h ('k') | content/browser/service_worker/service_worker_database.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698