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

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: Added Status checks. 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 (s.ok() && db_schema_version < 2) {
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();
1071 if (!s.ok())
1072 break;
1051 continue; 1073 continue;
1052 } 1074 }
1053 1075
1054 int64 object_store_id = meta_data_key.ObjectStoreId(); 1076 int64 object_store_id = meta_data_key.ObjectStoreId();
1055 1077
1056 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1078 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1057 // simplify. 1079 // simplify.
1058 base::string16 object_store_name; 1080 base::string16 object_store_name;
1059 { 1081 {
1060 StringPiece slice(it->Value()); 1082 StringPiece slice(it->Value());
1061 if (!DecodeString(&slice, &object_store_name) || !slice.empty()) 1083 if (!DecodeString(&slice, &object_store_name) || !slice.empty())
1062 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1084 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1063 } 1085 }
1064 1086
1065 it->Next(); 1087 s = it->Next();
1088 if (!s.ok())
1089 break;
1066 if (!CheckObjectStoreAndMetaDataType(it.get(), 1090 if (!CheckObjectStoreAndMetaDataType(it.get(),
1067 stop_key, 1091 stop_key,
1068 object_store_id, 1092 object_store_id,
1069 ObjectStoreMetaDataKey::KEY_PATH)) { 1093 ObjectStoreMetaDataKey::KEY_PATH)) {
1070 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1094 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1071 break; 1095 break;
1072 } 1096 }
1073 IndexedDBKeyPath key_path; 1097 IndexedDBKeyPath key_path;
1074 { 1098 {
1075 StringPiece slice(it->Value()); 1099 StringPiece slice(it->Value());
1076 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1100 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1077 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1101 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1078 } 1102 }
1079 1103
1080 it->Next(); 1104 s = it->Next();
1105 if (!s.ok())
1106 break;
1081 if (!CheckObjectStoreAndMetaDataType( 1107 if (!CheckObjectStoreAndMetaDataType(
1082 it.get(), 1108 it.get(),
1083 stop_key, 1109 stop_key,
1084 object_store_id, 1110 object_store_id,
1085 ObjectStoreMetaDataKey::AUTO_INCREMENT)) { 1111 ObjectStoreMetaDataKey::AUTO_INCREMENT)) {
1086 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1112 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1087 break; 1113 break;
1088 } 1114 }
1089 bool auto_increment; 1115 bool auto_increment;
1090 { 1116 {
1091 StringPiece slice(it->Value()); 1117 StringPiece slice(it->Value());
1092 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) 1118 if (!DecodeBool(&slice, &auto_increment) || !slice.empty())
1093 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1119 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1094 } 1120 }
1095 1121
1096 it->Next(); // Is evicatble. 1122 s = it->Next(); // Is evicatble.
1123 if (!s.ok())
1124 break;
1097 if (!CheckObjectStoreAndMetaDataType(it.get(), 1125 if (!CheckObjectStoreAndMetaDataType(it.get(),
1098 stop_key, 1126 stop_key,
1099 object_store_id, 1127 object_store_id,
1100 ObjectStoreMetaDataKey::EVICTABLE)) { 1128 ObjectStoreMetaDataKey::EVICTABLE)) {
1101 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1129 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1102 break; 1130 break;
1103 } 1131 }
1104 1132
1105 it->Next(); // Last version. 1133 s = it->Next(); // Last version.
1134 if (!s.ok())
1135 break;
1106 if (!CheckObjectStoreAndMetaDataType( 1136 if (!CheckObjectStoreAndMetaDataType(
1107 it.get(), 1137 it.get(),
1108 stop_key, 1138 stop_key,
1109 object_store_id, 1139 object_store_id,
1110 ObjectStoreMetaDataKey::LAST_VERSION)) { 1140 ObjectStoreMetaDataKey::LAST_VERSION)) {
1111 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1141 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1112 break; 1142 break;
1113 } 1143 }
1114 1144
1115 it->Next(); // Maximum index id allocated. 1145 s = it->Next(); // Maximum index id allocated.
1146 if (!s.ok())
1147 break;
1116 if (!CheckObjectStoreAndMetaDataType( 1148 if (!CheckObjectStoreAndMetaDataType(
1117 it.get(), 1149 it.get(),
1118 stop_key, 1150 stop_key,
1119 object_store_id, 1151 object_store_id,
1120 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { 1152 ObjectStoreMetaDataKey::MAX_INDEX_ID)) {
1121 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1153 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1122 break; 1154 break;
1123 } 1155 }
1124 int64 max_index_id; 1156 int64 max_index_id;
1125 { 1157 {
1126 StringPiece slice(it->Value()); 1158 StringPiece slice(it->Value());
1127 if (!DecodeInt(&slice, &max_index_id) || !slice.empty()) 1159 if (!DecodeInt(&slice, &max_index_id) || !slice.empty())
1128 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1160 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1129 } 1161 }
1130 1162
1131 it->Next(); // [optional] has key path (is not null) 1163 s = it->Next(); // [optional] has key path (is not null)
1164 if (!s.ok())
1165 break;
1132 if (CheckObjectStoreAndMetaDataType(it.get(), 1166 if (CheckObjectStoreAndMetaDataType(it.get(),
1133 stop_key, 1167 stop_key,
1134 object_store_id, 1168 object_store_id,
1135 ObjectStoreMetaDataKey::HAS_KEY_PATH)) { 1169 ObjectStoreMetaDataKey::HAS_KEY_PATH)) {
1136 bool has_key_path; 1170 bool has_key_path;
1137 { 1171 {
1138 StringPiece slice(it->Value()); 1172 StringPiece slice(it->Value());
1139 if (!DecodeBool(&slice, &has_key_path)) 1173 if (!DecodeBool(&slice, &has_key_path))
1140 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1174 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1141 } 1175 }
1142 // This check accounts for two layers of legacy coding: 1176 // This check accounts for two layers of legacy coding:
1143 // (1) Initially, has_key_path was added to distinguish null vs. string. 1177 // (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. 1178 // (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. 1179 // So this check is only relevant for string-type key_paths.
1146 if (!has_key_path && 1180 if (!has_key_path &&
1147 (key_path.type() == blink::WebIDBKeyPathTypeString && 1181 (key_path.type() == blink::WebIDBKeyPathTypeString &&
1148 !key_path.string().empty())) { 1182 !key_path.string().empty())) {
1149 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1183 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1150 break; 1184 break;
1151 } 1185 }
1152 if (!has_key_path) 1186 if (!has_key_path)
1153 key_path = IndexedDBKeyPath(); 1187 key_path = IndexedDBKeyPath();
1154 it->Next(); 1188 s = it->Next();
1189 if (!s.ok())
1190 break;
1155 } 1191 }
1156 1192
1157 int64 key_generator_current_number = -1; 1193 int64 key_generator_current_number = -1;
1158 if (CheckObjectStoreAndMetaDataType( 1194 if (CheckObjectStoreAndMetaDataType(
1159 it.get(), 1195 it.get(),
1160 stop_key, 1196 stop_key,
1161 object_store_id, 1197 object_store_id,
1162 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { 1198 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) {
1163 StringPiece slice(it->Value()); 1199 StringPiece slice(it->Value());
1164 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) 1200 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty())
1165 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES); 1201 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_OBJECT_STORES);
1166 1202
1167 // TODO(jsbell): Return key_generator_current_number, cache in 1203 // TODO(jsbell): Return key_generator_current_number, cache in
1168 // object store, and write lazily to backing store. For now, 1204 // object store, and write lazily to backing store. For now,
1169 // just assert that if it was written it was valid. 1205 // just assert that if it was written it was valid.
1170 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber); 1206 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber);
1171 it->Next(); 1207 s = it->Next();
1208 if (!s.ok())
1209 break;
1172 } 1210 }
1173 1211
1174 IndexedDBObjectStoreMetadata metadata(object_store_name, 1212 IndexedDBObjectStoreMetadata metadata(object_store_name,
1175 object_store_id, 1213 object_store_id,
1176 key_path, 1214 key_path,
1177 auto_increment, 1215 auto_increment,
1178 max_index_id); 1216 max_index_id);
1179 leveldb::Status s = 1217 s = GetIndexes(database_id, object_store_id, &metadata.indexes);
1180 GetIndexes(database_id, object_store_id, &metadata.indexes);
1181 if (!s.ok()) 1218 if (!s.ok())
1182 return s; 1219 break;
1183 (*object_stores)[object_store_id] = metadata; 1220 (*object_stores)[object_store_id] = metadata;
1184 } 1221 }
1185 return leveldb::Status::OK(); 1222
1223 if (!s.ok())
1224 INTERNAL_READ_ERROR_UNTESTED(GET_OBJECT_STORES);
1225
1226 return s;
1186 } 1227 }
1187 1228
1188 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId( 1229 WARN_UNUSED_RESULT static leveldb::Status SetMaxObjectStoreId(
1189 LevelDBTransaction* transaction, 1230 LevelDBTransaction* transaction,
1190 int64 database_id, 1231 int64 database_id,
1191 int64 object_store_id) { 1232 int64 object_store_id) {
1192 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode( 1233 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
1193 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); 1234 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
1194 int64 max_object_store_id = -1; 1235 int64 max_object_store_id = -1;
1195 leveldb::Status s = GetMaxObjectStoreId( 1236 leveldb::Status s = GetMaxObjectStoreId(
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 &found); 1320 &found);
1280 if (!s.ok()) { 1321 if (!s.ok()) {
1281 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1322 INTERNAL_READ_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1282 return s; 1323 return s;
1283 } 1324 }
1284 if (!found) { 1325 if (!found) {
1285 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE); 1326 INTERNAL_CONSISTENCY_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1286 return InternalInconsistencyStatus(); 1327 return InternalInconsistencyStatus();
1287 } 1328 }
1288 1329
1289 DeleteRange( 1330 s = DeleteRange(
1290 leveldb_transaction, 1331 leveldb_transaction,
1291 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), 1332 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0),
1292 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1333 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1293 1334
1294 leveldb_transaction->Remove( 1335 if (s.ok()) {
1295 ObjectStoreNamesKey::Encode(database_id, object_store_name)); 1336 leveldb_transaction->Remove(
1337 ObjectStoreNamesKey::Encode(database_id, object_store_name));
1296 1338
1297 DeleteRange(leveldb_transaction, 1339 s = DeleteRange(
1298 IndexFreeListKey::Encode(database_id, object_store_id, 0), 1340 leveldb_transaction,
1299 IndexFreeListKey::EncodeMaxKey(database_id, object_store_id)); 1341 IndexFreeListKey::Encode(database_id, object_store_id, 0),
1300 DeleteRange(leveldb_transaction, 1342 IndexFreeListKey::EncodeMaxKey(database_id, object_store_id));
1301 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0), 1343 }
1302 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1344
1345 if (s.ok()) {
1346 s = DeleteRange(
1347 leveldb_transaction,
1348 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0),
1349 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1350 }
1351
1352 if (!s.ok()) {
1353 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_OBJECT_STORE);
1354 return s;
1355 }
1303 1356
1304 return ClearObjectStore(transaction, database_id, object_store_id); 1357 return ClearObjectStore(transaction, database_id, object_store_id);
1305 } 1358 }
1306 1359
1307 leveldb::Status IndexedDBBackingStore::GetRecord( 1360 leveldb::Status IndexedDBBackingStore::GetRecord(
1308 IndexedDBBackingStore::Transaction* transaction, 1361 IndexedDBBackingStore::Transaction* transaction,
1309 int64 database_id, 1362 int64 database_id,
1310 int64 object_store_id, 1363 int64 object_store_id,
1311 const IndexedDBKey& key, 1364 const IndexedDBKey& key,
1312 IndexedDBValue* record) { 1365 IndexedDBValue* record) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1422 int64 database_id, 1475 int64 database_id,
1423 int64 object_store_id) { 1476 int64 object_store_id) {
1424 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); 1477 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore");
1425 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1478 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1426 return InvalidDBKeyStatus(); 1479 return InvalidDBKeyStatus();
1427 const std::string start_key = 1480 const std::string start_key =
1428 KeyPrefix(database_id, object_store_id).Encode(); 1481 KeyPrefix(database_id, object_store_id).Encode();
1429 const std::string stop_key = 1482 const std::string stop_key =
1430 KeyPrefix(database_id, object_store_id + 1).Encode(); 1483 KeyPrefix(database_id, object_store_id + 1).Encode();
1431 1484
1432 DeleteRange(transaction->transaction(), start_key, stop_key); 1485 leveldb::Status s =
1433 return leveldb::Status::OK(); 1486 DeleteRange(transaction->transaction(), start_key, stop_key);
1487 if (!s.ok())
1488 INTERNAL_WRITE_ERROR_UNTESTED(CLEAR_OBJECT_STORE);
1489 return s;
1434 } 1490 }
1435 1491
1436 leveldb::Status IndexedDBBackingStore::DeleteRecord( 1492 leveldb::Status IndexedDBBackingStore::DeleteRecord(
1437 IndexedDBBackingStore::Transaction* transaction, 1493 IndexedDBBackingStore::Transaction* transaction,
1438 int64 database_id, 1494 int64 database_id,
1439 int64 object_store_id, 1495 int64 object_store_id,
1440 const RecordIdentifier& record_identifier) { 1496 const RecordIdentifier& record_identifier) {
1441 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); 1497 IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
1442 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1498 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1443 return InvalidDBKeyStatus(); 1499 return InvalidDBKeyStatus();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1493 // key generator state must be preserved. 1549 // key generator state must be preserved.
1494 // TODO(jsbell): Fix this for all stores on database open? 1550 // TODO(jsbell): Fix this for all stores on database open?
1495 const std::string start_key = 1551 const std::string start_key =
1496 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 1552 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
1497 const std::string stop_key = 1553 const std::string stop_key =
1498 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 1554 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
1499 1555
1500 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1556 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1501 int64 max_numeric_key = 0; 1557 int64 max_numeric_key = 0;
1502 1558
1503 for (it->Seek(start_key); 1559 for (s = it->Seek(start_key);
1504 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0; 1560 s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
1505 it->Next()) { 1561 s = it->Next()) {
1506 StringPiece slice(it->Key()); 1562 StringPiece slice(it->Key());
1507 ObjectStoreDataKey data_key; 1563 ObjectStoreDataKey data_key;
1508 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) { 1564 if (!ObjectStoreDataKey::Decode(&slice, &data_key)) {
1509 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER); 1565 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1510 return InternalInconsistencyStatus(); 1566 return InternalInconsistencyStatus();
1511 } 1567 }
1512 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); 1568 scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
1513 if (user_key->type() == blink::WebIDBKeyTypeNumber) { 1569 if (user_key->type() == blink::WebIDBKeyTypeNumber) {
1514 int64 n = static_cast<int64>(user_key->number()); 1570 int64 n = static_cast<int64>(user_key->number());
1515 if (n > max_numeric_key) 1571 if (n > max_numeric_key)
1516 max_numeric_key = n; 1572 max_numeric_key = n;
1517 } 1573 }
1518 } 1574 }
1519 1575
1520 *key_generator_current_number = max_numeric_key + 1; 1576 if (s.ok())
1577 *key_generator_current_number = max_numeric_key + 1;
1578 else
1579 INTERNAL_READ_ERROR_UNTESTED(GET_KEY_GENERATOR_CURRENT_NUMBER);
1580
1521 return s; 1581 return s;
1522 } 1582 }
1523 1583
1524 leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber( 1584 leveldb::Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
1525 IndexedDBBackingStore::Transaction* transaction, 1585 IndexedDBBackingStore::Transaction* transaction,
1526 int64 database_id, 1586 int64 database_id,
1527 int64 object_store_id, 1587 int64 object_store_id,
1528 int64 new_number, 1588 int64 new_number,
1529 bool check_current) { 1589 bool check_current) {
1530 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1590 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)) 1677 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1618 return InvalidDBKeyStatus(); 1678 return InvalidDBKeyStatus();
1619 const std::string start_key = 1679 const std::string start_key =
1620 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0); 1680 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0);
1621 const std::string stop_key = 1681 const std::string stop_key =
1622 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0); 1682 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0);
1623 1683
1624 DCHECK(indexes->empty()); 1684 DCHECK(indexes->empty());
1625 1685
1626 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1686 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1627 it->Seek(start_key); 1687 leveldb::Status s = it->Seek(start_key);
1628 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) { 1688 while (s.ok() && it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
1629 StringPiece slice(it->Key()); 1689 StringPiece slice(it->Key());
1630 IndexMetaDataKey meta_data_key; 1690 IndexMetaDataKey meta_data_key;
1631 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key); 1691 bool ok = IndexMetaDataKey::Decode(&slice, &meta_data_key);
1632 DCHECK(ok); 1692 DCHECK(ok);
1633 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) { 1693 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) {
1634 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1694 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1635 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail 1695 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail
1636 // the load. 1696 // the load.
1637 it->Next(); 1697 s = it->Next();
1698 if (!s.ok())
1699 break;
1638 continue; 1700 continue;
1639 } 1701 }
1640 1702
1641 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1703 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1642 // simplify. 1704 // simplify.
1643 int64 index_id = meta_data_key.IndexId(); 1705 int64 index_id = meta_data_key.IndexId();
1644 base::string16 index_name; 1706 base::string16 index_name;
1645 { 1707 {
1646 StringPiece slice(it->Value()); 1708 StringPiece slice(it->Value());
1647 if (!DecodeString(&slice, &index_name) || !slice.empty()) 1709 if (!DecodeString(&slice, &index_name) || !slice.empty())
1648 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1710 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1649 } 1711 }
1650 1712
1651 it->Next(); // unique flag 1713 s = it->Next(); // unique flag
1714 if (!s.ok())
1715 break;
1652 if (!CheckIndexAndMetaDataKey( 1716 if (!CheckIndexAndMetaDataKey(
1653 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { 1717 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) {
1654 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1718 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1655 break; 1719 break;
1656 } 1720 }
1657 bool index_unique; 1721 bool index_unique;
1658 { 1722 {
1659 StringPiece slice(it->Value()); 1723 StringPiece slice(it->Value());
1660 if (!DecodeBool(&slice, &index_unique) || !slice.empty()) 1724 if (!DecodeBool(&slice, &index_unique) || !slice.empty())
1661 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1725 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1662 } 1726 }
1663 1727
1664 it->Next(); // key_path 1728 s = it->Next(); // key_path
1729 if (!s.ok())
1730 break;
1665 if (!CheckIndexAndMetaDataKey( 1731 if (!CheckIndexAndMetaDataKey(
1666 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { 1732 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) {
1667 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1733 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1668 break; 1734 break;
1669 } 1735 }
1670 IndexedDBKeyPath key_path; 1736 IndexedDBKeyPath key_path;
1671 { 1737 {
1672 StringPiece slice(it->Value()); 1738 StringPiece slice(it->Value());
1673 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1739 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1674 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1740 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1675 } 1741 }
1676 1742
1677 it->Next(); // [optional] multi_entry flag 1743 s = it->Next(); // [optional] multi_entry flag
1744 if (!s.ok())
1745 break;
1678 bool index_multi_entry = false; 1746 bool index_multi_entry = false;
1679 if (CheckIndexAndMetaDataKey( 1747 if (CheckIndexAndMetaDataKey(
1680 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { 1748 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) {
1681 StringPiece slice(it->Value()); 1749 StringPiece slice(it->Value());
1682 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty()) 1750 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty())
1683 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES); 1751 INTERNAL_CONSISTENCY_ERROR_UNTESTED(GET_INDEXES);
1684 1752
1685 it->Next(); 1753 s = it->Next();
1754 if (!s.ok())
1755 break;
1686 } 1756 }
1687 1757
1688 (*indexes)[index_id] = IndexedDBIndexMetadata( 1758 (*indexes)[index_id] = IndexedDBIndexMetadata(
1689 index_name, index_id, key_path, index_unique, index_multi_entry); 1759 index_name, index_id, key_path, index_unique, index_multi_entry);
1690 } 1760 }
1691 return leveldb::Status::OK(); 1761
1762 if (!s.ok())
1763 INTERNAL_READ_ERROR_UNTESTED(GET_INDEXES);
1764
1765 return s;
1692 } 1766 }
1693 1767
1694 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId( 1768 WARN_UNUSED_RESULT static leveldb::Status SetMaxIndexId(
1695 LevelDBTransaction* transaction, 1769 LevelDBTransaction* transaction,
1696 int64 database_id, 1770 int64 database_id,
1697 int64 object_store_id, 1771 int64 object_store_id,
1698 int64 index_id) { 1772 int64 index_id) {
1699 int64 max_index_id = -1; 1773 int64 max_index_id = -1;
1700 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode( 1774 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode(
1701 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); 1775 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) { 1834 int64 index_id) {
1761 IDB_TRACE("IndexedDBBackingStore::DeleteIndex"); 1835 IDB_TRACE("IndexedDBBackingStore::DeleteIndex");
1762 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1836 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1763 return InvalidDBKeyStatus(); 1837 return InvalidDBKeyStatus();
1764 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 1838 LevelDBTransaction* leveldb_transaction = transaction->transaction();
1765 1839
1766 const std::string index_meta_data_start = 1840 const std::string index_meta_data_start =
1767 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0); 1841 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0);
1768 const std::string index_meta_data_end = 1842 const std::string index_meta_data_end =
1769 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 1843 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
1770 DeleteRange(leveldb_transaction, index_meta_data_start, index_meta_data_end); 1844 leveldb::Status s = DeleteRange(
1845 leveldb_transaction, index_meta_data_start, index_meta_data_end);
1771 1846
1772 const std::string index_data_start = 1847 if (s.ok()) {
1773 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); 1848 const std::string index_data_start =
1774 const std::string index_data_end = 1849 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id);
1775 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 1850 const std::string index_data_end =
1776 DeleteRange(leveldb_transaction, index_data_start, index_data_end); 1851 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
1777 return leveldb::Status::OK(); 1852 s = DeleteRange(leveldb_transaction, index_data_start, index_data_end);
1853 }
1854
1855 if (!s.ok())
1856 INTERNAL_WRITE_ERROR_UNTESTED(DELETE_INDEX);
1857
1858 return s;
1778 } 1859 }
1779 1860
1780 leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord( 1861 leveldb::Status IndexedDBBackingStore::PutIndexDataForRecord(
1781 IndexedDBBackingStore::Transaction* transaction, 1862 IndexedDBBackingStore::Transaction* transaction,
1782 int64 database_id, 1863 int64 database_id,
1783 int64 object_store_id, 1864 int64 object_store_id,
1784 int64 index_id, 1865 int64 index_id,
1785 const IndexedDBKey& key, 1866 const IndexedDBKey& key,
1786 const RecordIdentifier& record_identifier) { 1867 const RecordIdentifier& record_identifier) {
1787 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord"); 1868 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord");
(...skipping 15 matching lines...) Expand all
1803 std::string data; 1884 std::string data;
1804 EncodeVarInt(record_identifier.version(), &data); 1885 EncodeVarInt(record_identifier.version(), &data);
1805 data.append(record_identifier.primary_key()); 1886 data.append(record_identifier.primary_key());
1806 1887
1807 transaction->transaction()->Put(index_data_key, &data); 1888 transaction->transaction()->Put(index_data_key, &data);
1808 return leveldb::Status::OK(); 1889 return leveldb::Status::OK();
1809 } 1890 }
1810 1891
1811 static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, 1892 static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction,
1812 const std::string& target, 1893 const std::string& target,
1813 std::string* found_key) { 1894 std::string* found_key,
1895 leveldb::Status& s) {
1814 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 1896 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
1815 it->Seek(target); 1897 s = it->Seek(target);
1898 if (!s.ok())
1899 return false;
1816 1900
1817 if (!it->IsValid()) { 1901 if (!it->IsValid()) {
1818 it->SeekToLast(); 1902 s = it->SeekToLast();
1819 if (!it->IsValid()) 1903 if (!s.ok() || !it->IsValid())
1820 return false; 1904 return false;
1821 } 1905 }
1822 1906
1823 while (CompareIndexKeys(it->Key(), target) > 0) { 1907 while (CompareIndexKeys(it->Key(), target) > 0) {
1824 it->Prev(); 1908 s = it->Prev();
1825 if (!it->IsValid()) 1909 if (!s.ok() || !it->IsValid())
1826 return false; 1910 return false;
1827 } 1911 }
1828 1912
1829 do { 1913 do {
1830 *found_key = it->Key().as_string(); 1914 *found_key = it->Key().as_string();
1831 1915
1832 // There can be several index keys that compare equal. We want the last one. 1916 // There can be several index keys that compare equal. We want the last one.
1833 it->Next(); 1917 s = it->Next();
1834 } while (it->IsValid() && !CompareIndexKeys(it->Key(), target)); 1918 } while (s.ok() && it->IsValid() && !CompareIndexKeys(it->Key(), target));
1835 1919
1836 return true; 1920 return true;
1837 } 1921 }
1838 1922
1839 static leveldb::Status VersionExists(LevelDBTransaction* transaction, 1923 static leveldb::Status VersionExists(LevelDBTransaction* transaction,
1840 int64 database_id, 1924 int64 database_id,
1841 int64 object_store_id, 1925 int64 object_store_id,
1842 int64 version, 1926 int64 version,
1843 const std::string& encoded_primary_key, 1927 const std::string& encoded_primary_key,
1844 bool* exists) { 1928 bool* exists) {
(...skipping 28 matching lines...) Expand all
1873 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex"); 1957 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex");
1874 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id)); 1958 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id));
1875 1959
1876 DCHECK(found_encoded_primary_key->empty()); 1960 DCHECK(found_encoded_primary_key->empty());
1877 *found = false; 1961 *found = false;
1878 1962
1879 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 1963 LevelDBTransaction* leveldb_transaction = transaction->transaction();
1880 const std::string leveldb_key = 1964 const std::string leveldb_key =
1881 IndexDataKey::Encode(database_id, object_store_id, index_id, key); 1965 IndexDataKey::Encode(database_id, object_store_id, index_id, key);
1882 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1966 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1883 it->Seek(leveldb_key); 1967 leveldb::Status s = it->Seek(leveldb_key);
1968 if (!s.ok()) {
1969 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX);
1970 return s;
1971 }
1884 1972
1885 for (;;) { 1973 for (;;) {
1886 if (!it->IsValid()) 1974 if (!it->IsValid())
1887 return leveldb::Status::OK(); 1975 return leveldb::Status::OK();
1888 if (CompareIndexKeys(it->Key(), leveldb_key) > 0) 1976 if (CompareIndexKeys(it->Key(), leveldb_key) > 0)
1889 return leveldb::Status::OK(); 1977 return leveldb::Status::OK();
1890 1978
1891 StringPiece slice(it->Value()); 1979 StringPiece slice(it->Value());
1892 1980
1893 int64 version; 1981 int64 version;
1894 if (!DecodeVarInt(&slice, &version)) { 1982 if (!DecodeVarInt(&slice, &version)) {
1895 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX); 1983 INTERNAL_READ_ERROR_UNTESTED(FIND_KEY_IN_INDEX);
1896 return InternalInconsistencyStatus(); 1984 return InternalInconsistencyStatus();
1897 } 1985 }
1898 *found_encoded_primary_key = slice.as_string(); 1986 *found_encoded_primary_key = slice.as_string();
1899 1987
1900 bool exists = false; 1988 bool exists = false;
1901 leveldb::Status s = VersionExists(leveldb_transaction, 1989 s = VersionExists(leveldb_transaction,
1902 database_id, 1990 database_id,
1903 object_store_id, 1991 object_store_id,
1904 version, 1992 version,
1905 *found_encoded_primary_key, 1993 *found_encoded_primary_key,
1906 &exists); 1994 &exists);
1907 if (!s.ok()) 1995 if (!s.ok())
1908 return s; 1996 return s;
1909 if (!exists) { 1997 if (!exists) {
1910 // Delete stale index data entry and continue. 1998 // Delete stale index data entry and continue.
1911 leveldb_transaction->Remove(it->Key()); 1999 leveldb_transaction->Remove(it->Key());
1912 it->Next(); 2000 s = it->Next();
1913 continue; 2001 continue;
1914 } 2002 }
1915 *found = true; 2003 *found = true;
1916 return s; 2004 return s;
1917 } 2005 }
1918 } 2006 }
1919 2007
1920 leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex( 2008 leveldb::Status IndexedDBBackingStore::GetPrimaryKeyViaIndex(
1921 IndexedDBBackingStore::Transaction* transaction, 2009 IndexedDBBackingStore::Transaction* transaction,
1922 int64 database_id, 2010 int64 database_id,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2001 2089
2002 IndexedDBBackingStore::Cursor::Cursor( 2090 IndexedDBBackingStore::Cursor::Cursor(
2003 const IndexedDBBackingStore::Cursor* other) 2091 const IndexedDBBackingStore::Cursor* other)
2004 : transaction_(other->transaction_), 2092 : transaction_(other->transaction_),
2005 cursor_options_(other->cursor_options_), 2093 cursor_options_(other->cursor_options_),
2006 current_key_(new IndexedDBKey(*other->current_key_)) { 2094 current_key_(new IndexedDBKey(*other->current_key_)) {
2007 if (other->iterator_) { 2095 if (other->iterator_) {
2008 iterator_ = transaction_->CreateIterator(); 2096 iterator_ = transaction_->CreateIterator();
2009 2097
2010 if (other->iterator_->IsValid()) { 2098 if (other->iterator_->IsValid()) {
2011 iterator_->Seek(other->iterator_->Key()); 2099 leveldb::Status s = iterator_->Seek(other->iterator_->Key());
2100 // TODO(cmumford): Handle this error (crbug.com/363397)
2012 DCHECK(iterator_->IsValid()); 2101 DCHECK(iterator_->IsValid());
2013 } 2102 }
2014 } 2103 }
2015 } 2104 }
2016 2105
2017 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction, 2106 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction,
2018 const CursorOptions& cursor_options) 2107 const CursorOptions& cursor_options)
2019 : transaction_(transaction), cursor_options_(cursor_options) {} 2108 : transaction_(transaction), cursor_options_(cursor_options) {}
2020 IndexedDBBackingStore::Cursor::~Cursor() {} 2109 IndexedDBBackingStore::Cursor::~Cursor() {}
2021 2110
2022 bool IndexedDBBackingStore::Cursor::FirstSeek() { 2111 bool IndexedDBBackingStore::Cursor::FirstSeek(leveldb::Status* s) {
2023 iterator_ = transaction_->CreateIterator(); 2112 iterator_ = transaction_->CreateIterator();
2024 if (cursor_options_.forward) 2113 if (cursor_options_.forward)
2025 iterator_->Seek(cursor_options_.low_key); 2114 *s = iterator_->Seek(cursor_options_.low_key);
2026 else 2115 else
2027 iterator_->Seek(cursor_options_.high_key); 2116 *s = iterator_->Seek(cursor_options_.high_key);
2117 if (!s->ok())
2118 return false;
2028 2119
2029 return Continue(0, READY); 2120 return Continue(0, READY, s);
2030 } 2121 }
2031 2122
2032 bool IndexedDBBackingStore::Cursor::Advance(uint32 count) { 2123 bool IndexedDBBackingStore::Cursor::Advance(uint32 count, leveldb::Status* s) {
2124 *s = leveldb::Status::OK();
2033 while (count--) { 2125 while (count--) {
2034 if (!Continue()) 2126 if (!Continue(s))
2035 return false; 2127 return false;
2036 } 2128 }
2037 return true; 2129 return true;
2038 } 2130 }
2039 2131
2040 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, 2132 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key,
2041 const IndexedDBKey* primary_key, 2133 const IndexedDBKey* primary_key,
2042 IteratorState next_state) { 2134 IteratorState next_state,
2135 leveldb::Status* s) {
2043 DCHECK(!key || key->IsValid()); 2136 DCHECK(!key || key->IsValid());
2044 DCHECK(!primary_key || primary_key->IsValid()); 2137 DCHECK(!primary_key || primary_key->IsValid());
2138 *s = leveldb::Status::OK();
2045 2139
2046 // TODO(alecflett): avoid a copy here? 2140 // TODO(alecflett): avoid a copy here?
2047 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey(); 2141 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey();
2048 2142
2049 bool first_iteration = true; 2143 bool first_iteration = true;
2050 2144
2051 // When iterating with PrevNoDuplicate, spec requires that the 2145 // When iterating with PrevNoDuplicate, spec requires that the
2052 // value we yield for each key is the first duplicate in forwards 2146 // value we yield for each key is the first duplicate in forwards
2053 // order. 2147 // order.
2054 IndexedDBKey last_duplicate_key; 2148 IndexedDBKey last_duplicate_key;
2055 2149
2056 bool forward = cursor_options_.forward; 2150 bool forward = cursor_options_.forward;
2057 2151
2058 for (;;) { 2152 for (;;) {
2059 if (next_state == SEEK) { 2153 if (next_state == SEEK) {
2060 // TODO(jsbell): Optimize seeking for reverse cursors as well. 2154 // TODO(jsbell): Optimize seeking for reverse cursors as well.
2061 if (first_iteration && key && forward) { 2155 if (first_iteration && key && forward) {
2062 std::string leveldb_key; 2156 std::string leveldb_key;
2063 if (primary_key) { 2157 if (primary_key) {
2064 leveldb_key = EncodeKey(*key, *primary_key); 2158 leveldb_key = EncodeKey(*key, *primary_key);
2065 } else { 2159 } else {
2066 leveldb_key = EncodeKey(*key); 2160 leveldb_key = EncodeKey(*key);
2067 } 2161 }
2068 iterator_->Seek(leveldb_key); 2162 *s = iterator_->Seek(leveldb_key);
2069 first_iteration = false; 2163 first_iteration = false;
2070 } else if (forward) { 2164 } else if (forward) {
2071 iterator_->Next(); 2165 *s = iterator_->Next();
2072 } else { 2166 } else {
2073 iterator_->Prev(); 2167 *s = iterator_->Prev();
2074 } 2168 }
2169 if (!s->ok())
2170 return false;
2075 } else { 2171 } else {
2076 next_state = SEEK; // for subsequent iterations 2172 next_state = SEEK; // for subsequent iterations
2077 } 2173 }
2078 2174
2079 if (!iterator_->IsValid()) { 2175 if (!iterator_->IsValid()) {
2080 if (!forward && last_duplicate_key.IsValid()) { 2176 if (!forward && last_duplicate_key.IsValid()) {
2081 // We need to walk forward because we hit the end of 2177 // We need to walk forward because we hit the end of
2082 // the data. 2178 // the data.
2083 forward = true; 2179 forward = true;
2084 continue; 2180 continue;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 if (!lower_bound) { 2642 if (!lower_bound) {
2547 cursor_options->low_key = 2643 cursor_options->low_key =
2548 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 2644 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
2549 cursor_options->low_open = true; // Not included. 2645 cursor_options->low_open = true; // Not included.
2550 } else { 2646 } else {
2551 cursor_options->low_key = 2647 cursor_options->low_key =
2552 ObjectStoreDataKey::Encode(database_id, object_store_id, range.lower()); 2648 ObjectStoreDataKey::Encode(database_id, object_store_id, range.lower());
2553 cursor_options->low_open = range.lowerOpen(); 2649 cursor_options->low_open = range.lowerOpen();
2554 } 2650 }
2555 2651
2652 leveldb::Status s;
2653
2556 if (!upper_bound) { 2654 if (!upper_bound) {
2557 cursor_options->high_key = 2655 cursor_options->high_key =
2558 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 2656 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
2559 2657
2560 if (cursor_options->forward) { 2658 if (cursor_options->forward) {
2561 cursor_options->high_open = true; // Not included. 2659 cursor_options->high_open = true; // Not included.
2562 } else { 2660 } else {
2563 // We need a key that exists. 2661 // We need a key that exists.
2662 // TODO(cmumford): Handle this error (crbug.com/363397)
2564 if (!FindGreatestKeyLessThanOrEqual(transaction, 2663 if (!FindGreatestKeyLessThanOrEqual(transaction,
2565 cursor_options->high_key, 2664 cursor_options->high_key,
2566 &cursor_options->high_key)) 2665 &cursor_options->high_key,
2666 s))
2567 return false; 2667 return false;
2568 cursor_options->high_open = false; 2668 cursor_options->high_open = false;
2569 } 2669 }
2570 } else { 2670 } else {
2571 cursor_options->high_key = 2671 cursor_options->high_key =
2572 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper()); 2672 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper());
2573 cursor_options->high_open = range.upperOpen(); 2673 cursor_options->high_open = range.upperOpen();
2574 2674
2575 if (!cursor_options->forward) { 2675 if (!cursor_options->forward) {
2576 // For reverse cursors, we need a key that exists. 2676 // For reverse cursors, we need a key that exists.
2577 std::string found_high_key; 2677 std::string found_high_key;
2678 // TODO(cmumford): Handle this error (crbug.com/363397)
2578 if (!FindGreatestKeyLessThanOrEqual( 2679 if (!FindGreatestKeyLessThanOrEqual(
2579 transaction, cursor_options->high_key, &found_high_key)) 2680 transaction, cursor_options->high_key, &found_high_key, s))
2580 return false; 2681 return false;
2581 2682
2582 // If the target key should not be included, but we end up with a smaller 2683 // If the target key should not be included, but we end up with a smaller
2583 // key, we should include that. 2684 // key, we should include that.
2584 if (cursor_options->high_open && 2685 if (cursor_options->high_open &&
2585 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0) 2686 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
2586 cursor_options->high_open = false; 2687 cursor_options->high_open = false;
2587 2688
2588 cursor_options->high_key = found_high_key; 2689 cursor_options->high_key = found_high_key;
2589 } 2690 }
(...skipping 29 matching lines...) Expand all
2619 if (!lower_bound) { 2720 if (!lower_bound) {
2620 cursor_options->low_key = 2721 cursor_options->low_key =
2621 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); 2722 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id);
2622 cursor_options->low_open = false; // Included. 2723 cursor_options->low_open = false; // Included.
2623 } else { 2724 } else {
2624 cursor_options->low_key = IndexDataKey::Encode( 2725 cursor_options->low_key = IndexDataKey::Encode(
2625 database_id, object_store_id, index_id, range.lower()); 2726 database_id, object_store_id, index_id, range.lower());
2626 cursor_options->low_open = range.lowerOpen(); 2727 cursor_options->low_open = range.lowerOpen();
2627 } 2728 }
2628 2729
2730 leveldb::Status s;
2731
2629 if (!upper_bound) { 2732 if (!upper_bound) {
2630 cursor_options->high_key = 2733 cursor_options->high_key =
2631 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 2734 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
2632 cursor_options->high_open = false; // Included. 2735 cursor_options->high_open = false; // Included.
2633 2736
2634 if (!cursor_options->forward) { // We need a key that exists. 2737 if (!cursor_options->forward) { // We need a key that exists.
2635 if (!FindGreatestKeyLessThanOrEqual(transaction, 2738 if (!FindGreatestKeyLessThanOrEqual(transaction,
2636 cursor_options->high_key, 2739 cursor_options->high_key,
2637 &cursor_options->high_key)) 2740 &cursor_options->high_key,
2741 s))
2638 return false; 2742 return false;
2639 cursor_options->high_open = false; 2743 cursor_options->high_open = false;
2640 } 2744 }
2641 } else { 2745 } else {
2642 cursor_options->high_key = IndexDataKey::Encode( 2746 cursor_options->high_key = IndexDataKey::Encode(
2643 database_id, object_store_id, index_id, range.upper()); 2747 database_id, object_store_id, index_id, range.upper());
2644 cursor_options->high_open = range.upperOpen(); 2748 cursor_options->high_open = range.upperOpen();
2645 2749
2646 std::string found_high_key; 2750 std::string found_high_key;
2647 // Seek to the *last* key in the set of non-unique keys 2751 // Seek to the *last* key in the set of non-unique keys
2752 // TODO(cmumford): Handle this error (crbug.com/363397)
2648 if (!FindGreatestKeyLessThanOrEqual( 2753 if (!FindGreatestKeyLessThanOrEqual(
2649 transaction, cursor_options->high_key, &found_high_key)) 2754 transaction, cursor_options->high_key, &found_high_key, s))
2650 return false; 2755 return false;
2651 2756
2652 // If the target key should not be included, but we end up with a smaller 2757 // If the target key should not be included, but we end up with a smaller
2653 // key, we should include that. 2758 // key, we should include that.
2654 if (cursor_options->high_open && 2759 if (cursor_options->high_open &&
2655 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0) 2760 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
2656 cursor_options->high_open = false; 2761 cursor_options->high_open = false;
2657 2762
2658 cursor_options->high_key = found_high_key; 2763 cursor_options->high_key = found_high_key;
2659 } 2764 }
2660 2765
2661 return true; 2766 return true;
2662 } 2767 }
2663 2768
2664 scoped_ptr<IndexedDBBackingStore::Cursor> 2769 scoped_ptr<IndexedDBBackingStore::Cursor>
2665 IndexedDBBackingStore::OpenObjectStoreCursor( 2770 IndexedDBBackingStore::OpenObjectStoreCursor(
2666 IndexedDBBackingStore::Transaction* transaction, 2771 IndexedDBBackingStore::Transaction* transaction,
2667 int64 database_id, 2772 int64 database_id,
2668 int64 object_store_id, 2773 int64 object_store_id,
2669 const IndexedDBKeyRange& range, 2774 const IndexedDBKeyRange& range,
2670 indexed_db::CursorDirection direction) { 2775 indexed_db::CursorDirection direction,
2776 leveldb::Status* s) {
2671 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor"); 2777 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor");
2778 *s = leveldb::Status::OK();
2672 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2779 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2673 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2780 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2674 if (!ObjectStoreCursorOptions(leveldb_transaction, 2781 if (!ObjectStoreCursorOptions(leveldb_transaction,
2675 database_id, 2782 database_id,
2676 object_store_id, 2783 object_store_id,
2677 range, 2784 range,
2678 direction, 2785 direction,
2679 &cursor_options)) 2786 &cursor_options))
2680 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2787 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2681 scoped_ptr<ObjectStoreCursorImpl> cursor( 2788 scoped_ptr<ObjectStoreCursorImpl> cursor(
2682 new ObjectStoreCursorImpl(leveldb_transaction, cursor_options)); 2789 new ObjectStoreCursorImpl(leveldb_transaction, cursor_options));
2683 if (!cursor->FirstSeek()) 2790 if (!cursor->FirstSeek(s))
2684 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2791 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2685 2792
2686 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2793 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2687 } 2794 }
2688 2795
2689 scoped_ptr<IndexedDBBackingStore::Cursor> 2796 scoped_ptr<IndexedDBBackingStore::Cursor>
2690 IndexedDBBackingStore::OpenObjectStoreKeyCursor( 2797 IndexedDBBackingStore::OpenObjectStoreKeyCursor(
2691 IndexedDBBackingStore::Transaction* transaction, 2798 IndexedDBBackingStore::Transaction* transaction,
2692 int64 database_id, 2799 int64 database_id,
2693 int64 object_store_id, 2800 int64 object_store_id,
2694 const IndexedDBKeyRange& range, 2801 const IndexedDBKeyRange& range,
2695 indexed_db::CursorDirection direction) { 2802 indexed_db::CursorDirection direction,
2803 leveldb::Status* s) {
2696 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); 2804 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
2805 *s = leveldb::Status::OK();
2697 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2806 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2698 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2807 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2699 if (!ObjectStoreCursorOptions(leveldb_transaction, 2808 if (!ObjectStoreCursorOptions(leveldb_transaction,
2700 database_id, 2809 database_id,
2701 object_store_id, 2810 object_store_id,
2702 range, 2811 range,
2703 direction, 2812 direction,
2704 &cursor_options)) 2813 &cursor_options))
2705 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2814 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2706 scoped_ptr<ObjectStoreKeyCursorImpl> cursor( 2815 scoped_ptr<ObjectStoreKeyCursorImpl> cursor(
2707 new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options)); 2816 new ObjectStoreKeyCursorImpl(leveldb_transaction, cursor_options));
2708 if (!cursor->FirstSeek()) 2817 if (!cursor->FirstSeek(s))
2709 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2818 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2710 2819
2711 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2820 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2712 } 2821 }
2713 2822
2714 scoped_ptr<IndexedDBBackingStore::Cursor> 2823 scoped_ptr<IndexedDBBackingStore::Cursor>
2715 IndexedDBBackingStore::OpenIndexKeyCursor( 2824 IndexedDBBackingStore::OpenIndexKeyCursor(
2716 IndexedDBBackingStore::Transaction* transaction, 2825 IndexedDBBackingStore::Transaction* transaction,
2717 int64 database_id, 2826 int64 database_id,
2718 int64 object_store_id, 2827 int64 object_store_id,
2719 int64 index_id, 2828 int64 index_id,
2720 const IndexedDBKeyRange& range, 2829 const IndexedDBKeyRange& range,
2721 indexed_db::CursorDirection direction) { 2830 indexed_db::CursorDirection direction,
2831 leveldb::Status* s) {
2722 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); 2832 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
2833 *s = leveldb::Status::OK();
2723 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2834 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2724 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2835 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2725 if (!IndexCursorOptions(leveldb_transaction, 2836 if (!IndexCursorOptions(leveldb_transaction,
2726 database_id, 2837 database_id,
2727 object_store_id, 2838 object_store_id,
2728 index_id, 2839 index_id,
2729 range, 2840 range,
2730 direction, 2841 direction,
2731 &cursor_options)) 2842 &cursor_options))
2732 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2843 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2733 scoped_ptr<IndexKeyCursorImpl> cursor( 2844 scoped_ptr<IndexKeyCursorImpl> cursor(
2734 new IndexKeyCursorImpl(leveldb_transaction, cursor_options)); 2845 new IndexKeyCursorImpl(leveldb_transaction, cursor_options));
2735 if (!cursor->FirstSeek()) 2846 if (!cursor->FirstSeek(s))
2736 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2847 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2737 2848
2738 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2849 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2739 } 2850 }
2740 2851
2741 scoped_ptr<IndexedDBBackingStore::Cursor> 2852 scoped_ptr<IndexedDBBackingStore::Cursor>
2742 IndexedDBBackingStore::OpenIndexCursor( 2853 IndexedDBBackingStore::OpenIndexCursor(
2743 IndexedDBBackingStore::Transaction* transaction, 2854 IndexedDBBackingStore::Transaction* transaction,
2744 int64 database_id, 2855 int64 database_id,
2745 int64 object_store_id, 2856 int64 object_store_id,
2746 int64 index_id, 2857 int64 index_id,
2747 const IndexedDBKeyRange& range, 2858 const IndexedDBKeyRange& range,
2748 indexed_db::CursorDirection direction) { 2859 indexed_db::CursorDirection direction,
2860 leveldb::Status* s) {
2749 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); 2861 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
2750 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 2862 LevelDBTransaction* leveldb_transaction = transaction->transaction();
2751 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 2863 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
2752 if (!IndexCursorOptions(leveldb_transaction, 2864 if (!IndexCursorOptions(leveldb_transaction,
2753 database_id, 2865 database_id,
2754 object_store_id, 2866 object_store_id,
2755 index_id, 2867 index_id,
2756 range, 2868 range,
2757 direction, 2869 direction,
2758 &cursor_options)) 2870 &cursor_options))
2759 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2871 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2760 scoped_ptr<IndexCursorImpl> cursor( 2872 scoped_ptr<IndexCursorImpl> cursor(
2761 new IndexCursorImpl(leveldb_transaction, cursor_options)); 2873 new IndexCursorImpl(leveldb_transaction, cursor_options));
2762 if (!cursor->FirstSeek()) 2874 if (!cursor->FirstSeek(s))
2763 return scoped_ptr<IndexedDBBackingStore::Cursor>(); 2875 return scoped_ptr<IndexedDBBackingStore::Cursor>();
2764 2876
2765 return cursor.PassAs<IndexedDBBackingStore::Cursor>(); 2877 return cursor.PassAs<IndexedDBBackingStore::Cursor>();
2766 } 2878 }
2767 2879
2768 IndexedDBBackingStore::Transaction::Transaction( 2880 IndexedDBBackingStore::Transaction::Transaction(
2769 IndexedDBBackingStore* backing_store) 2881 IndexedDBBackingStore* backing_store)
2770 : backing_store_(backing_store) {} 2882 : backing_store_(backing_store) {}
2771 2883
2772 IndexedDBBackingStore::Transaction::~Transaction() {} 2884 IndexedDBBackingStore::Transaction::~Transaction() {}
(...skipping 15 matching lines...) Expand all
2788 } 2900 }
2789 2901
2790 void IndexedDBBackingStore::Transaction::Rollback() { 2902 void IndexedDBBackingStore::Transaction::Rollback() {
2791 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); 2903 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
2792 DCHECK(transaction_.get()); 2904 DCHECK(transaction_.get());
2793 transaction_->Rollback(); 2905 transaction_->Rollback();
2794 transaction_ = NULL; 2906 transaction_ = NULL;
2795 } 2907 }
2796 2908
2797 } // namespace content 2909 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698