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

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

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

Powered by Google App Engine
This is Rietveld 408576698