OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |