Chromium Code Reviews| 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 |