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

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

Issue 197333009: Handling LevelDB errors encountered after open. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed buffer overflow (woops) in original test Created 6 years, 9 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
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/json/json_reader.h"
9 #include "base/json/json_writer.h"
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/platform_file.h"
10 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/indexed_db/indexed_db_database_error.h"
12 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 16 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
13 #include "content/browser/indexed_db/indexed_db_metadata.h" 17 #include "content/browser/indexed_db/indexed_db_metadata.h"
14 #include "content/browser/indexed_db/indexed_db_tracing.h" 18 #include "content/browser/indexed_db/indexed_db_tracing.h"
15 #include "content/browser/indexed_db/indexed_db_value.h" 19 #include "content/browser/indexed_db/indexed_db_value.h"
16 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 20 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
17 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 21 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
18 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 22 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
19 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 23 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
20 #include "content/common/indexed_db/indexed_db_key.h" 24 #include "content/common/indexed_db/indexed_db_key.h"
21 #include "content/common/indexed_db/indexed_db_key_path.h" 25 #include "content/common/indexed_db/indexed_db_key_path.h"
(...skipping 12 matching lines...) Expand all
34 static std::string ComputeOriginIdentifier(const GURL& origin_url) { 38 static std::string ComputeOriginIdentifier(const GURL& origin_url) {
35 return webkit_database::GetIdentifierFromOrigin(origin_url) + "@1"; 39 return webkit_database::GetIdentifierFromOrigin(origin_url) + "@1";
36 } 40 }
37 41
38 static base::FilePath ComputeFileName(const GURL& origin_url) { 42 static base::FilePath ComputeFileName(const GURL& origin_url) {
39 return base::FilePath() 43 return base::FilePath()
40 .AppendASCII(webkit_database::GetIdentifierFromOrigin(origin_url)) 44 .AppendASCII(webkit_database::GetIdentifierFromOrigin(origin_url))
41 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); 45 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb"));
42 } 46 }
43 47
48 static base::FilePath ComputeCorruptionFileName(const GURL& origin_url) {
49 return ComputeFileName(origin_url)
50 .Append(FILE_PATH_LITERAL("corruption_info.json"));
51 }
52
44 } // namespace 53 } // namespace
45 54
46 static const int64 kKeyGeneratorInitialNumber = 55 static const int64 kKeyGeneratorInitialNumber =
47 1; // From the IndexedDB specification. 56 1; // From the IndexedDB specification.
48 57
49 enum IndexedDBBackingStoreErrorSource { 58 enum IndexedDBBackingStoreErrorSource {
50 // 0 - 2 are no longer used. 59 // 0 - 2 are no longer used.
51 FIND_KEY_IN_INDEX = 3, 60 FIND_KEY_IN_INDEX = 3,
52 GET_IDBDATABASE_METADATA, 61 GET_IDBDATABASE_METADATA,
53 GET_INDEXES, 62 GET_INDEXES,
(...skipping 23 matching lines...) Expand all
77 std::string name; 86 std::string name;
78 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error"); 87 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error");
79 base::Histogram::FactoryGet(name, 88 base::Histogram::FactoryGet(name,
80 1, 89 1,
81 INTERNAL_ERROR_MAX, 90 INTERNAL_ERROR_MAX,
82 INTERNAL_ERROR_MAX + 1, 91 INTERNAL_ERROR_MAX + 1,
83 base::HistogramBase::kUmaTargetedHistogramFlag) 92 base::HistogramBase::kUmaTargetedHistogramFlag)
84 ->Add(location); 93 ->Add(location);
85 } 94 }
86 95
87 // Use to signal conditions that usually indicate developer error, but 96 // Use to signal conditions caused by data corruption.
88 // could be caused by data corruption. A macro is used instead of an 97 // A macro is used instead of an inline function so that the assert and log
89 // inline function so that the assert and log report the line number. 98 // report the line number.
90 #define REPORT_ERROR(type, location) \ 99 #define REPORT_ERROR(type, location) \
91 do { \ 100 do { \
92 LOG(ERROR) << "IndexedDB " type " Error: " #location; \ 101 LOG(ERROR) << "IndexedDB " type " Error: " #location; \
93 NOTREACHED(); \
94 RecordInternalError(type, location); \ 102 RecordInternalError(type, location); \
95 } while (0) 103 } while (0)
96 104
97 #define INTERNAL_READ_ERROR(location) REPORT_ERROR("Read", location) 105 #define INTERNAL_READ_ERROR(location) REPORT_ERROR("Read", location)
98 #define INTERNAL_CONSISTENCY_ERROR(location) \ 106 #define INTERNAL_CONSISTENCY_ERROR(location) \
99 REPORT_ERROR("Consistency", location) 107 REPORT_ERROR("Consistency", location)
100 #define INTERNAL_WRITE_ERROR(location) REPORT_ERROR("Write", location) 108 #define INTERNAL_WRITE_ERROR(location) REPORT_ERROR("Write", location)
101 109
110 // Use to signal conditions that usually indicate developer error, but
111 // could be caused by data corruption. A macro is used instead of an
112 // inline function so that the assert and log report the line number.
113 // TODO: Improve test coverage so that all error conditions are "tested" and
114 // then delete this macro.
115 #define REPORT_ERROR_UNTESTED(type, location) \
116 do { \
117 LOG(ERROR) << "IndexedDB " type " Error: " #location; \
118 NOTREACHED(); \
119 RecordInternalError(type, location); \
120 } while (0)
121
122 #define INTERNAL_READ_ERROR_UNTESTED(location) \
123 REPORT_ERROR_UNTESTED("Read", location)
124 #define INTERNAL_CONSISTENCY_ERROR_UNTESTED(location) \
125 REPORT_ERROR_UNTESTED("Consistency", location)
126 #define INTERNAL_WRITE_ERROR_UNTESTED(location) \
127 REPORT_ERROR_UNTESTED("Write", location)
128
102 static void PutBool(LevelDBTransaction* transaction, 129 static void PutBool(LevelDBTransaction* transaction,
103 const StringPiece& key, 130 const StringPiece& key,
104 bool value) { 131 bool value) {
105 std::string buffer; 132 std::string buffer;
106 EncodeBool(value, &buffer); 133 EncodeBool(value, &buffer);
107 transaction->Put(key, &buffer); 134 transaction->Put(key, &buffer);
108 } 135 }
109 136
110 // Was able to use LevelDB to read the data w/o error, but the data read was not 137 // Was able to use LevelDB to read the data w/o error, but the data read was not
111 // in the expected format. 138 // in the expected format.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 const std::string data_version_key = DataVersionKey::Encode(); 296 const std::string data_version_key = DataVersionKey::Encode();
270 297
271 scoped_refptr<LevelDBTransaction> transaction = new LevelDBTransaction(db); 298 scoped_refptr<LevelDBTransaction> transaction = new LevelDBTransaction(db);
272 299
273 int64 db_schema_version = 0; 300 int64 db_schema_version = 0;
274 int64 db_data_version = 0; 301 int64 db_data_version = 0;
275 bool found = false; 302 bool found = false;
276 leveldb::Status s = 303 leveldb::Status s =
277 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found); 304 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
278 if (!s.ok()) { 305 if (!s.ok()) {
279 INTERNAL_READ_ERROR(SET_UP_METADATA); 306 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
280 return false; 307 return false;
281 } 308 }
282 if (!found) { 309 if (!found) {
283 // Initialize new backing store. 310 // Initialize new backing store.
284 db_schema_version = kLatestKnownSchemaVersion; 311 db_schema_version = kLatestKnownSchemaVersion;
285 PutInt(transaction.get(), schema_version_key, db_schema_version); 312 PutInt(transaction.get(), schema_version_key, db_schema_version);
286 db_data_version = latest_known_data_version; 313 db_data_version = latest_known_data_version;
287 PutInt(transaction.get(), data_version_key, db_data_version); 314 PutInt(transaction.get(), data_version_key, db_data_version);
288 } else { 315 } else {
289 // Upgrade old backing store. 316 // Upgrade old backing store.
290 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); 317 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion);
291 if (db_schema_version < 1) { 318 if (db_schema_version < 1) {
292 db_schema_version = 1; 319 db_schema_version = 1;
293 PutInt(transaction.get(), schema_version_key, db_schema_version); 320 PutInt(transaction.get(), schema_version_key, db_schema_version);
294 const std::string start_key = 321 const std::string start_key =
295 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); 322 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier);
296 const std::string stop_key = 323 const std::string stop_key =
297 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); 324 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier);
298 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); 325 scoped_ptr<LevelDBIterator> it = db->CreateIterator();
299 for (it->Seek(start_key); 326 for (it->Seek(start_key);
300 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 327 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
301 it->Next()) { 328 it->Next()) {
302 int64 database_id = 0; 329 int64 database_id = 0;
303 found = false; 330 found = false;
304 s = GetInt(transaction.get(), it->Key(), &database_id, &found); 331 s = GetInt(transaction.get(), it->Key(), &database_id, &found);
305 if (!s.ok()) { 332 if (!s.ok()) {
306 INTERNAL_READ_ERROR(SET_UP_METADATA); 333 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
307 return false; 334 return false;
308 } 335 }
309 if (!found) { 336 if (!found) {
310 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA); 337 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
311 return false; 338 return false;
312 } 339 }
313 std::string int_version_key = DatabaseMetaDataKey::Encode( 340 std::string int_version_key = DatabaseMetaDataKey::Encode(
314 database_id, DatabaseMetaDataKey::USER_INT_VERSION); 341 database_id, DatabaseMetaDataKey::USER_INT_VERSION);
315 PutVarInt(transaction.get(), 342 PutVarInt(transaction.get(),
316 int_version_key, 343 int_version_key,
317 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); 344 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
318 } 345 }
319 } 346 }
320 if (db_schema_version < 2) { 347 if (db_schema_version < 2) {
321 db_schema_version = 2; 348 db_schema_version = 2;
322 PutInt(transaction.get(), schema_version_key, db_schema_version); 349 PutInt(transaction.get(), schema_version_key, db_schema_version);
323 db_data_version = blink::kSerializedScriptValueVersion; 350 db_data_version = blink::kSerializedScriptValueVersion;
324 PutInt(transaction.get(), data_version_key, db_data_version); 351 PutInt(transaction.get(), data_version_key, db_data_version);
325 } 352 }
326 } 353 }
327 354
328 // All new values will be written using this serialization version. 355 // All new values will be written using this serialization version.
329 found = false; 356 found = false;
330 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found); 357 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found);
331 if (!s.ok()) { 358 if (!s.ok()) {
332 INTERNAL_READ_ERROR(SET_UP_METADATA); 359 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
333 return false; 360 return false;
334 } 361 }
335 if (!found) { 362 if (!found) {
336 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA); 363 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
337 return false; 364 return false;
338 } 365 }
339 if (db_data_version < latest_known_data_version) { 366 if (db_data_version < latest_known_data_version) {
340 db_data_version = latest_known_data_version; 367 db_data_version = latest_known_data_version;
341 PutInt(transaction.get(), data_version_key, db_data_version); 368 PutInt(transaction.get(), data_version_key, db_data_version);
342 } 369 }
343 370
344 DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion); 371 DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion);
345 DCHECK_EQ(db_data_version, latest_known_data_version); 372 DCHECK_EQ(db_data_version, latest_known_data_version);
346 373
347 s = transaction->Commit(); 374 s = transaction->Commit();
348 if (!s.ok()) { 375 if (!s.ok()) {
349 INTERNAL_WRITE_ERROR(SET_UP_METADATA); 376 INTERNAL_WRITE_ERROR_UNTESTED(SET_UP_METADATA);
350 return false; 377 return false;
351 } 378 }
352 return true; 379 return true;
353 } 380 }
354 381
355 template <typename DBOrTransaction> 382 template <typename DBOrTransaction>
356 WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId( 383 WARN_UNUSED_RESULT static leveldb::Status GetMaxObjectStoreId(
357 DBOrTransaction* db, 384 DBOrTransaction* db,
358 int64 database_id, 385 int64 database_id,
359 int64* max_object_store_id) { 386 int64* max_object_store_id) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_DESTROY_FAILED, 457 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_DESTROY_FAILED,
431 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED, 458 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_FAILED,
432 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS, 459 INDEXED_DB_BACKING_STORE_OPEN_CLEANUP_REOPEN_SUCCESS,
433 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, 460 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA,
434 INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR, 461 INDEXED_DB_BACKING_STORE_OPEN_FAILED_UNKNOWN_ERR,
435 INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED, 462 INDEXED_DB_BACKING_STORE_OPEN_MEMORY_FAILED,
436 INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII, 463 INDEXED_DB_BACKING_STORE_OPEN_ATTEMPT_NON_ASCII,
437 INDEXED_DB_BACKING_STORE_OPEN_DISK_FULL_DEPRECATED, 464 INDEXED_DB_BACKING_STORE_OPEN_DISK_FULL_DEPRECATED,
438 INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG, 465 INDEXED_DB_BACKING_STORE_OPEN_ORIGIN_TOO_LONG,
439 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY, 466 INDEXED_DB_BACKING_STORE_OPEN_NO_RECOVERY,
467 INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION,
440 INDEXED_DB_BACKING_STORE_OPEN_MAX, 468 INDEXED_DB_BACKING_STORE_OPEN_MAX,
441 }; 469 };
442 470
443 // static 471 // static
444 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( 472 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
445 const GURL& origin_url, 473 const GURL& origin_url,
446 const base::FilePath& path_base, 474 const base::FilePath& path_base,
447 blink::WebIDBDataLoss* data_loss, 475 blink::WebIDBDataLoss* data_loss,
448 std::string* data_loss_message, 476 std::string* data_loss_message,
449 bool* disk_full) { 477 bool* disk_full) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 "WebCore.IndexedDB.BackingStore.OverlyLargeOriginLength", 534 "WebCore.IndexedDB.BackingStore.OverlyLargeOriginLength",
507 component_length, 535 component_length,
508 min, 536 min,
509 max, 537 max,
510 num_buckets); 538 num_buckets);
511 return true; 539 return true;
512 } 540 }
513 return false; 541 return false;
514 } 542 }
515 543
544 leveldb::Status IndexedDBBackingStore::DestroyBackingStore(
545 const base::FilePath& path_base,
546 const GURL& origin_url) {
547 const base::FilePath file_path =
548 path_base.Append(ComputeFileName(origin_url));
549 DefaultLevelDBFactory leveldb_factory;
550 return leveldb_factory.DestroyLevelDB(file_path);
551 }
552
553 bool IndexedDBBackingStore::ReadCorruptionInfo(const base::FilePath& path_base,
554 const GURL& origin_url,
555 std::string& message) {
556
557 const base::FilePath info_path =
558 path_base.Append(ComputeCorruptionFileName(origin_url));
559
560 if (IsPathTooLong(info_path))
561 return false;
562
563 const int64 max_json_len = 4096;
564 int64 file_size(0);
565 if (!GetFileSize(info_path, &file_size) || file_size > max_json_len)
566 return false;
567 if (!file_size) {
568 NOTREACHED();
569 return false;
570 }
571
572 bool created(false);
573 base::PlatformFileError error(base::PLATFORM_FILE_OK);
574 base::PlatformFile file = base::CreatePlatformFile(
575 info_path,
576 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
577 &created,
578 &error);
579 bool success = false;
580 if (file) {
581 std::vector<char> bytes(file_size);
582 if (file_size == base::ReadPlatformFile(file, 0, &bytes[0], file_size)) {
583 std::string input_js(&bytes[0], file_size);
584 base::JSONReader reader;
585 scoped_ptr<base::Value> val(reader.ReadToValue(input_js));
586 if (val && val->GetType() == base::Value::TYPE_DICTIONARY) {
587 base::DictionaryValue* dict_val =
588 static_cast<base::DictionaryValue*>(val.get());
589 success = dict_val->GetString("message", &message);
590 }
591 }
592 base::ClosePlatformFile(file);
593 }
594
595 base::DeleteFile(info_path, false);
596
597 return success;
598 }
599
600 bool IndexedDBBackingStore::RecordCorruptionInfo(
601 const base::FilePath& path_base,
602 const GURL& origin_url,
603 const std::string& message) {
604 const base::FilePath info_path =
605 path_base.Append(ComputeCorruptionFileName(origin_url));
606 if (IsPathTooLong(info_path))
607 return false;
608
609 base::DictionaryValue root_dict;
610 root_dict.SetString("message", message);
611 std::string output_js;
612 base::JSONWriter::Write(&root_dict, &output_js);
613
614 bool created(false);
615 base::PlatformFileError error(base::PLATFORM_FILE_OK);
616 base::PlatformFile file = base::CreatePlatformFile(
617 info_path,
618 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
619 &created,
620 &error);
621 if (!file)
622 return false;
623 int written =
624 base::WritePlatformFile(file, 0, output_js.c_str(), output_js.length());
625 base::ClosePlatformFile(file);
626 return size_t(written) == output_js.length();
627 }
628
516 // static 629 // static
517 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open( 630 scoped_refptr<IndexedDBBackingStore> IndexedDBBackingStore::Open(
518 const GURL& origin_url, 631 const GURL& origin_url,
519 const base::FilePath& path_base, 632 const base::FilePath& path_base,
520 blink::WebIDBDataLoss* data_loss, 633 blink::WebIDBDataLoss* data_loss,
521 std::string* data_loss_message, 634 std::string* data_loss_message,
522 bool* is_disk_full, 635 bool* is_disk_full,
523 LevelDBFactory* leveldb_factory) { 636 LevelDBFactory* leveldb_factory) {
524 IDB_TRACE("IndexedDBBackingStore::Open"); 637 IDB_TRACE("IndexedDBBackingStore::Open");
525 DCHECK(!path_base.empty()); 638 DCHECK(!path_base.empty());
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 if (leveldb_env::IndicatesDiskFull(status)) { 672 if (leveldb_env::IndicatesDiskFull(status)) {
560 *is_disk_full = true; 673 *is_disk_full = true;
561 } else if (leveldb_env::IsCorruption(status)) { 674 } else if (leveldb_env::IsCorruption(status)) {
562 *data_loss = blink::WebIDBDataLossTotal; 675 *data_loss = blink::WebIDBDataLossTotal;
563 *data_loss_message = leveldb_env::GetCorruptionMessage(status); 676 *data_loss_message = leveldb_env::GetCorruptionMessage(status);
564 } 677 }
565 } 678 }
566 679
567 bool is_schema_known = false; 680 bool is_schema_known = false;
568 if (db) { 681 if (db) {
569 bool ok = IsSchemaKnown(db.get(), &is_schema_known); 682 std::string corruption_message;
570 if (!ok) { 683 if (ReadCorruptionInfo(path_base, origin_url, corruption_message)) {
684 LOG(ERROR) << "IndexedDB recovering from a corrupted (and deleted) "
685 "database.";
686 HistogramOpenStatus(INDEXED_DB_BACKING_STORE_OPEN_FAILED_PRIOR_CORRUPTION,
687 origin_url);
688 db.reset();
689 *data_loss = blink::WebIDBDataLossTotal;
690 *data_loss_message =
691 "IndexedDB (database was corrupt): " + corruption_message;
692 } else if (!IsSchemaKnown(db.get(), &is_schema_known)) {
571 LOG(ERROR) << "IndexedDB had IO error checking schema, treating it as " 693 LOG(ERROR) << "IndexedDB had IO error checking schema, treating it as "
572 "failure to open"; 694 "failure to open";
573 HistogramOpenStatus( 695 HistogramOpenStatus(
574 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA, 696 INDEXED_DB_BACKING_STORE_OPEN_FAILED_IO_ERROR_CHECKING_SCHEMA,
575 origin_url); 697 origin_url);
576 db.reset(); 698 db.reset();
577 *data_loss = blink::WebIDBDataLossTotal; 699 *data_loss = blink::WebIDBDataLossTotal;
578 *data_loss_message = "I/O error checking schema"; 700 *data_loss_message = "I/O error checking schema";
579 } else if (!is_schema_known) { 701 } else if (!is_schema_known) {
580 LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it " 702 LOG(ERROR) << "IndexedDB backing store had unknown schema, treating it "
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 804
683 DCHECK(found_names.empty()); 805 DCHECK(found_names.empty());
684 806
685 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 807 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
686 for (it->Seek(start_key); 808 for (it->Seek(start_key);
687 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 809 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
688 it->Next()) { 810 it->Next()) {
689 StringPiece slice(it->Key()); 811 StringPiece slice(it->Key());
690 DatabaseNameKey database_name_key; 812 DatabaseNameKey database_name_key;
691 if (!DatabaseNameKey::Decode(&slice, &database_name_key)) { 813 if (!DatabaseNameKey::Decode(&slice, &database_name_key)) {
692 INTERNAL_CONSISTENCY_ERROR(GET_DATABASE_NAMES); 814 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
693 continue; 815 continue;
694 } 816 }
695 found_names.push_back(database_name_key.database_name()); 817 found_names.push_back(database_name_key.database_name());
696 } 818 }
697 return found_names; 819 return found_names;
698 } 820 }
699 821
700 leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData( 822 leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData(
701 const base::string16& name, 823 const base::string16& name,
702 IndexedDBDatabaseMetadata* metadata, 824 IndexedDBDatabaseMetadata* metadata,
703 bool* found) { 825 bool* found) {
704 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); 826 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
705 *found = false; 827 *found = false;
706 828
707 leveldb::Status s = GetInt(db_.get(), key, &metadata->id, found); 829 leveldb::Status s = GetInt(db_.get(), key, &metadata->id, found);
708 if (!s.ok()) { 830 if (!s.ok()) {
709 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 831 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
710 return s; 832 return s;
711 } 833 }
712 if (!*found) 834 if (!*found)
713 return leveldb::Status::OK(); 835 return leveldb::Status::OK();
714 836
715 s = GetString(db_.get(), 837 s = GetString(db_.get(),
716 DatabaseMetaDataKey::Encode(metadata->id, 838 DatabaseMetaDataKey::Encode(metadata->id,
717 DatabaseMetaDataKey::USER_VERSION), 839 DatabaseMetaDataKey::USER_VERSION),
718 &metadata->version, 840 &metadata->version,
719 found); 841 found);
720 if (!s.ok()) { 842 if (!s.ok()) {
721 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 843 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
722 return s; 844 return s;
723 } 845 }
724 if (!*found) { 846 if (!*found) {
725 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA); 847 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
726 return InternalInconsistencyStatus(); 848 return InternalInconsistencyStatus();
727 } 849 }
728 850
729 s = GetVarInt(db_.get(), 851 s = GetVarInt(db_.get(),
730 DatabaseMetaDataKey::Encode( 852 DatabaseMetaDataKey::Encode(
731 metadata->id, DatabaseMetaDataKey::USER_INT_VERSION), 853 metadata->id, DatabaseMetaDataKey::USER_INT_VERSION),
732 &metadata->int_version, 854 &metadata->int_version,
733 found); 855 found);
734 if (!s.ok()) { 856 if (!s.ok()) {
735 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 857 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
736 return s; 858 return s;
737 } 859 }
738 if (!*found) { 860 if (!*found) {
739 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA); 861 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
740 return InternalInconsistencyStatus(); 862 return InternalInconsistencyStatus();
741 } 863 }
742 864
743 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION) 865 if (metadata->int_version == IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION)
744 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION; 866 metadata->int_version = IndexedDBDatabaseMetadata::NO_INT_VERSION;
745 867
746 s = GetMaxObjectStoreId( 868 s = GetMaxObjectStoreId(
747 db_.get(), metadata->id, &metadata->max_object_store_id); 869 db_.get(), metadata->id, &metadata->max_object_store_id);
748 if (!s.ok()) { 870 if (!s.ok()) {
749 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 871 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA);
750 } 872 }
751 873
752 return s; 874 return s;
753 } 875 }
754 876
755 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId( 877 WARN_UNUSED_RESULT static leveldb::Status GetNewDatabaseId(
756 LevelDBTransaction* transaction, 878 LevelDBTransaction* transaction,
757 int64* new_id) { 879 int64* new_id) {
758 *new_id = -1; 880 *new_id = -1;
759 int64 max_database_id = -1; 881 int64 max_database_id = -1;
760 bool found = false; 882 bool found = false;
761 leveldb::Status s = 883 leveldb::Status s =
762 GetInt(transaction, MaxDatabaseIdKey::Encode(), &max_database_id, &found); 884 GetInt(transaction, MaxDatabaseIdKey::Encode(), &max_database_id, &found);
763 if (!s.ok()) { 885 if (!s.ok()) {
764 INTERNAL_READ_ERROR(GET_NEW_DATABASE_ID); 886 INTERNAL_READ_ERROR_UNTESTED(GET_NEW_DATABASE_ID);
765 return s; 887 return s;
766 } 888 }
767 if (!found) 889 if (!found)
768 max_database_id = 0; 890 max_database_id = 0;
769 891
770 DCHECK_GE(max_database_id, 0); 892 DCHECK_GE(max_database_id, 0);
771 893
772 int64 database_id = max_database_id + 1; 894 int64 database_id = max_database_id + 1;
773 PutInt(transaction, MaxDatabaseIdKey::Encode(), database_id); 895 PutInt(transaction, MaxDatabaseIdKey::Encode(), database_id);
774 *new_id = database_id; 896 *new_id = database_id;
(...skipping 22 matching lines...) Expand all
797 PutString( 919 PutString(
798 transaction.get(), 920 transaction.get(),
799 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION), 921 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION),
800 version); 922 version);
801 PutVarInt(transaction.get(), 923 PutVarInt(transaction.get(),
802 DatabaseMetaDataKey::Encode(*row_id, 924 DatabaseMetaDataKey::Encode(*row_id,
803 DatabaseMetaDataKey::USER_INT_VERSION), 925 DatabaseMetaDataKey::USER_INT_VERSION),
804 int_version); 926 int_version);
805 s = transaction->Commit(); 927 s = transaction->Commit();
806 if (!s.ok()) 928 if (!s.ok())
807 INTERNAL_WRITE_ERROR(CREATE_IDBDATABASE_METADATA); 929 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA);
808 return s; 930 return s;
809 } 931 }
810 932
811 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( 933 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion(
812 IndexedDBBackingStore::Transaction* transaction, 934 IndexedDBBackingStore::Transaction* transaction,
813 int64 row_id, 935 int64 row_id,
814 int64 int_version) { 936 int64 int_version) {
815 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) 937 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
816 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; 938 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
817 DCHECK_GE(int_version, 0) << "int_version was " << int_version; 939 DCHECK_GE(int_version, 0) << "int_version was " << int_version;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 for (it->Seek(start_key); 975 for (it->Seek(start_key);
854 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 976 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
855 it->Next()) 977 it->Next())
856 transaction->Remove(it->Key()); 978 transaction->Remove(it->Key());
857 979
858 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); 980 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
859 transaction->Remove(key); 981 transaction->Remove(key);
860 982
861 s = transaction->Commit(); 983 s = transaction->Commit();
862 if (!s.ok()) { 984 if (!s.ok()) {
863 INTERNAL_WRITE_ERROR(DELETE_DATABASE); 985 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
864 return s; 986 return s;
865 } 987 }
866 db_->Compact(start_key, stop_key); 988 db_->Compact(start_key, stop_key);
867 return s; 989 return s;
868 } 990 }
869 991
870 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it, 992 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it,
871 const std::string& stop_key, 993 const std::string& stop_key,
872 int64 object_store_id, 994 int64 object_store_id,
873 int64 meta_data_type) { 995 int64 meta_data_type) {
(...skipping 27 matching lines...) Expand all
901 DCHECK(object_stores->empty()); 1023 DCHECK(object_stores->empty());
902 1024
903 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1025 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
904 it->Seek(start_key); 1026 it->Seek(start_key);
905 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { 1027 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
906 StringPiece slice(it->Key()); 1028 StringPiece slice(it->Key());
907 ObjectStoreMetaDataKey meta_data_key; 1029 ObjectStoreMetaDataKey meta_data_key;
908 bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key); 1030 bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key);
909 DCHECK(ok); 1031 DCHECK(ok);
910 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { 1032 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) {
911 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1033 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
912 // Possible stale metadata, but don't fail the load. 1034 // Possible stale metadata, but don't fail the load.
913 it->Next(); 1035 it->Next();
914 continue; 1036 continue;
915 } 1037 }
916 1038
917 int64 object_store_id = meta_data_key.ObjectStoreId(); 1039 int64 object_store_id = meta_data_key.ObjectStoreId();
918 1040
919 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1041 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
920 // simplify. 1042 // simplify.
921 base::string16 object_store_name; 1043 base::string16 object_store_name;
922 { 1044 {
923 StringPiece slice(it->Value()); 1045 StringPiece slice(it->Value());
924 if (!DecodeString(&slice, &object_store_name) || !slice.empty()) 1046 if (!DecodeString(&slice, &object_store_name) || !slice.empty())
925 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1047 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
926 } 1048 }
927 1049
928 it->Next(); 1050 it->Next();
929 if (!CheckObjectStoreAndMetaDataType(it.get(), 1051 if (!CheckObjectStoreAndMetaDataType(it.get(),
930 stop_key, 1052 stop_key,
931 object_store_id, 1053 object_store_id,
932 ObjectStoreMetaDataKey::KEY_PATH)) { 1054 ObjectStoreMetaDataKey::KEY_PATH)) {
933 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1055 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
934 break; 1056 break;
935 } 1057 }
936 IndexedDBKeyPath key_path; 1058 IndexedDBKeyPath key_path;
937 { 1059 {
938 StringPiece slice(it->Value()); 1060 StringPiece slice(it->Value());
939 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1061 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
940 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1062 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
941 } 1063 }
942 1064
943 it->Next(); 1065 it->Next();
944 if (!CheckObjectStoreAndMetaDataType( 1066 if (!CheckObjectStoreAndMetaDataType(
945 it.get(), 1067 it.get(),
946 stop_key, 1068 stop_key,
947 object_store_id, 1069 object_store_id,
948 ObjectStoreMetaDataKey::AUTO_INCREMENT)) { 1070 ObjectStoreMetaDataKey::AUTO_INCREMENT)) {
949 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1071 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
950 break; 1072 break;
951 } 1073 }
952 bool auto_increment; 1074 bool auto_increment;
953 { 1075 {
954 StringPiece slice(it->Value()); 1076 StringPiece slice(it->Value());
955 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) 1077 if (!DecodeBool(&slice, &auto_increment) || !slice.empty())
956 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1078 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
957 } 1079 }
958 1080
959 it->Next(); // Is evicatble. 1081 it->Next(); // Is evicatble.
960 if (!CheckObjectStoreAndMetaDataType(it.get(), 1082 if (!CheckObjectStoreAndMetaDataType(it.get(),
961 stop_key, 1083 stop_key,
962 object_store_id, 1084 object_store_id,
963 ObjectStoreMetaDataKey::EVICTABLE)) { 1085 ObjectStoreMetaDataKey::EVICTABLE)) {
964 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1086 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
965 break; 1087 break;
966 } 1088 }
967 1089
968 it->Next(); // Last version. 1090 it->Next(); // Last version.
969 if (!CheckObjectStoreAndMetaDataType( 1091 if (!CheckObjectStoreAndMetaDataType(
970 it.get(), 1092 it.get(),
971 stop_key, 1093 stop_key,
972 object_store_id, 1094 object_store_id,
973 ObjectStoreMetaDataKey::LAST_VERSION)) { 1095 ObjectStoreMetaDataKey::LAST_VERSION)) {
974 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1096 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
975 break; 1097 break;
976 } 1098 }
977 1099
978 it->Next(); // Maximum index id allocated. 1100 it->Next(); // Maximum index id allocated.
979 if (!CheckObjectStoreAndMetaDataType( 1101 if (!CheckObjectStoreAndMetaDataType(
980 it.get(), 1102 it.get(),
981 stop_key, 1103 stop_key,
982 object_store_id, 1104 object_store_id,
983 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { 1105 ObjectStoreMetaDataKey::MAX_INDEX_ID)) {
984 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1106 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
985 break; 1107 break;
986 } 1108 }
987 int64 max_index_id; 1109 int64 max_index_id;
988 { 1110 {
989 StringPiece slice(it->Value()); 1111 StringPiece slice(it->Value());
990 if (!DecodeInt(&slice, &max_index_id) || !slice.empty()) 1112 if (!DecodeInt(&slice, &max_index_id) || !slice.empty())
991 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1113 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
992 } 1114 }
993 1115
994 it->Next(); // [optional] has key path (is not null) 1116 it->Next(); // [optional] has key path (is not null)
995 if (CheckObjectStoreAndMetaDataType(it.get(), 1117 if (CheckObjectStoreAndMetaDataType(it.get(),
996 stop_key, 1118 stop_key,
997 object_store_id, 1119 object_store_id,
998 ObjectStoreMetaDataKey::HAS_KEY_PATH)) { 1120 ObjectStoreMetaDataKey::HAS_KEY_PATH)) {
999 bool has_key_path; 1121 bool has_key_path;
1000 { 1122 {
1001 StringPiece slice(it->Value()); 1123 StringPiece slice(it->Value());
1002 if (!DecodeBool(&slice, &has_key_path)) 1124 if (!DecodeBool(&slice, &has_key_path))
1003 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1125 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1004 } 1126 }
1005 // This check accounts for two layers of legacy coding: 1127 // This check accounts for two layers of legacy coding:
1006 // (1) Initially, has_key_path was added to distinguish null vs. string. 1128 // (1) Initially, has_key_path was added to distinguish null vs. string.
1007 // (2) Later, null vs. string vs. array was stored in the key_path itself. 1129 // (2) Later, null vs. string vs. array was stored in the key_path itself.
1008 // So this check is only relevant for string-type key_paths. 1130 // So this check is only relevant for string-type key_paths.
1009 if (!has_key_path && 1131 if (!has_key_path &&
1010 (key_path.type() == blink::WebIDBKeyPathTypeString && 1132 (key_path.type() == blink::WebIDBKeyPathTypeString &&
1011 !key_path.string().empty())) { 1133 !key_path.string().empty())) {
1012 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1134 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1013 break; 1135 break;
1014 } 1136 }
1015 if (!has_key_path) 1137 if (!has_key_path)
1016 key_path = IndexedDBKeyPath(); 1138 key_path = IndexedDBKeyPath();
1017 it->Next(); 1139 it->Next();
1018 } 1140 }
1019 1141
1020 int64 key_generator_current_number = -1; 1142 int64 key_generator_current_number = -1;
1021 if (CheckObjectStoreAndMetaDataType( 1143 if (CheckObjectStoreAndMetaDataType(
1022 it.get(), 1144 it.get(),
1023 stop_key, 1145 stop_key,
1024 object_store_id, 1146 object_store_id,
1025 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { 1147 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) {
1026 StringPiece slice(it->Value()); 1148 StringPiece slice(it->Value());
1027 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) 1149 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty())
1028 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1150 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1029 1151
1030 // TODO(jsbell): Return key_generator_current_number, cache in 1152 // TODO(jsbell): Return key_generator_current_number, cache in
1031 // object store, and write lazily to backing store. For now, 1153 // object store, and write lazily to backing store. For now,
1032 // just assert that if it was written it was valid. 1154 // just assert that if it was written it was valid.
1033 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber); 1155 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber);
1034 it->Next(); 1156 it->Next();
1035 } 1157 }
1036 1158
1037 IndexedDBObjectStoreMetadata metadata(object_store_name, 1159 IndexedDBObjectStoreMetadata metadata(object_store_name,
1038 object_store_id, 1160 object_store_id,
(...skipping 12 matching lines...) Expand all
1051 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId( 1173 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId(
1052 LevelDBTransaction* transaction, 1174 LevelDBTransaction* transaction,
1053 int64 database_id, 1175 int64 database_id,
1054 int64 object_store_id) { 1176 int64 object_store_id) {
1055 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( 1177 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
1056 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); 1178 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
1057 int64 max_object_store_id = -1; 1179 int64 max_object_store_id = -1;
1058 leveldb::Status s = GetMaxObjectStoreId( 1180 leveldb::Status s = GetMaxObjectStoreId(
1059 transaction, max_object_store_id_key, &max_object_store_id); 1181 transaction, max_object_store_id_key, &max_object_store_id);
1060 if (!s.ok()) { 1182 if (!s.ok()) {
1061 INTERNAL_READ_ERROR(SET_MAX_OBJECT_STORE_ID); 1183 INTERNAL_READ_ERROR_UNTESTED(SET_MAX_OBJECT_STORE_ID);
1062 return s; 1184 return s;
1063 } 1185 }
1064 1186
1065 if (object_store_id <= max_object_store_id) { 1187 if (object_store_id <= max_object_store_id) {
1066 INTERNAL_CONSISTENCY_ERROR(SET_MAX_OBJECT_STORE_ID); 1188 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_MAX_OBJECT_STORE_ID);
1067 return InternalInconsistencyStatus(); 1189 return InternalInconsistencyStatus();
1068 } 1190 }
1069 PutInt(transaction, max_object_store_id_key, object_store_id); 1191 PutInt(transaction, max_object_store_id_key, object_store_id);
1070 return s; 1192 return s;
1071 } 1193 }
1072 1194
1195 void IndexedDBBackingStore::Compact() { db_->CompactAll(); }
1196
1073 leveldb::Status IndexedDBBackingStore::CreateObjectStore( 1197 leveldb::Status IndexedDBBackingStore::CreateObjectStore(
1074 IndexedDBBackingStore::Transaction* transaction, 1198 IndexedDBBackingStore::Transaction* transaction,
1075 int64 database_id, 1199 int64 database_id,
1076 int64 object_store_id, 1200 int64 object_store_id,
1077 const base::string16& name, 1201 const base::string16& name,
1078 const IndexedDBKeyPath& key_path, 1202 const IndexedDBKeyPath& key_path,
1079 bool auto_increment) { 1203 bool auto_increment) {
1080 IDB_TRACE("IndexedDBBackingStore::CreateObjectStore"); 1204 IDB_TRACE("IndexedDBBackingStore::CreateObjectStore");
1081 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1205 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1082 return InvalidDBKeyStatus(); 1206 return InvalidDBKeyStatus();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 1256
1133 base::string16 object_store_name; 1257 base::string16 object_store_name;
1134 bool found = false; 1258 bool found = false;
1135 leveldb::Status s = 1259 leveldb::Status s =
1136 GetString(leveldb_transaction, 1260 GetString(leveldb_transaction,
1137 ObjectStoreMetaDataKey::Encode( 1261 ObjectStoreMetaDataKey::Encode(
1138 database_id, object_store_id, ObjectStoreMetaDataKey::NAME), 1262 database_id, object_store_id, ObjectStoreMetaDataKey::NAME),
1139 &object_store_name, 1263 &object_store_name,
1140 &found); 1264 &found);
1141 if (!s.ok()) { 1265 if (!s.ok()) {
1142 INTERNAL_READ_ERROR(DELETE_OBJECT_STORE); 1266 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1143 return s; 1267 return s;
1144 } 1268 }
1145 if (!found) { 1269 if (!found) {
1146 INTERNAL_CONSISTENCY_ERROR(DELETE_OBJECT_STORE); 1270 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1147 return InternalInconsistencyStatus(); 1271 return InternalInconsistencyStatus();
1148 } 1272 }
1149 1273
1150 DeleteRange( 1274 DeleteRange(
1151 leveldb_transaction, 1275 leveldb_transaction,
1152 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), 1276 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0),
1153 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1277 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1154 1278
1155 leveldb_transaction->Remove( 1279 leveldb_transaction->Remove(
1156 ObjectStoreNamesKey::Encode(database_id, object_store_name)); 1280 ObjectStoreNamesKey::Encode(database_id, object_store_name));
(...skipping 27 matching lines...) Expand all
1184 1308
1185 bool found = false; 1309 bool found = false;
1186 leveldb::Status s = leveldb_transaction->Get(leveldb_key, &data, &found); 1310 leveldb::Status s = leveldb_transaction->Get(leveldb_key, &data, &found);
1187 if (!s.ok()) { 1311 if (!s.ok()) {
1188 INTERNAL_READ_ERROR(GET_RECORD); 1312 INTERNAL_READ_ERROR(GET_RECORD);
1189 return s; 1313 return s;
1190 } 1314 }
1191 if (!found) 1315 if (!found)
1192 return s; 1316 return s;
1193 if (data.empty()) { 1317 if (data.empty()) {
1194 INTERNAL_READ_ERROR(GET_RECORD); 1318 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD);
1195 return leveldb::Status::NotFound("Record contained no data"); 1319 return leveldb::Status::NotFound("Record contained no data");
1196 } 1320 }
1197 1321
1198 int64 version; 1322 int64 version;
1199 StringPiece slice(data); 1323 StringPiece slice(data);
1200 if (!DecodeVarInt(&slice, &version)) { 1324 if (!DecodeVarInt(&slice, &version)) {
1201 INTERNAL_READ_ERROR(GET_RECORD); 1325 INTERNAL_READ_ERROR_UNTESTED(GET_RECORD);
1202 return InternalInconsistencyStatus(); 1326 return InternalInconsistencyStatus();
1203 } 1327 }
1204 1328
1205 record->bits = slice.as_string(); 1329 record->bits = slice.as_string();
1206 return s; 1330 return s;
1207 } 1331 }
1208 1332
1209 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber( 1333 WARN_UNUSED_RESULT static leveldb::Status GetNewVersionNumber(
1210 LevelDBTransaction* transaction, 1334 LevelDBTransaction* transaction,
1211 int64 database_id, 1335 int64 database_id,
1212 int64 object_store_id, 1336 int64 object_store_id,
1213 int64* new_version_number) { 1337 int64* new_version_number) {
1214 const std::string last_version_key = ObjectStoreMetaDataKey::Encode( 1338 const std::string last_version_key = ObjectStoreMetaDataKey::Encode(
1215 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); 1339 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
1216 1340
1217 *new_version_number = -1; 1341 *new_version_number = -1;
1218 int64 last_version = -1; 1342 int64 last_version = -1;
1219 bool found = false; 1343 bool found = false;
1220 leveldb::Status s = 1344 leveldb::Status s =
1221 GetInt(transaction, last_version_key, &last_version, &found); 1345 GetInt(transaction, last_version_key, &last_version, &found);
1222 if (!s.ok()) { 1346 if (!s.ok()) {
1223 INTERNAL_READ_ERROR(GET_NEW_VERSION_NUMBER); 1347 INTERNAL_READ_ERROR_UNTESTED(GET_NEW_VERSION_NUMBER);
1224 return s; 1348 return s;
1225 } 1349 }
1226 if (!found) 1350 if (!found)
1227 last_version = 0; 1351 last_version = 0;
1228 1352
1229 DCHECK_GE(last_version, 0); 1353 DCHECK_GE(last_version, 0);
1230 1354
1231 int64 version = last_version + 1; 1355 int64 version = last_version + 1;
1232 PutInt(transaction, last_version_key, version); 1356 PutInt(transaction, last_version_key, version);
1233 1357
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 object_store_id, 1453 object_store_id,
1330 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); 1454 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER);
1331 1455
1332 *key_generator_current_number = -1; 1456 *key_generator_current_number = -1;
1333 std::string data; 1457 std::string data;
1334 1458
1335 bool found = false; 1459 bool found = false;
1336 leveldb::Status s = 1460 leveldb::Status s =
1337 leveldb_transaction->Get(key_generator_current_number_key, &data, &found); 1461 leveldb_transaction->Get(key_generator_current_number_key, &data, &found);
1338 if (!s.ok()) { 1462 if (!s.ok()) {
1339 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER); 1463 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1340 return s; 1464 return s;
1341 } 1465 }
1342 if (found && !data.empty()) { 1466 if (found && !data.empty()) {
1343 StringPiece slice(data); 1467 StringPiece slice(data);
1344 if (!DecodeInt(&slice, key_generator_current_number) || !slice.empty()) { 1468 if (!DecodeInt(&slice, key_generator_current_number) || !slice.empty()) {
1345 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER); 1469 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1346 return InternalInconsistencyStatus(); 1470 return InternalInconsistencyStatus();
1347 } 1471 }
1348 return s; 1472 return s;
1349 } 1473 }
1350 1474
1351 // Previously, the key generator state was not stored explicitly 1475 // Previously, the key generator state was not stored explicitly
1352 // but derived from the maximum numeric key present in existing 1476 // but derived from the maximum numeric key present in existing
1353 // data. This violates the spec as the data may be cleared but the 1477 // data. This violates the spec as the data may be cleared but the
1354 // key generator state must be preserved. 1478 // key generator state must be preserved.
1355 // TODO(jsbell): Fix this for all stores on database open? 1479 // TODO(jsbell): Fix this for all stores on database open?
1356 const std::string start_key = 1480 const std::string start_key =
1357 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 1481 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
1358 const std::string stop_key = 1482 const std::string stop_key =
1359 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 1483 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
1360 1484
1361 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1485 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1362 int64 max_numeric_key = 0; 1486 int64 max_numeric_key = 0;
1363 1487
1364 for (it->Seek(start_key); 1488 for (it->Seek(start_key);
1365 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 1489 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
1366 it->Next()) { 1490 it->Next()) {
1367 StringPiece slice(it->Key()); 1491 StringPiece slice(it->Key());
1368 ObjectStoreDataKey data_key; 1492 ObjectStoreDataKey data_key;
1369 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) { 1493 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) {
1370 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER); 1494 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1371 return InternalInconsistencyStatus(); 1495 return InternalInconsistencyStatus();
1372 } 1496 }
1373 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); 1497 scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
1374 if (user_key->type() == blink::WebIDBKeyTypeNumber) { 1498 if (user_key->type() == blink::WebIDBKeyTypeNumber) {
1375 int64 n = static_cast<int64>(user_key->number()); 1499 int64 n = static_cast<int64>(user_key->number());
1376 if (n > max_numeric_key) 1500 if (n > max_numeric_key)
1377 max_numeric_key = n; 1501 max_numeric_key = n;
1378 } 1502 }
1379 } 1503 }
1380 1504
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1546 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1423 return InvalidDBKeyStatus(); 1547 return InvalidDBKeyStatus();
1424 *found = false; 1548 *found = false;
1425 const std::string leveldb_key = 1549 const std::string leveldb_key =
1426 ObjectStoreDataKey::Encode(database_id, object_store_id, key); 1550 ObjectStoreDataKey::Encode(database_id, object_store_id, key);
1427 std::string data; 1551 std::string data;
1428 1552
1429 leveldb::Status s = 1553 leveldb::Status s =
1430 transaction->transaction()->Get(leveldb_key, &data, found); 1554 transaction->transaction()->Get(leveldb_key, &data, found);
1431 if (!s.ok()) { 1555 if (!s.ok()) {
1432 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE); 1556 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_OBJECT_STORE);
1433 return s; 1557 return s;
1434 } 1558 }
1435 if (!*found) 1559 if (!*found)
1436 return leveldb::Status::OK(); 1560 return leveldb::Status::OK();
1437 if (!data.size()) { 1561 if (!data.size()) {
1438 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE); 1562 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_OBJECT_STORE);
1439 return InternalInconsistencyStatus(); 1563 return InternalInconsistencyStatus();
1440 } 1564 }
1441 1565
1442 int64 version; 1566 int64 version;
1443 StringPiece slice(data); 1567 StringPiece slice(data);
1444 if (!DecodeVarInt(&slice, &version)) 1568 if (!DecodeVarInt(&slice, &version))
1445 return InternalInconsistencyStatus(); 1569 return InternalInconsistencyStatus();
1446 1570
1447 std::string encoded_key; 1571 std::string encoded_key;
1448 EncodeIDBKey(key, &encoded_key); 1572 EncodeIDBKey(key, &encoded_key);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 DCHECK(indexes->empty()); 1609 DCHECK(indexes->empty());
1486 1610
1487 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1611 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1488 it->Seek(start_key); 1612 it->Seek(start_key);
1489 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { 1613 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
1490 StringPiece slice(it->Key()); 1614 StringPiece slice(it->Key());
1491 IndexMetaDataKey meta_data_key; 1615 IndexMetaDataKey meta_data_key;
1492 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key); 1616 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key);
1493 DCHECK(ok); 1617 DCHECK(ok);
1494 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) { 1618 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) {
1495 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1619 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1496 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail 1620 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail
1497 // the load. 1621 // the load.
1498 it->Next(); 1622 it->Next();
1499 continue; 1623 continue;
1500 } 1624 }
1501 1625
1502 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1626 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1503 // simplify. 1627 // simplify.
1504 int64 index_id = meta_data_key.IndexId(); 1628 int64 index_id = meta_data_key.IndexId();
1505 base::string16 index_name; 1629 base::string16 index_name;
1506 { 1630 {
1507 StringPiece slice(it->Value()); 1631 StringPiece slice(it->Value());
1508 if (!DecodeString(&slice, &index_name) || !slice.empty()) 1632 if (!DecodeString(&slice, &index_name) || !slice.empty())
1509 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1633 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1510 } 1634 }
1511 1635
1512 it->Next(); // unique flag 1636 it->Next(); // unique flag
1513 if (!CheckIndexAndMetaDataKey( 1637 if (!CheckIndexAndMetaDataKey(
1514 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { 1638 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) {
1515 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1639 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1516 break; 1640 break;
1517 } 1641 }
1518 bool index_unique; 1642 bool index_unique;
1519 { 1643 {
1520 StringPiece slice(it->Value()); 1644 StringPiece slice(it->Value());
1521 if (!DecodeBool(&slice, &index_unique) || !slice.empty()) 1645 if (!DecodeBool(&slice, &index_unique) || !slice.empty())
1522 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1646 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1523 } 1647 }
1524 1648
1525 it->Next(); // key_path 1649 it->Next(); // key_path
1526 if (!CheckIndexAndMetaDataKey( 1650 if (!CheckIndexAndMetaDataKey(
1527 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { 1651 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) {
1528 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1652 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1529 break; 1653 break;
1530 } 1654 }
1531 IndexedDBKeyPath key_path; 1655 IndexedDBKeyPath key_path;
1532 { 1656 {
1533 StringPiece slice(it->Value()); 1657 StringPiece slice(it->Value());
1534 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1658 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1535 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1659 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1536 } 1660 }
1537 1661
1538 it->Next(); // [optional] multi_entry flag 1662 it->Next(); // [optional] multi_entry flag
1539 bool index_multi_entry = false; 1663 bool index_multi_entry = false;
1540 if (CheckIndexAndMetaDataKey( 1664 if (CheckIndexAndMetaDataKey(
1541 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { 1665 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) {
1542 StringPiece slice(it->Value()); 1666 StringPiece slice(it->Value());
1543 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty()) 1667 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty())
1544 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1668 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1545 1669
1546 it->Next(); 1670 it->Next();
1547 } 1671 }
1548 1672
1549 (*indexes)[index_id] = IndexedDBIndexMetadata( 1673 (*indexes)[index_id] = IndexedDBIndexMetadata(
1550 index_name, index_id, key_path, index_unique, index_multi_entry); 1674 index_name, index_id, key_path, index_unique, index_multi_entry);
1551 } 1675 }
1552 return leveldb::Status::OK(); 1676 return leveldb::Status::OK();
1553 } 1677 }
1554 1678
1555 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( 1679 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
1556 LevelDBTransaction* transaction, 1680 LevelDBTransaction* transaction,
1557 int64 database_id, 1681 int64 database_id,
1558 int64 object_store_id, 1682 int64 object_store_id,
1559 int64 index_id) { 1683 int64 index_id) {
1560 int64 max_index_id = -1; 1684 int64 max_index_id = -1;
1561 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode( 1685 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode(
1562 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); 1686 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID);
1563 bool found = false; 1687 bool found = false;
1564 leveldb::Status s = 1688 leveldb::Status s =
1565 GetInt(transaction, max_index_id_key, &max_index_id, &found); 1689 GetInt(transaction, max_index_id_key, &max_index_id, &found);
1566 if (!s.ok()) { 1690 if (!s.ok()) {
1567 INTERNAL_READ_ERROR(SET_MAX_INDEX_ID); 1691 INTERNAL_READ_ERROR_UNTESTED(SET_MAX_INDEX_ID);
1568 return s; 1692 return s;
1569 } 1693 }
1570 if (!found) 1694 if (!found)
1571 max_index_id = kMinimumIndexId; 1695 max_index_id = kMinimumIndexId;
1572 1696
1573 if (index_id <= max_index_id) { 1697 if (index_id <= max_index_id) {
1574 INTERNAL_CONSISTENCY_ERROR(SET_MAX_INDEX_ID); 1698 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_MAX_INDEX_ID);
1575 return InternalInconsistencyStatus(); 1699 return InternalInconsistencyStatus();
1576 } 1700 }
1577 1701
1578 PutInt(transaction, max_index_id_key, index_id); 1702 PutInt(transaction, max_index_id_key, index_id);
1579 return s; 1703 return s;
1580 } 1704 }
1581 1705
1582 leveldb::Status IndexedDBBackingStore::CreateIndex( 1706 leveldb::Status IndexedDBBackingStore::CreateIndex(
1583 IndexedDBBackingStore::Transaction* transaction, 1707 IndexedDBBackingStore::Transaction* transaction,
1584 int64 database_id, 1708 int64 database_id,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1702 int64 object_store_id, 1826 int64 object_store_id,
1703 int64 version, 1827 int64 version,
1704 const std::string& encoded_primary_key, 1828 const std::string& encoded_primary_key,
1705 bool* exists) { 1829 bool* exists) {
1706 const std::string key = 1830 const std::string key =
1707 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key); 1831 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key);
1708 std::string data; 1832 std::string data;
1709 1833
1710 leveldb::Status s = transaction->Get(key, &data, exists); 1834 leveldb::Status s = transaction->Get(key, &data, exists);
1711 if (!s.ok()) { 1835 if (!s.ok()) {
1712 INTERNAL_READ_ERROR(VERSION_EXISTS); 1836 INTERNAL_READ_ERROR_UNTESTED(VERSION_EXISTS);
1713 return s; 1837 return s;
1714 } 1838 }
1715 if (!*exists) 1839 if (!*exists)
1716 return s; 1840 return s;
1717 1841
1718 StringPiece slice(data); 1842 StringPiece slice(data);
1719 int64 decoded; 1843 int64 decoded;
1720 if (!DecodeInt(&slice, &decoded) || !slice.empty()) 1844 if (!DecodeInt(&slice, &decoded) || !slice.empty())
1721 return InternalInconsistencyStatus(); 1845 return InternalInconsistencyStatus();
1722 *exists = (decoded == version); 1846 *exists = (decoded == version);
(...skipping 23 matching lines...) Expand all
1746 for (;;) { 1870 for (;;) {
1747 if (!it->IsValid()) 1871 if (!it->IsValid())
1748 return leveldb::Status::OK(); 1872 return leveldb::Status::OK();
1749 if (CompareIndexKeys(it->Key(), leveldb_key) > 0) 1873 if (CompareIndexKeys(it->Key(), leveldb_key) > 0)
1750 return leveldb::Status::OK(); 1874 return leveldb::Status::OK();
1751 1875
1752 StringPiece slice(it->Value()); 1876 StringPiece slice(it->Value());
1753 1877
1754 int64 version; 1878 int64 version;
1755 if (!DecodeVarInt(&slice, &version)) { 1879 if (!DecodeVarInt(&slice, &version)) {
1756 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX); 1880 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX);
1757 return InternalInconsistencyStatus(); 1881 return InternalInconsistencyStatus();
1758 } 1882 }
1759 *found_encoded_primary_key = slice.as_string(); 1883 *found_encoded_primary_key = slice.as_string();
1760 1884
1761 bool exists = false; 1885 bool exists = false;
1762 leveldb::Status s = VersionExists(leveldb_transaction, 1886 leveldb::Status s = VersionExists(leveldb_transaction,
1763 database_id, 1887 database_id,
1764 object_store_id, 1888 object_store_id,
1765 version, 1889 version,
1766 *found_encoded_primary_key, 1890 *found_encoded_primary_key,
(...skipping 25 matching lines...) Expand all
1792 bool found = false; 1916 bool found = false;
1793 std::string found_encoded_primary_key; 1917 std::string found_encoded_primary_key;
1794 leveldb::Status s = FindKeyInIndex(transaction, 1918 leveldb::Status s = FindKeyInIndex(transaction,
1795 database_id, 1919 database_id,
1796 object_store_id, 1920 object_store_id,
1797 index_id, 1921 index_id,
1798 key, 1922 key,
1799 &found_encoded_primary_key, 1923 &found_encoded_primary_key,
1800 &found); 1924 &found);
1801 if (!s.ok()) { 1925 if (!s.ok()) {
1802 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1926 INTERNAL_READ_ERROR_UNTESTED(GET_PRIMARY_KEY_VIA_INDEX);
1803 return s; 1927 return s;
1804 } 1928 }
1805 if (!found) 1929 if (!found)
1806 return s; 1930 return s;
1807 if (!found_encoded_primary_key.size()) { 1931 if (!found_encoded_primary_key.size()) {
1808 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1932 INTERNAL_READ_ERROR_UNTESTED(GET_PRIMARY_KEY_VIA_INDEX);
1809 return InvalidDBKeyStatus(); 1933 return InvalidDBKeyStatus();
1810 } 1934 }
1811 1935
1812 StringPiece slice(found_encoded_primary_key); 1936 StringPiece slice(found_encoded_primary_key);
1813 if (DecodeIDBKey(&slice, primary_key) && slice.empty()) 1937 if (DecodeIDBKey(&slice, primary_key) && slice.empty())
1814 return s; 1938 return s;
1815 else 1939 else
1816 return InvalidDBKeyStatus(); 1940 return InvalidDBKeyStatus();
1817 } 1941 }
1818 1942
(...skipping 12 matching lines...) Expand all
1831 *exists = false; 1955 *exists = false;
1832 std::string found_encoded_primary_key; 1956 std::string found_encoded_primary_key;
1833 leveldb::Status s = FindKeyInIndex(transaction, 1957 leveldb::Status s = FindKeyInIndex(transaction,
1834 database_id, 1958 database_id,
1835 object_store_id, 1959 object_store_id,
1836 index_id, 1960 index_id,
1837 index_key, 1961 index_key,
1838 &found_encoded_primary_key, 1962 &found_encoded_primary_key,
1839 exists); 1963 exists);
1840 if (!s.ok()) { 1964 if (!s.ok()) {
1841 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1965 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_INDEX);
1842 return s; 1966 return s;
1843 } 1967 }
1844 if (!*exists) 1968 if (!*exists)
1845 return leveldb::Status::OK(); 1969 return leveldb::Status::OK();
1846 if (found_encoded_primary_key.empty()) { 1970 if (found_encoded_primary_key.empty()) {
1847 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1971 INTERNAL_READ_ERROR_UNTESTED(KEY_EXISTS_IN_INDEX);
1848 return InvalidDBKeyStatus(); 1972 return InvalidDBKeyStatus();
1849 } 1973 }
1850 1974
1851 StringPiece slice(found_encoded_primary_key); 1975 StringPiece slice(found_encoded_primary_key);
1852 if (DecodeIDBKey(&slice, found_primary_key) && slice.empty()) 1976 if (DecodeIDBKey(&slice, found_primary_key) && slice.empty())
1853 return s; 1977 return s;
1854 else 1978 else
1855 return InvalidDBKeyStatus(); 1979 return InvalidDBKeyStatus();
1856 } 1980 }
1857 1981
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2080 2204
2081 private: 2205 private:
2082 explicit ObjectStoreKeyCursorImpl(const ObjectStoreKeyCursorImpl* other) 2206 explicit ObjectStoreKeyCursorImpl(const ObjectStoreKeyCursorImpl* other)
2083 : IndexedDBBackingStore::Cursor(other) {} 2207 : IndexedDBBackingStore::Cursor(other) {}
2084 }; 2208 };
2085 2209
2086 bool ObjectStoreKeyCursorImpl::LoadCurrentRow() { 2210 bool ObjectStoreKeyCursorImpl::LoadCurrentRow() {
2087 StringPiece slice(iterator_->Key()); 2211 StringPiece slice(iterator_->Key());
2088 ObjectStoreDataKey object_store_data_key; 2212 ObjectStoreDataKey object_store_data_key;
2089 if (!ObjectStoreDataKey::Decode(&slice, &object_store_data_key)) { 2213 if (!ObjectStoreDataKey::Decode(&slice, &object_store_data_key)) {
2090 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2214 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2091 return false; 2215 return false;
2092 } 2216 }
2093 2217
2094 current_key_ = object_store_data_key.user_key(); 2218 current_key_ = object_store_data_key.user_key();
2095 2219
2096 int64 version; 2220 int64 version;
2097 slice = StringPiece(iterator_->Value()); 2221 slice = StringPiece(iterator_->Value());
2098 if (!DecodeVarInt(&slice, &version)) { 2222 if (!DecodeVarInt(&slice, &version)) {
2099 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2223 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2100 return false; 2224 return false;
2101 } 2225 }
2102 2226
2103 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2227 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2104 std::string encoded_key; 2228 std::string encoded_key;
2105 EncodeIDBKey(*current_key_, &encoded_key); 2229 EncodeIDBKey(*current_key_, &encoded_key);
2106 record_identifier_.Reset(encoded_key, version); 2230 record_identifier_.Reset(encoded_key, version);
2107 2231
2108 return true; 2232 return true;
2109 } 2233 }
(...skipping 27 matching lines...) Expand all
2137 : IndexedDBBackingStore::Cursor(other), 2261 : IndexedDBBackingStore::Cursor(other),
2138 current_value_(other->current_value_) {} 2262 current_value_(other->current_value_) {}
2139 2263
2140 IndexedDBValue current_value_; 2264 IndexedDBValue current_value_;
2141 }; 2265 };
2142 2266
2143 bool ObjectStoreCursorImpl::LoadCurrentRow() { 2267 bool ObjectStoreCursorImpl::LoadCurrentRow() {
2144 StringPiece key_slice(iterator_->Key()); 2268 StringPiece key_slice(iterator_->Key());
2145 ObjectStoreDataKey object_store_data_key; 2269 ObjectStoreDataKey object_store_data_key;
2146 if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) { 2270 if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) {
2147 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2271 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2148 return false; 2272 return false;
2149 } 2273 }
2150 2274
2151 current_key_ = object_store_data_key.user_key(); 2275 current_key_ = object_store_data_key.user_key();
2152 2276
2153 int64 version; 2277 int64 version;
2154 StringPiece value_slice = StringPiece(iterator_->Value()); 2278 StringPiece value_slice = StringPiece(iterator_->Value());
2155 if (!DecodeVarInt(&value_slice, &version)) { 2279 if (!DecodeVarInt(&value_slice, &version)) {
2156 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2280 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2157 return false; 2281 return false;
2158 } 2282 }
2159 2283
2160 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2284 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2161 std::string encoded_key; 2285 std::string encoded_key;
2162 EncodeIDBKey(*current_key_, &encoded_key); 2286 EncodeIDBKey(*current_key_, &encoded_key);
2163 record_identifier_.Reset(encoded_key, version); 2287 record_identifier_.Reset(encoded_key, version);
2164 2288
2165 current_value_.bits = value_slice.as_string(); 2289 current_value_.bits = value_slice.as_string();
2166 return true; 2290 return true;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 : IndexedDBBackingStore::Cursor(other), 2335 : IndexedDBBackingStore::Cursor(other),
2212 primary_key_(new IndexedDBKey(*other->primary_key_)) {} 2336 primary_key_(new IndexedDBKey(*other->primary_key_)) {}
2213 2337
2214 scoped_ptr<IndexedDBKey> primary_key_; 2338 scoped_ptr<IndexedDBKey> primary_key_;
2215 }; 2339 };
2216 2340
2217 bool IndexKeyCursorImpl::LoadCurrentRow() { 2341 bool IndexKeyCursorImpl::LoadCurrentRow() {
2218 StringPiece slice(iterator_->Key()); 2342 StringPiece slice(iterator_->Key());
2219 IndexDataKey index_data_key; 2343 IndexDataKey index_data_key;
2220 if (!IndexDataKey::Decode(&slice, &index_data_key)) { 2344 if (!IndexDataKey::Decode(&slice, &index_data_key)) {
2221 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2345 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2222 return false; 2346 return false;
2223 } 2347 }
2224 2348
2225 current_key_ = index_data_key.user_key(); 2349 current_key_ = index_data_key.user_key();
2226 DCHECK(current_key_); 2350 DCHECK(current_key_);
2227 2351
2228 slice = StringPiece(iterator_->Value()); 2352 slice = StringPiece(iterator_->Value());
2229 int64 index_data_version; 2353 int64 index_data_version;
2230 if (!DecodeVarInt(&slice, &index_data_version)) { 2354 if (!DecodeVarInt(&slice, &index_data_version)) {
2231 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2355 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2232 return false; 2356 return false;
2233 } 2357 }
2234 2358
2235 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) { 2359 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) {
2236 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2360 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2237 return false; 2361 return false;
2238 } 2362 }
2239 2363
2240 std::string primary_leveldb_key = 2364 std::string primary_leveldb_key =
2241 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2365 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2242 index_data_key.ObjectStoreId(), 2366 index_data_key.ObjectStoreId(),
2243 *primary_key_); 2367 *primary_key_);
2244 2368
2245 std::string result; 2369 std::string result;
2246 bool found = false; 2370 bool found = false;
2247 leveldb::Status s = transaction_->Get(primary_leveldb_key, &result, &found); 2371 leveldb::Status s = transaction_->Get(primary_leveldb_key, &result, &found);
2248 if (!s.ok()) { 2372 if (!s.ok()) {
2249 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2373 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2250 return false; 2374 return false;
2251 } 2375 }
2252 if (!found) { 2376 if (!found) {
2253 transaction_->Remove(iterator_->Key()); 2377 transaction_->Remove(iterator_->Key());
2254 return false; 2378 return false;
2255 } 2379 }
2256 if (!result.size()) { 2380 if (!result.size()) {
2257 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2381 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2258 return false; 2382 return false;
2259 } 2383 }
2260 2384
2261 int64 object_store_data_version; 2385 int64 object_store_data_version;
2262 slice = StringPiece(result); 2386 slice = StringPiece(result);
2263 if (!DecodeVarInt(&slice, &object_store_data_version)) { 2387 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2264 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2388 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2265 return false; 2389 return false;
2266 } 2390 }
2267 2391
2268 if (object_store_data_version != index_data_version) { 2392 if (object_store_data_version != index_data_version) {
2269 transaction_->Remove(iterator_->Key()); 2393 transaction_->Remove(iterator_->Key());
2270 return false; 2394 return false;
2271 } 2395 }
2272 2396
2273 return true; 2397 return true;
2274 } 2398 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 2443
2320 scoped_ptr<IndexedDBKey> primary_key_; 2444 scoped_ptr<IndexedDBKey> primary_key_;
2321 IndexedDBValue current_value_; 2445 IndexedDBValue current_value_;
2322 std::string primary_leveldb_key_; 2446 std::string primary_leveldb_key_;
2323 }; 2447 };
2324 2448
2325 bool IndexCursorImpl::LoadCurrentRow() { 2449 bool IndexCursorImpl::LoadCurrentRow() {
2326 StringPiece slice(iterator_->Key()); 2450 StringPiece slice(iterator_->Key());
2327 IndexDataKey index_data_key; 2451 IndexDataKey index_data_key;
2328 if (!IndexDataKey::Decode(&slice, &index_data_key)) { 2452 if (!IndexDataKey::Decode(&slice, &index_data_key)) {
2329 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2453 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2330 return false; 2454 return false;
2331 } 2455 }
2332 2456
2333 current_key_ = index_data_key.user_key(); 2457 current_key_ = index_data_key.user_key();
2334 DCHECK(current_key_); 2458 DCHECK(current_key_);
2335 2459
2336 slice = StringPiece(iterator_->Value()); 2460 slice = StringPiece(iterator_->Value());
2337 int64 index_data_version; 2461 int64 index_data_version;
2338 if (!DecodeVarInt(&slice, &index_data_version)) { 2462 if (!DecodeVarInt(&slice, &index_data_version)) {
2339 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2463 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2340 return false; 2464 return false;
2341 } 2465 }
2342 if (!DecodeIDBKey(&slice, &primary_key_)) { 2466 if (!DecodeIDBKey(&slice, &primary_key_)) {
2343 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2467 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2344 return false; 2468 return false;
2345 } 2469 }
2346 2470
2347 primary_leveldb_key_ = 2471 primary_leveldb_key_ =
2348 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2472 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2349 index_data_key.ObjectStoreId(), 2473 index_data_key.ObjectStoreId(),
2350 *primary_key_); 2474 *primary_key_);
2351 2475
2352 std::string result; 2476 std::string result;
2353 bool found = false; 2477 bool found = false;
2354 leveldb::Status s = transaction_->Get(primary_leveldb_key_, &result, &found); 2478 leveldb::Status s = transaction_->Get(primary_leveldb_key_, &result, &found);
2355 if (!s.ok()) { 2479 if (!s.ok()) {
2356 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2480 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2357 return false; 2481 return false;
2358 } 2482 }
2359 if (!found) { 2483 if (!found) {
2360 transaction_->Remove(iterator_->Key()); 2484 transaction_->Remove(iterator_->Key());
2361 return false; 2485 return false;
2362 } 2486 }
2363 if (!result.size()) { 2487 if (!result.size()) {
2364 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2488 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2365 return false; 2489 return false;
2366 } 2490 }
2367 2491
2368 int64 object_store_data_version; 2492 int64 object_store_data_version;
2369 slice = StringPiece(result); 2493 slice = StringPiece(result);
2370 if (!DecodeVarInt(&slice, &object_store_data_version)) { 2494 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2371 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2495 INTERNAL_READ_ERROR_UNTESTED(LOAD_CURRENT_ROW);
2372 return false; 2496 return false;
2373 } 2497 }
2374 2498
2375 if (object_store_data_version != index_data_version) { 2499 if (object_store_data_version != index_data_version) {
2376 transaction_->Remove(iterator_->Key()); 2500 transaction_->Remove(iterator_->Key());
2377 return false; 2501 return false;
2378 } 2502 }
2379 2503
2380 current_value_.bits = slice.as_string(); 2504 current_value_.bits = slice.as_string();
2381 return true; 2505 return true;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
2632 DCHECK(!transaction_.get()); 2756 DCHECK(!transaction_.get());
2633 transaction_ = new LevelDBTransaction(backing_store_->db_.get()); 2757 transaction_ = new LevelDBTransaction(backing_store_->db_.get());
2634 } 2758 }
2635 2759
2636 leveldb::Status IndexedDBBackingStore::Transaction::Commit() { 2760 leveldb::Status IndexedDBBackingStore::Transaction::Commit() {
2637 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit"); 2761 IDB_TRACE("IndexedDBBackingStore::Transaction::Commit");
2638 DCHECK(transaction_.get()); 2762 DCHECK(transaction_.get());
2639 leveldb::Status s = transaction_->Commit(); 2763 leveldb::Status s = transaction_->Commit();
2640 transaction_ = NULL; 2764 transaction_ = NULL;
2641 if (!s.ok()) 2765 if (!s.ok())
2642 INTERNAL_WRITE_ERROR(TRANSACTION_COMMIT_METHOD); 2766 INTERNAL_WRITE_ERROR_UNTESTED(TRANSACTION_COMMIT_METHOD);
2643 return s; 2767 return s;
2644 } 2768 }
2645 2769
2646 void IndexedDBBackingStore::Transaction::Rollback() { 2770 void IndexedDBBackingStore::Transaction::Rollback() {
2647 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); 2771 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
2648 DCHECK(transaction_.get()); 2772 DCHECK(transaction_.get());
2649 transaction_->Rollback(); 2773 transaction_->Rollback();
2650 transaction_ = NULL; 2774 transaction_ = NULL;
2651 } 2775 }
2652 2776
2653 } // namespace content 2777 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698