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

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

Issue 287843002: ServiceWorker: DB functions should return status code instead of boolean (2) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments partially 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"
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 253
254 ServiceWorkerStatusCode ServiceWorkerDatabase::GetNextAvailableIds( 254 ServiceWorkerStatusCode ServiceWorkerDatabase::GetNextAvailableIds(
255 int64* next_avail_registration_id, 255 int64* next_avail_registration_id,
256 int64* next_avail_version_id, 256 int64* next_avail_version_id,
257 int64* next_avail_resource_id) { 257 int64* next_avail_resource_id) {
258 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 258 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
259 DCHECK(next_avail_registration_id); 259 DCHECK(next_avail_registration_id);
260 DCHECK(next_avail_version_id); 260 DCHECK(next_avail_version_id);
261 DCHECK(next_avail_resource_id); 261 DCHECK(next_avail_resource_id);
262 262
263 if (!LazyOpen(false)) { 263 ServiceWorkerStatusCode status = LazyOpen(false);
264 if (is_disabled_) 264 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
265 return SERVICE_WORKER_ERROR_FAILED; 265 (status == SERVICE_WORKER_OK && !is_initialized_)) {
266 // Database has never been used. 266 // Database has never been used.
267 *next_avail_registration_id = 0; 267 *next_avail_registration_id = 0;
268 *next_avail_version_id = 0; 268 *next_avail_version_id = 0;
269 *next_avail_resource_id = 0; 269 *next_avail_resource_id = 0;
270 return SERVICE_WORKER_OK; 270 return SERVICE_WORKER_OK;
271 } 271 }
272 if (status != SERVICE_WORKER_OK)
273 return status;
272 274
273 ServiceWorkerStatusCode status = 275 status = ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_);
274 ReadNextAvailableId(kNextRegIdKey, &next_avail_registration_id_);
275 if (status != SERVICE_WORKER_OK) 276 if (status != SERVICE_WORKER_OK)
276 return status; 277 return status;
277 status = ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_); 278 status = ReadNextAvailableId(kNextVerIdKey, &next_avail_version_id_);
278 if (status != SERVICE_WORKER_OK) 279 if (status != SERVICE_WORKER_OK)
279 return status; 280 return status;
280 status = ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_); 281 status = ReadNextAvailableId(kNextResIdKey, &next_avail_resource_id_);
281 if (status != SERVICE_WORKER_OK) 282 if (status != SERVICE_WORKER_OK)
282 return status; 283 return status;
283 284
284 *next_avail_registration_id = next_avail_registration_id_; 285 *next_avail_registration_id = next_avail_registration_id_;
285 *next_avail_version_id = next_avail_version_id_; 286 *next_avail_version_id = next_avail_version_id_;
286 *next_avail_resource_id = next_avail_resource_id_; 287 *next_avail_resource_id = next_avail_resource_id_;
287 return SERVICE_WORKER_OK; 288 return SERVICE_WORKER_OK;
288 } 289 }
289 290
290 ServiceWorkerStatusCode ServiceWorkerDatabase::GetOriginsWithRegistrations( 291 ServiceWorkerStatusCode ServiceWorkerDatabase::GetOriginsWithRegistrations(
291 std::set<GURL>* origins) { 292 std::set<GURL>* origins) {
292 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 293 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
293 DCHECK(origins); 294 DCHECK(origins->empty());
294 295
295 if (!LazyOpen(false)) { 296 ServiceWorkerStatusCode status = LazyOpen(false);
296 if (is_disabled_) 297 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
297 return SERVICE_WORKER_ERROR_FAILED; 298 (status == SERVICE_WORKER_OK && !is_initialized_)) {
298 // Database has never been used. 299 // Database has never been used.
299 origins->clear();
300 return SERVICE_WORKER_OK; 300 return SERVICE_WORKER_OK;
301 } 301 }
302 if (status != SERVICE_WORKER_OK)
303 return status;
302 304
303 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); 305 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
304 for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) { 306 for (itr->Seek(kUniqueOriginKey); itr->Valid(); itr->Next()) {
305 if (!itr->status().ok()) { 307 if (!itr->status().ok()) {
306 HandleError(FROM_HERE, itr->status()); 308 HandleError(FROM_HERE, itr->status());
307 origins->clear(); 309 origins->clear();
308 return LevelDBStatusToServiceWorkerStatusCode(itr->status()); 310 return LevelDBStatusToServiceWorkerStatusCode(itr->status());
309 } 311 }
310 312
311 std::string origin; 313 std::string origin;
312 if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin)) 314 if (!RemovePrefix(itr->key().ToString(), kUniqueOriginKey, &origin))
313 break; 315 break;
314 origins->insert(GURL(origin)); 316 origins->insert(GURL(origin));
315 } 317 }
316 return SERVICE_WORKER_OK; 318 return SERVICE_WORKER_OK;
317 } 319 }
318 320
319 bool ServiceWorkerDatabase::GetRegistrationsForOrigin( 321 ServiceWorkerStatusCode ServiceWorkerDatabase::GetRegistrationsForOrigin(
320 const GURL& origin, 322 const GURL& origin,
321 std::vector<RegistrationData>* registrations) { 323 std::vector<RegistrationData>* registrations) {
322 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 324 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
323 DCHECK(registrations); 325 DCHECK(registrations->empty());
324 326
325 if (!LazyOpen(false)) { 327 ServiceWorkerStatusCode status = LazyOpen(false);
326 if (is_disabled_) 328 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
327 return false; 329 (status == SERVICE_WORKER_OK && !is_initialized_)) {
328 // Database has never been used. 330 // Database has never been used.
329 registrations->clear(); 331 return SERVICE_WORKER_OK;
330 return true;
331 } 332 }
333 if (status != SERVICE_WORKER_OK)
334 return status;
332 335
333 // Create a key prefix for registrations. 336 // Create a key prefix for registrations.
334 std::string prefix = base::StringPrintf( 337 std::string prefix = base::StringPrintf(
335 "%s%s%c", kRegKeyPrefix, origin.spec().c_str(), kKeySeparator); 338 "%s%s%c", kRegKeyPrefix, origin.spec().c_str(), kKeySeparator);
336 339
337 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); 340 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
338 for (itr->Seek(prefix); itr->Valid(); itr->Next()) { 341 for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
339 if (!itr->status().ok()) { 342 if (!itr->status().ok()) {
340 HandleError(FROM_HERE, itr->status()); 343 HandleError(FROM_HERE, itr->status());
341 registrations->clear(); 344 registrations->clear();
342 return false; 345 return LevelDBStatusToServiceWorkerStatusCode(itr->status());
343 } 346 }
344 347
345 if (!RemovePrefix(itr->key().ToString(), prefix, NULL)) 348 if (!RemovePrefix(itr->key().ToString(), prefix, NULL))
346 break; 349 break;
347 350
348 RegistrationData registration; 351 RegistrationData registration;
349 if (!ParseRegistrationData(itr->value().ToString(), &registration)) { 352 if (!ParseRegistrationData(itr->value().ToString(), &registration)) {
350 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse")); 353 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
351 registrations->clear(); 354 registrations->clear();
352 return false; 355 return SERVICE_WORKER_ERROR_DB_CORRUPTED;
353 } 356 }
354 registrations->push_back(registration); 357 registrations->push_back(registration);
355 } 358 }
356 return true; 359 return SERVICE_WORKER_OK;
357 } 360 }
358 361
359 bool ServiceWorkerDatabase::GetAllRegistrations( 362 ServiceWorkerStatusCode ServiceWorkerDatabase::GetAllRegistrations(
360 std::vector<RegistrationData>* registrations) { 363 std::vector<RegistrationData>* registrations) {
361 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 364 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
362 DCHECK(registrations); 365 DCHECK(registrations->empty());
363 366
364 if (!LazyOpen(false)) { 367 ServiceWorkerStatusCode status = LazyOpen(false);
365 if (is_disabled_) 368 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
366 return false; 369 (status == SERVICE_WORKER_OK && !is_initialized_)) {
367 // Database has never been used. 370 // Database has never been used.
368 registrations->clear(); 371 return SERVICE_WORKER_OK;
369 return true;
370 } 372 }
373 if (status != SERVICE_WORKER_OK)
374 return status;
371 375
372 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); 376 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
373 for (itr->Seek(kRegKeyPrefix); itr->Valid(); itr->Next()) { 377 for (itr->Seek(kRegKeyPrefix); itr->Valid(); itr->Next()) {
374 if (!itr->status().ok()) { 378 if (!itr->status().ok()) {
375 HandleError(FROM_HERE, itr->status()); 379 HandleError(FROM_HERE, itr->status());
376 registrations->clear(); 380 registrations->clear();
377 return false; 381 return LevelDBStatusToServiceWorkerStatusCode(itr->status());
378 } 382 }
379 383
380 if (!RemovePrefix(itr->key().ToString(), kRegKeyPrefix, NULL)) 384 if (!RemovePrefix(itr->key().ToString(), kRegKeyPrefix, NULL))
381 break; 385 break;
382 386
383 RegistrationData registration; 387 RegistrationData registration;
384 if (!ParseRegistrationData(itr->value().ToString(), &registration)) { 388 if (!ParseRegistrationData(itr->value().ToString(), &registration)) {
385 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse")); 389 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
386 registrations->clear(); 390 registrations->clear();
387 return false; 391 return SERVICE_WORKER_ERROR_DB_CORRUPTED;
388 } 392 }
389 registrations->push_back(registration); 393 registrations->push_back(registration);
390 } 394 }
391 return true; 395 return SERVICE_WORKER_OK;
392 } 396 }
393 397
394 bool ServiceWorkerDatabase::ReadRegistration( 398 bool ServiceWorkerDatabase::ReadRegistration(
395 int64 registration_id, 399 int64 registration_id,
396 const GURL& origin, 400 const GURL& origin,
397 RegistrationData* registration, 401 RegistrationData* registration,
398 std::vector<ResourceRecord>* resources) { 402 std::vector<ResourceRecord>* resources) {
399 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 403 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
400 DCHECK(registration); 404 DCHECK(registration);
401 DCHECK(resources); 405 DCHECK(resources);
402 406
403 if (!LazyOpen(false) || is_disabled_) 407 ServiceWorkerStatusCode status = LazyOpen(false);
408 if (status != SERVICE_WORKER_OK || !is_initialized_)
404 return false; 409 return false;
405 410
406 RegistrationData value; 411 RegistrationData value;
407 if (!ReadRegistrationData(registration_id, origin, &value)) 412 if (!ReadRegistrationData(registration_id, origin, &value))
408 return false; 413 return false;
409 414
410 if (!ReadResourceRecords(value.version_id, resources)) 415 if (!ReadResourceRecords(value.version_id, resources))
411 return false; 416 return false;
412 417
413 *registration = value; 418 *registration = value;
414 return true; 419 return true;
415 } 420 }
416 421
417 bool ServiceWorkerDatabase::WriteRegistration( 422 bool ServiceWorkerDatabase::WriteRegistration(
418 const RegistrationData& registration, 423 const RegistrationData& registration,
419 const std::vector<ResourceRecord>& resources) { 424 const std::vector<ResourceRecord>& resources) {
420 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 425 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
421 if (!LazyOpen(true) || is_disabled_) 426 if (LazyOpen(true) != SERVICE_WORKER_OK)
422 return false; 427 return false;
423 428
424 leveldb::WriteBatch batch; 429 leveldb::WriteBatch batch;
425 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch); 430 BumpNextRegistrationIdIfNeeded(registration.registration_id, &batch);
426 BumpNextVersionIdIfNeeded(registration.version_id, &batch); 431 BumpNextVersionIdIfNeeded(registration.version_id, &batch);
427 432
428 // TODO(nhiroki): Skip to add the origin into the unique origin list if it 433 // TODO(nhiroki): Skip to add the origin into the unique origin list if it
429 // has already been added. 434 // has already been added.
430 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch); 435 PutUniqueOriginToBatch(registration.scope.GetOrigin(), &batch);
431 436
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 batch.Delete(CreateResourceIdKey( 472 batch.Delete(CreateResourceIdKey(
468 kUncommittedResIdKeyPrefix, itr->resource_id)); 473 kUncommittedResIdKeyPrefix, itr->resource_id));
469 } 474 }
470 475
471 return WriteBatch(&batch); 476 return WriteBatch(&batch);
472 } 477 }
473 478
474 bool ServiceWorkerDatabase::UpdateVersionToActive(int64 registration_id, 479 bool ServiceWorkerDatabase::UpdateVersionToActive(int64 registration_id,
475 const GURL& origin) { 480 const GURL& origin) {
476 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 481 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
477 if (!LazyOpen(false) || is_disabled_) 482 if (LazyOpen(false) != SERVICE_WORKER_OK || !is_initialized_)
478 return false; 483 return false;
479 484
480 RegistrationData registration; 485 RegistrationData registration;
481 if (!ReadRegistrationData(registration_id, origin, &registration)) 486 if (!ReadRegistrationData(registration_id, origin, &registration))
482 return false; 487 return false;
483 488
484 registration.is_active = true; 489 registration.is_active = true;
485 490
486 leveldb::WriteBatch batch; 491 leveldb::WriteBatch batch;
487 PutRegistrationDataToBatch(registration, &batch); 492 PutRegistrationDataToBatch(registration, &batch);
488 return WriteBatch(&batch); 493 return WriteBatch(&batch);
489 } 494 }
490 495
491 bool ServiceWorkerDatabase::UpdateLastCheckTime(int64 registration_id, 496 bool ServiceWorkerDatabase::UpdateLastCheckTime(int64 registration_id,
492 const GURL& origin, 497 const GURL& origin,
493 const base::Time& time) { 498 const base::Time& time) {
494 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 499 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
495 if (!LazyOpen(false) || is_disabled_) 500 if (LazyOpen(false) != SERVICE_WORKER_OK || !is_initialized_)
496 return false; 501 return false;
497 502
498 RegistrationData registration; 503 RegistrationData registration;
499 if (!ReadRegistrationData(registration_id, origin, &registration)) 504 if (!ReadRegistrationData(registration_id, origin, &registration))
500 return false; 505 return false;
501 506
502 registration.last_update_check = time; 507 registration.last_update_check = time;
503 508
504 leveldb::WriteBatch batch; 509 leveldb::WriteBatch batch;
505 PutRegistrationDataToBatch(registration, &batch); 510 PutRegistrationDataToBatch(registration, &batch);
506 return WriteBatch(&batch); 511 return WriteBatch(&batch);
507 } 512 }
508 513
509 bool ServiceWorkerDatabase::DeleteRegistration(int64 registration_id, 514 bool ServiceWorkerDatabase::DeleteRegistration(int64 registration_id,
510 const GURL& origin) { 515 const GURL& origin) {
511 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 516 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
512 if (!LazyOpen(false) || is_disabled_) 517 ServiceWorkerStatusCode status = LazyOpen(false);
518 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
519 (status == SERVICE_WORKER_OK && !is_initialized_)) {
520 // Database has never been used.
521 return true;
522 }
523 if (status != SERVICE_WORKER_OK || !origin.is_valid())
513 return false; 524 return false;
514 525
515 leveldb::WriteBatch batch; 526 leveldb::WriteBatch batch;
516 527
517 // Remove |origin| from unique origins if a registration specified by 528 // Remove |origin| from unique origins if a registration specified by
518 // |registration_id| is the only one for |origin|. 529 // |registration_id| is the only one for |origin|.
519 // TODO(nhiroki): Check the uniqueness by more efficient way. 530 // TODO(nhiroki): Check the uniqueness by more efficient way.
520 std::vector<RegistrationData> registrations; 531 std::vector<RegistrationData> registrations;
521 if (!GetRegistrationsForOrigin(origin, &registrations)) 532 if (GetRegistrationsForOrigin(origin, &registrations) != SERVICE_WORKER_OK)
522 return false; 533 return false;
523 if (registrations.size() == 1 && 534 if (registrations.size() == 1 &&
524 registrations[0].registration_id == registration_id) { 535 registrations[0].registration_id == registration_id) {
525 batch.Delete(CreateUniqueOriginKey(origin)); 536 batch.Delete(CreateUniqueOriginKey(origin));
526 } 537 }
527 538
528 // Delete a registration specified by |registration_id|. 539 // Delete a registration specified by |registration_id|.
529 batch.Delete(CreateRegistrationKey(registration_id, origin)); 540 batch.Delete(CreateRegistrationKey(registration_id, origin));
530 541
531 // Delete resource records associated with the registration. 542 // Delete resource records associated with the registration.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 return WriteResourceIds(kPurgeableResIdKeyPrefix, ids); 575 return WriteResourceIds(kPurgeableResIdKeyPrefix, ids);
565 } 576 }
566 577
567 bool ServiceWorkerDatabase::ClearPurgeableResourceIds( 578 bool ServiceWorkerDatabase::ClearPurgeableResourceIds(
568 const std::set<int64>& ids) { 579 const std::set<int64>& ids) {
569 return DeleteResourceIds(kPurgeableResIdKeyPrefix, ids); 580 return DeleteResourceIds(kPurgeableResIdKeyPrefix, ids);
570 } 581 }
571 582
572 bool ServiceWorkerDatabase::DeleteAllDataForOrigin(const GURL& origin) { 583 bool ServiceWorkerDatabase::DeleteAllDataForOrigin(const GURL& origin) {
573 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 584 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
574 if (!LazyOpen(true) || is_disabled_ || !origin.is_valid()) 585 ServiceWorkerStatusCode status = LazyOpen(false);
586 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
587 (status == SERVICE_WORKER_OK && !is_initialized_)) {
588 // Database has never been used.
589 return true;
590 }
591 if (status != SERVICE_WORKER_OK || !origin.is_valid())
575 return false; 592 return false;
576 593
577 leveldb::WriteBatch batch; 594 leveldb::WriteBatch batch;
578 595
579 // Delete from the unique origin list. 596 // Delete from the unique origin list.
580 batch.Delete(CreateUniqueOriginKey(origin)); 597 batch.Delete(CreateUniqueOriginKey(origin));
581 598
582 std::vector<RegistrationData> registrations; 599 std::vector<RegistrationData> registrations;
583 if (!GetRegistrationsForOrigin(origin, &registrations)) 600 if (GetRegistrationsForOrigin(origin, &registrations) != SERVICE_WORKER_OK)
584 return false; 601 return false;
585 602
586 // Delete registrations and resource records. 603 // Delete registrations and resource records.
587 for (std::vector<RegistrationData>::const_iterator itr = 604 for (std::vector<RegistrationData>::const_iterator itr =
588 registrations.begin(); itr != registrations.end(); ++itr) { 605 registrations.begin(); itr != registrations.end(); ++itr) {
589 batch.Delete(CreateRegistrationKey(itr->registration_id, origin)); 606 batch.Delete(CreateRegistrationKey(itr->registration_id, origin));
590 if (!DeleteResourceRecords(itr->version_id, &batch)) 607 if (!DeleteResourceRecords(itr->version_id, &batch))
591 return false; 608 return false;
592 } 609 }
593 610
594 return WriteBatch(&batch); 611 return WriteBatch(&batch);
595 } 612 }
596 613
597 bool ServiceWorkerDatabase::LazyOpen(bool create_if_needed) { 614 ServiceWorkerStatusCode ServiceWorkerDatabase::LazyOpen(
615 bool create_if_missing) {
598 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 616 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
599 if (IsOpen())
600 return true;
601 617
602 // Do not try to open a database if we tried and failed once. 618 // Do not try to open a database if we tried and failed once.
603 if (is_disabled_) 619 if (is_disabled_)
604 return false; 620 return SERVICE_WORKER_ERROR_FAILED;
621 if (IsOpen())
622 return SERVICE_WORKER_OK;
605 623
606 // When |path_| is empty, open a database in-memory. 624 // When |path_| is empty, open a database in-memory.
607 bool use_in_memory_db = path_.empty(); 625 bool use_in_memory_db = path_.empty();
608 626
609 if (!create_if_needed) { 627 if (!create_if_missing) {
610 // Avoid opening a database if it does not exist at the |path_|. 628 // Avoid opening a database if it does not exist at the |path_|.
611 if (use_in_memory_db || 629 if (use_in_memory_db ||
612 !base::PathExists(path_) || 630 !base::PathExists(path_) ||
613 base::IsDirectoryEmpty(path_)) { 631 base::IsDirectoryEmpty(path_)) {
614 return false; 632 return SERVICE_WORKER_ERROR_NOT_FOUND;
615 } 633 }
616 } 634 }
617 635
618 leveldb::Options options; 636 leveldb::Options options;
619 options.create_if_missing = create_if_needed; 637 options.create_if_missing = create_if_missing;
620 if (use_in_memory_db) { 638 if (use_in_memory_db) {
621 env_.reset(leveldb::NewMemEnv(leveldb::Env::Default())); 639 env_.reset(leveldb::NewMemEnv(leveldb::Env::Default()));
622 options.env = env_.get(); 640 options.env = env_.get();
623 } 641 }
624 642
625 leveldb::DB* db = NULL; 643 leveldb::DB* db = NULL;
626 leveldb::Status status = 644 leveldb::Status db_status =
627 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db); 645 leveldb::DB::Open(options, path_.AsUTF8Unsafe(), &db);
628 if (!status.ok()) { 646 if (!db_status.ok()) {
629 DCHECK(!db); 647 DCHECK(!db);
630 // TODO(nhiroki): Should we retry to open the database? 648 // TODO(nhiroki): Should we retry to open the database?
631 HandleError(FROM_HERE, status); 649 HandleError(FROM_HERE, db_status);
632 return false; 650 return LevelDBStatusToServiceWorkerStatusCode(db_status);
633 } 651 }
634 db_.reset(db); 652 db_.reset(db);
635 653
636 int64 db_version; 654 int64 db_version;
637 if (!ReadDatabaseVersion(&db_version)) 655 ServiceWorkerStatusCode status = ReadDatabaseVersion(&db_version);
638 return false; 656 if (status != SERVICE_WORKER_OK)
657 return status;
658 DCHECK_LE(0, db_version);
639 if (db_version > 0) 659 if (db_version > 0)
640 is_initialized_ = true; 660 is_initialized_ = true;
641 return true; 661 return SERVICE_WORKER_OK;
642 } 662 }
643 663
644 ServiceWorkerStatusCode ServiceWorkerDatabase::ReadNextAvailableId( 664 ServiceWorkerStatusCode ServiceWorkerDatabase::ReadNextAvailableId(
645 const char* id_key, 665 const char* id_key,
646 int64* next_avail_id) { 666 int64* next_avail_id) {
647 DCHECK(id_key); 667 DCHECK(id_key);
648 DCHECK(next_avail_id); 668 DCHECK(next_avail_id);
649 669
650 std::string value; 670 std::string value;
651 leveldb::Status status = db_->Get(leveldb::ReadOptions(), id_key, &value); 671 leveldb::Status status = db_->Get(leveldb::ReadOptions(), id_key, &value);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 // supported, so we can purge this without caring about it. 775 // supported, so we can purge this without caring about it.
756 PutPurgeableResourceIdToBatch(resource_id, batch); 776 PutPurgeableResourceIdToBatch(resource_id, batch);
757 } 777 }
758 return true; 778 return true;
759 } 779 }
760 780
761 bool ServiceWorkerDatabase::ReadResourceIds(const char* id_key_prefix, 781 bool ServiceWorkerDatabase::ReadResourceIds(const char* id_key_prefix,
762 std::set<int64>* ids) { 782 std::set<int64>* ids) {
763 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 783 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
764 DCHECK(id_key_prefix); 784 DCHECK(id_key_prefix);
765 DCHECK(ids); 785 DCHECK(ids->clear());
nhiroki 2014/05/16 02:48:20 Oops... will fix this.
766 786
767 if (!LazyOpen(false) || is_disabled_) 787 ServiceWorkerStatusCode status = LazyOpen(false);
788 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
789 (status == SERVICE_WORKER_OK && !is_initialized_)) {
790 // Database has never been used.
791 return true;
792 }
793 if (status != SERVICE_WORKER_OK)
768 return false; 794 return false;
769 795
770 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions())); 796 scoped_ptr<leveldb::Iterator> itr(db_->NewIterator(leveldb::ReadOptions()));
771 for (itr->Seek(id_key_prefix); itr->Valid(); itr->Next()) { 797 for (itr->Seek(id_key_prefix); itr->Valid(); itr->Next()) {
772 if (!itr->status().ok()) { 798 if (!itr->status().ok()) {
773 HandleError(FROM_HERE, itr->status()); 799 HandleError(FROM_HERE, itr->status());
774 ids->clear(); 800 ids->clear();
775 return false; 801 return false;
776 } 802 }
777 803
(...skipping 10 matching lines...) Expand all
788 ids->insert(resource_id); 814 ids->insert(resource_id);
789 } 815 }
790 return true; 816 return true;
791 } 817 }
792 818
793 bool ServiceWorkerDatabase::WriteResourceIds(const char* id_key_prefix, 819 bool ServiceWorkerDatabase::WriteResourceIds(const char* id_key_prefix,
794 const std::set<int64>& ids) { 820 const std::set<int64>& ids) {
795 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 821 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
796 DCHECK(id_key_prefix); 822 DCHECK(id_key_prefix);
797 823
798 if (!LazyOpen(true) || is_disabled_) 824 if (LazyOpen(true) != SERVICE_WORKER_OK)
799 return false; 825 return false;
800 if (ids.empty()) 826 if (ids.empty())
801 return true; 827 return true;
802 828
803 leveldb::WriteBatch batch; 829 leveldb::WriteBatch batch;
804 for (std::set<int64>::const_iterator itr = ids.begin(); 830 for (std::set<int64>::const_iterator itr = ids.begin();
805 itr != ids.end(); ++itr) { 831 itr != ids.end(); ++itr) {
806 // Value should be empty. 832 // Value should be empty.
807 batch.Put(CreateResourceIdKey(id_key_prefix, *itr), ""); 833 batch.Put(CreateResourceIdKey(id_key_prefix, *itr), "");
808 } 834 }
809 return WriteBatch(&batch); 835 return WriteBatch(&batch);
810 } 836 }
811 837
812 bool ServiceWorkerDatabase::DeleteResourceIds(const char* id_key_prefix, 838 bool ServiceWorkerDatabase::DeleteResourceIds(const char* id_key_prefix,
813 const std::set<int64>& ids) { 839 const std::set<int64>& ids) {
814 DCHECK(sequence_checker_.CalledOnValidSequencedThread()); 840 DCHECK(sequence_checker_.CalledOnValidSequencedThread());
815 DCHECK(id_key_prefix); 841 DCHECK(id_key_prefix);
816 842
817 if (!LazyOpen(true) || is_disabled_) 843 ServiceWorkerStatusCode status = LazyOpen(false);
844 if (status == SERVICE_WORKER_ERROR_NOT_FOUND ||
845 (status == SERVICE_WORKER_OK && !is_initialized_)) {
846 // Database has never been used.
847 return true;
848 }
849 if (status != SERVICE_WORKER_OK)
818 return false; 850 return false;
851
819 if (ids.empty()) 852 if (ids.empty())
820 return true; 853 return true;
821 854
822 leveldb::WriteBatch batch; 855 leveldb::WriteBatch batch;
823 for (std::set<int64>::const_iterator itr = ids.begin(); 856 for (std::set<int64>::const_iterator itr = ids.begin();
824 itr != ids.end(); ++itr) { 857 itr != ids.end(); ++itr) {
825 batch.Delete(CreateResourceIdKey(id_key_prefix, *itr)); 858 batch.Delete(CreateResourceIdKey(id_key_prefix, *itr));
826 } 859 }
827 return WriteBatch(&batch); 860 return WriteBatch(&batch);
828 } 861 }
829 862
830 bool ServiceWorkerDatabase::ReadDatabaseVersion(int64* db_version) { 863 ServiceWorkerStatusCode ServiceWorkerDatabase::ReadDatabaseVersion(
864 int64* db_version) {
831 std::string value; 865 std::string value;
832 leveldb::Status status = 866 leveldb::Status status =
833 db_->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value); 867 db_->Get(leveldb::ReadOptions(), kDatabaseVersionKey, &value);
834 if (status.IsNotFound()) { 868 if (status.IsNotFound()) {
835 // The database hasn't been initialized yet. 869 // The database hasn't been initialized yet.
836 *db_version = 0; 870 *db_version = 0;
837 return true; 871 return SERVICE_WORKER_OK;
838 } 872 }
839 if (!status.ok()) { 873 if (!status.ok()) {
840 HandleError(FROM_HERE, status); 874 HandleError(FROM_HERE, status);
841 return false; 875 return LevelDBStatusToServiceWorkerStatusCode(status);
842 } 876 }
843 877
844 int64 parsed; 878 int64 parsed;
845 if (!base::StringToInt64(value, &parsed)) { 879 if (!base::StringToInt64(value, &parsed)) {
846 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse")); 880 HandleError(FROM_HERE, leveldb::Status::Corruption("failed to parse"));
847 return false; 881 return SERVICE_WORKER_ERROR_DB_CORRUPTED;
848 } 882 }
849 883
850 const int kFirstValidVersion = 1; 884 const int kFirstValidVersion = 1;
851 if (parsed < kFirstValidVersion || kCurrentSchemaVersion < parsed) { 885 if (parsed < kFirstValidVersion || kCurrentSchemaVersion < parsed) {
852 HandleError(FROM_HERE, leveldb::Status::Corruption("invalid DB version")); 886 HandleError(FROM_HERE, leveldb::Status::Corruption("invalid DB version"));
853 return false; 887 return SERVICE_WORKER_ERROR_DB_CORRUPTED;
854 } 888 }
855 889
856 *db_version = parsed; 890 *db_version = parsed;
857 return true; 891 return SERVICE_WORKER_OK;
858 } 892 }
859 893
860 bool ServiceWorkerDatabase::WriteBatch(leveldb::WriteBatch* batch) { 894 bool ServiceWorkerDatabase::WriteBatch(leveldb::WriteBatch* batch) {
861 DCHECK(batch); 895 DCHECK(batch);
862 DCHECK(!is_disabled_); 896 DCHECK(!is_disabled_);
863 897
864 if (!is_initialized_) { 898 if (!is_initialized_) {
865 // Write the database schema version. 899 // Write the database schema version.
866 batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion)); 900 batch->Put(kDatabaseVersionKey, base::Int64ToString(kCurrentSchemaVersion));
867 is_initialized_ = true; 901 is_initialized_ = true;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 // TODO(nhiroki): Add an UMA histogram. 937 // TODO(nhiroki): Add an UMA histogram.
904 DLOG(ERROR) << "Failed at: " << from_here.ToString() 938 DLOG(ERROR) << "Failed at: " << from_here.ToString()
905 << " with error: " << status.ToString(); 939 << " with error: " << status.ToString();
906 is_disabled_ = true; 940 is_disabled_ = true;
907 if (status.IsCorruption()) 941 if (status.IsCorruption())
908 was_corruption_detected_ = true; 942 was_corruption_detected_ = true;
909 db_.reset(); 943 db_.reset();
910 } 944 }
911 945
912 } // namespace content 946 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698