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