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

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

Issue 237143006: Make iterating over a corrupted IndexedDB fail. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/indexed_db_backing_store.h" 5 #include "content/browser/indexed_db/indexed_db_backing_store.h"
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/json/json_reader.h" 9 #include "base/json/json_reader.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 VERSION_EXISTS, 71 VERSION_EXISTS,
72 DELETE_OBJECT_STORE, 72 DELETE_OBJECT_STORE,
73 SET_MAX_OBJECT_STORE_ID, 73 SET_MAX_OBJECT_STORE_ID,
74 SET_MAX_INDEX_ID, 74 SET_MAX_INDEX_ID,
75 GET_NEW_DATABASE_ID, 75 GET_NEW_DATABASE_ID,
76 GET_NEW_VERSION_NUMBER, 76 GET_NEW_VERSION_NUMBER,
77 CREATE_IDBDATABASE_METADATA, 77 CREATE_IDBDATABASE_METADATA,
78 DELETE_DATABASE, 78 DELETE_DATABASE,
79 TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro 79 TRANSACTION_COMMIT_METHOD, // TRANSACTION_COMMIT is a WinNT.h macro
80 GET_DATABASE_NAMES, 80 GET_DATABASE_NAMES,
81 DELETE_INDEX,
82 CLEAR_OBJECT_STORE,
81 INTERNAL_ERROR_MAX, 83 INTERNAL_ERROR_MAX,
82 }; 84 };
83 85
84 static void RecordInternalError(const char* type, 86 static void RecordInternalError(const char* type,
85 IndexedDBBackingStoreErrorSource location) { 87 IndexedDBBackingStoreErrorSource location) {
86 std::string name; 88 std::string name;
87 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error"); 89 name.append("WebCore.IndexedDB.BackingStore.").append(type).append("Error");
88 base::Histogram::FactoryGet(name, 90 base::Histogram::FactoryGet(name,
89 1, 91 1,
90 INTERNAL_ERROR_MAX, 92 INTERNAL_ERROR_MAX,
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 // Upgrade old backing store. 318 // Upgrade old backing store.
317 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); 319 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion);
318 if (db_schema_version < 1) { 320 if (db_schema_version < 1) {
319 db_schema_version = 1; 321 db_schema_version = 1;
320 PutInt(transaction.get(), schema_version_key, db_schema_version); 322 PutInt(transaction.get(), schema_version_key, db_schema_version);
321 const std::string start_key = 323 const std::string start_key =
322 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); 324 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier);
323 const std::string stop_key = 325 const std::string stop_key =
324 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); 326 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier);
325 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); 327 scoped_ptr<LevelDBIterator> it = db->CreateIterator();
326 for (it->Seek(start_key); 328 for (s = it->Seek(start_key);
327 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 329 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
328 it->Next()) { 330 s = it->Next()) {
329 int64 database_id = 0; 331 int64 database_id = 0;
330 found = false; 332 found = false;
331 s = GetInt(transaction.get(), it->Key(), &database_id, &found); 333 s = GetInt(transaction.get(), it->Key(), &database_id, &found);
332 if (!s.ok()) { 334 if (!s.ok()) {
333 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 335 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
334 return false; 336 return false;
335 } 337 }
336 if (!found) { 338 if (!found) {
337 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA); 339 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
338 return false; 340 return false;
339 } 341 }
340 std::string int_version_key = DatabaseMetaDataKey::Encode( 342 std::string int_version_key = DatabaseMetaDataKey::Encode(
341 database_id, DatabaseMetaDataKey::USER_INT_VERSION); 343 database_id, DatabaseMetaDataKey::USER_INT_VERSION);
342 PutVarInt(transaction.get(), 344 PutVarInt(transaction.get(),
343 int_version_key, 345 int_version_key,
344 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); 346 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
345 } 347 }
346 } 348 }
347 if (db_schema_version < 2) { 349 if (db_schema_version < 2) {
jsbell 2014/04/14 20:44:20 Not strictly necessary, but I'd add a `s->ok() &&`
cmumford 2014/04/14 23:39:23 Done.
348 db_schema_version = 2; 350 db_schema_version = 2;
349 PutInt(transaction.get(), schema_version_key, db_schema_version); 351 PutInt(transaction.get(), schema_version_key, db_schema_version);
350 db_data_version = blink::kSerializedScriptValueVersion; 352 db_data_version = blink::kSerializedScriptValueVersion;
351 PutInt(transaction.get(), data_version_key, db_data_version); 353 PutInt(transaction.get(), data_version_key, db_data_version);
352 } 354 }
353 } 355 }
354 356
357 if (!s.ok()) {
358 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
359 return false;
360 }
361
355 // All new values will be written using this serialization version. 362 // All new values will be written using this serialization version.
356 found = false; 363 found = false;
357 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found); 364 s = GetInt(transaction.get(), data_version_key, &db_data_version, &found);
358 if (!s.ok()) { 365 if (!s.ok()) {
359 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA); 366 INTERNAL_READ_ERROR_UNTESTED(SET_UP_METADATA);
360 return false; 367 return false;
361 } 368 }
362 if (!found) { 369 if (!found) {
363 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA); 370 INTERNAL_CONSISTENCY_ERROR_UNTESTED(SET_UP_METADATA);
364 return false; 371 return false;
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 db.Pass(), 810 db.Pass(),
804 comparator.Pass(), 811 comparator.Pass(),
805 task_runner)); 812 task_runner));
806 if (!SetUpMetadata(backing_store->db_.get(), 813 if (!SetUpMetadata(backing_store->db_.get(),
807 backing_store->origin_identifier_)) 814 backing_store->origin_identifier_))
808 return scoped_refptr<IndexedDBBackingStore>(); 815 return scoped_refptr<IndexedDBBackingStore>();
809 816
810 return backing_store; 817 return backing_store;
811 } 818 }
812 819
813 std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames() { 820 std::vector<base::string16> IndexedDBBackingStore::GetDatabaseNames(
821 leveldb::Status& s) {
822 s = leveldb::Status::OK();
814 std::vector<base::string16> found_names; 823 std::vector<base::string16> found_names;
815 const std::string start_key = 824 const std::string start_key =
816 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_); 825 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier_);
817 const std::string stop_key = 826 const std::string stop_key =
818 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_); 827 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier_);
819 828
820 DCHECK(found_names.empty()); 829 DCHECK(found_names.empty());
821 830
822 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 831 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
823 for (it->Seek(start_key); 832 for (s = it->Seek(start_key);
824 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 833 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
825 it->Next()) { 834 s = it->Next()) {
826 StringPiece slice(it->Key()); 835 StringPiece slice(it->Key());
827 DatabaseNameKey database_name_key; 836 DatabaseNameKey database_name_key;
828 if (!DatabaseNameKey::Decode(&slice, &database_name_key)) { 837 if (!DatabaseNameKey::Decode(&slice, &database_name_key)) {
829 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES); 838 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_DATABASE_NAMES);
830 continue; 839 continue;
831 } 840 }
832 found_names.push_back(database_name_key.database_name()); 841 found_names.push_back(database_name_key.database_name());
833 } 842 }
843
844 if (!s.ok())
845 INTERNAL_READ_ERROR_UNTESTED(GET_DATABASE_NAMES);
846
834 return found_names; 847 return found_names;
835 } 848 }
836 849
837 leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData( 850 leveldb::Status IndexedDBBackingStore::GetIDBDatabaseMetaData(
838 const base::string16& name, 851 const base::string16& name,
839 IndexedDBDatabaseMetadata* metadata, 852 IndexedDBDatabaseMetadata* metadata,
840 bool* found) { 853 bool* found) {
841 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); 854 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
842 *found = false; 855 *found = false;
843 856
844 leveldb::Status s = GetInt(db_.get(), key, &metadata->id, found); 857 leveldb::Status s = GetInt(db_.get(), key, &metadata->id, found);
845 if (!s.ok()) { 858 if (!s.ok()) {
846 INTERNAL_READ_ERROR_UNTESTED(GET_IDBDATABASE_METADATA); 859 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA);
847 return s; 860 return s;
848 } 861 }
849 if (!*found) 862 if (!*found)
850 return leveldb::Status::OK(); 863 return leveldb::Status::OK();
851 864
852 s = GetString(db_.get(), 865 s = GetString(db_.get(),
853 DatabaseMetaDataKey::Encode(metadata->id, 866 DatabaseMetaDataKey::Encode(metadata->id,
854 DatabaseMetaDataKey::USER_VERSION), 867 DatabaseMetaDataKey::USER_VERSION),
855 &metadata->version, 868 &metadata->version,
856 found); 869 found);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) 965 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
953 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; 966 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
954 DCHECK_GE(int_version, 0) << "int_version was " << int_version; 967 DCHECK_GE(int_version, 0) << "int_version was " << int_version;
955 PutVarInt(transaction->transaction(), 968 PutVarInt(transaction->transaction(),
956 DatabaseMetaDataKey::Encode(row_id, 969 DatabaseMetaDataKey::Encode(row_id,
957 DatabaseMetaDataKey::USER_INT_VERSION), 970 DatabaseMetaDataKey::USER_INT_VERSION),
958 int_version); 971 int_version);
959 return true; 972 return true;
960 } 973 }
961 974
962 static void DeleteRange(LevelDBTransaction* transaction, 975 static leveldb::Status DeleteRange(LevelDBTransaction* transaction,
963 const std::string& begin, 976 const std::string& begin,
964 const std::string& end) { 977 const std::string& end) {
965 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 978 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
966 for (it->Seek(begin); it->IsValid() && CompareKeys(it->Key(), end) < 0; 979 leveldb::Status s;
967 it->Next()) 980 for (s = it->Seek(begin);
981 s.ok() && it->IsValid() && CompareKeys(it->Key(), end) < 0;
982 s = it->Next())
968 transaction->Remove(it->Key()); 983 transaction->Remove(it->Key());
984 return s;
969 } 985 }
970 986
971 leveldb::Status IndexedDBBackingStore::DeleteDatabase( 987 leveldb::Status IndexedDBBackingStore::DeleteDatabase(
972 const base::string16& name) { 988 const base::string16& name) {
973 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase"); 989 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase");
974 scoped_ptr<LevelDBDirectTransaction> transaction = 990 scoped_ptr<LevelDBDirectTransaction> transaction =
975 LevelDBDirectTransaction::Create(db_.get()); 991 LevelDBDirectTransaction::Create(db_.get());
976 992
977 IndexedDBDatabaseMetadata metadata; 993 IndexedDBDatabaseMetadata metadata;
978 bool success = false; 994 bool success = false;
979 leveldb::Status s = GetIDBDatabaseMetaData(name, &metadata, &success); 995 leveldb::Status s = GetIDBDatabaseMetaData(name, &metadata, &success);
980 if (!s.ok()) 996 if (!s.ok())
981 return s; 997 return s;
982 if (!success) 998 if (!success)
983 return leveldb::Status::OK(); 999 return leveldb::Status::OK();
984 1000
985 const std::string start_key = DatabaseMetaDataKey::Encode( 1001 const std::string start_key = DatabaseMetaDataKey::Encode(
986 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME); 1002 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME);
987 const std::string stop_key = DatabaseMetaDataKey::Encode( 1003 const std::string stop_key = DatabaseMetaDataKey::Encode(
988 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME); 1004 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME);
989 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1005 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
990 for (it->Seek(start_key); 1006 for (s = it->Seek(start_key);
991 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 1007 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
992 it->Next()) 1008 s = it->Next())
993 transaction->Remove(it->Key()); 1009 transaction->Remove(it->Key());
1010 if (!s.ok()) {
1011 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
1012 return s;
1013 }
994 1014
995 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name); 1015 const std::string key = DatabaseNameKey::Encode(origin_identifier_, name);
996 transaction->Remove(key); 1016 transaction->Remove(key);
997 1017
998 s = transaction->Commit(); 1018 s = transaction->Commit();
999 if (!s.ok()) { 1019 if (!s.ok()) {
1000 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE); 1020 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_DATABASE);
1001 return s; 1021 return s;
1002 } 1022 }
1003 db_->Compact(start_key, stop_key); 1023 db_->Compact(start_key, stop_key);
(...skipping 27 matching lines...) Expand all
1031 if (!KeyPrefix::IsValidDatabaseId(database_id)) 1051 if (!KeyPrefix::IsValidDatabaseId(database_id))
1032 return InvalidDBKeyStatus(); 1052 return InvalidDBKeyStatus();
1033 const std::string start_key = 1053 const std::string start_key =
1034 ObjectStoreMetaDataKey::Encode(database_id, 1, 0); 1054 ObjectStoreMetaDataKey::Encode(database_id, 1, 0);
1035 const std::string stop_key = 1055 const std::string stop_key =
1036 ObjectStoreMetaDataKey::EncodeMaxKey(database_id); 1056 ObjectStoreMetaDataKey::EncodeMaxKey(database_id);
1037 1057
1038 DCHECK(object_stores->empty()); 1058 DCHECK(object_stores->empty());
1039 1059
1040 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1060 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1041 it->Seek(start_key); 1061 leveldb::Status s = it->Seek(start_key);
1042 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { 1062 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
1043 StringPiece slice(it->Key()); 1063 StringPiece slice(it->Key());
1044 ObjectStoreMetaDataKey meta_data_key; 1064 ObjectStoreMetaDataKey meta_data_key;
1045 bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key); 1065 bool ok = ObjectStoreMetaDataKey::Decode(&slice, &meta_data_key);
1046 DCHECK(ok); 1066 DCHECK(ok);
1047 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { 1067 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) {
1048 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1068 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1049 // Possible stale metadata, but don't fail the load. 1069 // Possible stale metadata, but don't fail the load.
1050 it->Next(); 1070 s = it->Next();
jsbell 2014/04/14 20:44:20 Check value of s here? (see next comment...)
1051 continue; 1071 continue;
1052 } 1072 }
1053 1073
1054 int64 object_store_id = meta_data_key.ObjectStoreId(); 1074 int64 object_store_id = meta_data_key.ObjectStoreId();
1055 1075
1056 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1076 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1057 // simplify. 1077 // simplify.
1058 base::string16 object_store_name; 1078 base::string16 object_store_name;
1059 { 1079 {
1060 StringPiece slice(it->Value()); 1080 StringPiece slice(it->Value());
1061 if (!DecodeString(&slice, &object_store_name) || !slice.empty()) 1081 if (!DecodeString(&slice, &object_store_name) || !slice.empty())
1062 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1082 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1063 } 1083 }
1064 1084
1065 it->Next(); 1085 s = it->Next();
1086 if (!s.ok())
1087 continue;
jsbell 2014/04/14 20:44:20 continue or break? They'll do the same thing sinc
cmumford 2014/04/14 23:39:23 I'll do what you think is most obvious, but if we
1066 if (!CheckObjectStoreAndMetaDataType(it.get(), 1088 if (!CheckObjectStoreAndMetaDataType(it.get(),
1067 stop_key, 1089 stop_key,
1068 object_store_id, 1090 object_store_id,
1069 ObjectStoreMetaDataKey::KEY_PATH)) { 1091 ObjectStoreMetaDataKey::KEY_PATH)) {
1070 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1092 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1071 break; 1093 break;
1072 } 1094 }
1073 IndexedDBKeyPath key_path; 1095 IndexedDBKeyPath key_path;
1074 { 1096 {
1075 StringPiece slice(it->Value()); 1097 StringPiece slice(it->Value());
1076 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1098 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1077 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1099 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1078 } 1100 }
1079 1101
1080 it->Next(); 1102 s = it->Next();
1103 if (!s.ok())
1104 continue;
1081 if (!CheckObjectStoreAndMetaDataType( 1105 if (!CheckObjectStoreAndMetaDataType(
1082 it.get(), 1106 it.get(),
1083 stop_key, 1107 stop_key,
1084 object_store_id, 1108 object_store_id,
1085 ObjectStoreMetaDataKey::AUTO_INCREMENT)) { 1109 ObjectStoreMetaDataKey::AUTO_INCREMENT)) {
1086 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1110 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1087 break; 1111 break;
1088 } 1112 }
1089 bool auto_increment; 1113 bool auto_increment;
1090 { 1114 {
1091 StringPiece slice(it->Value()); 1115 StringPiece slice(it->Value());
1092 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) 1116 if (!DecodeBool(&slice, &auto_increment) || !slice.empty())
1093 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1117 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1094 } 1118 }
1095 1119
1096 it->Next(); // Is evicatble. 1120 s = it->Next(); // Is evicatble.
1121 if (!s.ok())
1122 continue;
1097 if (!CheckObjectStoreAndMetaDataType(it.get(), 1123 if (!CheckObjectStoreAndMetaDataType(it.get(),
1098 stop_key, 1124 stop_key,
1099 object_store_id, 1125 object_store_id,
1100 ObjectStoreMetaDataKey::EVICTABLE)) { 1126 ObjectStoreMetaDataKey::EVICTABLE)) {
1101 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1127 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1102 break; 1128 break;
1103 } 1129 }
1104 1130
1105 it->Next(); // Last version. 1131 s = it->Next(); // Last version.
1132 if (!s.ok())
1133 continue;
1106 if (!CheckObjectStoreAndMetaDataType( 1134 if (!CheckObjectStoreAndMetaDataType(
1107 it.get(), 1135 it.get(),
1108 stop_key, 1136 stop_key,
1109 object_store_id, 1137 object_store_id,
1110 ObjectStoreMetaDataKey::LAST_VERSION)) { 1138 ObjectStoreMetaDataKey::LAST_VERSION)) {
1111 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1139 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1112 break; 1140 break;
1113 } 1141 }
1114 1142
1115 it->Next(); // Maximum index id allocated. 1143 s = it->Next(); // Maximum index id allocated.
1144 if (!s.ok())
1145 continue;
1116 if (!CheckObjectStoreAndMetaDataType( 1146 if (!CheckObjectStoreAndMetaDataType(
1117 it.get(), 1147 it.get(),
1118 stop_key, 1148 stop_key,
1119 object_store_id, 1149 object_store_id,
1120 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { 1150 ObjectStoreMetaDataKey::MAX_INDEX_ID)) {
1121 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1151 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1122 break; 1152 break;
1123 } 1153 }
1124 int64 max_index_id; 1154 int64 max_index_id;
1125 { 1155 {
1126 StringPiece slice(it->Value()); 1156 StringPiece slice(it->Value());
1127 if (!DecodeInt(&slice, &max_index_id) || !slice.empty()) 1157 if (!DecodeInt(&slice, &max_index_id) || !slice.empty())
1128 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1158 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1129 } 1159 }
1130 1160
1131 it->Next(); // [optional] has key path (is not null) 1161 s = it->Next(); // [optional] has key path (is not null)
1162 if (!s.ok())
1163 continue;
1132 if (CheckObjectStoreAndMetaDataType(it.get(), 1164 if (CheckObjectStoreAndMetaDataType(it.get(),
1133 stop_key, 1165 stop_key,
1134 object_store_id, 1166 object_store_id,
1135 ObjectStoreMetaDataKey::HAS_KEY_PATH)) { 1167 ObjectStoreMetaDataKey::HAS_KEY_PATH)) {
1136 bool has_key_path; 1168 bool has_key_path;
1137 { 1169 {
1138 StringPiece slice(it->Value()); 1170 StringPiece slice(it->Value());
1139 if (!DecodeBool(&slice, &has_key_path)) 1171 if (!DecodeBool(&slice, &has_key_path))
1140 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1172 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1141 } 1173 }
1142 // This check accounts for two layers of legacy coding: 1174 // This check accounts for two layers of legacy coding:
1143 // (1) Initially, has_key_path was added to distinguish null vs. string. 1175 // (1) Initially, has_key_path was added to distinguish null vs. string.
1144 // (2) Later, null vs. string vs. array was stored in the key_path itself. 1176 // (2) Later, null vs. string vs. array was stored in the key_path itself.
1145 // So this check is only relevant for string-type key_paths. 1177 // So this check is only relevant for string-type key_paths.
1146 if (!has_key_path && 1178 if (!has_key_path &&
1147 (key_path.type() == blink::WebIDBKeyPathTypeString && 1179 (key_path.type() == blink::WebIDBKeyPathTypeString &&
1148 !key_path.string().empty())) { 1180 !key_path.string().empty())) {
1149 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1181 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1150 break; 1182 break;
1151 } 1183 }
1152 if (!has_key_path) 1184 if (!has_key_path)
1153 key_path = IndexedDBKeyPath(); 1185 key_path = IndexedDBKeyPath();
1154 it->Next(); 1186 s = it->Next();
1187 if (!s.ok())
1188 continue;
1155 } 1189 }
1156 1190
1157 int64 key_generator_current_number = -1; 1191 int64 key_generator_current_number = -1;
1158 if (CheckObjectStoreAndMetaDataType( 1192 if (CheckObjectStoreAndMetaDataType(
1159 it.get(), 1193 it.get(),
1160 stop_key, 1194 stop_key,
1161 object_store_id, 1195 object_store_id,
1162 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { 1196 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) {
1163 StringPiece slice(it->Value()); 1197 StringPiece slice(it->Value());
1164 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) 1198 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty())
1165 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1199 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1166 1200
1167 // TODO(jsbell): Return key_generator_current_number, cache in 1201 // TODO(jsbell): Return key_generator_current_number, cache in
1168 // object store, and write lazily to backing store. For now, 1202 // object store, and write lazily to backing store. For now,
1169 // just assert that if it was written it was valid. 1203 // just assert that if it was written it was valid.
1170 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber); 1204 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber);
1171 it->Next(); 1205 s = it->Next();
1206 if (!s.ok())
1207 continue;
1172 } 1208 }
1173 1209
1174 IndexedDBObjectStoreMetadata metadata(object_store_name, 1210 IndexedDBObjectStoreMetadata metadata(object_store_name,
1175 object_store_id, 1211 object_store_id,
1176 key_path, 1212 key_path,
1177 auto_increment, 1213 auto_increment,
1178 max_index_id); 1214 max_index_id);
1179 leveldb::Status s = 1215 s = GetIndexes(database_id, object_store_id, &metadata.indexes);
1180 GetIndexes(database_id, object_store_id, &metadata.indexes);
1181 if (!s.ok()) 1216 if (!s.ok())
1182 return s; 1217 continue;
1183 (*object_stores)[object_store_id] = metadata; 1218 (*object_stores)[object_store_id] = metadata;
1184 } 1219 }
1185 return leveldb::Status::OK(); 1220
1221 if (!s.ok())
1222 INTERNAL_READ_ERROR_UNTESTED(GET_OBJECT_STORES);
1223
1224 return s;
1186 } 1225 }
1187 1226
1188 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId( 1227 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId(
1189 LevelDBTransaction* transaction, 1228 LevelDBTransaction* transaction,
1190 int64 database_id, 1229 int64 database_id,
1191 int64 object_store_id) { 1230 int64 object_store_id) {
1192 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( 1231 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
1193 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); 1232 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
1194 int64 max_object_store_id = -1; 1233 int64 max_object_store_id = -1;
1195 leveldb::Status s = GetMaxObjectStoreId( 1234 leveldb::Status s = GetMaxObjectStoreId(
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 &found); 1318 &found);
1280 if (!s.ok()) { 1319 if (!s.ok()) {
1281 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1320 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1282 return s; 1321 return s;
1283 } 1322 }
1284 if (!found) { 1323 if (!found) {
1285 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1324 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1286 return InternalInconsistencyStatus(); 1325 return InternalInconsistencyStatus();
1287 } 1326 }
1288 1327
1289 DeleteRange( 1328 s = DeleteRange(
1290 leveldb_transaction, 1329 leveldb_transaction,
1291 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), 1330 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0),
1292 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1331 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1293 1332
1294 leveldb_transaction->Remove( 1333 if (s.ok()) {
1295 ObjectStoreNamesKey::Encode(database_id, object_store_name)); 1334 leveldb_transaction->Remove(
1335 ObjectStoreNamesKey::Encode(database_id, object_store_name));
1296 1336
1297 DeleteRange(leveldb_transaction, 1337 s = DeleteRange(
1298 IndexFreeListKey::Encode(database_id, object_store_id, 0), 1338 leveldb_transaction,
1299 IndexFreeListKey::EncodeMaxKey(database_id, object_store_id)); 1339 IndexFreeListKey::Encode(database_id, object_store_id, 0),
1300 DeleteRange(leveldb_transaction, 1340 IndexFreeListKey::EncodeMaxKey(database_id, object_store_id));
1301 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0), 1341 }
1302 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1342
1343 if (s.ok()) {
1344 s = DeleteRange(
1345 leveldb_transaction,
1346 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0),
1347 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1348 }
1349 if (!s.ok()) {
jsbell 2014/04/14 20:44:20 Nit: make the blank lines before the if()s consist
1350 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1351 return s;
1352 }
1303 1353
1304 return ClearObjectStore(transaction, database_id, object_store_id); 1354 return ClearObjectStore(transaction, database_id, object_store_id);
1305 } 1355 }
1306 1356
1307 leveldb::Status IndexedDBBackingStore::GetRecord( 1357 leveldb::Status IndexedDBBackingStore::GetRecord(
1308 IndexedDBBackingStore::Transaction* transaction, 1358 IndexedDBBackingStore::Transaction* transaction,
1309 int64 database_id, 1359 int64 database_id,
1310 int64 object_store_id, 1360 int64 object_store_id,
1311 const IndexedDBKey& key, 1361 const IndexedDBKey& key,
1312 IndexedDBValue* record) { 1362 IndexedDBValue* record) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 int64 database_id, 1472 int64 database_id,
1423 int64 object_store_id) { 1473 int64 object_store_id) {
1424 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); 1474 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore");
1425 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1475 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1426 return InvalidDBKeyStatus(); 1476 return InvalidDBKeyStatus();
1427 const std::string start_key = 1477 const std::string start_key =
1428 KeyPrefix(database_id, object_store_id).Encode(); 1478 KeyPrefix(database_id, object_store_id).Encode();
1429 const std::string stop_key = 1479 const std::string stop_key =
1430 KeyPrefix(database_id, object_store_id + 1).Encode(); 1480 KeyPrefix(database_id, object_store_id + 1).Encode();
1431 1481
1432 DeleteRange(transaction->transaction(), start_key, stop_key); 1482 leveldb::Status s =
1433 return leveldb::Status::OK(); 1483 DeleteRange(transaction->transaction(), start_key, stop_key);
1484 if (!s.ok())
1485 INTERNAL_WRITE_ERROR_UNTESTED(CLEAR_OBJECT_STORE);
1486 return s;
1434 } 1487 }
1435 1488
1436 leveldb::Status IndexedDBBackingStore::DeleteRecord( 1489 leveldb::Status IndexedDBBackingStore::DeleteRecord(
1437 IndexedDBBackingStore::Transaction* transaction, 1490 IndexedDBBackingStore::Transaction* transaction,
1438 int64 database_id, 1491 int64 database_id,
1439 int64 object_store_id, 1492 int64 object_store_id,
1440 const RecordIdentifier& record_identifier) { 1493 const RecordIdentifier& record_identifier) {
1441 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); 1494 IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
1442 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1495 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1443 return InvalidDBKeyStatus(); 1496 return InvalidDBKeyStatus();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 // key generator state must be preserved. 1546 // key generator state must be preserved.
1494 // TODO(jsbell): Fix this for all stores on database open? 1547 // TODO(jsbell): Fix this for all stores on database open?
1495 const std::string start_key = 1548 const std::string start_key =
1496 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 1549 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
1497 const std::string stop_key = 1550 const std::string stop_key =
1498 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 1551 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
1499 1552
1500 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1553 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1501 int64 max_numeric_key = 0; 1554 int64 max_numeric_key = 0;
1502 1555
1503 for (it->Seek(start_key); 1556 for (s = it->Seek(start_key);
1504 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 1557 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
1505 it->Next()) { 1558 s = it->Next()) {
1506 StringPiece slice(it->Key()); 1559 StringPiece slice(it->Key());
1507 ObjectStoreDataKey data_key; 1560 ObjectStoreDataKey data_key;
1508 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) { 1561 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) {
1509 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); 1562 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1510 return InternalInconsistencyStatus(); 1563 return InternalInconsistencyStatus();
1511 } 1564 }
1512 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); 1565 scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
1513 if (user_key->type() == blink::WebIDBKeyTypeNumber) { 1566 if (user_key->type() == blink::WebIDBKeyTypeNumber) {
1514 int64 n = static_cast<int64>(user_key->number()); 1567 int64 n = static_cast<int64>(user_key->number());
1515 if (n > max_numeric_key) 1568 if (n > max_numeric_key)
1516 max_numeric_key = n; 1569 max_numeric_key = n;
1517 } 1570 }
1518 } 1571 }
1519 1572
1520 *key_generator_current_number = max_numeric_key + 1; 1573 if (s.ok())
1574 *key_generator_current_number = max_numeric_key + 1;
1575 else
1576 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1577
1521 return s; 1578 return s;
1522 } 1579 }
1523 1580
1524 leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber( 1581 leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
1525 IndexedDBBackingStore::Transaction* transaction, 1582 IndexedDBBackingStore::Transaction* transaction,
1526 int64 database_id, 1583 int64 database_id,
1527 int64 object_store_id, 1584 int64 object_store_id,
1528 int64 new_number, 1585 int64 new_number,
1529 bool check_current) { 1586 bool check_current) {
1530 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1587 if (!KeyPrefix::ValidIds(database_id, object_store_id))
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1674 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1618 return InvalidDBKeyStatus(); 1675 return InvalidDBKeyStatus();
1619 const std::string start_key = 1676 const std::string start_key =
1620 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0); 1677 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0);
1621 const std::string stop_key = 1678 const std::string stop_key =
1622 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0); 1679 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0);
1623 1680
1624 DCHECK(indexes->empty()); 1681 DCHECK(indexes->empty());
1625 1682
1626 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1683 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1627 it->Seek(start_key); 1684 leveldb::Status s = it->Seek(start_key);
1628 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { 1685 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
1629 StringPiece slice(it->Key()); 1686 StringPiece slice(it->Key());
1630 IndexMetaDataKey meta_data_key; 1687 IndexMetaDataKey meta_data_key;
1631 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key); 1688 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key);
1632 DCHECK(ok); 1689 DCHECK(ok);
1633 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) { 1690 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) {
1634 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1691 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1635 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail 1692 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail
1636 // the load. 1693 // the load.
1637 it->Next(); 1694 s = it->Next();
jsbell 2014/04/14 20:44:20 Same as GetObjectStores here - `if(!s.ok()) break;
cmumford 2014/04/14 23:39:23 Done.
1638 continue; 1695 continue;
1639 } 1696 }
1640 1697
1641 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1698 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1642 // simplify. 1699 // simplify.
1643 int64 index_id = meta_data_key.IndexId(); 1700 int64 index_id = meta_data_key.IndexId();
1644 base::string16 index_name; 1701 base::string16 index_name;
1645 { 1702 {
1646 StringPiece slice(it->Value()); 1703 StringPiece slice(it->Value());
1647 if (!DecodeString(&slice, &index_name) || !slice.empty()) 1704 if (!DecodeString(&slice, &index_name) || !slice.empty())
1648 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1705 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1649 } 1706 }
1650 1707
1651 it->Next(); // unique flag 1708 s = it->Next(); // unique flag
1709 if (!s.ok())
1710 continue;
jsbell 2014/04/14 20:44:20 Same as GetObjectStores here - `continue` or `brea
cmumford 2014/04/14 23:39:23 Done.
1652 if (!CheckIndexAndMetaDataKey( 1711 if (!CheckIndexAndMetaDataKey(
1653 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { 1712 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) {
1654 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1713 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1655 break; 1714 break;
1656 } 1715 }
1657 bool index_unique; 1716 bool index_unique;
1658 { 1717 {
1659 StringPiece slice(it->Value()); 1718 StringPiece slice(it->Value());
1660 if (!DecodeBool(&slice, &index_unique) || !slice.empty()) 1719 if (!DecodeBool(&slice, &index_unique) || !slice.empty())
1661 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1720 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1662 } 1721 }
1663 1722
1664 it->Next(); // key_path 1723 s = it->Next(); // key_path
1724 if (!s.ok())
1725 continue;
1665 if (!CheckIndexAndMetaDataKey( 1726 if (!CheckIndexAndMetaDataKey(
1666 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { 1727 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) {
1667 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1728 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1668 break; 1729 break;
1669 } 1730 }
1670 IndexedDBKeyPath key_path; 1731 IndexedDBKeyPath key_path;
1671 { 1732 {
1672 StringPiece slice(it->Value()); 1733 StringPiece slice(it->Value());
1673 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1734 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1674 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1735 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1675 } 1736 }
1676 1737
1677 it->Next(); // [optional] multi_entry flag 1738 s = it->Next(); // [optional] multi_entry flag
1739 if (!s.ok())
1740 continue;
1678 bool index_multi_entry = false; 1741 bool index_multi_entry = false;
1679 if (CheckIndexAndMetaDataKey( 1742 if (CheckIndexAndMetaDataKey(
1680 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { 1743 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) {
1681 StringPiece slice(it->Value()); 1744 StringPiece slice(it->Value());
1682 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty()) 1745 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty())
1683 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1746 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1684 1747
1685 it->Next(); 1748 s = it->Next();
1749 if (!s.ok())
1750 continue;
1686 } 1751 }
1687 1752
1688 (*indexes)[index_id] = IndexedDBIndexMetadata( 1753 (*indexes)[index_id] = IndexedDBIndexMetadata(
1689 index_name, index_id, key_path, index_unique, index_multi_entry); 1754 index_name, index_id, key_path, index_unique, index_multi_entry);
1690 } 1755 }
1691 return leveldb::Status::OK(); 1756
1757 if (!s.ok())
1758 INTERNAL_READ_ERROR_UNTESTED(GET_INDEXES);
1759
1760 return s;
1692 } 1761 }
1693 1762
1694 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( 1763 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
1695 LevelDBTransaction* transaction, 1764 LevelDBTransaction* transaction,
1696 int64 database_id, 1765 int64 database_id,
1697 int64 object_store_id, 1766 int64 object_store_id,
1698 int64 index_id) { 1767 int64 index_id) {
1699 int64 max_index_id = -1; 1768 int64 max_index_id = -1;
1700 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode( 1769 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode(
1701 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); 1770 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 int64 index_id) { 1829 int64 index_id) {
1761 IDB_TRACE("IndexedDBBackingStore::DeleteIndex"); 1830 IDB_TRACE("IndexedDBBackingStore::DeleteIndex");
1762 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1831 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1763 return InvalidDBKeyStatus(); 1832 return InvalidDBKeyStatus();
1764 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 1833 LevelDBTransaction* leveldb_transaction = transaction->transaction();
1765 1834
1766 const std::string index_meta_data_start = 1835 const std::string index_meta_data_start =
1767 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0); 1836 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0);
1768 const std::string index_meta_data_end = 1837 const std::string index_meta_data_end =
1769 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 1838 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
1770 DeleteRange(leveldb_transaction, index_meta_data_start, index_meta_data_end); 1839 leveldb::Status s = DeleteRange(
1840 leveldb_transaction, index_meta_data_start, index_meta_data_end);
1771 1841
1772 const std::string index_data_start = 1842 if (s.ok()) {
1773 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); 1843 const std::string index_data_start =
1774 const std::string index_data_end = 1844 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id);
1775 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 1845 const std::string index_data_end =
1776 DeleteRange(leveldb_transaction, index_data_start, index_data_end); 1846 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
1777 return leveldb::Status::OK(); 1847 s = DeleteRange(leveldb_transaction, index_data_start, index_data_end);
1848 }
1849
1850 if (!s.ok())
1851 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_INDEX);
1852
1853 return s;
1778 } 1854 }
1779 1855
1780 leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord( 1856 leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord(
1781 IndexedDBBackingStore::Transaction* transaction, 1857 IndexedDBBackingStore::Transaction* transaction,
1782 int64 database_id, 1858 int64 database_id,
1783 int64 object_store_id, 1859 int64 object_store_id,
1784 int64 index_id, 1860 int64 index_id,
1785 const IndexedDBKey& key, 1861 const IndexedDBKey& key,
1786 const RecordIdentifier& record_identifier) { 1862 const RecordIdentifier& record_identifier) {
1787 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord"); 1863 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord");
(...skipping 15 matching lines...) Expand all
1803 std::string data; 1879 std::string data;
1804 EncodeVarInt(record_identifier.version(), &data); 1880 EncodeVarInt(record_identifier.version(), &data);
1805 data.append(record_identifier.primary_key()); 1881 data.append(record_identifier.primary_key());
1806 1882
1807 transaction->transaction()->Put(index_data_key, &data); 1883 transaction->transaction()->Put(index_data_key, &data);
1808 return leveldb::Status::OK(); 1884 return leveldb::Status::OK();
1809 } 1885 }
1810 1886
1811 static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, 1887 static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction,
1812 const std::string& target, 1888 const std::string& target,
1813 std::string* found_key) { 1889 std::string* found_key,
1890 leveldb::Status& s) {
1814 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 1891 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
1815 it->Seek(target); 1892 s = it->Seek(target);
1893 if (!s.ok())
1894 return false;
1816 1895
1817 if (!it->IsValid()) { 1896 if (!it->IsValid()) {
1818 it->SeekToLast(); 1897 s = it->SeekToLast();
1819 if (!it->IsValid()) 1898 if (!s.ok() || !it->IsValid())
1820 return false; 1899 return false;
1821 } 1900 }
1822 1901
1823 while (CompareIndexKeys(it->Key(), target) > 0) { 1902 while (CompareIndexKeys(it->Key(), target) > 0) {
1824 it->Prev(); 1903 s = it->Prev();
1825 if (!it->IsValid()) 1904 if (!s.ok() || !it->IsValid())
1826 return false; 1905 return false;
1827 } 1906 }
1828 1907
1829 do { 1908 do {
1830 *found_key = it->Key().as_string(); 1909 *found_key = it->Key().as_string();
1831 1910
1832 // There can be several index keys that compare equal. We want the last one. 1911 // There can be several index keys that compare equal. We want the last one.
1833 it->Next(); 1912 s = it->Next();
1834 } while (it->IsValid() && !CompareIndexKeys(it->Key(), target)); 1913 } while (s.ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target));
1835 1914
1836 return true; 1915 return true;
1837 } 1916 }
1838 1917
1839 static leveldb::Status VersionExists(LevelDBTransaction* transaction, 1918 static leveldb::Status VersionExists(LevelDBTransaction* transaction,
1840 int64 database_id, 1919 int64 database_id,
1841 int64 object_store_id, 1920 int64 object_store_id,
1842 int64 version, 1921 int64 version,
1843 const std::string& encoded_primary_key, 1922 const std::string& encoded_primary_key,
1844 bool* exists) { 1923 bool* exists) {
(...skipping 28 matching lines...) Expand all
1873 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex"); 1952 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex");
1874 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id)); 1953 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id));
1875 1954
1876 DCHECK(found_encoded_primary_key->empty()); 1955 DCHECK(found_encoded_primary_key->empty());
1877 *found = false; 1956 *found = false;
1878 1957
1879 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 1958 LevelDBTransaction* leveldb_transaction = transaction->transaction();
1880 const std::string leveldb_key = 1959 const std::string leveldb_key =
1881 IndexDataKey::Encode(database_id, object_store_id, index_id, key); 1960 IndexDataKey::Encode(database_id, object_store_id, index_id, key);
1882 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1961 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1883 it->Seek(leveldb_key); 1962 leveldb::Status s = it->Seek(leveldb_key);
1963 if (!s.ok()) {
1964 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX);
1965 return s;
1966 }
1884 1967
1885 for (;;) { 1968 for (;;) {
1886 if (!it->IsValid()) 1969 if (!it->IsValid())
1887 return leveldb::Status::OK(); 1970 return leveldb::Status::OK();
1888 if (CompareIndexKeys(it->Key(), leveldb_key) > 0) 1971 if (CompareIndexKeys(it->Key(), leveldb_key) > 0)
1889 return leveldb::Status::OK(); 1972 return leveldb::Status::OK();
1890 1973
1891 StringPiece slice(it->Value()); 1974 StringPiece slice(it->Value());
1892 1975
1893 int64 version; 1976 int64 version;
1894 if (!DecodeVarInt(&slice, &version)) { 1977 if (!DecodeVarInt(&slice, &version)) {
1895 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); 1978 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX);
1896 return InternalInconsistencyStatus(); 1979 return InternalInconsistencyStatus();
1897 } 1980 }
1898 *found_encoded_primary_key = slice.as_string(); 1981 *found_encoded_primary_key = slice.as_string();
1899 1982
1900 bool exists = false; 1983 bool exists = false;
1901 leveldb::Status s = VersionExists(leveldb_transaction, 1984 s = VersionExists(leveldb_transaction,
1902 database_id, 1985 database_id,
1903 object_store_id, 1986 object_store_id,
1904 version, 1987 version,
1905 *found_encoded_primary_key, 1988 *found_encoded_primary_key,
1906 &exists); 1989 &exists);
1907 if (!s.ok()) 1990 if (!s.ok())
1908 return s; 1991 return s;
1909 if (!exists) { 1992 if (!exists) {
1910 // Delete stale index data entry and continue. 1993 // Delete stale index data entry and continue.
1911 leveldb_transaction->Remove(it->Key()); 1994 leveldb_transaction->Remove(it->Key());
1912 it->Next(); 1995 s = it->Next();
1913 continue; 1996 continue;
1914 } 1997 }
1915 *found = true; 1998 *found = true;
1916 return s; 1999 return s;
1917 } 2000 }
1918 } 2001 }
1919 2002
1920 leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex( 2003 leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex(
1921 IndexedDBBackingStore::Transaction* transaction, 2004 IndexedDBBackingStore::Transaction* transaction,
1922 int64 database_id, 2005 int64 database_id,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 2084
2002 IndexedDBBackingStore::Cursor::Cursor( 2085 IndexedDBBackingStore::Cursor::Cursor(
2003 const IndexedDBBackingStore::Cursor* other) 2086 const IndexedDBBackingStore::Cursor* other)
2004 : transaction_(other->transaction_), 2087 : transaction_(other->transaction_),
2005 cursor_options_(other->cursor_options_), 2088 cursor_options_(other->cursor_options_),
2006 current_key_(new IndexedDBKey(*other->current_key_)) { 2089 current_key_(new IndexedDBKey(*other->current_key_)) {
2007 if (other->iterator_) { 2090 if (other->iterator_) {
2008 iterator_ = transaction_->CreateIterator(); 2091 iterator_ = transaction_->CreateIterator();
2009 2092
2010 if (other->iterator_->IsValid()) { 2093 if (other->iterator_->IsValid()) {
2011 iterator_->Seek(other->iterator_->Key()); 2094 leveldb::Status s = iterator_->Seek(other->iterator_->Key());
2095 // TODO(cmumford): Handle this error
2012 DCHECK(iterator_->IsValid()); 2096 DCHECK(iterator_->IsValid());
2013 } 2097 }
2014 } 2098 }
2015 } 2099 }
2016 2100
2017 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction, 2101 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction,
2018 const CursorOptions& cursor_options) 2102 const CursorOptions& cursor_options)
2019 : transaction_(transaction), cursor_options_(cursor_options) {} 2103 : transaction_(transaction), cursor_options_(cursor_options) {}
2020 IndexedDBBackingStore::Cursor::~Cursor() {} 2104 IndexedDBBackingStore::Cursor::~Cursor() {}
2021 2105
2022 bool IndexedDBBackingStore::Cursor::FirstSeek() { 2106 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status& s) {
2023 iterator_ = transaction_->CreateIterator(); 2107 iterator_ = transaction_->CreateIterator();
2024 if (cursor_options_.forward) 2108 if (cursor_options_.forward)
2025 iterator_->Seek(cursor_options_.low_key); 2109 s = iterator_->Seek(cursor_options_.low_key);
2026 else 2110 else
2027 iterator_->Seek(cursor_options_.high_key); 2111 s = iterator_->Seek(cursor_options_.high_key);
2112 if (!s.ok())
2113 return false;
2028 2114
2029 return Continue(0, READY); 2115 return Continue(0, READY, s);
2030 } 2116 }
2031 2117
2032 bool IndexedDBBackingStore::Cursor::Advance(uint32 count) { 2118 bool IndexedDBBackingStore::Cursor::Advance(uint32 count, leveldb::Status& s) {
2119 s = leveldb::Status::OK();
2033 while (count--) { 2120 while (count--) {
2034 if (!Continue()) 2121 if (!Continue(s))
2035 return false; 2122 return false;
2036 } 2123 }
2037 return true; 2124 return true;
2038 } 2125 }
2039 2126
2040 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, 2127 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key,
2041 const IndexedDBKey* primary_key, 2128 const IndexedDBKey* primary_key,
2042 IteratorState next_state) { 2129 IteratorState next_state,
2130 leveldb::Status& s) {
2043 DCHECK(!key || key->IsValid()); 2131 DCHECK(!key || key->IsValid());
2044 DCHECK(!primary_key || primary_key->IsValid()); 2132 DCHECK(!primary_key || primary_key->IsValid());
2133 s = leveldb::Status::OK();
2045 2134
2046 // TODO(alecflett): avoid a copy here? 2135 // TODO(alecflett): avoid a copy here?
2047 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey(); 2136 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey();
2048 2137
2049 bool first_iteration = true; 2138 bool first_iteration = true;
2050 2139
2051 // When iterating with PrevNoDuplicate, spec requires that the 2140 // When iterating with PrevNoDuplicate, spec requires that the
2052 // value we yield for each key is the first duplicate in forwards 2141 // value we yield for each key is the first duplicate in forwards
2053 // order. 2142 // order.
2054 IndexedDBKey last_duplicate_key; 2143 IndexedDBKey last_duplicate_key;
2055 2144
2056 bool forward = cursor_options_.forward; 2145 bool forward = cursor_options_.forward;
2057 2146
2058 for (;;) { 2147 for (;;) {
2059 if (next_state == SEEK) { 2148 if (next_state == SEEK) {
2060 // TODO(jsbell): Optimize seeking for reverse cursors as well. 2149 // TODO(jsbell): Optimize seeking for reverse cursors as well.
2061 if (first_iteration && key && forward) { 2150 if (first_iteration && key && forward) {
2062 std::string leveldb_key; 2151 std::string leveldb_key;
2063 if (primary_key) { 2152 if (primary_key) {
2064 leveldb_key = EncodeKey(*key, *primary_key); 2153 leveldb_key = EncodeKey(*key, *primary_key);
2065 } else { 2154 } else {
2066 leveldb_key = EncodeKey(*key); 2155 leveldb_key = EncodeKey(*key);
2067 } 2156 }
2068 iterator_->Seek(leveldb_key); 2157 s = iterator_->Seek(leveldb_key);
2069 first_iteration = false; 2158 first_iteration = false;
2070 } else if (forward) { 2159 } else if (forward) {
2071 iterator_->Next(); 2160 s = iterator_->Next();
2072 } else { 2161 } else {
2073 iterator_->Prev(); 2162 s = iterator_->Prev();
2074 } 2163 }
2164 if (!s.ok())
2165 return false;
2075 } else { 2166 } else {
2076 next_state = SEEK; // for subsequent iterations 2167 next_state = SEEK; // for subsequent iterations
2077 } 2168 }
2078 2169
2079 if (!iterator_->IsValid()) { 2170 if (!iterator_->IsValid()) {
2080 if (!forward && last_duplicate_key.IsValid()) { 2171 if (!forward && last_duplicate_key.IsValid()) {
2081 // We need to walk forward because we hit the end of 2172 // We need to walk forward because we hit the end of
2082 // the data. 2173 // the data.
2083 forward = true; 2174 forward = true;
2084 continue; 2175 continue;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 if (!lower_bound) { 2637 if (!lower_bound) {
2547 cursor_options->low_key = 2638 cursor_options->low_key =
2548 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 2639 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
2549 cursor_options->low_open = true; // Not included. 2640 cursor_options->low_open = true; // Not included.
2550 } else { 2641 } else {
2551 cursor_options->low_key = 2642 cursor_options->low_key =
2552 ObjectStoreDataKey::Encode(database_id, object_store_id, range.lower()); 2643 ObjectStoreDataKey::Encode(database_id, object_store_id, range.lower());
2553 cursor_options->low_open = range.lowerOpen(); 2644 cursor_options->low_open = range.lowerOpen();
2554 } 2645 }
2555 2646
2647 leveldb::Status s;
2648
2556 if (!upper_bound) { 2649 if (!upper_bound) {
2557 cursor_options->high_key = 2650 cursor_options->high_key =
2558 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 2651 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
2559 2652
2560 if (cursor_options->forward) { 2653 if (cursor_options->forward) {
2561 cursor_options->high_open = true; // Not included. 2654 cursor_options->high_open = true; // Not included.
2562 } else { 2655 } else {
2563 // We need a key that exists. 2656 // We need a key that exists.
2657 // TODO(cmumford): Handle this error
2564 if (!FindGreatestKeyLessThanOrEqual(transaction, 2658 if (!FindGreatestKeyLessThanOrEqual(transaction,
2565 cursor_options->high_key, 2659 cursor_options->high_key,
2566 &cursor_options->high_key)) 2660 &cursor_options->high_key,
2661 s))
2567 return false; 2662 return false;
2568 cursor_options->high_open = false; 2663 cursor_options->high_open = false;
2569 } 2664 }
2570 } else { 2665 } else {
2571 cursor_options->high_key = 2666 cursor_options->high_key =
2572 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper()); 2667 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper());
2573 cursor_options->high_open = range.upperOpen(); 2668 cursor_options->high_open = range.upperOpen();
2574 2669
2575 if (!cursor_options->forward) { 2670 if (!cursor_options->forward) {
2576 // For reverse cursors, we need a key that exists. 2671 // For reverse cursors, we need a key that exists.
2577 std::string found_high_key; 2672 std::string found_high_key;
2578 if (!FindGreatestKeyLessThanOrEqual( 2673 if (!FindGreatestKeyLessThanOrEqual(
2579 transaction, cursor_options->high_key, &found_high_key)) 2674 transaction, cursor_options->high_key, &found_high_key, s))
jsbell 2014/04/14 20:44:20 Add TODO here as well?
cmumford 2014/04/14 23:39:23 Done.
2580 return false; 2675 return false;
2581 2676
2582 // If the target key should not be included, but we end up with a smaller 2677 // If the target key should not be included, but we end up with a smaller
2583 // key, we should include that. 2678 // key, we should include that.
2584 if (cursor_options->high_open && 2679 if (cursor_options->high_open &&
2585 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0) 2680 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
2586 cursor_options->high_open = false; 2681 cursor_options->high_open = false;
2587 2682
2588 cursor_options->high_key = found_high_key; 2683 cursor_options->high_key = found_high_key;
2589 } 2684 }
(...skipping 29 matching lines...) Expand all
2619 if (!lower_bound) { 2714 if (!lower_bound) {
2620 cursor_options->low_key = 2715 cursor_options->low_key =
2621 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); 2716 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id);
2622 cursor_options->low_open = false; // Included. 2717 cursor_options->low_open = false; // Included.
2623 } else { 2718 } else {
2624 cursor_options->low_key = IndexDataKey::Encode( 2719 cursor_options->low_key = IndexDataKey::Encode(
2625 database_id, object_store_id, index_id, range.lower()); 2720 database_id, object_store_id, index_id, range.lower());
2626 cursor_options->low_open = range.lowerOpen(); 2721 cursor_options->low_open = range.lowerOpen();
2627 } 2722 }
2628 2723
2724 // TODO(cmumford): Handle this error
jsbell 2014/04/14 20:44:20 Nit: be consistent in placing the TODOs - near the
cmumford 2014/04/14 23:39:23 Done.
2725 leveldb::Status s;
2726
2629 if (!upper_bound) { 2727 if (!upper_bound) {
2630 cursor_options->high_key = 2728 cursor_options->high_key =
2631 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 2729 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
2632 cursor_options->high_open = false; // Included. 2730 cursor_options->high_open = false; // Included.
2633 2731
2634 if (!cursor_options->forward) { // We need a key that exists. 2732 if (!cursor_options->forward) { // We need a key that exists.
2635 if (!FindGreatestKeyLessThanOrEqual(transaction, 2733 if (!FindGreatestKeyLessThanOrEqual(transaction,
2636 cursor_options->high_key, 2734 cursor_options->high_key,
2637 &cursor_options->high_key)) 2735 &cursor_options->high_key,
2736 s))
2638 return false; 2737 return false;
2639 cursor_options->high_open = false; 2738 cursor_options->high_open = false;
2640 } 2739 }
2641 } else { 2740 } else {
2642 cursor_options->high_key = IndexDataKey::Encode( 2741 cursor_options->high_key = IndexDataKey::Encode(
2643 database_id, object_store_id, index_id, range.upper()); 2742 database_id, object_store_id, index_id, range.upper());
2644 cursor_options->high_open = range.upperOpen(); 2743 cursor_options->high_open = range.upperOpen();
2645 2744
2646 std::string found_high_key; 2745 std::string found_high_key;
2647 // Seek to the *last* key in the set of non-unique keys 2746 // Seek to the *last* key in the set of non-unique keys
2648 if (!FindGreatestKeyLessThanOrEqual( 2747 if (!FindGreatestKeyLessThanOrEqual(
2649 transaction, cursor_options->high_key, &found_high_key)) 2748 transaction, cursor_options->high_key, &found_high_key, s))
2650 return false; 2749 return false;
2651 2750
2652 // If the target key should not be included, but we end up with a smaller 2751 // If the target key should not be included, but we end up with a smaller
2653 // key, we should include that. 2752 // key, we should include that.
2654 if (cursor_options->high_open && 2753 if (cursor_options->high_open &&
2655 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0) 2754 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
2656 cursor_options->high_open = false; 2755 cursor_options->high_open = false;
2657 2756
2658 cursor_options->high_key = found_high_key; 2757 cursor_options->high_key = found_high_key;
2659 } 2758 }
2660 2759
2661 return true; 2760 return true;
2662 } 2761 }
2663 2762
2664 scoped_ptr<IndexedDBBackingStore::Cursor> 2763 scoped_ptr<IndexedDBBackingStore::Cursor>
2665 IndexedDBBackingStore::OpenObjectStoreCursor( 2764 IndexedDBBackingStore::OpenObjectStoreCursor(
2666 IndexedDBBackingStore::Transaction* transaction, 2765 IndexedDBBackingStore::Transaction* transaction,
2667 int64 database_id, 2766 int64 database_id,
2668 int64 object_store_id, 2767 int64 object_store_id,
2669 const IndexedDBKeyRange& range, 2768 const IndexedDBKeyRange& range,
2670 indexed_db::CursorDirection direction) { 2769 indexed_db::CursorDirection direction,
2770 leveldb::Status& s) {
2671 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor"); 2771 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor");
2772 s = leveldb::Status::OK();
2672 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2773 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2673 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2774 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2674 if (!ObjectStoreCursorOptions(leveldb_transaction, 2775 if (!ObjectStoreCursorOptions(leveldb_transaction,
2675 database_id, 2776 database_id,
2676 object_store_id, 2777 object_store_id,
2677 range, 2778 range,
2678 direction, 2779 direction,
2679 &cursor_options)) 2780 &cursor_options))
2680 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2781 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2681 scoped_ptr<ObjectStoreCursorImpl> cursor( 2782 scoped_ptr<ObjectStoreCursorImpl> cursor(
2682 new ObjectStoreCursorImpl(leveldb_transaction, cursor_options)); 2783 new ObjectStoreCursorImpl(leveldb_transaction, cursor_options));
2683 if (!cursor->FirstSeek()) 2784 if (!cursor->FirstSeek(s))
2684 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2785 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2685 2786
2686 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2787 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2687 } 2788 }
2688 2789
2689 scoped_ptr<IndexedDBBackingStore::Cursor> 2790 scoped_ptr<IndexedDBBackingStore::Cursor>
2690 IndexedDBBackingStore::OpenObjectStoreKeyCursor( 2791 IndexedDBBackingStore::OpenObjectStoreKeyCursor(
2691 IndexedDBBackingStore::Transaction* transaction, 2792 IndexedDBBackingStore::Transaction* transaction,
2692 int64 database_id, 2793 int64 database_id,
2693 int64 object_store_id, 2794 int64 object_store_id,
2694 const IndexedDBKeyRange& range, 2795 const IndexedDBKeyRange& range,
2695 indexed_db::CursorDirection direction) { 2796 indexed_db::CursorDirection direction,
2797 leveldb::Status& s) {
2696 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); 2798 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
2799 s = leveldb::Status::OK();
2697 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2800 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2698 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2801 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2699 if (!ObjectStoreCursorOptions(leveldb_transaction, 2802 if (!ObjectStoreCursorOptions(leveldb_transaction,
2700 database_id, 2803 database_id,
2701 object_store_id, 2804 object_store_id,
2702 range, 2805 range,
2703 direction, 2806 direction,
2704 &cursor_options)) 2807 &cursor_options))
2705 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2808 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2706 scoped_ptr<ObjectStoreKeyCursorImpl> cursor( 2809 scoped_ptr<ObjectStoreKeyCursorImpl> cursor(
2707 new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options)); 2810 new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options));
2708 if (!cursor->FirstSeek()) 2811 if (!cursor->FirstSeek(s))
2709 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2812 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2710 2813
2711 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2814 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2712 } 2815 }
2713 2816
2714 scoped_ptr<IndexedDBBackingStore::Cursor> 2817 scoped_ptr<IndexedDBBackingStore::Cursor>
2715 IndexedDBBackingStore::OpenIndexKeyCursor( 2818 IndexedDBBackingStore::OpenIndexKeyCursor(
2716 IndexedDBBackingStore::Transaction* transaction, 2819 IndexedDBBackingStore::Transaction* transaction,
2717 int64 database_id, 2820 int64 database_id,
2718 int64 object_store_id, 2821 int64 object_store_id,
2719 int64 index_id, 2822 int64 index_id,
2720 const IndexedDBKeyRange& range, 2823 const IndexedDBKeyRange& range,
2721 indexed_db::CursorDirection direction) { 2824 indexed_db::CursorDirection direction,
2825 leveldb::Status& s) {
2722 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); 2826 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
2827 s = leveldb::Status::OK();
2723 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2828 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2724 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2829 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2725 if (!IndexCursorOptions(leveldb_transaction, 2830 if (!IndexCursorOptions(leveldb_transaction,
2726 database_id, 2831 database_id,
2727 object_store_id, 2832 object_store_id,
2728 index_id, 2833 index_id,
2729 range, 2834 range,
2730 direction, 2835 direction,
2731 &cursor_options)) 2836 &cursor_options))
2732 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2837 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2733 scoped_ptr<IndexKeyCursorImpl> cursor( 2838 scoped_ptr<IndexKeyCursorImpl> cursor(
2734 new IndexKeyCursorImpl(leveldb_transaction, cursor_options)); 2839 new IndexKeyCursorImpl(leveldb_transaction, cursor_options));
2735 if (!cursor->FirstSeek()) 2840 if (!cursor->FirstSeek(s))
2736 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2841 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2737 2842
2738 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2843 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2739 } 2844 }
2740 2845
2741 scoped_ptr<IndexedDBBackingStore::Cursor> 2846 scoped_ptr<IndexedDBBackingStore::Cursor>
2742 IndexedDBBackingStore::OpenIndexCursor( 2847 IndexedDBBackingStore::OpenIndexCursor(
2743 IndexedDBBackingStore::Transaction* transaction, 2848 IndexedDBBackingStore::Transaction* transaction,
2744 int64 database_id, 2849 int64 database_id,
2745 int64 object_store_id, 2850 int64 object_store_id,
2746 int64 index_id, 2851 int64 index_id,
2747 const IndexedDBKeyRange& range, 2852 const IndexedDBKeyRange& range,
2748 indexed_db::CursorDirection direction) { 2853 indexed_db::CursorDirection direction,
2854 leveldb::Status& s) {
2749 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); 2855 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
2750 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2856 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2751 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2857 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2752 if (!IndexCursorOptions(leveldb_transaction, 2858 if (!IndexCursorOptions(leveldb_transaction,
2753 database_id, 2859 database_id,
2754 object_store_id, 2860 object_store_id,
2755 index_id, 2861 index_id,
2756 range, 2862 range,
2757 direction, 2863 direction,
2758 &cursor_options)) 2864 &cursor_options))
2759 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2865 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2760 scoped_ptr<IndexCursorImpl> cursor( 2866 scoped_ptr<IndexCursorImpl> cursor(
2761 new IndexCursorImpl(leveldb_transaction, cursor_options)); 2867 new IndexCursorImpl(leveldb_transaction, cursor_options));
2762 if (!cursor->FirstSeek()) 2868 if (!cursor->FirstSeek(s))
2763 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2869 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2764 2870
2765 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2871 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2766 } 2872 }
2767 2873
2768 IndexedDBBackingStore::Transaction::Transaction( 2874 IndexedDBBackingStore::Transaction::Transaction(
2769 IndexedDBBackingStore* backing_store) 2875 IndexedDBBackingStore* backing_store)
2770 : backing_store_(backing_store) {} 2876 : backing_store_(backing_store) {}
2771 2877
2772 IndexedDBBackingStore::Transaction::~Transaction() {} 2878 IndexedDBBackingStore::Transaction::~Transaction() {}
(...skipping 15 matching lines...) Expand all
2788 } 2894 }
2789 2895
2790 void IndexedDBBackingStore::Transaction::Rollback() { 2896 void IndexedDBBackingStore::Transaction::Rollback() {
2791 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); 2897 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
2792 DCHECK(transaction_.get()); 2898 DCHECK(transaction_.get());
2793 transaction_->Rollback(); 2899 transaction_->Rollback();
2794 transaction_ = NULL; 2900 transaction_ = NULL;
2795 } 2901 }
2796 2902
2797 } // namespace content 2903 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698