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