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

Side by Side Diff: content/browser/indexed_db/indexed_db_backing_store.cc

Issue 266333002: Add most of the metadata-handling code for blobs. It's not quite all there, but (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove debugging code; revert to approved version. 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/indexed_db/indexed_db_backing_store.h" 5 #include "content/browser/indexed_db/indexed_db_backing_store.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/format_macros.h" 9 #include "base/format_macros.h"
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 GET_NEW_DATABASE_ID, 121 GET_NEW_DATABASE_ID,
122 GET_NEW_VERSION_NUMBER, 122 GET_NEW_VERSION_NUMBER,
123 CREATE_IDBDATABASE_METADATA, 123 CREATE_IDBDATABASE_METADATA,
124 DELETE_DATABASE, 124 DELETE_DATABASE,
125 TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro 125 TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro
126 GET_DATABASE_NAMES, 126 GET_DATABASE_NAMES,
127 DELETE_INDEX, 127 DELETE_INDEX,
128 CLEAR_OBJECT_STORE, 128 CLEAR_OBJECT_STORE,
129 READ_BLOB_JOURNAL, 129 READ_BLOB_JOURNAL,
130 DECODE_BLOB_JOURNAL, 130 DECODE_BLOB_JOURNAL,
131 GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER,
132 GET_BLOB_INFO_FOR_RECORD,
131 INTERNAL_ERROR_MAX, 133 INTERNAL_ERROR_MAX,
132 }; 134 };
133 135
134 static void RecordInternalError(const char* type, 136 static void RecordInternalError(const char* type,
135 IndexedDBBackingStoreErrorSource location) { 137 IndexedDBBackingStoreErrorSource location) {
136 std::string name; 138 std::string name;
137 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error"); 139 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error");
138 base::Histogram::FactoryGet(name, 140 base::Histogram::FactoryGet(name,
139 1, 141 1,
140 INTERNAL_ERROR_MAX, 142 INTERNAL_ERROR_MAX,
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 return content::Compare(a, b, false /*index_keys*/); 299 return content::Compare(a, b, false /*index_keys*/);
298 } 300 }
299 301
300 const char* IndexedDBBackingStore::Comparator::Name() const { 302 const char* IndexedDBBackingStore::Comparator::Name() const {
301 return "idb_cmp1"; 303 return "idb_cmp1";
302 } 304 }
303 305
304 // 0 - Initial version. 306 // 0 - Initial version.
305 // 1 - Adds UserIntVersion to DatabaseMetaData. 307 // 1 - Adds UserIntVersion to DatabaseMetaData.
306 // 2 - Adds DataVersion to to global metadata. 308 // 2 - Adds DataVersion to to global metadata.
307 static const int64 kLatestKnownSchemaVersion = 2; 309 // 3 - Adds metadata needed for blob support.
310 static const int64 kLatestKnownSchemaVersion = 3;
308 WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) { 311 WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) {
309 int64 db_schema_version = 0; 312 int64 db_schema_version = 0;
310 bool found = false; 313 bool found = false;
311 leveldb::Status s = 314 leveldb::Status s =
312 GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found); 315 GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found);
313 if (!s.ok()) 316 if (!s.ok())
314 return false; 317 return false;
315 if (!found) { 318 if (!found) {
316 *known = true; 319 *known = true;
317 return true; 320 return true;
(...skipping 16 matching lines...) Expand all
334 337
335 if (db_data_version > latest_known_data_version) { 338 if (db_data_version > latest_known_data_version) {
336 *known = false; 339 *known = false;
337 return true; 340 return true;
338 } 341 }
339 342
340 *known = true; 343 *known = true;
341 return true; 344 return true;
342 } 345 }
343 346
344 WARN_UNUSED_RESULT static bool SetUpMetadata( 347 // TODO(ericu): Move this down into the member section of this file. I'm
345 LevelDBDatabase* db, 348 // leaving it here for this CL as it's easier to see the diffs in place.
346 const std::string& origin_identifier) { 349 WARN_UNUSED_RESULT bool IndexedDBBackingStore::SetUpMetadata() {
347 const uint32 latest_known_data_version = 350 const uint32 latest_known_data_version =
348 blink::kSerializedScriptValueVersion; 351 blink::kSerializedScriptValueVersion;
349 const std::string schema_version_key = SchemaVersionKey::Encode(); 352 const std::string schema_version_key = SchemaVersionKey::Encode();
350 const std::string data_version_key = DataVersionKey::Encode(); 353 const std::string data_version_key = DataVersionKey::Encode();
351 354
352 scoped_refptr<LevelDBTransaction> transaction = new LevelDBTransaction(db); 355 scoped_refptr<LevelDBTransaction> transaction =
356 new LevelDBTransaction(db_.get());
353 357
354 int64 db_schema_version = 0; 358 int64 db_schema_version = 0;
355 int64 db_data_version = 0; 359 int64 db_data_version = 0;
356 bool found = false; 360 bool found = false;
357 leveldb::Status s = 361 leveldb::Status s =
358 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found); 362 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
359 if (!s.ok()) { 363 if (!s.ok()) {
360 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 364 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
361 return false; 365 return false;
362 } 366 }
363 if (!found) { 367 if (!found) {
364 // Initialize new backing store. 368 // Initialize new backing store.
365 db_schema_version = kLatestKnownSchemaVersion; 369 db_schema_version = kLatestKnownSchemaVersion;
366 PutInt(transaction.get(), schema_version_key, db_schema_version); 370 PutInt(transaction.get(), schema_version_key, db_schema_version);
367 db_data_version = latest_known_data_version; 371 db_data_version = latest_known_data_version;
368 PutInt(transaction.get(), data_version_key, db_data_version); 372 PutInt(transaction.get(), data_version_key, db_data_version);
373 // If a blob directory already exists for this database, blow it away. It's
374 // leftover from a partially-purged previous generation of data.
375 if (!base::DeleteFile(blob_path_, true)) {
376 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
377 return false;
378 }
369 } else { 379 } else {
370 // Upgrade old backing store. 380 // Upgrade old backing store.
371 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); 381 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion);
372 if (db_schema_version < 1) { 382 if (db_schema_version < 1) {
373 db_schema_version = 1; 383 db_schema_version = 1;
374 PutInt(transaction.get(), schema_version_key, db_schema_version); 384 PutInt(transaction.get(), schema_version_key, db_schema_version);
375 const std::string start_key = 385 const std::string start_key =
376 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); 386 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_);
377 const std::string stop_key = 387 const std::string stop_key =
378 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); 388 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_);
379 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); 389 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
380 for (s = it->Seek(start_key); 390 for (s = it->Seek(start_key);
381 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 391 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
382 s = it->Next()) { 392 s = it->Next()) {
383 int64 database_id = 0; 393 int64 database_id = 0;
384 found = false; 394 found = false;
385 s = GetInt(transaction.get(), it->Key(), &database_id, &found); 395 s = GetInt(transaction.get(), it->Key(), &database_id, &found);
386 if (!s.ok()) { 396 if (!s.ok()) {
387 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 397 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
388 return false; 398 return false;
389 } 399 }
390 if (!found) { 400 if (!found) {
391 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA); 401 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
392 return false; 402 return false;
393 } 403 }
394 std::string int_version_key = DatabaseMetaDataKey::Encode( 404 std::string int_version_key = DatabaseMetaDataKey::Encode(
395 database_id, DatabaseMetaDataKey::USER_INT_VERSION); 405 database_id, DatabaseMetaDataKey::USER_INT_VERSION);
396 PutVarInt(transaction.get(), 406 PutVarInt(transaction.get(),
397 int_version_key, 407 int_version_key,
398 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); 408 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
399 } 409 }
400 } 410 }
401 if (s.ok() && db_schema_version < 2) { 411 if (s.ok() && db_schema_version < 2) {
402 db_schema_version = 2; 412 db_schema_version = 2;
403 PutInt(transaction.get(), schema_version_key, db_schema_version); 413 PutInt(transaction.get(), schema_version_key, db_schema_version);
404 db_data_version = blink::kSerializedScriptValueVersion; 414 db_data_version = blink::kSerializedScriptValueVersion;
405 PutInt(transaction.get(), data_version_key, db_data_version); 415 PutInt(transaction.get(), data_version_key, db_data_version);
406 } 416 }
417 if (db_schema_version < 3) {
418 db_schema_version = 3;
419 if (!base::DeleteFile(blob_path_, true)) {
420 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
421 return false;
422 }
423 }
407 } 424 }
408 425
409 if (!s.ok()) { 426 if (!s.ok()) {
410 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 427 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
411 return false; 428 return false;
412 } 429 }
413 430
414 // All new values will be written using this serialization version. 431 // All new values will be written using this serialization version.
415 found = false; 432 found = false;
416 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found); 433 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 scoped_ptr<LevelDBDatabase>* db, 490 scoped_ptr<LevelDBDatabase>* db,
474 bool* is_disk_full) OVERRIDE { 491 bool* is_disk_full) OVERRIDE {
475 return LevelDBDatabase::Open(file_name, comparator, db, is_disk_full); 492 return LevelDBDatabase::Open(file_name, comparator, db, is_disk_full);
476 } 493 }
477 virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name) 494 virtual leveldb::Status DestroyLevelDB(const base::FilePath& file_name)
478 OVERRIDE { 495 OVERRIDE {
479 return LevelDBDatabase::Destroy(file_name); 496 return LevelDBDatabase::Destroy(file_name);
480 } 497 }
481 }; 498 };
482 499
500 static bool GetBlobKeyGeneratorCurrentNumber(
501 LevelDBTransaction* leveldb_transaction,
502 int64 database_id,
503 int64* blob_key_generator_current_number) {
504 const std::string key_gen_key = DatabaseMetaDataKey::Encode(
505 database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER);
506
507 // Default to initial number if not found.
508 int64 cur_number = DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber;
509 std::string data;
510
511 bool found = false;
512 bool ok = leveldb_transaction->Get(key_gen_key, &data, &found).ok();
513 if (!ok) {
514 INTERNAL_READ_ERROR_UNTESTED(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER);
515 return false;
516 }
517 if (found) {
518 StringPiece slice(data);
519 if (!DecodeVarInt(&slice, &cur_number) || !slice.empty() ||
520 !DatabaseMetaDataKey::IsValidBlobKey(cur_number)) {
521 INTERNAL_READ_ERROR_UNTESTED(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER);
522 return false;
523 }
524 }
525 *blob_key_generator_current_number = cur_number;
526 return true;
527 }
528
529 static bool UpdateBlobKeyGeneratorCurrentNumber(
530 LevelDBTransaction* leveldb_transaction,
531 int64 database_id,
532 int64 blob_key_generator_current_number) {
533 #ifndef NDEBUG
534 int64 old_number;
535 if (!GetBlobKeyGeneratorCurrentNumber(
536 leveldb_transaction, database_id, &old_number))
537 return false;
538 DCHECK_LT(old_number, blob_key_generator_current_number);
539 #endif
540 DCHECK(
541 DatabaseMetaDataKey::IsValidBlobKey(blob_key_generator_current_number));
542 const std::string key = DatabaseMetaDataKey::Encode(
543 database_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER);
544
545 PutVarInt(leveldb_transaction, key, blob_key_generator_current_number);
546 return true;
547 }
548
483 // TODO(ericu): Error recovery. If we persistently can't read the 549 // TODO(ericu): Error recovery. If we persistently can't read the
484 // blob journal, the safe thing to do is to clear it and leak the blobs, 550 // blob journal, the safe thing to do is to clear it and leak the blobs,
485 // though that may be costly. Still, database/directory deletion should always 551 // though that may be costly. Still, database/directory deletion should always
486 // clean things up, and we can write an fsck that will do a full correction if 552 // clean things up, and we can write an fsck that will do a full correction if
487 // need be. 553 // need be.
488 template <typename T> 554 template <typename T>
489 static leveldb::Status GetBlobJournal(const StringPiece& leveldb_key, 555 static leveldb::Status GetBlobJournal(const StringPiece& leveldb_key,
490 T* leveldb_transaction, 556 T* leveldb_transaction,
491 BlobJournalType* journal) { 557 BlobJournalType* journal) {
492 std::string data; 558 std::string data;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 if (!s.ok()) 632 if (!s.ok())
567 return s; 633 return s;
568 journal.push_back( 634 journal.push_back(
569 std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey)); 635 std::make_pair(database_id, DatabaseMetaDataKey::kAllBlobsKey));
570 std::string data; 636 std::string data;
571 EncodeBlobJournal(journal, &data); 637 EncodeBlobJournal(journal, &data);
572 leveldb_transaction->Put(key, &data); 638 leveldb_transaction->Put(key, &data);
573 return leveldb::Status::OK(); 639 return leveldb::Status::OK();
574 } 640 }
575 641
642 // Blob Data is encoded as a series of:
643 // { is_file [bool], key [int64 as varInt],
644 // type [string-with-length, may be empty],
645 // (for Blobs only) size [int64 as varInt]
646 // (for Files only) fileName [string-with-length]
647 // }
648 // There is no length field; just read until you run out of data.
649 static std::string EncodeBlobData(
650 const std::vector<IndexedDBBlobInfo*>& blob_info) {
651 std::string ret;
652 std::vector<IndexedDBBlobInfo*>::const_iterator iter;
653 for (iter = blob_info.begin(); iter != blob_info.end(); ++iter) {
654 const IndexedDBBlobInfo& info = **iter;
655 EncodeBool(info.is_file(), &ret);
656 EncodeVarInt(info.key(), &ret);
657 EncodeStringWithLength(info.type(), &ret);
658 if (info.is_file())
659 EncodeStringWithLength(info.file_name(), &ret);
660 else
661 EncodeVarInt(info.size(), &ret);
662 }
663 return ret;
664 }
665
666 static bool DecodeBlobData(const std::string& data,
667 std::vector<IndexedDBBlobInfo>* output) {
668 std::vector<IndexedDBBlobInfo> ret;
669 output->clear();
670 StringPiece slice(data);
671 while (!slice.empty()) {
672 bool is_file;
673 int64 key;
674 base::string16 type;
675 int64 size;
676 base::string16 file_name;
677
678 if (!DecodeBool(&slice, &is_file))
679 return false;
680 if (!DecodeVarInt(&slice, &key) ||
681 !DatabaseMetaDataKey::IsValidBlobKey(key))
682 return false;
683 if (!DecodeStringWithLength(&slice, &type))
684 return false;
685 if (is_file) {
686 if (!DecodeStringWithLength(&slice, &file_name))
687 return false;
688 ret.push_back(IndexedDBBlobInfo(key, type, file_name));
689 } else {
690 if (!DecodeVarInt(&slice, &size) || size < 0)
691 return false;
692 ret.push_back(IndexedDBBlobInfo(type, static_cast<uint64>(size), key));
693 }
694 }
695 output->swap(ret);
696
697 return true;
698 }
699
576 IndexedDBBackingStore::IndexedDBBackingStore( 700 IndexedDBBackingStore::IndexedDBBackingStore(
577 IndexedDBFactory* indexed_db_factory, 701 IndexedDBFactory* indexed_db_factory,
578 const GURL& origin_url, 702 const GURL& origin_url,
579 const base::FilePath& blob_path, 703 const base::FilePath& blob_path,
580 net::URLRequestContext* request_context, 704 net::URLRequestContext* request_context,
581 scoped_ptr<LevelDBDatabase> db, 705 scoped_ptr<LevelDBDatabase> db,
582 scoped_ptr<LevelDBComparator> comparator, 706 scoped_ptr<LevelDBComparator> comparator,
583 base::TaskRunner* task_runner) 707 base::TaskRunner* task_runner)
584 : indexed_db_factory_(indexed_db_factory), 708 : indexed_db_factory_(indexed_db_factory),
585 origin_url_(origin_url), 709 origin_url_(origin_url),
586 blob_path_(blob_path), 710 blob_path_(blob_path),
587 origin_identifier_(ComputeOriginIdentifier(origin_url)), 711 origin_identifier_(ComputeOriginIdentifier(origin_url)),
588 request_context_(request_context), 712 request_context_(request_context),
589 task_runner_(task_runner), 713 task_runner_(task_runner),
590 db_(db.Pass()), 714 db_(db.Pass()),
591 comparator_(comparator.Pass()), 715 comparator_(comparator.Pass()),
592 active_blob_registry_(this) {} 716 active_blob_registry_(this) {
717 }
593 718
594 IndexedDBBackingStore::~IndexedDBBackingStore() { 719 IndexedDBBackingStore::~IndexedDBBackingStore() {
595 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) { 720 if (!blob_path_.empty() && !child_process_ids_granted_.empty()) {
596 ChildProcessSecurityPolicyImpl* policy = 721 ChildProcessSecurityPolicyImpl* policy =
597 ChildProcessSecurityPolicyImpl::GetInstance(); 722 ChildProcessSecurityPolicyImpl::GetInstance();
598 std::set<int>::const_iterator iter; 723 std::set<int>::const_iterator iter;
599 for (iter = child_process_ids_granted_.begin(); 724 for (iter = child_process_ids_granted_.begin();
600 iter != child_process_ids_granted_.end(); 725 iter != child_process_ids_granted_.end();
601 ++iter) { 726 ++iter) {
602 policy->RevokeAllPermissionsForFile(*iter, blob_path_); 727 policy->RevokeAllPermissionsForFile(*iter, blob_path_);
(...skipping 28 matching lines...) Expand all
631 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED, 756 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED,
632 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS, 757 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS,
633 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, 758 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA,
634 INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, 759 INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR,
635 INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, 760 INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED,
636 INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, 761 INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII,
637 INDEXED_DB_BACKING_STORE_OPEN_DISK_FULL_DEPRECATED, 762 INDEXED_DB_BACKING_STORE_OPEN_DISK_FULL_DEPRECATED,
638 INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, 763 INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG,
639 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, 764 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
640 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION, 765 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION,
766 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR,
641 INDEXED_DB_BACKING_STORE_OPEN_MAX, 767 INDEXED_DB_BACKING_STORE_OPEN_MAX,
642 }; 768 };
643 769
644 // static 770 // static
645 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( 771 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
646 IndexedDBFactory* indexed_db_factory, 772 IndexedDBFactory* indexed_db_factory,
647 const GURL& origin_url, 773 const GURL& origin_url,
648 const base::FilePath& path_base, 774 const base::FilePath& path_base,
649 net::URLRequestContext* request_context, 775 net::URLRequestContext* request_context,
650 blink::WebIDBDataLoss* data_loss, 776 blink::WebIDBDataLoss* data_loss,
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 origin_url); 1042 origin_url);
917 } 1043 }
918 1044
919 if (!db) { 1045 if (!db) {
920 NOTREACHED(); 1046 NOTREACHED();
921 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, 1047 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR,
922 origin_url); 1048 origin_url);
923 return scoped_refptr<IndexedDBBackingStore>(); 1049 return scoped_refptr<IndexedDBBackingStore>();
924 } 1050 }
925 1051
926 return Create(indexed_db_factory, 1052 scoped_refptr<IndexedDBBackingStore> backing_store =
927 origin_url, 1053 Create(indexed_db_factory,
928 blob_path, 1054 origin_url,
929 request_context, 1055 blob_path,
930 db.Pass(), 1056 request_context,
931 comparator.Pass(), 1057 db.Pass(),
932 task_runner); 1058 comparator.Pass(),
1059 task_runner);
1060
1061 if (clean_journal && backing_store &&
1062 !backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()).ok()) {
1063 HistogramOpenStatus(
1064 INDEXED_DB_BACKING_STORE_OPEN_FAILED_CLEANUP_JOURNAL_ERROR, origin_url);
1065 return scoped_refptr<IndexedDBBackingStore>();
1066 }
1067 return backing_store;
933 } 1068 }
934 1069
935 // static 1070 // static
936 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( 1071 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
937 const GURL& origin_url, 1072 const GURL& origin_url,
938 base::TaskRunner* task_runner) { 1073 base::TaskRunner* task_runner) {
939 DefaultLevelDBFactory leveldb_factory; 1074 DefaultLevelDBFactory leveldb_factory;
940 return IndexedDBBackingStore::OpenInMemory( 1075 return IndexedDBBackingStore::OpenInMemory(
941 origin_url, &leveldb_factory, task_runner); 1076 origin_url, &leveldb_factory, task_runner);
942 } 1077 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 base::TaskRunner* task_runner) { 1114 base::TaskRunner* task_runner) {
980 // TODO(jsbell): Handle comparator name changes. 1115 // TODO(jsbell): Handle comparator name changes.
981 scoped_refptr<IndexedDBBackingStore> backing_store( 1116 scoped_refptr<IndexedDBBackingStore> backing_store(
982 new IndexedDBBackingStore(indexed_db_factory, 1117 new IndexedDBBackingStore(indexed_db_factory,
983 origin_url, 1118 origin_url,
984 blob_path, 1119 blob_path,
985 request_context, 1120 request_context,
986 db.Pass(), 1121 db.Pass(),
987 comparator.Pass(), 1122 comparator.Pass(),
988 task_runner)); 1123 task_runner));
989 if (!SetUpMetadata(backing_store->db_.get(), 1124 if (!backing_store->SetUpMetadata())
990 backing_store->origin_identifier_))
991 return scoped_refptr<IndexedDBBackingStore>(); 1125 return scoped_refptr<IndexedDBBackingStore>();
992 1126
993 return backing_store; 1127 return backing_store;
994 } 1128 }
995 1129
996 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) { 1130 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) {
997 if (!child_process_ids_granted_.count(child_process_id)) { 1131 if (!child_process_ids_granted_.count(child_process_id)) {
998 child_process_ids_granted_.insert(child_process_id); 1132 child_process_ids_granted_.insert(child_process_id);
999 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( 1133 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
1000 child_process_id, blob_path_); 1134 child_process_id, blob_path_);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 1211
1078 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) 1212 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION)
1079 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 1213 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION;
1080 1214
1081 s = GetMaxObjectStoreId( 1215 s = GetMaxObjectStoreId(
1082 db_.get(), metadata->id, &metadata->max_object_store_id); 1216 db_.get(), metadata->id, &metadata->max_object_store_id);
1083 if (!s.ok()) { 1217 if (!s.ok()) {
1084 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); 1218 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
1085 } 1219 }
1086 1220
1221 // We don't cache this, we just check it if it's there.
1222 int64 blob_key_generator_current_number =
1223 DatabaseMetaDataKey::kInvalidBlobKey;
1224
1225 s = GetVarInt(
1226 db_.get(),
1227 DatabaseMetaDataKey::Encode(
1228 metadata->id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER),
1229 &blob_key_generator_current_number,
1230 found);
1231 if (!s.ok()) {
1232 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
1233 return s;
1234 }
1235 if (!*found) {
1236 // This database predates blob support.
1237 *found = true;
1238 } else if (!DatabaseMetaDataKey::IsValidBlobKey(
1239 blob_key_generator_current_number)) {
1240 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
1241 return InternalInconsistencyStatus();
1242 }
1243
1087 return s; 1244 return s;
1088 } 1245 }
1089 1246
1090 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId( 1247 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId(
1091 LevelDBTransaction* transaction, 1248 LevelDBTransaction* transaction,
1092 int64* new_id) { 1249 int64* new_id) {
1093 *new_id = -1; 1250 *new_id = -1;
1094 int64 max_database_id = -1; 1251 int64 max_database_id = -1;
1095 bool found = false; 1252 bool found = false;
1096 leveldb::Status s = 1253 leveldb::Status s =
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 DatabaseNameKey::Encode(origin_identifier_, name), 1287 DatabaseNameKey::Encode(origin_identifier_, name),
1131 *row_id); 1288 *row_id);
1132 PutString( 1289 PutString(
1133 transaction.get(), 1290 transaction.get(),
1134 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION), 1291 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION),
1135 version); 1292 version);
1136 PutVarInt(transaction.get(), 1293 PutVarInt(transaction.get(),
1137 DatabaseMetaDataKey::Encode(*row_id, 1294 DatabaseMetaDataKey::Encode(*row_id,
1138 DatabaseMetaDataKey::USER_INT_VERSION), 1295 DatabaseMetaDataKey::USER_INT_VERSION),
1139 int_version); 1296 int_version);
1297 PutVarInt(
1298 transaction.get(),
1299 DatabaseMetaDataKey::Encode(
1300 *row_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER),
1301 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber);
1302
1140 s = transaction->Commit(); 1303 s = transaction->Commit();
1141 if (!s.ok()) 1304 if (!s.ok())
1142 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA); 1305 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA);
1143 return s; 1306 return s;
1144 } 1307 }
1145 1308
1146 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( 1309 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion(
1147 IndexedDBBackingStore::Transaction* transaction, 1310 IndexedDBBackingStore::Transaction* transaction,
1148 int64 row_id, 1311 int64 row_id,
1149 int64 int_version) { 1312 int64 int_version) {
(...skipping 12 matching lines...) Expand all
1162 const std::string& end) { 1325 const std::string& end) {
1163 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 1326 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
1164 leveldb::Status s; 1327 leveldb::Status s;
1165 for (s = it->Seek(begin); 1328 for (s = it->Seek(begin);
1166 s.ok() && it->IsValid() && CompareKeys(it->Key(), end) < 0; 1329 s.ok() && it->IsValid() && CompareKeys(it->Key(), end) < 0;
1167 s = it->Next()) 1330 s = it->Next())
1168 transaction->Remove(it->Key()); 1331 transaction->Remove(it->Key());
1169 return s; 1332 return s;
1170 } 1333 }
1171 1334
1335 static leveldb::Status DeleteBlobsInObjectStore(
1336 IndexedDBBackingStore::Transaction* transaction,
1337 int64 database_id,
1338 int64 object_store_id) {
1339 std::string start_key, end_key;
1340 start_key =
1341 BlobEntryKey::EncodeMinKeyForObjectStore(database_id, object_store_id);
1342 end_key =
1343 BlobEntryKey::EncodeStopKeyForObjectStore(database_id, object_store_id);
1344
1345 scoped_ptr<LevelDBIterator> it = transaction->transaction()->CreateIterator();
1346
1347 leveldb::Status s = it->Seek(start_key);
1348 for (; s.ok() && it->IsValid() && CompareKeys(it->Key(), end_key) < 0;
1349 s = it->Next()) {
1350 StringPiece key_piece(it->Key());
1351 std::string user_key =
1352 BlobEntryKey::ReencodeToObjectStoreDataKey(&key_piece);
1353 if (!user_key.size()) {
1354 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
1355 return InternalInconsistencyStatus();
1356 }
1357 transaction->PutBlobInfo(
1358 database_id, object_store_id, user_key, NULL, NULL);
1359 }
1360 return s;
1361 }
1362
1172 leveldb::Status IndexedDBBackingStore::DeleteDatabase( 1363 leveldb::Status IndexedDBBackingStore::DeleteDatabase(
1173 const base::string16& name) { 1364 const base::string16& name) {
1174 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase"); 1365 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase");
1175 scoped_ptr<LevelDBDirectTransaction> transaction = 1366 scoped_ptr<LevelDBDirectTransaction> transaction =
1176 LevelDBDirectTransaction::Create(db_.get()); 1367 LevelDBDirectTransaction::Create(db_.get());
1177 1368
1369 leveldb::Status s;
1370 s = CleanUpBlobJournal(BlobJournalKey::Encode());
1371 if (!s.ok())
1372 return s;
1373
1178 IndexedDBDatabaseMetadata metadata; 1374 IndexedDBDatabaseMetadata metadata;
1179 bool success = false; 1375 bool success = false;
1180 leveldb::Status s = GetIDBDatabaseMetaData(name, &metadata, &success); 1376 s = GetIDBDatabaseMetaData(name, &metadata, &success);
1181 if (!s.ok()) 1377 if (!s.ok())
1182 return s; 1378 return s;
1183 if (!success) 1379 if (!success)
1184 return leveldb::Status::OK(); 1380 return leveldb::Status::OK();
1185 1381
1186 const std::string start_key = DatabaseMetaDataKey::Encode( 1382 const std::string start_key = DatabaseMetaDataKey::Encode(
1187 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME); 1383 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME);
1188 const std::string stop_key = DatabaseMetaDataKey::Encode( 1384 const std::string stop_key = DatabaseMetaDataKey::Encode(
1189 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME); 1385 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME);
1190 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1386 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1191 for (s = it->Seek(start_key); 1387 for (s = it->Seek(start_key);
1192 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 1388 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
1193 s = it->Next()) 1389 s = it->Next())
1194 transaction->Remove(it->Key()); 1390 transaction->Remove(it->Key());
1195 if (!s.ok()) { 1391 if (!s.ok()) {
1196 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE); 1392 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
1197 return s; 1393 return s;
1198 } 1394 }
1199 1395
1200 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); 1396 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
1201 transaction->Remove(key); 1397 transaction->Remove(key);
1202 1398
1203 // TODO(ericu): Put the real calls to the blob journal code here. For now, 1399 bool need_cleanup = false;
1204 // I've inserted fake calls so that we don't get "you didn't use this static 1400 if (active_blob_registry()->MarkDeletedCheckIfUsed(
1205 // function" compiler errors. 1401 metadata.id, DatabaseMetaDataKey::kAllBlobsKey)) {
1402 s = MergeDatabaseIntoLiveBlobJournal(transaction.get(), metadata.id);
1403 if (!s.ok())
1404 return s;
1405 } else {
1406 UpdateBlobJournalWithDatabase(transaction.get(), metadata.id);
1407 need_cleanup = true;
1408 }
1409
1410 // TODO(ericu): Remove these fake calls, added to avoid "defined but unused"
1411 // compiler errors until the code that makes the real calls can be added.
1206 if (false) { 1412 if (false) {
1413 std::vector<IndexedDBBlobInfo*> fake;
1414 EncodeBlobData(fake);
1415
1207 scoped_refptr<LevelDBTransaction> fake_transaction = 1416 scoped_refptr<LevelDBTransaction> fake_transaction =
1208 new LevelDBTransaction(NULL); 1417 new LevelDBTransaction(NULL);
1209 BlobJournalType fake_journal; 1418 BlobJournalType fake_journal;
1210 MergeDatabaseIntoLiveBlobJournal(transaction.get(), metadata.id);
1211 UpdateBlobJournalWithDatabase(transaction.get(), metadata.id);
1212 MergeBlobsIntoLiveBlobJournal(fake_transaction.get(), fake_journal); 1419 MergeBlobsIntoLiveBlobJournal(fake_transaction.get(), fake_journal);
1420 UpdateBlobKeyGeneratorCurrentNumber(fake_transaction.get(), 0, 0);
1421 int64 arg;
1422 GetBlobKeyGeneratorCurrentNumber(fake_transaction.get(), 0, &arg);
1213 } 1423 }
1214 1424
1215 s = transaction->Commit(); 1425 s = transaction->Commit();
1216 if (!s.ok()) { 1426 if (!s.ok()) {
1217 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE); 1427 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
1218 return s; 1428 return s;
1219 } 1429 }
1430
1431 if (need_cleanup)
1432 CleanUpBlobJournal(BlobJournalKey::Encode());
1433
1220 db_->Compact(start_key, stop_key); 1434 db_->Compact(start_key, stop_key);
1221 return s; 1435 return s;
1222 } 1436 }
1223 1437
1224 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it, 1438 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it,
1225 const std::string& stop_key, 1439 const std::string& stop_key,
1226 int64 object_store_id, 1440 int64 object_store_id,
1227 int64 meta_data_type) { 1441 int64 meta_data_type) {
1228 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0) 1442 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0)
1229 return false; 1443 return false;
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 &found); 1732 &found);
1519 if (!s.ok()) { 1733 if (!s.ok()) {
1520 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1734 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1521 return s; 1735 return s;
1522 } 1736 }
1523 if (!found) { 1737 if (!found) {
1524 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1738 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1525 return InternalInconsistencyStatus(); 1739 return InternalInconsistencyStatus();
1526 } 1740 }
1527 1741
1742 s = DeleteBlobsInObjectStore(transaction, database_id, object_store_id);
1743 if (!s.ok()) {
1744 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1745 return s;
1746 }
1747
1528 s = DeleteRange( 1748 s = DeleteRange(
1529 leveldb_transaction, 1749 leveldb_transaction,
1530 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), 1750 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0),
1531 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1751 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1532 1752
1533 if (s.ok()) { 1753 if (s.ok()) {
1534 leveldb_transaction->Remove( 1754 leveldb_transaction->Remove(
1535 ObjectStoreNamesKey::Encode(database_id, object_store_name)); 1755 ObjectStoreNamesKey::Encode(database_id, object_store_name));
1536 1756
1537 s = DeleteRange( 1757 s = DeleteRange(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 } 1806 }
1587 1807
1588 int64 version; 1808 int64 version;
1589 StringPiece slice(data); 1809 StringPiece slice(data);
1590 if (!DecodeVarInt(&slice, &version)) { 1810 if (!DecodeVarInt(&slice, &version)) {
1591 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD); 1811 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD);
1592 return InternalInconsistencyStatus(); 1812 return InternalInconsistencyStatus();
1593 } 1813 }
1594 1814
1595 record->bits = slice.as_string(); 1815 record->bits = slice.as_string();
1596 return s; 1816 return transaction->GetBlobInfoForRecord(database_id, leveldb_key, record);
1597 } 1817 }
1598 1818
1599 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber( 1819 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber(
1600 LevelDBTransaction* transaction, 1820 LevelDBTransaction* transaction,
1601 int64 database_id, 1821 int64 database_id,
1602 int64 object_store_id, 1822 int64 object_store_id,
1603 int64* new_version_number) { 1823 int64* new_version_number) {
1604 const std::string last_version_key = ObjectStoreMetaDataKey::Encode( 1824 const std::string last_version_key = ObjectStoreMetaDataKey::Encode(
1605 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); 1825 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
1606 1826
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); 1902 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore");
1683 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1903 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1684 return InvalidDBKeyStatus(); 1904 return InvalidDBKeyStatus();
1685 const std::string start_key = 1905 const std::string start_key =
1686 KeyPrefix(database_id, object_store_id).Encode(); 1906 KeyPrefix(database_id, object_store_id).Encode();
1687 const std::string stop_key = 1907 const std::string stop_key =
1688 KeyPrefix(database_id, object_store_id + 1).Encode(); 1908 KeyPrefix(database_id, object_store_id + 1).Encode();
1689 1909
1690 leveldb::Status s = 1910 leveldb::Status s =
1691 DeleteRange(transaction->transaction(), start_key, stop_key); 1911 DeleteRange(transaction->transaction(), start_key, stop_key);
1692 if (!s.ok()) 1912 if (!s.ok()) {
1693 INTERNAL_WRITE_ERROR(CLEAR_OBJECT_STORE); 1913 INTERNAL_WRITE_ERROR(CLEAR_OBJECT_STORE);
1694 return s; 1914 return s;
1915 }
1916 return DeleteBlobsInObjectStore(transaction, database_id, object_store_id);
1695 } 1917 }
1696 1918
1697 leveldb::Status IndexedDBBackingStore::DeleteRecord( 1919 leveldb::Status IndexedDBBackingStore::DeleteRecord(
1698 IndexedDBBackingStore::Transaction* transaction, 1920 IndexedDBBackingStore::Transaction* transaction,
1699 int64 database_id, 1921 int64 database_id,
1700 int64 object_store_id, 1922 int64 object_store_id,
1701 const RecordIdentifier& record_identifier) { 1923 const RecordIdentifier& record_identifier) {
1702 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); 1924 IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
1703 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1925 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1704 return InvalidDBKeyStatus(); 1926 return InvalidDBKeyStatus();
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
2283 } else { 2505 } else {
2284 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); 2506 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
2285 if (!RemoveBlobFile(database_id, blob_key)) 2507 if (!RemoveBlobFile(database_id, blob_key))
2286 return IOErrorStatus(); 2508 return IOErrorStatus();
2287 } 2509 }
2288 } 2510 }
2289 ClearBlobJournal(journal_transaction.get(), level_db_key); 2511 ClearBlobJournal(journal_transaction.get(), level_db_key);
2290 return journal_transaction->Commit(); 2512 return journal_transaction->Commit();
2291 } 2513 }
2292 2514
2515 leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord(
2516 int64 database_id,
2517 const std::string& object_store_data_key,
2518 IndexedDBValue* value) {
2519 BlobChangeRecord* change_record = NULL;
2520 BlobChangeMap::const_iterator blob_iter =
2521 blob_change_map_.find(object_store_data_key);
2522 if (blob_iter != blob_change_map_.end()) {
2523 change_record = blob_iter->second;
2524 } else {
2525 blob_iter = incognito_blob_map_.find(object_store_data_key);
2526 if (blob_iter != incognito_blob_map_.end())
2527 change_record = blob_iter->second;
2528 }
2529 if (change_record) {
2530 // Either we haven't written the blob to disk yet or we're in incognito
2531 // mode, so we have to send back the one they sent us. This change record
2532 // includes the original UUID.
2533 value->blob_info = change_record->blob_info();
2534 return leveldb::Status::OK();
2535 }
2536
2537 BlobEntryKey blob_entry_key;
2538 StringPiece leveldb_key_piece(object_store_data_key);
2539 if (!BlobEntryKey::FromObjectStoreDataKey(&leveldb_key_piece,
2540 &blob_entry_key)) {
2541 NOTREACHED();
2542 return InternalInconsistencyStatus();
2543 }
2544 scoped_ptr<LevelDBIterator> it = transaction()->CreateIterator();
2545 std::string encoded_key = blob_entry_key.Encode();
2546 leveldb::Status s = it->Seek(encoded_key);
2547 if (!s.ok())
2548 return s;
2549 if (it->IsValid() && CompareKeys(it->Key(), encoded_key) == 0) {
2550 if (!DecodeBlobData(it->Value().as_string(), &value->blob_info)) {
2551 INTERNAL_READ_ERROR(GET_BLOB_INFO_FOR_RECORD);
2552 return InternalInconsistencyStatus();
2553 }
2554 std::vector<IndexedDBBlobInfo>::iterator iter;
2555 for (iter = value->blob_info.begin(); iter != value->blob_info.end();
2556 ++iter) {
2557 iter->set_file_path(
2558 backing_store_->GetBlobFileName(database_id, iter->key()));
2559 iter->set_mark_used_callback(
2560 backing_store_->active_blob_registry()->GetAddBlobRefCallback(
2561 database_id, iter->key()));
2562 iter->set_release_callback(
2563 backing_store_->active_blob_registry()->GetFinalReleaseCallback(
2564 database_id, iter->key()));
2565 if (iter->is_file()) {
2566 base::File::Info info;
2567 if (base::GetFileInfo(iter->file_path(), &info)) {
2568 // This should always work, but it isn't fatal if it doesn't; it just
2569 // means a potential slow synchronous call from the renderer later.
2570 iter->set_last_modified(info.last_modified);
2571 iter->set_size(info.size);
2572 }
2573 }
2574 }
2575 }
2576 return leveldb::Status::OK();
2577 }
2578
2293 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() { 2579 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() {
2294 CleanUpBlobJournal(BlobJournalKey::Encode()); 2580 CleanUpBlobJournal(BlobJournalKey::Encode());
2295 } 2581 }
2296 2582
2297 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( 2583 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
2298 LevelDBTransaction* transaction, 2584 LevelDBTransaction* transaction,
2299 int64 database_id, 2585 int64 database_id,
2300 int64 object_store_id, 2586 int64 object_store_id,
2301 int64 index_id) { 2587 int64 index_id) {
2302 int64 max_index_id = -1; 2588 int64 max_index_id = -1;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 2892
2607 StringPiece slice(found_encoded_primary_key); 2893 StringPiece slice(found_encoded_primary_key);
2608 if (DecodeIDBKey(&slice, found_primary_key) && slice.empty()) 2894 if (DecodeIDBKey(&slice, found_primary_key) && slice.empty())
2609 return s; 2895 return s;
2610 else 2896 else
2611 return InvalidDBKeyStatus(); 2897 return InvalidDBKeyStatus();
2612 } 2898 }
2613 2899
2614 IndexedDBBackingStore::Cursor::Cursor( 2900 IndexedDBBackingStore::Cursor::Cursor(
2615 const IndexedDBBackingStore::Cursor* other) 2901 const IndexedDBBackingStore::Cursor* other)
2616 : transaction_(other->transaction_), 2902 : backing_store_(other->backing_store_),
2903 transaction_(other->transaction_),
2904 database_id_(other->database_id_),
2617 cursor_options_(other->cursor_options_), 2905 cursor_options_(other->cursor_options_),
2618 current_key_(new IndexedDBKey(*other->current_key_)) { 2906 current_key_(new IndexedDBKey(*other->current_key_)) {
2619 if (other->iterator_) { 2907 if (other->iterator_) {
2620 iterator_ = transaction_->CreateIterator(); 2908 iterator_ = transaction_->transaction()->CreateIterator();
2621 2909
2622 if (other->iterator_->IsValid()) { 2910 if (other->iterator_->IsValid()) {
2623 leveldb::Status s = iterator_->Seek(other->iterator_->Key()); 2911 leveldb::Status s = iterator_->Seek(other->iterator_->Key());
2624 // TODO(cmumford): Handle this error (crbug.com/363397) 2912 // TODO(cmumford): Handle this error (crbug.com/363397)
2625 DCHECK(iterator_->IsValid()); 2913 DCHECK(iterator_->IsValid());
2626 } 2914 }
2627 } 2915 }
2628 } 2916 }
2629 2917
2630 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction, 2918 IndexedDBBackingStore::Cursor::Cursor(
2631 const CursorOptions& cursor_options) 2919 scoped_refptr<IndexedDBBackingStore> backing_store,
2632 : transaction_(transaction), cursor_options_(cursor_options) {} 2920 IndexedDBBackingStore::Transaction* transaction,
2921 int64 database_id,
2922 const CursorOptions& cursor_options)
2923 : backing_store_(backing_store),
2924 transaction_(transaction),
2925 database_id_(database_id),
2926 cursor_options_(cursor_options) {
2927 }
2633 IndexedDBBackingStore::Cursor::~Cursor() {} 2928 IndexedDBBackingStore::Cursor::~Cursor() {}
2634 2929
2635 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) { 2930 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) {
2636 iterator_ = transaction_->CreateIterator(); 2931 iterator_ = transaction_->transaction()->CreateIterator();
2637 if (cursor_options_.forward) 2932 if (cursor_options_.forward)
2638 *s = iterator_->Seek(cursor_options_.low_key); 2933 *s = iterator_->Seek(cursor_options_.low_key);
2639 else 2934 else
2640 *s = iterator_->Seek(cursor_options_.high_key); 2935 *s = iterator_->Seek(cursor_options_.high_key);
2641 if (!s->ok()) 2936 if (!s->ok())
2642 return false; 2937 return false;
2643 2938
2644 return Continue(0, READY, s); 2939 return Continue(0, READY, s);
2645 } 2940 }
2646 2941
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2809 } 3104 }
2810 3105
2811 const IndexedDBBackingStore::RecordIdentifier& 3106 const IndexedDBBackingStore::RecordIdentifier&
2812 IndexedDBBackingStore::Cursor::record_identifier() const { 3107 IndexedDBBackingStore::Cursor::record_identifier() const {
2813 return record_identifier_; 3108 return record_identifier_;
2814 } 3109 }
2815 3110
2816 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { 3111 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2817 public: 3112 public:
2818 ObjectStoreKeyCursorImpl( 3113 ObjectStoreKeyCursorImpl(
2819 LevelDBTransaction* transaction, 3114 scoped_refptr<IndexedDBBackingStore> backing_store,
3115 IndexedDBBackingStore::Transaction* transaction,
3116 int64 database_id,
2820 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3117 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2821 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3118 : IndexedDBBackingStore::Cursor(backing_store,
3119 transaction,
3120 database_id,
3121 cursor_options) {}
2822 3122
2823 virtual Cursor* Clone() OVERRIDE { 3123 virtual Cursor* Clone() OVERRIDE {
2824 return new ObjectStoreKeyCursorImpl(this); 3124 return new ObjectStoreKeyCursorImpl(this);
2825 } 3125 }
2826 3126
2827 // IndexedDBBackingStore::Cursor 3127 // IndexedDBBackingStore::Cursor
2828 virtual IndexedDBValue* value() OVERRIDE { 3128 virtual IndexedDBValue* value() OVERRIDE {
2829 NOTREACHED(); 3129 NOTREACHED();
2830 return NULL; 3130 return NULL;
2831 } 3131 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2868 std::string encoded_key; 3168 std::string encoded_key;
2869 EncodeIDBKey(*current_key_, &encoded_key); 3169 EncodeIDBKey(*current_key_, &encoded_key);
2870 record_identifier_.Reset(encoded_key, version); 3170 record_identifier_.Reset(encoded_key, version);
2871 3171
2872 return true; 3172 return true;
2873 } 3173 }
2874 3174
2875 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { 3175 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
2876 public: 3176 public:
2877 ObjectStoreCursorImpl( 3177 ObjectStoreCursorImpl(
2878 LevelDBTransaction* transaction, 3178 scoped_refptr<IndexedDBBackingStore> backing_store,
3179 IndexedDBBackingStore::Transaction* transaction,
3180 int64 database_id,
2879 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3181 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2880 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3182 : IndexedDBBackingStore::Cursor(backing_store,
3183 transaction,
3184 database_id,
3185 cursor_options) {}
2881 3186
2882 virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); } 3187 virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); }
2883 3188
2884 // IndexedDBBackingStore::Cursor 3189 // IndexedDBBackingStore::Cursor
2885 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; } 3190 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; }
2886 virtual bool LoadCurrentRow() OVERRIDE; 3191 virtual bool LoadCurrentRow() OVERRIDE;
2887 3192
2888 protected: 3193 protected:
2889 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE { 3194 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE {
2890 return ObjectStoreDataKey::Encode( 3195 return ObjectStoreDataKey::Encode(
(...skipping 28 matching lines...) Expand all
2919 if (!DecodeVarInt(&value_slice, &version)) { 3224 if (!DecodeVarInt(&value_slice, &version)) {
2920 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3225 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2921 return false; 3226 return false;
2922 } 3227 }
2923 3228
2924 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 3229 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2925 std::string encoded_key; 3230 std::string encoded_key;
2926 EncodeIDBKey(*current_key_, &encoded_key); 3231 EncodeIDBKey(*current_key_, &encoded_key);
2927 record_identifier_.Reset(encoded_key, version); 3232 record_identifier_.Reset(encoded_key, version);
2928 3233
3234 if (!transaction_->GetBlobInfoForRecord(database_id_,
3235 iterator_->Key().as_string(),
3236 &current_value_).ok()) {
3237 return false;
3238 }
2929 current_value_.bits = value_slice.as_string(); 3239 current_value_.bits = value_slice.as_string();
2930 return true; 3240 return true;
2931 } 3241 }
2932 3242
2933 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { 3243 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2934 public: 3244 public:
2935 IndexKeyCursorImpl( 3245 IndexKeyCursorImpl(
2936 LevelDBTransaction* transaction, 3246 scoped_refptr<IndexedDBBackingStore> backing_store,
3247 IndexedDBBackingStore::Transaction* transaction,
3248 int64 database_id,
2937 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3249 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2938 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3250 : IndexedDBBackingStore::Cursor(backing_store,
3251 transaction,
3252 database_id,
3253 cursor_options) {}
2939 3254
2940 virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); } 3255 virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); }
2941 3256
2942 // IndexedDBBackingStore::Cursor 3257 // IndexedDBBackingStore::Cursor
2943 virtual IndexedDBValue* value() OVERRIDE { 3258 virtual IndexedDBValue* value() OVERRIDE {
2944 NOTREACHED(); 3259 NOTREACHED();
2945 return NULL; 3260 return NULL;
2946 } 3261 }
2947 virtual const IndexedDBKey& primary_key() const OVERRIDE { 3262 virtual const IndexedDBKey& primary_key() const OVERRIDE {
2948 return *primary_key_; 3263 return *primary_key_;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3001 return false; 3316 return false;
3002 } 3317 }
3003 3318
3004 std::string primary_leveldb_key = 3319 std::string primary_leveldb_key =
3005 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 3320 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
3006 index_data_key.ObjectStoreId(), 3321 index_data_key.ObjectStoreId(),
3007 *primary_key_); 3322 *primary_key_);
3008 3323
3009 std::string result; 3324 std::string result;
3010 bool found = false; 3325 bool found = false;
3011 leveldb::Status s = transaction_->Get(primary_leveldb_key, &result, &found); 3326 leveldb::Status s =
3327 transaction_->transaction()->Get(primary_leveldb_key, &result, &found);
3012 if (!s.ok()) { 3328 if (!s.ok()) {
3013 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3329 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3014 return false; 3330 return false;
3015 } 3331 }
3016 if (!found) { 3332 if (!found) {
3017 transaction_->Remove(iterator_->Key()); 3333 transaction_->transaction()->Remove(iterator_->Key());
3018 return false; 3334 return false;
3019 } 3335 }
3020 if (!result.size()) { 3336 if (!result.size()) {
3021 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3337 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3022 return false; 3338 return false;
3023 } 3339 }
3024 3340
3025 int64 object_store_data_version; 3341 int64 object_store_data_version;
3026 slice = StringPiece(result); 3342 slice = StringPiece(result);
3027 if (!DecodeVarInt(&slice, &object_store_data_version)) { 3343 if (!DecodeVarInt(&slice, &object_store_data_version)) {
3028 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3344 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3029 return false; 3345 return false;
3030 } 3346 }
3031 3347
3032 if (object_store_data_version != index_data_version) { 3348 if (object_store_data_version != index_data_version) {
3033 transaction_->Remove(iterator_->Key()); 3349 transaction_->transaction()->Remove(iterator_->Key());
3034 return false; 3350 return false;
3035 } 3351 }
3036 3352
3037 return true; 3353 return true;
3038 } 3354 }
3039 3355
3040 class IndexCursorImpl : public IndexedDBBackingStore::Cursor { 3356 class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
3041 public: 3357 public:
3042 IndexCursorImpl( 3358 IndexCursorImpl(
3043 LevelDBTransaction* transaction, 3359 scoped_refptr<IndexedDBBackingStore> backing_store,
3360 IndexedDBBackingStore::Transaction* transaction,
3361 int64 database_id,
3044 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3362 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
3045 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3363 : IndexedDBBackingStore::Cursor(backing_store,
3364 transaction,
3365 database_id,
3366 cursor_options) {}
3046 3367
3047 virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); } 3368 virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); }
3048 3369
3049 // IndexedDBBackingStore::Cursor 3370 // IndexedDBBackingStore::Cursor
3050 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; } 3371 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; }
3051 virtual const IndexedDBKey& primary_key() const OVERRIDE { 3372 virtual const IndexedDBKey& primary_key() const OVERRIDE {
3052 return *primary_key_; 3373 return *primary_key_;
3053 } 3374 }
3054 virtual const IndexedDBBackingStore::RecordIdentifier& record_identifier() 3375 virtual const IndexedDBBackingStore::RecordIdentifier& record_identifier()
3055 const OVERRIDE { 3376 const OVERRIDE {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3101 int64 index_data_version; 3422 int64 index_data_version;
3102 if (!DecodeVarInt(&slice, &index_data_version)) { 3423 if (!DecodeVarInt(&slice, &index_data_version)) {
3103 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3424 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3104 return false; 3425 return false;
3105 } 3426 }
3106 if (!DecodeIDBKey(&slice, &primary_key_)) { 3427 if (!DecodeIDBKey(&slice, &primary_key_)) {
3107 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3428 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3108 return false; 3429 return false;
3109 } 3430 }
3110 3431
3432 DCHECK_EQ(index_data_key.DatabaseId(), database_id_);
3111 primary_leveldb_key_ = 3433 primary_leveldb_key_ =
3112 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 3434 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
3113 index_data_key.ObjectStoreId(), 3435 index_data_key.ObjectStoreId(),
3114 *primary_key_); 3436 *primary_key_);
3115 3437
3116 std::string result; 3438 std::string result;
3117 bool found = false; 3439 bool found = false;
3118 leveldb::Status s = transaction_->Get(primary_leveldb_key_, &result, &found); 3440 leveldb::Status s =
3441 transaction_->transaction()->Get(primary_leveldb_key_, &result, &found);
3119 if (!s.ok()) { 3442 if (!s.ok()) {
3120 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3443 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3121 return false; 3444 return false;
3122 } 3445 }
3123 if (!found) { 3446 if (!found) {
3124 transaction_->Remove(iterator_->Key()); 3447 transaction_->transaction()->Remove(iterator_->Key());
3125 return false; 3448 return false;
3126 } 3449 }
3127 if (!result.size()) { 3450 if (!result.size()) {
3128 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3451 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3129 return false; 3452 return false;
3130 } 3453 }
3131 3454
3132 int64 object_store_data_version; 3455 int64 object_store_data_version;
3133 slice = StringPiece(result); 3456 slice = StringPiece(result);
3134 if (!DecodeVarInt(&slice, &object_store_data_version)) { 3457 if (!DecodeVarInt(&slice, &object_store_data_version)) {
3135 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3458 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3136 return false; 3459 return false;
3137 } 3460 }
3138 3461
3139 if (object_store_data_version != index_data_version) { 3462 if (object_store_data_version != index_data_version) {
3140 transaction_->Remove(iterator_->Key()); 3463 transaction_->transaction()->Remove(iterator_->Key());
3141 return false; 3464 return false;
3142 } 3465 }
3143 3466
3144 current_value_.bits = slice.as_string(); 3467 current_value_.bits = slice.as_string();
3145 return true; 3468 return transaction_->GetBlobInfoForRecord(database_id_,
3469 primary_leveldb_key_,
3470 &current_value_).ok();
3146 } 3471 }
3147 3472
3148 bool ObjectStoreCursorOptions( 3473 bool ObjectStoreCursorOptions(
3149 LevelDBTransaction* transaction, 3474 LevelDBTransaction* transaction,
3150 int64 database_id, 3475 int64 database_id,
3151 int64 object_store_id, 3476 int64 object_store_id,
3152 const IndexedDBKeyRange& range, 3477 const IndexedDBKeyRange& range,
3153 indexed_db::CursorDirection direction, 3478 indexed_db::CursorDirection direction,
3154 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { 3479 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
3155 cursor_options->database_id = database_id; 3480 cursor_options->database_id = database_id;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
3302 *s = leveldb::Status::OK(); 3627 *s = leveldb::Status::OK();
3303 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3628 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3304 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3629 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3305 if (!ObjectStoreCursorOptions(leveldb_transaction, 3630 if (!ObjectStoreCursorOptions(leveldb_transaction,
3306 database_id, 3631 database_id,
3307 object_store_id, 3632 object_store_id,
3308 range, 3633 range,
3309 direction, 3634 direction,
3310 &cursor_options)) 3635 &cursor_options))
3311 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3636 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3312 scoped_ptr<ObjectStoreCursorImpl> cursor( 3637 scoped_ptr<ObjectStoreCursorImpl> cursor(new ObjectStoreCursorImpl(
3313 new ObjectStoreCursorImpl(leveldb_transaction, cursor_options)); 3638 this, transaction, database_id, cursor_options));
3314 if (!cursor->FirstSeek(s)) 3639 if (!cursor->FirstSeek(s))
3315 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3640 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3316 3641
3317 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3642 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3318 } 3643 }
3319 3644
3320 scoped_ptr<IndexedDBBackingStore::Cursor> 3645 scoped_ptr<IndexedDBBackingStore::Cursor>
3321 IndexedDBBackingStore::OpenObjectStoreKeyCursor( 3646 IndexedDBBackingStore::OpenObjectStoreKeyCursor(
3322 IndexedDBBackingStore::Transaction* transaction, 3647 IndexedDBBackingStore::Transaction* transaction,
3323 int64 database_id, 3648 int64 database_id,
3324 int64 object_store_id, 3649 int64 object_store_id,
3325 const IndexedDBKeyRange& range, 3650 const IndexedDBKeyRange& range,
3326 indexed_db::CursorDirection direction, 3651 indexed_db::CursorDirection direction,
3327 leveldb::Status* s) { 3652 leveldb::Status* s) {
3328 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); 3653 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
3329 *s = leveldb::Status::OK(); 3654 *s = leveldb::Status::OK();
3330 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3655 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3331 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3656 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3332 if (!ObjectStoreCursorOptions(leveldb_transaction, 3657 if (!ObjectStoreCursorOptions(leveldb_transaction,
3333 database_id, 3658 database_id,
3334 object_store_id, 3659 object_store_id,
3335 range, 3660 range,
3336 direction, 3661 direction,
3337 &cursor_options)) 3662 &cursor_options))
3338 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3663 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3339 scoped_ptr<ObjectStoreKeyCursorImpl> cursor( 3664 scoped_ptr<ObjectStoreKeyCursorImpl> cursor(new ObjectStoreKeyCursorImpl(
3340 new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options)); 3665 this, transaction, database_id, cursor_options));
3341 if (!cursor->FirstSeek(s)) 3666 if (!cursor->FirstSeek(s))
3342 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3667 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3343 3668
3344 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3669 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3345 } 3670 }
3346 3671
3347 scoped_ptr<IndexedDBBackingStore::Cursor> 3672 scoped_ptr<IndexedDBBackingStore::Cursor>
3348 IndexedDBBackingStore::OpenIndexKeyCursor( 3673 IndexedDBBackingStore::OpenIndexKeyCursor(
3349 IndexedDBBackingStore::Transaction* transaction, 3674 IndexedDBBackingStore::Transaction* transaction,
3350 int64 database_id, 3675 int64 database_id,
3351 int64 object_store_id, 3676 int64 object_store_id,
3352 int64 index_id, 3677 int64 index_id,
3353 const IndexedDBKeyRange& range, 3678 const IndexedDBKeyRange& range,
3354 indexed_db::CursorDirection direction, 3679 indexed_db::CursorDirection direction,
3355 leveldb::Status* s) { 3680 leveldb::Status* s) {
3356 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); 3681 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
3357 *s = leveldb::Status::OK(); 3682 *s = leveldb::Status::OK();
3358 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3683 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3359 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3684 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3360 if (!IndexCursorOptions(leveldb_transaction, 3685 if (!IndexCursorOptions(leveldb_transaction,
3361 database_id, 3686 database_id,
3362 object_store_id, 3687 object_store_id,
3363 index_id, 3688 index_id,
3364 range, 3689 range,
3365 direction, 3690 direction,
3366 &cursor_options)) 3691 &cursor_options))
3367 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3692 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3368 scoped_ptr<IndexKeyCursorImpl> cursor( 3693 scoped_ptr<IndexKeyCursorImpl> cursor(
3369 new IndexKeyCursorImpl(leveldb_transaction, cursor_options)); 3694 new IndexKeyCursorImpl(this, transaction, database_id, cursor_options));
3370 if (!cursor->FirstSeek(s)) 3695 if (!cursor->FirstSeek(s))
3371 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3696 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3372 3697
3373 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3698 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3374 } 3699 }
3375 3700
3376 scoped_ptr<IndexedDBBackingStore::Cursor> 3701 scoped_ptr<IndexedDBBackingStore::Cursor>
3377 IndexedDBBackingStore::OpenIndexCursor( 3702 IndexedDBBackingStore::OpenIndexCursor(
3378 IndexedDBBackingStore::Transaction* transaction, 3703 IndexedDBBackingStore::Transaction* transaction,
3379 int64 database_id, 3704 int64 database_id,
3380 int64 object_store_id, 3705 int64 object_store_id,
3381 int64 index_id, 3706 int64 index_id,
3382 const IndexedDBKeyRange& range, 3707 const IndexedDBKeyRange& range,
3383 indexed_db::CursorDirection direction, 3708 indexed_db::CursorDirection direction,
3384 leveldb::Status* s) { 3709 leveldb::Status* s) {
3385 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); 3710 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
3386 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3711 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3387 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3712 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3388 if (!IndexCursorOptions(leveldb_transaction, 3713 if (!IndexCursorOptions(leveldb_transaction,
3389 database_id, 3714 database_id,
3390 object_store_id, 3715 object_store_id,
3391 index_id, 3716 index_id,
3392 range, 3717 range,
3393 direction, 3718 direction,
3394 &cursor_options)) 3719 &cursor_options))
3395 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3720 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3396 scoped_ptr<IndexCursorImpl> cursor( 3721 scoped_ptr<IndexCursorImpl> cursor(
3397 new IndexCursorImpl(leveldb_transaction, cursor_options)); 3722 new IndexCursorImpl(this, transaction, database_id, cursor_options));
3398 if (!cursor->FirstSeek(s)) 3723 if (!cursor->FirstSeek(s))
3399 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3724 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3400 3725
3401 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3726 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3402 } 3727 }
3403 3728
3404 IndexedDBBackingStore::Transaction::Transaction( 3729 IndexedDBBackingStore::Transaction::Transaction(
3405 IndexedDBBackingStore* backing_store) 3730 IndexedDBBackingStore* backing_store)
3406 : backing_store_(backing_store), database_id_(-1) { 3731 : backing_store_(backing_store), database_id_(-1) {
3407 } 3732 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3579 const GURL& url, 3904 const GURL& url,
3580 int64_t key) 3905 int64_t key)
3581 : is_file_(false), url_(url), key_(key) {} 3906 : is_file_(false), url_(url), key_(key) {}
3582 3907
3583 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( 3908 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor(
3584 const FilePath& file_path, 3909 const FilePath& file_path,
3585 int64_t key) 3910 int64_t key)
3586 : is_file_(true), file_path_(file_path), key_(key) {} 3911 : is_file_(true), file_path_(file_path), key_(key) {}
3587 3912
3588 } // namespace content 3913 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_backing_store.h ('k') | content/browser/indexed_db/indexed_db_leveldb_coding.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698