OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |