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

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

Powered by Google App Engine
This is Rietveld 408576698