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

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: Rolled in Josh's feedback 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
« no previous file with comments | « content/browser/indexed_db/indexed_db_backing_store.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(SET_UP_METADATA);
cmumford 2014/05/06 18:33:11 INTERNAL_READ_ERROR_UNTESTED
ericu 2014/05/06 20:07:42 INTERNAL_WRITE_ERROR_UNTESTED? Switched to that.
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(SET_UP_METADATA);
cmumford 2014/05/06 18:33:11 INTERNAL_READ_ERROR_UNTESTED
ericu 2014/05/06 20:07:42 Same?
cmumford 2014/05/06 20:41:47 Woops - my note was bad (READ vs. WRITE). But yes,
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(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER);
cmumford 2014/05/06 18:33:11 INTERNAL_READ_ERROR_UNTESTED
ericu 2014/05/06 20:07:42 Done.
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(GET_BLOB_KEY_GENERATOR_CURRENT_NUMBER);
cmumford 2014/05/06 18:33:11 INTERNAL_READ_ERROR_UNTESTED
ericu 2014/05/06 20:07:42 Done.
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);
jsbell 2014/05/06 18:29:48 Can you add '(var int') to the docs at the top of
ericu 2014/05/06 20:07:42 Done. That's the blob journal, not this blob data
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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 origin_url); 1041 origin_url);
917 } 1042 }
918 1043
919 if (!db) { 1044 if (!db) {
920 NOTREACHED(); 1045 NOTREACHED();
921 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, 1046 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR,
922 origin_url); 1047 origin_url);
923 return scoped_refptr<IndexedDBBackingStore>(); 1048 return scoped_refptr<IndexedDBBackingStore>();
924 } 1049 }
925 1050
926 return Create(indexed_db_factory, 1051 scoped_refptr<IndexedDBBackingStore> backing_store =
927 origin_url, 1052 Create(indexed_db_factory,
928 blob_path, 1053 origin_url,
929 request_context, 1054 blob_path,
930 db.Pass(), 1055 request_context,
931 comparator.Pass(), 1056 db.Pass(),
932 task_runner); 1057 comparator.Pass(),
1058 task_runner);
1059
1060 if (clean_journal &&
1061 !backing_store->CleanUpBlobJournal(LiveBlobJournalKey::Encode()).ok())
cmumford 2014/05/06 18:33:11 If SetupMetaData fails for whatever reason backing
ericu 2014/05/06 20:07:42 Fixed.
1062 return scoped_refptr<IndexedDBBackingStore>();
cmumford 2014/05/06 18:33:11 Do you want to record a histogram value here in ca
ericu 2014/05/06 20:07:42 Yeah, good idea.
1063 return backing_store;
933 } 1064 }
934 1065
935 // static 1066 // static
936 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory( 1067 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::OpenInMemory(
937 const GURL& origin_url, 1068 const GURL& origin_url,
938 base::TaskRunner* task_runner) { 1069 base::TaskRunner* task_runner) {
939 DefaultLevelDBFactory leveldb_factory; 1070 DefaultLevelDBFactory leveldb_factory;
940 return IndexedDBBackingStore::OpenInMemory( 1071 return IndexedDBBackingStore::OpenInMemory(
941 origin_url, &leveldb_factory, task_runner); 1072 origin_url, &leveldb_factory, task_runner);
942 } 1073 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 base::TaskRunner* task_runner) { 1110 base::TaskRunner* task_runner) {
980 // TODO(jsbell): Handle comparator name changes. 1111 // TODO(jsbell): Handle comparator name changes.
981 scoped_refptr<IndexedDBBackingStore> backing_store( 1112 scoped_refptr<IndexedDBBackingStore> backing_store(
982 new IndexedDBBackingStore(indexed_db_factory, 1113 new IndexedDBBackingStore(indexed_db_factory,
983 origin_url, 1114 origin_url,
984 blob_path, 1115 blob_path,
985 request_context, 1116 request_context,
986 db.Pass(), 1117 db.Pass(),
987 comparator.Pass(), 1118 comparator.Pass(),
988 task_runner)); 1119 task_runner));
989 if (!SetUpMetadata(backing_store->db_.get(), 1120 if (!backing_store->SetUpMetadata())
990 backing_store->origin_identifier_))
991 return scoped_refptr<IndexedDBBackingStore>(); 1121 return scoped_refptr<IndexedDBBackingStore>();
992 1122
993 return backing_store; 1123 return backing_store;
994 } 1124 }
995 1125
996 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) { 1126 void IndexedDBBackingStore::GrantChildProcessPermissions(int child_process_id) {
997 if (!child_process_ids_granted_.count(child_process_id)) { 1127 if (!child_process_ids_granted_.count(child_process_id)) {
998 child_process_ids_granted_.insert(child_process_id); 1128 child_process_ids_granted_.insert(child_process_id);
999 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile( 1129 ChildProcessSecurityPolicyImpl::GetInstance()->GrantReadFile(
1000 child_process_id, blob_path_); 1130 child_process_id, blob_path_);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 1207
1078 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) 1208 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION)
1079 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 1209 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION;
1080 1210
1081 s = GetMaxObjectStoreId( 1211 s = GetMaxObjectStoreId(
1082 db_.get(), metadata->id, &metadata->max_object_store_id); 1212 db_.get(), metadata->id, &metadata->max_object_store_id);
1083 if (!s.ok()) { 1213 if (!s.ok()) {
1084 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); 1214 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
1085 } 1215 }
1086 1216
1217 // We don't cache this, we just check it if it's there.
1218 int64 blob_key_generator_current_number =
1219 DatabaseMetaDataKey::kInvalidBlobKey;
1220
1221 s = GetVarInt(
1222 db_.get(),
1223 DatabaseMetaDataKey::Encode(
1224 metadata->id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER),
1225 &blob_key_generator_current_number,
1226 found);
1227 if (!s.ok()) {
1228 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA);
cmumford 2014/05/06 18:33:11 _UNTESTED
ericu 2014/05/06 20:07:42 Done.
1229 return s;
1230 }
1231 if (!*found) {
1232 // This database predates blob support.
1233 *found = true;
1234 } else if (!DatabaseMetaDataKey::IsValidBlobKey(
1235 blob_key_generator_current_number)) {
1236 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA);
cmumford 2014/05/06 18:33:11 _UNTESTED
ericu 2014/05/06 20:07:42 Done.
1237 return InternalInconsistencyStatus();
1238 }
1239
1087 return s; 1240 return s;
1088 } 1241 }
1089 1242
1090 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId( 1243 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId(
1091 LevelDBTransaction* transaction, 1244 LevelDBTransaction* transaction,
1092 int64* new_id) { 1245 int64* new_id) {
1093 *new_id = -1; 1246 *new_id = -1;
1094 int64 max_database_id = -1; 1247 int64 max_database_id = -1;
1095 bool found = false; 1248 bool found = false;
1096 leveldb::Status s = 1249 leveldb::Status s =
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1130 DatabaseNameKey::Encode(origin_identifier_, name), 1283 DatabaseNameKey::Encode(origin_identifier_, name),
1131 *row_id); 1284 *row_id);
1132 PutString( 1285 PutString(
1133 transaction.get(), 1286 transaction.get(),
1134 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION), 1287 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION),
1135 version); 1288 version);
1136 PutVarInt(transaction.get(), 1289 PutVarInt(transaction.get(),
1137 DatabaseMetaDataKey::Encode(*row_id, 1290 DatabaseMetaDataKey::Encode(*row_id,
1138 DatabaseMetaDataKey::USER_INT_VERSION), 1291 DatabaseMetaDataKey::USER_INT_VERSION),
1139 int_version); 1292 int_version);
1293 PutVarInt(
1294 transaction.get(),
1295 DatabaseMetaDataKey::Encode(
1296 *row_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER),
1297 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber);
1298
1140 s = transaction->Commit(); 1299 s = transaction->Commit();
1141 if (!s.ok()) 1300 if (!s.ok())
1142 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA); 1301 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA);
1143 return s; 1302 return s;
1144 } 1303 }
1145 1304
1146 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( 1305 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion(
1147 IndexedDBBackingStore::Transaction* transaction, 1306 IndexedDBBackingStore::Transaction* transaction,
1148 int64 row_id, 1307 int64 row_id,
1149 int64 int_version) { 1308 int64 int_version) {
(...skipping 12 matching lines...) Expand all
1162 const std::string& end) { 1321 const std::string& end) {
1163 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 1322 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
1164 leveldb::Status s; 1323 leveldb::Status s;
1165 for (s = it->Seek(begin); 1324 for (s = it->Seek(begin);
1166 s.ok() && it->IsValid() && CompareKeys(it->Key(), end) < 0; 1325 s.ok() && it->IsValid() && CompareKeys(it->Key(), end) < 0;
1167 s = it->Next()) 1326 s = it->Next())
1168 transaction->Remove(it->Key()); 1327 transaction->Remove(it->Key());
1169 return s; 1328 return s;
1170 } 1329 }
1171 1330
1331 static leveldb::Status DeleteBlobsInObjectStore(
1332 IndexedDBBackingStore::Transaction* transaction,
1333 int64 database_id,
1334 int64 object_store_id) {
1335 std::string start_key, end_key;
1336 start_key =
1337 BlobEntryKey::EncodeMinKeyForObjectStore(database_id, object_store_id);
1338 end_key =
1339 BlobEntryKey::EncodeStopKeyForObjectStore(database_id, object_store_id);
1340
1341 scoped_ptr<LevelDBIterator> it = transaction->transaction()->CreateIterator();
1342 for (it->Seek(start_key);
cmumford 2014/05/06 18:33:11 Seek/Next/etc. now return Status objects. should c
ericu 2014/05/06 20:07:42 Working on that now. On the last step of an itera
cmumford 2014/05/06 20:41:47 I believe that it will return OK() and the iterato
1343 it->IsValid() && CompareKeys(it->Key(), end_key) < 0;
1344 it->Next()) {
1345 StringPiece key_piece(it->Key());
1346 std::string user_key =
1347 BlobEntryKey::ReencodeToObjectStoreDataKey(&key_piece);
1348 if (!user_key.size()) {
1349 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA);
cmumford 2014/05/06 18:33:11 _UNTESTED
ericu 2014/05/06 20:07:42 Done.
1350 return InternalInconsistencyStatus();
1351 }
1352 transaction->PutBlobInfo(
1353 database_id, object_store_id, user_key, NULL, NULL);
1354 }
1355 return leveldb::Status::OK();
1356 }
1357
1172 leveldb::Status IndexedDBBackingStore::DeleteDatabase( 1358 leveldb::Status IndexedDBBackingStore::DeleteDatabase(
1173 const base::string16& name) { 1359 const base::string16& name) {
1174 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase"); 1360 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase");
1175 scoped_ptr<LevelDBDirectTransaction> transaction = 1361 scoped_ptr<LevelDBDirectTransaction> transaction =
1176 LevelDBDirectTransaction::Create(db_.get()); 1362 LevelDBDirectTransaction::Create(db_.get());
1177 1363
1364 leveldb::Status s;
1365 s = CleanUpBlobJournal(BlobJournalKey::Encode());
1366 if (!s.ok())
1367 return InternalInconsistencyStatus();
cmumford 2014/05/06 18:33:11 Why not return "s" here?
ericu 2014/05/06 20:07:42 Done.
1368
1178 IndexedDBDatabaseMetadata metadata; 1369 IndexedDBDatabaseMetadata metadata;
1179 bool success = false; 1370 bool success = false;
1180 leveldb::Status s = GetIDBDatabaseMetaData(name, &metadata, &success); 1371 s = GetIDBDatabaseMetaData(name, &metadata, &success);
1181 if (!s.ok()) 1372 if (!s.ok())
1182 return s; 1373 return s;
1183 if (!success) 1374 if (!success)
1184 return leveldb::Status::OK(); 1375 return leveldb::Status::OK();
1185 1376
1186 const std::string start_key = DatabaseMetaDataKey::Encode( 1377 const std::string start_key = DatabaseMetaDataKey::Encode(
1187 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME); 1378 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME);
1188 const std::string stop_key = DatabaseMetaDataKey::Encode( 1379 const std::string stop_key = DatabaseMetaDataKey::Encode(
1189 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME); 1380 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME);
1190 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1381 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1191 for (s = it->Seek(start_key); 1382 for (s = it->Seek(start_key);
1192 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 1383 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
1193 s = it->Next()) 1384 s = it->Next())
1194 transaction->Remove(it->Key()); 1385 transaction->Remove(it->Key());
1195 if (!s.ok()) { 1386 if (!s.ok()) {
1196 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE); 1387 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
1197 return s; 1388 return s;
1198 } 1389 }
1199 1390
1200 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); 1391 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
1201 transaction->Remove(key); 1392 transaction->Remove(key);
1202 1393
1203 // TODO(ericu): Put the real calls to the blob journal code here. For now, 1394 bool need_cleanup = false;
1204 // I've inserted fake calls so that we don't get "you didn't use this static 1395 if (active_blob_registry()->MarkDeletedCheckIfUsed(
1205 // function" compiler errors. 1396 metadata.id, DatabaseMetaDataKey::kAllBlobsKey)) {
1397 s = MergeDatabaseIntoLiveBlobJournal(transaction.get(), metadata.id);
1398 if (!s.ok())
1399 return s;
1400 } else {
1401 UpdateBlobJournalWithDatabase(transaction.get(), metadata.id);
1402 need_cleanup = true;
1403 }
1404
1405 // TODO(ericu): Remove these fake calls, added to avoid "defined but unused"
1406 // compiler errors until the code that makes the real calls can be added.
1206 if (false) { 1407 if (false) {
1408 std::vector<IndexedDBBlobInfo*> fake;
1409 EncodeBlobData(fake);
1410
1207 scoped_refptr<LevelDBTransaction> fake_transaction = 1411 scoped_refptr<LevelDBTransaction> fake_transaction =
1208 new LevelDBTransaction(NULL); 1412 new LevelDBTransaction(NULL);
1209 BlobJournalType fake_journal; 1413 BlobJournalType fake_journal;
1210 MergeDatabaseIntoLiveBlobJournal(transaction.get(), metadata.id);
1211 UpdateBlobJournalWithDatabase(transaction.get(), metadata.id);
1212 MergeBlobsIntoLiveBlobJournal(fake_transaction.get(), fake_journal); 1414 MergeBlobsIntoLiveBlobJournal(fake_transaction.get(), fake_journal);
1415 UpdateBlobKeyGeneratorCurrentNumber(fake_transaction.get(), 0, 0);
1213 } 1416 }
1214 1417
1215 s = transaction->Commit(); 1418 s = transaction->Commit();
1216 if (!s.ok()) { 1419 if (!s.ok()) {
1217 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE); 1420 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
1218 return s; 1421 return s;
1219 } 1422 }
1423
1424 if (need_cleanup)
1425 CleanUpBlobJournal(BlobJournalKey::Encode());
1426
1220 db_->Compact(start_key, stop_key); 1427 db_->Compact(start_key, stop_key);
1221 return s; 1428 return s;
1222 } 1429 }
1223 1430
1224 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it, 1431 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it,
1225 const std::string& stop_key, 1432 const std::string& stop_key,
1226 int64 object_store_id, 1433 int64 object_store_id,
1227 int64 meta_data_type) { 1434 int64 meta_data_type) {
1228 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0) 1435 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0)
1229 return false; 1436 return false;
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 &found); 1725 &found);
1519 if (!s.ok()) { 1726 if (!s.ok()) {
1520 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1727 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1521 return s; 1728 return s;
1522 } 1729 }
1523 if (!found) { 1730 if (!found) {
1524 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1731 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1525 return InternalInconsistencyStatus(); 1732 return InternalInconsistencyStatus();
1526 } 1733 }
1527 1734
1735 s = DeleteBlobsInObjectStore(transaction, database_id, object_store_id);
1736 if (!s.ok()) {
1737 INTERNAL_CONSISTENCY_ERROR(DELETE_OBJECT_STORE);
cmumford 2014/05/06 18:33:11 _UNTESTED
ericu 2014/05/06 20:07:42 Done.
1738 return s;
1739 }
1740
1528 s = DeleteRange( 1741 s = DeleteRange(
1529 leveldb_transaction, 1742 leveldb_transaction,
1530 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), 1743 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0),
1531 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1744 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1532 1745
1533 if (s.ok()) { 1746 if (s.ok()) {
1534 leveldb_transaction->Remove( 1747 leveldb_transaction->Remove(
1535 ObjectStoreNamesKey::Encode(database_id, object_store_name)); 1748 ObjectStoreNamesKey::Encode(database_id, object_store_name));
1536 1749
1537 s = DeleteRange( 1750 s = DeleteRange(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 } 1799 }
1587 1800
1588 int64 version; 1801 int64 version;
1589 StringPiece slice(data); 1802 StringPiece slice(data);
1590 if (!DecodeVarInt(&slice, &version)) { 1803 if (!DecodeVarInt(&slice, &version)) {
1591 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD); 1804 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD);
1592 return InternalInconsistencyStatus(); 1805 return InternalInconsistencyStatus();
1593 } 1806 }
1594 1807
1595 record->bits = slice.as_string(); 1808 record->bits = slice.as_string();
1596 return s; 1809 return transaction->GetBlobInfoForRecord(database_id, leveldb_key, record);
1597 } 1810 }
1598 1811
1599 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber( 1812 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber(
1600 LevelDBTransaction* transaction, 1813 LevelDBTransaction* transaction,
1601 int64 database_id, 1814 int64 database_id,
1602 int64 object_store_id, 1815 int64 object_store_id,
1603 int64* new_version_number) { 1816 int64* new_version_number) {
1604 const std::string last_version_key = ObjectStoreMetaDataKey::Encode( 1817 const std::string last_version_key = ObjectStoreMetaDataKey::Encode(
1605 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); 1818 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
1606 1819
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1682 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); 1895 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore");
1683 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1896 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1684 return InvalidDBKeyStatus(); 1897 return InvalidDBKeyStatus();
1685 const std::string start_key = 1898 const std::string start_key =
1686 KeyPrefix(database_id, object_store_id).Encode(); 1899 KeyPrefix(database_id, object_store_id).Encode();
1687 const std::string stop_key = 1900 const std::string stop_key =
1688 KeyPrefix(database_id, object_store_id + 1).Encode(); 1901 KeyPrefix(database_id, object_store_id + 1).Encode();
1689 1902
1690 leveldb::Status s = 1903 leveldb::Status s =
1691 DeleteRange(transaction->transaction(), start_key, stop_key); 1904 DeleteRange(transaction->transaction(), start_key, stop_key);
1692 if (!s.ok()) 1905 if (!s.ok()) {
1693 INTERNAL_WRITE_ERROR(CLEAR_OBJECT_STORE); 1906 INTERNAL_WRITE_ERROR(CLEAR_OBJECT_STORE);
1694 return s; 1907 return s;
1908 }
1909 return DeleteBlobsInObjectStore(transaction, database_id, object_store_id);
1695 } 1910 }
1696 1911
1697 leveldb::Status IndexedDBBackingStore::DeleteRecord( 1912 leveldb::Status IndexedDBBackingStore::DeleteRecord(
1698 IndexedDBBackingStore::Transaction* transaction, 1913 IndexedDBBackingStore::Transaction* transaction,
1699 int64 database_id, 1914 int64 database_id,
1700 int64 object_store_id, 1915 int64 object_store_id,
1701 const RecordIdentifier& record_identifier) { 1916 const RecordIdentifier& record_identifier) {
1702 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); 1917 IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
1703 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1918 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1704 return InvalidDBKeyStatus(); 1919 return InvalidDBKeyStatus();
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
2282 } else { 2497 } else {
2283 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); 2498 DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
2284 if (!RemoveBlobFile(database_id, blob_key)) 2499 if (!RemoveBlobFile(database_id, blob_key))
2285 return IOErrorStatus(); 2500 return IOErrorStatus();
2286 } 2501 }
2287 } 2502 }
2288 ClearBlobJournal(journal_transaction.get(), level_db_key); 2503 ClearBlobJournal(journal_transaction.get(), level_db_key);
2289 return journal_transaction->Commit(); 2504 return journal_transaction->Commit();
2290 } 2505 }
2291 2506
2507 leveldb::Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord(
2508 int64 database_id,
2509 const std::string& object_store_data_key,
2510 IndexedDBValue* value) {
2511 BlobChangeRecord* change_record = NULL;
2512 BlobChangeMap::const_iterator blob_iter =
2513 blob_change_map_.find(object_store_data_key);
2514 if (blob_iter != blob_change_map_.end())
2515 change_record = blob_iter->second;
2516 else {
jsbell 2014/05/06 18:29:48 Inconsistent bracing (if any if/else branch uses b
ericu 2014/05/06 20:07:42 Done.
2517 blob_iter = incognito_blob_map_.find(object_store_data_key);
2518 if (blob_iter != incognito_blob_map_.end())
2519 change_record = blob_iter->second;
2520 }
2521 if (change_record) {
2522 // Either we haven't written the blob to disk yet or we're in incognito
2523 // mode, so we have to send back the one they sent us. This change record
2524 // includes the original UUID.
2525 value->blob_info = change_record->blob_info();
2526 return leveldb::Status::OK();
2527 }
2528
2529 BlobEntryKey blob_entry_key;
2530 StringPiece leveldb_key_piece(object_store_data_key);
2531 if (!BlobEntryKey::FromObjectStoreDataKey(&leveldb_key_piece,
2532 &blob_entry_key)) {
2533 NOTREACHED();
2534 return InternalInconsistencyStatus();
2535 }
2536 scoped_ptr<LevelDBIterator> it = transaction()->CreateIterator();
2537 std::string encoded_key = blob_entry_key.Encode();
2538 it->Seek(encoded_key);
cmumford 2014/05/06 18:33:11 Status
ericu 2014/05/06 20:07:42 Done.
2539 if (it->IsValid() && CompareKeys(it->Key(), encoded_key) == 0) {
2540 if (!DecodeBlobData(it->Value().as_string(), &value->blob_info)) {
2541 INTERNAL_READ_ERROR(GET_BLOB_INFO_FOR_RECORD);
2542 return InternalInconsistencyStatus();
2543 }
2544 std::vector<IndexedDBBlobInfo>::iterator iter;
2545 for (iter = value->blob_info.begin(); iter != value->blob_info.end();
2546 ++iter) {
2547 iter->set_file_path(
2548 backing_store_->GetBlobFileName(database_id, iter->key()));
2549 iter->set_mark_used_callback(
2550 backing_store_->active_blob_registry()->GetAddBlobRefCallback(
2551 database_id, iter->key()));
2552 iter->set_release_callback(
2553 backing_store_->active_blob_registry()->GetFinalReleaseCallback(
2554 database_id, iter->key()));
2555 if (iter->is_file()) {
2556 base::File::Info info;
2557 if (base::GetFileInfo(iter->file_path(), &info)) {
2558 // This should always work, but it isn't fatal if it doesn't; it just
2559 // means a potential slow synchronous call from the renderer later.
2560 iter->set_last_modified(info.last_modified);
2561 iter->set_size(info.size);
2562 }
2563 }
2564 }
2565 }
2566 return leveldb::Status::OK();
2567 }
2568
2292 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() { 2569 void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() {
2293 CleanUpBlobJournal(BlobJournalKey::Encode()); 2570 CleanUpBlobJournal(BlobJournalKey::Encode());
2294 } 2571 }
2295 2572
2296 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( 2573 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
2297 LevelDBTransaction* transaction, 2574 LevelDBTransaction* transaction,
2298 int64 database_id, 2575 int64 database_id,
2299 int64 object_store_id, 2576 int64 object_store_id,
2300 int64 index_id) { 2577 int64 index_id) {
2301 int64 max_index_id = -1; 2578 int64 max_index_id = -1;
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2605 2882
2606 StringPiece slice(found_encoded_primary_key); 2883 StringPiece slice(found_encoded_primary_key);
2607 if (DecodeIDBKey(&slice, found_primary_key) && slice.empty()) 2884 if (DecodeIDBKey(&slice, found_primary_key) && slice.empty())
2608 return s; 2885 return s;
2609 else 2886 else
2610 return InvalidDBKeyStatus(); 2887 return InvalidDBKeyStatus();
2611 } 2888 }
2612 2889
2613 IndexedDBBackingStore::Cursor::Cursor( 2890 IndexedDBBackingStore::Cursor::Cursor(
2614 const IndexedDBBackingStore::Cursor* other) 2891 const IndexedDBBackingStore::Cursor* other)
2615 : transaction_(other->transaction_), 2892 : backing_store_(other->backing_store_),
2893 transaction_(other->transaction_),
2894 database_id_(other->database_id_),
2616 cursor_options_(other->cursor_options_), 2895 cursor_options_(other->cursor_options_),
2617 current_key_(new IndexedDBKey(*other->current_key_)) { 2896 current_key_(new IndexedDBKey(*other->current_key_)) {
2618 if (other->iterator_) { 2897 if (other->iterator_) {
2619 iterator_ = transaction_->CreateIterator(); 2898 iterator_ = transaction_->transaction()->CreateIterator();
2620 2899
2621 if (other->iterator_->IsValid()) { 2900 if (other->iterator_->IsValid()) {
2622 leveldb::Status s = iterator_->Seek(other->iterator_->Key()); 2901 leveldb::Status s = iterator_->Seek(other->iterator_->Key());
2623 // TODO(cmumford): Handle this error (crbug.com/363397) 2902 // TODO(cmumford): Handle this error (crbug.com/363397)
2624 DCHECK(iterator_->IsValid()); 2903 DCHECK(iterator_->IsValid());
2625 } 2904 }
2626 } 2905 }
2627 } 2906 }
2628 2907
2629 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction, 2908 IndexedDBBackingStore::Cursor::Cursor(
2630 const CursorOptions& cursor_options) 2909 scoped_refptr<IndexedDBBackingStore> backing_store,
2631 : transaction_(transaction), cursor_options_(cursor_options) {} 2910 IndexedDBBackingStore::Transaction* transaction,
2911 int64 database_id,
2912 const CursorOptions& cursor_options)
2913 : backing_store_(backing_store),
2914 transaction_(transaction),
2915 database_id_(database_id),
2916 cursor_options_(cursor_options) {
2917 }
2632 IndexedDBBackingStore::Cursor::~Cursor() {} 2918 IndexedDBBackingStore::Cursor::~Cursor() {}
2633 2919
2634 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) { 2920 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) {
2635 iterator_ = transaction_->CreateIterator(); 2921 iterator_ = transaction_->transaction()->CreateIterator();
2636 if (cursor_options_.forward) 2922 if (cursor_options_.forward)
2637 *s = iterator_->Seek(cursor_options_.low_key); 2923 *s = iterator_->Seek(cursor_options_.low_key);
2638 else 2924 else
2639 *s = iterator_->Seek(cursor_options_.high_key); 2925 *s = iterator_->Seek(cursor_options_.high_key);
2640 if (!s->ok()) 2926 if (!s->ok())
2641 return false; 2927 return false;
2642 2928
2643 return Continue(0, READY, s); 2929 return Continue(0, READY, s);
2644 } 2930 }
2645 2931
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2808 } 3094 }
2809 3095
2810 const IndexedDBBackingStore::RecordIdentifier& 3096 const IndexedDBBackingStore::RecordIdentifier&
2811 IndexedDBBackingStore::Cursor::record_identifier() const { 3097 IndexedDBBackingStore::Cursor::record_identifier() const {
2812 return record_identifier_; 3098 return record_identifier_;
2813 } 3099 }
2814 3100
2815 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { 3101 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2816 public: 3102 public:
2817 ObjectStoreKeyCursorImpl( 3103 ObjectStoreKeyCursorImpl(
2818 LevelDBTransaction* transaction, 3104 scoped_refptr<IndexedDBBackingStore> backing_store,
3105 IndexedDBBackingStore::Transaction* transaction,
3106 int64 database_id,
2819 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3107 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2820 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3108 : IndexedDBBackingStore::Cursor(backing_store,
3109 transaction,
3110 database_id,
3111 cursor_options) {}
2821 3112
2822 virtual Cursor* Clone() OVERRIDE { 3113 virtual Cursor* Clone() OVERRIDE {
2823 return new ObjectStoreKeyCursorImpl(this); 3114 return new ObjectStoreKeyCursorImpl(this);
2824 } 3115 }
2825 3116
2826 // IndexedDBBackingStore::Cursor 3117 // IndexedDBBackingStore::Cursor
2827 virtual IndexedDBValue* value() OVERRIDE { 3118 virtual IndexedDBValue* value() OVERRIDE {
2828 NOTREACHED(); 3119 NOTREACHED();
2829 return NULL; 3120 return NULL;
2830 } 3121 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2867 std::string encoded_key; 3158 std::string encoded_key;
2868 EncodeIDBKey(*current_key_, &encoded_key); 3159 EncodeIDBKey(*current_key_, &encoded_key);
2869 record_identifier_.Reset(encoded_key, version); 3160 record_identifier_.Reset(encoded_key, version);
2870 3161
2871 return true; 3162 return true;
2872 } 3163 }
2873 3164
2874 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { 3165 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
2875 public: 3166 public:
2876 ObjectStoreCursorImpl( 3167 ObjectStoreCursorImpl(
2877 LevelDBTransaction* transaction, 3168 scoped_refptr<IndexedDBBackingStore> backing_store,
3169 IndexedDBBackingStore::Transaction* transaction,
3170 int64 database_id,
2878 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3171 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2879 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3172 : IndexedDBBackingStore::Cursor(backing_store,
3173 transaction,
3174 database_id,
3175 cursor_options) {}
2880 3176
2881 virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); } 3177 virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); }
2882 3178
2883 // IndexedDBBackingStore::Cursor 3179 // IndexedDBBackingStore::Cursor
2884 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; } 3180 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; }
2885 virtual bool LoadCurrentRow() OVERRIDE; 3181 virtual bool LoadCurrentRow() OVERRIDE;
2886 3182
2887 protected: 3183 protected:
2888 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE { 3184 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE {
2889 return ObjectStoreDataKey::Encode( 3185 return ObjectStoreDataKey::Encode(
(...skipping 28 matching lines...) Expand all
2918 if (!DecodeVarInt(&value_slice, &version)) { 3214 if (!DecodeVarInt(&value_slice, &version)) {
2919 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3215 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2920 return false; 3216 return false;
2921 } 3217 }
2922 3218
2923 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 3219 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2924 std::string encoded_key; 3220 std::string encoded_key;
2925 EncodeIDBKey(*current_key_, &encoded_key); 3221 EncodeIDBKey(*current_key_, &encoded_key);
2926 record_identifier_.Reset(encoded_key, version); 3222 record_identifier_.Reset(encoded_key, version);
2927 3223
3224 if (!transaction_->GetBlobInfoForRecord(database_id_,
3225 iterator_->Key().as_string(),
3226 &current_value_).ok()) {
3227 return false;
3228 }
2928 current_value_.bits = value_slice.as_string(); 3229 current_value_.bits = value_slice.as_string();
2929 return true; 3230 return true;
2930 } 3231 }
2931 3232
2932 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { 3233 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2933 public: 3234 public:
2934 IndexKeyCursorImpl( 3235 IndexKeyCursorImpl(
2935 LevelDBTransaction* transaction, 3236 scoped_refptr<IndexedDBBackingStore> backing_store,
3237 IndexedDBBackingStore::Transaction* transaction,
3238 int64 database_id,
2936 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3239 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2937 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3240 : IndexedDBBackingStore::Cursor(backing_store,
3241 transaction,
3242 database_id,
3243 cursor_options) {}
2938 3244
2939 virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); } 3245 virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); }
2940 3246
2941 // IndexedDBBackingStore::Cursor 3247 // IndexedDBBackingStore::Cursor
2942 virtual IndexedDBValue* value() OVERRIDE { 3248 virtual IndexedDBValue* value() OVERRIDE {
2943 NOTREACHED(); 3249 NOTREACHED();
2944 return NULL; 3250 return NULL;
2945 } 3251 }
2946 virtual const IndexedDBKey& primary_key() const OVERRIDE { 3252 virtual const IndexedDBKey& primary_key() const OVERRIDE {
2947 return *primary_key_; 3253 return *primary_key_;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 return false; 3306 return false;
3001 } 3307 }
3002 3308
3003 std::string primary_leveldb_key = 3309 std::string primary_leveldb_key =
3004 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 3310 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
3005 index_data_key.ObjectStoreId(), 3311 index_data_key.ObjectStoreId(),
3006 *primary_key_); 3312 *primary_key_);
3007 3313
3008 std::string result; 3314 std::string result;
3009 bool found = false; 3315 bool found = false;
3010 leveldb::Status s = transaction_->Get(primary_leveldb_key, &result, &found); 3316 leveldb::Status s =
3317 transaction_->transaction()->Get(primary_leveldb_key, &result, &found);
3011 if (!s.ok()) { 3318 if (!s.ok()) {
3012 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3319 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3013 return false; 3320 return false;
3014 } 3321 }
3015 if (!found) { 3322 if (!found) {
3016 transaction_->Remove(iterator_->Key()); 3323 transaction_->transaction()->Remove(iterator_->Key());
3017 return false; 3324 return false;
3018 } 3325 }
3019 if (!result.size()) { 3326 if (!result.size()) {
3020 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3327 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3021 return false; 3328 return false;
3022 } 3329 }
3023 3330
3024 int64 object_store_data_version; 3331 int64 object_store_data_version;
3025 slice = StringPiece(result); 3332 slice = StringPiece(result);
3026 if (!DecodeVarInt(&slice, &object_store_data_version)) { 3333 if (!DecodeVarInt(&slice, &object_store_data_version)) {
3027 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3334 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3028 return false; 3335 return false;
3029 } 3336 }
3030 3337
3031 if (object_store_data_version != index_data_version) { 3338 if (object_store_data_version != index_data_version) {
3032 transaction_->Remove(iterator_->Key()); 3339 transaction_->transaction()->Remove(iterator_->Key());
3033 return false; 3340 return false;
3034 } 3341 }
3035 3342
3036 return true; 3343 return true;
3037 } 3344 }
3038 3345
3039 class IndexCursorImpl : public IndexedDBBackingStore::Cursor { 3346 class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
3040 public: 3347 public:
3041 IndexCursorImpl( 3348 IndexCursorImpl(
3042 LevelDBTransaction* transaction, 3349 scoped_refptr<IndexedDBBackingStore> backing_store,
3350 IndexedDBBackingStore::Transaction* transaction,
3351 int64 database_id,
3043 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 3352 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
3044 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 3353 : IndexedDBBackingStore::Cursor(backing_store,
3354 transaction,
3355 database_id,
3356 cursor_options) {}
3045 3357
3046 virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); } 3358 virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); }
3047 3359
3048 // IndexedDBBackingStore::Cursor 3360 // IndexedDBBackingStore::Cursor
3049 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; } 3361 virtual IndexedDBValue* value() OVERRIDE { return &current_value_; }
3050 virtual const IndexedDBKey& primary_key() const OVERRIDE { 3362 virtual const IndexedDBKey& primary_key() const OVERRIDE {
3051 return *primary_key_; 3363 return *primary_key_;
3052 } 3364 }
3053 virtual const IndexedDBBackingStore::RecordIdentifier& record_identifier() 3365 virtual const IndexedDBBackingStore::RecordIdentifier& record_identifier()
3054 const OVERRIDE { 3366 const OVERRIDE {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 int64 index_data_version; 3412 int64 index_data_version;
3101 if (!DecodeVarInt(&slice, &index_data_version)) { 3413 if (!DecodeVarInt(&slice, &index_data_version)) {
3102 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3414 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3103 return false; 3415 return false;
3104 } 3416 }
3105 if (!DecodeIDBKey(&slice, &primary_key_)) { 3417 if (!DecodeIDBKey(&slice, &primary_key_)) {
3106 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3418 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3107 return false; 3419 return false;
3108 } 3420 }
3109 3421
3422 DCHECK_EQ(index_data_key.DatabaseId(), database_id_);
3110 primary_leveldb_key_ = 3423 primary_leveldb_key_ =
3111 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 3424 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
3112 index_data_key.ObjectStoreId(), 3425 index_data_key.ObjectStoreId(),
3113 *primary_key_); 3426 *primary_key_);
3114 3427
3115 std::string result; 3428 std::string result;
3116 bool found = false; 3429 bool found = false;
3117 leveldb::Status s = transaction_->Get(primary_leveldb_key_, &result, &found); 3430 leveldb::Status s =
3431 transaction_->transaction()->Get(primary_leveldb_key_, &result, &found);
3118 if (!s.ok()) { 3432 if (!s.ok()) {
3119 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3433 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3120 return false; 3434 return false;
3121 } 3435 }
3122 if (!found) { 3436 if (!found) {
3123 transaction_->Remove(iterator_->Key()); 3437 transaction_->transaction()->Remove(iterator_->Key());
3124 return false; 3438 return false;
3125 } 3439 }
3126 if (!result.size()) { 3440 if (!result.size()) {
3127 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3441 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3128 return false; 3442 return false;
3129 } 3443 }
3130 3444
3131 int64 object_store_data_version; 3445 int64 object_store_data_version;
3132 slice = StringPiece(result); 3446 slice = StringPiece(result);
3133 if (!DecodeVarInt(&slice, &object_store_data_version)) { 3447 if (!DecodeVarInt(&slice, &object_store_data_version)) {
3134 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW); 3448 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
3135 return false; 3449 return false;
3136 } 3450 }
3137 3451
3138 if (object_store_data_version != index_data_version) { 3452 if (object_store_data_version != index_data_version) {
3139 transaction_->Remove(iterator_->Key()); 3453 transaction_->transaction()->Remove(iterator_->Key());
3140 return false; 3454 return false;
3141 } 3455 }
3142 3456
3143 current_value_.bits = slice.as_string(); 3457 current_value_.bits = slice.as_string();
3144 return true; 3458 return transaction_->GetBlobInfoForRecord(database_id_,
3459 primary_leveldb_key_,
3460 &current_value_).ok();
3145 } 3461 }
3146 3462
3147 bool ObjectStoreCursorOptions( 3463 bool ObjectStoreCursorOptions(
3148 LevelDBTransaction* transaction, 3464 LevelDBTransaction* transaction,
3149 int64 database_id, 3465 int64 database_id,
3150 int64 object_store_id, 3466 int64 object_store_id,
3151 const IndexedDBKeyRange& range, 3467 const IndexedDBKeyRange& range,
3152 indexed_db::CursorDirection direction, 3468 indexed_db::CursorDirection direction,
3153 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { 3469 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
3154 cursor_options->database_id = database_id; 3470 cursor_options->database_id = database_id;
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
3301 *s = leveldb::Status::OK(); 3617 *s = leveldb::Status::OK();
3302 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3618 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3303 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3619 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3304 if (!ObjectStoreCursorOptions(leveldb_transaction, 3620 if (!ObjectStoreCursorOptions(leveldb_transaction,
3305 database_id, 3621 database_id,
3306 object_store_id, 3622 object_store_id,
3307 range, 3623 range,
3308 direction, 3624 direction,
3309 &cursor_options)) 3625 &cursor_options))
3310 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3626 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3311 scoped_ptr<ObjectStoreCursorImpl> cursor( 3627 scoped_ptr<ObjectStoreCursorImpl> cursor(new ObjectStoreCursorImpl(
3312 new ObjectStoreCursorImpl(leveldb_transaction, cursor_options)); 3628 this, transaction, database_id, cursor_options));
3313 if (!cursor->FirstSeek(s)) 3629 if (!cursor->FirstSeek(s))
3314 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3630 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3315 3631
3316 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3632 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3317 } 3633 }
3318 3634
3319 scoped_ptr<IndexedDBBackingStore::Cursor> 3635 scoped_ptr<IndexedDBBackingStore::Cursor>
3320 IndexedDBBackingStore::OpenObjectStoreKeyCursor( 3636 IndexedDBBackingStore::OpenObjectStoreKeyCursor(
3321 IndexedDBBackingStore::Transaction* transaction, 3637 IndexedDBBackingStore::Transaction* transaction,
3322 int64 database_id, 3638 int64 database_id,
3323 int64 object_store_id, 3639 int64 object_store_id,
3324 const IndexedDBKeyRange& range, 3640 const IndexedDBKeyRange& range,
3325 indexed_db::CursorDirection direction, 3641 indexed_db::CursorDirection direction,
3326 leveldb::Status* s) { 3642 leveldb::Status* s) {
3327 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); 3643 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
3328 *s = leveldb::Status::OK(); 3644 *s = leveldb::Status::OK();
3329 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3645 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3330 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3646 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3331 if (!ObjectStoreCursorOptions(leveldb_transaction, 3647 if (!ObjectStoreCursorOptions(leveldb_transaction,
3332 database_id, 3648 database_id,
3333 object_store_id, 3649 object_store_id,
3334 range, 3650 range,
3335 direction, 3651 direction,
3336 &cursor_options)) 3652 &cursor_options))
3337 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3653 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3338 scoped_ptr<ObjectStoreKeyCursorImpl> cursor( 3654 scoped_ptr<ObjectStoreKeyCursorImpl> cursor(new ObjectStoreKeyCursorImpl(
3339 new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options)); 3655 this, transaction, database_id, cursor_options));
3340 if (!cursor->FirstSeek(s)) 3656 if (!cursor->FirstSeek(s))
3341 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3657 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3342 3658
3343 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3659 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3344 } 3660 }
3345 3661
3346 scoped_ptr<IndexedDBBackingStore::Cursor> 3662 scoped_ptr<IndexedDBBackingStore::Cursor>
3347 IndexedDBBackingStore::OpenIndexKeyCursor( 3663 IndexedDBBackingStore::OpenIndexKeyCursor(
3348 IndexedDBBackingStore::Transaction* transaction, 3664 IndexedDBBackingStore::Transaction* transaction,
3349 int64 database_id, 3665 int64 database_id,
3350 int64 object_store_id, 3666 int64 object_store_id,
3351 int64 index_id, 3667 int64 index_id,
3352 const IndexedDBKeyRange& range, 3668 const IndexedDBKeyRange& range,
3353 indexed_db::CursorDirection direction, 3669 indexed_db::CursorDirection direction,
3354 leveldb::Status* s) { 3670 leveldb::Status* s) {
3355 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); 3671 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
3356 *s = leveldb::Status::OK(); 3672 *s = leveldb::Status::OK();
3357 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3673 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3358 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3674 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3359 if (!IndexCursorOptions(leveldb_transaction, 3675 if (!IndexCursorOptions(leveldb_transaction,
3360 database_id, 3676 database_id,
3361 object_store_id, 3677 object_store_id,
3362 index_id, 3678 index_id,
3363 range, 3679 range,
3364 direction, 3680 direction,
3365 &cursor_options)) 3681 &cursor_options))
3366 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3682 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3367 scoped_ptr<IndexKeyCursorImpl> cursor( 3683 scoped_ptr<IndexKeyCursorImpl> cursor(
3368 new IndexKeyCursorImpl(leveldb_transaction, cursor_options)); 3684 new IndexKeyCursorImpl(this, transaction, database_id, cursor_options));
3369 if (!cursor->FirstSeek(s)) 3685 if (!cursor->FirstSeek(s))
3370 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3686 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3371 3687
3372 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3688 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3373 } 3689 }
3374 3690
3375 scoped_ptr<IndexedDBBackingStore::Cursor> 3691 scoped_ptr<IndexedDBBackingStore::Cursor>
3376 IndexedDBBackingStore::OpenIndexCursor( 3692 IndexedDBBackingStore::OpenIndexCursor(
3377 IndexedDBBackingStore::Transaction* transaction, 3693 IndexedDBBackingStore::Transaction* transaction,
3378 int64 database_id, 3694 int64 database_id,
3379 int64 object_store_id, 3695 int64 object_store_id,
3380 int64 index_id, 3696 int64 index_id,
3381 const IndexedDBKeyRange& range, 3697 const IndexedDBKeyRange& range,
3382 indexed_db::CursorDirection direction, 3698 indexed_db::CursorDirection direction,
3383 leveldb::Status* s) { 3699 leveldb::Status* s) {
3384 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); 3700 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
3385 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3701 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3386 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3702 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3387 if (!IndexCursorOptions(leveldb_transaction, 3703 if (!IndexCursorOptions(leveldb_transaction,
3388 database_id, 3704 database_id,
3389 object_store_id, 3705 object_store_id,
3390 index_id, 3706 index_id,
3391 range, 3707 range,
3392 direction, 3708 direction,
3393 &cursor_options)) 3709 &cursor_options))
3394 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3710 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3395 scoped_ptr<IndexCursorImpl> cursor( 3711 scoped_ptr<IndexCursorImpl> cursor(
3396 new IndexCursorImpl(leveldb_transaction, cursor_options)); 3712 new IndexCursorImpl(this, transaction, database_id, cursor_options));
3397 if (!cursor->FirstSeek(s)) 3713 if (!cursor->FirstSeek(s))
3398 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 3714 return scoped_ptr<IndexedDBBackingStore::Cursor>();
3399 3715
3400 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 3716 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
3401 } 3717 }
3402 3718
3403 IndexedDBBackingStore::Transaction::Transaction( 3719 IndexedDBBackingStore::Transaction::Transaction(
3404 IndexedDBBackingStore* backing_store) 3720 IndexedDBBackingStore* backing_store)
3405 : backing_store_(backing_store), database_id_(-1) { 3721 : backing_store_(backing_store), database_id_(-1) {
3406 } 3722 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3578 const GURL& url, 3894 const GURL& url,
3579 int64_t key) 3895 int64_t key)
3580 : is_file_(false), url_(url), key_(key) {} 3896 : is_file_(false), url_(url), key_(key) {}
3581 3897
3582 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( 3898 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor(
3583 const FilePath& file_path, 3899 const FilePath& file_path,
3584 int64_t key) 3900 int64_t key)
3585 : is_file_(true), file_path_(file_path), key_(key) {} 3901 : is_file_(true), file_path_(file_path), key_(key) {}
3586 3902
3587 } // namespace content 3903 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_backing_store.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698