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

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

Issue 16256014: IndexedDB: Convert decoding functions to pass StringPieces vs. pointers (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Correct bogus iterator dereference in unit test Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | content/browser/indexed_db/indexed_db_backing_store_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/indexed_db_backing_store.h" 5 #include "content/browser/indexed_db/indexed_db_backing_store.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/strings/string_piece.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 14 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
14 #include "content/browser/indexed_db/indexed_db_metadata.h" 15 #include "content/browser/indexed_db/indexed_db_metadata.h"
15 #include "content/browser/indexed_db/indexed_db_tracing.h" 16 #include "content/browser/indexed_db/indexed_db_tracing.h"
16 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 17 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
17 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 18 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
18 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 19 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
19 #include "content/browser/indexed_db/leveldb/leveldb_slice.h" 20 #include "content/browser/indexed_db/leveldb/leveldb_slice.h"
20 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 21 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
21 #include "content/common/indexed_db/indexed_db_key.h" 22 #include "content/common/indexed_db/indexed_db_key.h"
22 #include "content/common/indexed_db/indexed_db_key_path.h" 23 #include "content/common/indexed_db/indexed_db_key_path.h"
23 #include "content/common/indexed_db/indexed_db_key_range.h" 24 #include "content/common/indexed_db/indexed_db_key_range.h"
24 #include "third_party/WebKit/public/platform/WebIDBKey.h" 25 #include "third_party/WebKit/public/platform/WebIDBKey.h"
25 #include "third_party/WebKit/public/platform/WebIDBKeyPath.h" 26 #include "third_party/WebKit/public/platform/WebIDBKeyPath.h"
26 27
28 using base::StringPiece;
29
27 // TODO(jsbell): Make blink push the version during the open() call. 30 // TODO(jsbell): Make blink push the version during the open() call.
28 static const uint32 kWireVersion = 2; 31 static const uint32 kWireVersion = 2;
29 32
30 namespace content { 33 namespace content {
31 34
32 static const int64 kKeyGeneratorInitialNumber = 35 static const int64 kKeyGeneratorInitialNumber =
33 1; // From the IndexedDB specification. 36 1; // From the IndexedDB specification.
34 37
35 enum IndexedDBBackingStoreErrorSource { 38 enum IndexedDBBackingStoreErrorSource {
36 // 0 - 2 are no longer used. 39 // 0 - 2 are no longer used.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 std::vector<char> buffer; 93 std::vector<char> buffer;
91 EncodeBool(value, &buffer); 94 EncodeBool(value, &buffer);
92 transaction->Put(key, buffer); 95 transaction->Put(key, buffer);
93 } 96 }
94 97
95 template <typename DBOrTransaction> 98 template <typename DBOrTransaction>
96 static bool GetInt(DBOrTransaction* db, 99 static bool GetInt(DBOrTransaction* db,
97 const LevelDBSlice& key, 100 const LevelDBSlice& key,
98 int64& found_int, 101 int64& found_int,
99 bool& found) { 102 bool& found) {
100 std::vector<char> result; 103 std::string result;
101 bool ok = db->Get(key, result, found); 104 bool ok = db->Get(key, &result, found);
102 if (!ok) 105 if (!ok)
103 return false; 106 return false;
104 if (!found) 107 if (!found)
105 return true; 108 return true;
106 109 StringPiece slice(result);
107 found_int = DecodeInt(result.begin(), result.end()); 110 return DecodeInt(&slice, &found_int) && slice.empty();
108 return true;
109 } 111 }
110 112
111 static void PutInt(LevelDBTransaction* transaction, 113 static void PutInt(LevelDBTransaction* transaction,
112 const LevelDBSlice& key, 114 const LevelDBSlice& key,
113 int64 value) { 115 int64 value) {
114 DCHECK_GE(value, 0); 116 DCHECK_GE(value, 0);
115 std::vector<char> buffer; 117 std::vector<char> buffer;
116 EncodeInt(value, &buffer); 118 EncodeInt(value, &buffer);
117 transaction->Put(key, buffer); 119 transaction->Put(key, buffer);
118 } 120 }
119 121
120 template <typename DBOrTransaction> 122 template <typename DBOrTransaction>
121 WARN_UNUSED_RESULT static bool GetVarInt(DBOrTransaction* db, 123 WARN_UNUSED_RESULT static bool GetVarInt(DBOrTransaction* db,
122 const LevelDBSlice& key, 124 const LevelDBSlice& key,
123 int64& found_int, 125 int64& found_int,
124 bool& found) { 126 bool& found) {
125 std::vector<char> result; 127 std::string result;
126 bool ok = db->Get(key, result, found); 128 bool ok = db->Get(key, &result, found);
127 if (!ok) 129 if (!ok)
128 return false; 130 return false;
129 if (!found) 131 if (!found)
130 return true; 132 return true;
131 if (!result.size()) 133 StringPiece slice(result);
132 return false; 134 return DecodeVarInt(&slice, &found_int) && slice.empty();
133
134 found = DecodeVarInt(&*result.begin(), &*result.rbegin() + 1, found_int) ==
135 &*result.rbegin() + 1;
136 return true;
137 } 135 }
138 136
139 static void PutVarInt(LevelDBTransaction* transaction, 137 static void PutVarInt(LevelDBTransaction* transaction,
140 const LevelDBSlice& key, 138 const LevelDBSlice& key,
141 int64 value) { 139 int64 value) {
142 std::vector<char> buffer; 140 std::vector<char> buffer;
143 EncodeVarInt(value, &buffer); 141 EncodeVarInt(value, &buffer);
144 transaction->Put(key, buffer); 142 transaction->Put(key, buffer);
145 } 143 }
146 144
147 template <typename DBOrTransaction> 145 template <typename DBOrTransaction>
148 WARN_UNUSED_RESULT static bool GetString(DBOrTransaction* db, 146 WARN_UNUSED_RESULT static bool GetString(DBOrTransaction* db,
149 const LevelDBSlice& key, 147 const LevelDBSlice& key,
150 string16& found_string, 148 string16& found_string,
151 bool& found) { 149 bool& found) {
152 std::vector<char> result; 150 std::string result;
153 found = false; 151 found = false;
154 bool ok = db->Get(key, result, found); 152 bool ok = db->Get(key, &result, found);
155 if (!ok) 153 if (!ok)
156 return false; 154 return false;
157 if (!found) 155 if (!found)
158 return true; 156 return true;
159 if (!result.size()) { 157 StringPiece slice(result);
160 found_string.clear(); 158 return DecodeString(&slice, &found_string) && slice.empty();
161 return true;
162 }
163
164 found_string = DecodeString(&*result.begin(), &*result.rbegin() + 1);
165 return true;
166 } 159 }
167 160
168 static void PutString(LevelDBTransaction* transaction, 161 static void PutString(LevelDBTransaction* transaction,
169 const LevelDBSlice& key, 162 const LevelDBSlice& key,
170 const string16& value) { 163 const string16& value) {
171 std::vector<char> buffer; 164 std::vector<char> buffer;
172 EncodeString(value, &buffer); 165 EncodeString(value, &buffer);
173 transaction->Put(key, buffer); 166 transaction->Put(key, buffer);
174 } 167 }
175 168
(...skipping 688 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 857 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
865 // Possible stale metadata, but don't fail the load. 858 // Possible stale metadata, but don't fail the load.
866 it->Next(); 859 it->Next();
867 continue; 860 continue;
868 } 861 }
869 862
870 int64 object_store_id = meta_data_key.ObjectStoreId(); 863 int64 object_store_id = meta_data_key.ObjectStoreId();
871 864
872 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 865 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
873 // simplify. 866 // simplify.
874 string16 object_store_name = 867 string16 object_store_name;
875 DecodeString(it->Value().begin(), it->Value().end()); 868 {
869 StringPiece slice(it->Value().AsStringPiece());
870 if (!DecodeString(&slice, &object_store_name) || !slice.empty())
871 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
872 }
876 873
877 it->Next(); 874 it->Next();
878 if (!CheckObjectStoreAndMetaDataType(it.get(), 875 if (!CheckObjectStoreAndMetaDataType(it.get(),
879 stop_key, 876 stop_key,
880 object_store_id, 877 object_store_id,
881 ObjectStoreMetaDataKey::KEY_PATH)) { 878 ObjectStoreMetaDataKey::KEY_PATH)) {
882 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 879 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
883 break; 880 break;
884 } 881 }
885 IndexedDBKeyPath key_path = 882 IndexedDBKeyPath key_path;
886 DecodeIDBKeyPath(it->Value().begin(), it->Value().end()); 883 {
884 StringPiece slice(it->Value().AsStringPiece());
885 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
886 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
887 }
887 888
888 it->Next(); 889 it->Next();
889 if (!CheckObjectStoreAndMetaDataType( 890 if (!CheckObjectStoreAndMetaDataType(
890 it.get(), 891 it.get(),
891 stop_key, 892 stop_key,
892 object_store_id, 893 object_store_id,
893 ObjectStoreMetaDataKey::AUTO_INCREMENT)) { 894 ObjectStoreMetaDataKey::AUTO_INCREMENT)) {
894 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 895 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
895 break; 896 break;
896 } 897 }
897 bool auto_increment = DecodeBool(it->Value().begin(), it->Value().end()); 898 bool auto_increment;
899 {
900 StringPiece slice(it->Value().AsStringPiece());
901 if (!DecodeBool(&slice, &auto_increment) || !slice.empty())
902 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
903 }
898 904
899 it->Next(); // Is evicatble. 905 it->Next(); // Is evicatble.
900 if (!CheckObjectStoreAndMetaDataType(it.get(), 906 if (!CheckObjectStoreAndMetaDataType(it.get(),
901 stop_key, 907 stop_key,
902 object_store_id, 908 object_store_id,
903 ObjectStoreMetaDataKey::EVICTABLE)) { 909 ObjectStoreMetaDataKey::EVICTABLE)) {
904 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 910 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
905 break; 911 break;
906 } 912 }
907 913
908 it->Next(); // Last version. 914 it->Next(); // Last version.
909 if (!CheckObjectStoreAndMetaDataType( 915 if (!CheckObjectStoreAndMetaDataType(
910 it.get(), 916 it.get(),
911 stop_key, 917 stop_key,
912 object_store_id, 918 object_store_id,
913 ObjectStoreMetaDataKey::LAST_VERSION)) { 919 ObjectStoreMetaDataKey::LAST_VERSION)) {
914 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 920 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
915 break; 921 break;
916 } 922 }
917 923
918 it->Next(); // Maximum index id allocated. 924 it->Next(); // Maximum index id allocated.
919 if (!CheckObjectStoreAndMetaDataType( 925 if (!CheckObjectStoreAndMetaDataType(
920 it.get(), 926 it.get(),
921 stop_key, 927 stop_key,
922 object_store_id, 928 object_store_id,
923 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { 929 ObjectStoreMetaDataKey::MAX_INDEX_ID)) {
924 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 930 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
925 break; 931 break;
926 } 932 }
927 int64 max_index_id = DecodeInt(it->Value().begin(), it->Value().end()); 933 int64 max_index_id;
934 {
935 StringPiece slice(it->Value().AsStringPiece());
936 if (!DecodeInt(&slice, &max_index_id) || !slice.empty())
937 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
938 }
928 939
929 it->Next(); // [optional] has key path (is not null) 940 it->Next(); // [optional] has key path (is not null)
930 if (CheckObjectStoreAndMetaDataType(it.get(), 941 if (CheckObjectStoreAndMetaDataType(it.get(),
931 stop_key, 942 stop_key,
932 object_store_id, 943 object_store_id,
933 ObjectStoreMetaDataKey::HAS_KEY_PATH)) { 944 ObjectStoreMetaDataKey::HAS_KEY_PATH)) {
934 bool has_key_path = DecodeBool(it->Value().begin(), it->Value().end()); 945 bool has_key_path;
946 {
947 StringPiece slice(it->Value().AsStringPiece());
948 if (!DecodeBool(&slice, &has_key_path))
949 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
950 }
935 // This check accounts for two layers of legacy coding: 951 // This check accounts for two layers of legacy coding:
936 // (1) Initially, has_key_path was added to distinguish null vs. string. 952 // (1) Initially, has_key_path was added to distinguish null vs. string.
937 // (2) Later, null vs. string vs. array was stored in the key_path itself. 953 // (2) Later, null vs. string vs. array was stored in the key_path itself.
938 // So this check is only relevant for string-type key_paths. 954 // So this check is only relevant for string-type key_paths.
939 if (!has_key_path && 955 if (!has_key_path &&
940 (key_path.type() == WebKit::WebIDBKeyPath::StringType && 956 (key_path.type() == WebKit::WebIDBKeyPath::StringType &&
941 !key_path.string().empty())) { 957 !key_path.string().empty())) {
942 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 958 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
943 break; 959 break;
944 } 960 }
945 if (!has_key_path) 961 if (!has_key_path)
946 key_path = IndexedDBKeyPath(); 962 key_path = IndexedDBKeyPath();
947 it->Next(); 963 it->Next();
948 } 964 }
949 965
950 int64 key_generator_current_number = -1; 966 int64 key_generator_current_number = -1;
951 if (CheckObjectStoreAndMetaDataType( 967 if (CheckObjectStoreAndMetaDataType(
952 it.get(), 968 it.get(),
953 stop_key, 969 stop_key,
954 object_store_id, 970 object_store_id,
955 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { 971 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) {
956 key_generator_current_number = 972 StringPiece slice(it->Value().AsStringPiece());
957 DecodeInt(it->Value().begin(), it->Value().end()); 973 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty())
974 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
975
958 // TODO(jsbell): Return key_generator_current_number, cache in 976 // TODO(jsbell): Return key_generator_current_number, cache in
959 // object store, and write lazily to backing store. For now, 977 // object store, and write lazily to backing store. For now,
960 // just assert that if it was written it was valid. 978 // just assert that if it was written it was valid.
961 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber); 979 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber);
962 it->Next(); 980 it->Next();
963 } 981 }
964 982
965 IndexedDBObjectStoreMetadata metadata(object_store_name, 983 IndexedDBObjectStoreMetadata metadata(object_store_name,
966 object_store_id, 984 object_store_id,
967 key_path, 985 key_path,
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 const IndexedDBKey& key, 1118 const IndexedDBKey& key,
1101 std::vector<char>& record) { 1119 std::vector<char>& record) {
1102 IDB_TRACE("IndexedDBBackingStore::get_record"); 1120 IDB_TRACE("IndexedDBBackingStore::get_record");
1103 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1121 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1104 return false; 1122 return false;
1105 LevelDBTransaction* leveldb_transaction = 1123 LevelDBTransaction* leveldb_transaction =
1106 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1124 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1107 1125
1108 const std::vector<char> leveldb_key = 1126 const std::vector<char> leveldb_key =
1109 ObjectStoreDataKey::Encode(database_id, object_store_id, key); 1127 ObjectStoreDataKey::Encode(database_id, object_store_id, key);
1110 std::vector<char> data; 1128 std::string data;
1111 1129
1112 record.clear(); 1130 record.clear();
1113 1131
1114 bool found = false; 1132 bool found = false;
1115 bool ok = leveldb_transaction->Get(LevelDBSlice(leveldb_key), data, found); 1133 bool ok = leveldb_transaction->Get(LevelDBSlice(leveldb_key), &data, found);
1116 if (!ok) { 1134 if (!ok) {
1117 INTERNAL_READ_ERROR(GET_RECORD); 1135 INTERNAL_READ_ERROR(GET_RECORD);
1118 return false; 1136 return false;
1119 } 1137 }
1120 if (!found) 1138 if (!found)
1121 return true; 1139 return true;
1122 if (!data.size()) { 1140 if (data.empty()) {
1123 INTERNAL_READ_ERROR(GET_RECORD); 1141 INTERNAL_READ_ERROR(GET_RECORD);
1124 return false; 1142 return false;
1125 } 1143 }
1126 1144
1127 int64 version; 1145 int64 version;
1128 const char* p = DecodeVarInt(&*data.begin(), &*data.rbegin() + 1, version); 1146 StringPiece slice(data);
1129 if (!p) { 1147 if (!DecodeVarInt(&slice, &version)) {
1130 INTERNAL_READ_ERROR(GET_RECORD); 1148 INTERNAL_READ_ERROR(GET_RECORD);
1131 return false; 1149 return false;
1132 } 1150 }
1133 1151
1134 record.insert(record.end(), p, static_cast<const char*>(&*data.rbegin()) + 1); 1152 record.insert(record.end(), slice.begin(), slice.end());
1135 return true; 1153 return true;
1136 } 1154 }
1137 1155
1138 WARN_UNUSED_RESULT static bool GetNewVersionNumber( 1156 WARN_UNUSED_RESULT static bool GetNewVersionNumber(
1139 LevelDBTransaction* transaction, 1157 LevelDBTransaction* transaction,
1140 int64 database_id, 1158 int64 database_id,
1141 int64 object_store_id, 1159 int64 object_store_id,
1142 int64& new_version_number) { 1160 int64& new_version_number) {
1143 const std::vector<char> last_version_key = ObjectStoreMetaDataKey::Encode( 1161 const std::vector<char> last_version_key = ObjectStoreMetaDataKey::Encode(
1144 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); 1162 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 v.insert(v.end(), value.begin(), value.end()); 1214 v.insert(v.end(), value.begin(), value.end());
1197 1215
1198 leveldb_transaction->Put(LevelDBSlice(object_storedata_key), v); 1216 leveldb_transaction->Put(LevelDBSlice(object_storedata_key), v);
1199 1217
1200 const std::vector<char> exists_entry_key = 1218 const std::vector<char> exists_entry_key =
1201 ExistsEntryKey::Encode(database_id, object_store_id, key); 1219 ExistsEntryKey::Encode(database_id, object_store_id, key);
1202 std::vector<char> version_encoded; 1220 std::vector<char> version_encoded;
1203 EncodeInt(version, &version_encoded); 1221 EncodeInt(version, &version_encoded);
1204 leveldb_transaction->Put(LevelDBSlice(exists_entry_key), version_encoded); 1222 leveldb_transaction->Put(LevelDBSlice(exists_entry_key), version_encoded);
1205 1223
1206 record_identifier->Reset(EncodeIDBKey(key), version); 1224 std::vector<char> key_encoded;
1225 EncodeIDBKey(key, &key_encoded);
1226 record_identifier->Reset(key_encoded, version);
1207 return true; 1227 return true;
1208 } 1228 }
1209 1229
1210 bool IndexedDBBackingStore::ClearObjectStore( 1230 bool IndexedDBBackingStore::ClearObjectStore(
1211 IndexedDBBackingStore::Transaction* transaction, 1231 IndexedDBBackingStore::Transaction* transaction,
1212 int64 database_id, 1232 int64 database_id,
1213 int64 object_store_id) { 1233 int64 object_store_id) {
1214 IDB_TRACE("IndexedDBBackingStore::clear_object_store"); 1234 IDB_TRACE("IndexedDBBackingStore::clear_object_store");
1215 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1235 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1216 return false; 1236 return false;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 LevelDBTransaction* leveldb_transaction = 1276 LevelDBTransaction* leveldb_transaction =
1257 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1277 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1258 1278
1259 const std::vector<char> key_generator_current_number_key = 1279 const std::vector<char> key_generator_current_number_key =
1260 ObjectStoreMetaDataKey::Encode( 1280 ObjectStoreMetaDataKey::Encode(
1261 database_id, 1281 database_id,
1262 object_store_id, 1282 object_store_id,
1263 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); 1283 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER);
1264 1284
1265 key_generator_current_number = -1; 1285 key_generator_current_number = -1;
1266 std::vector<char> data; 1286 std::string data;
1267 1287
1268 bool found = false; 1288 bool found = false;
1269 bool ok = leveldb_transaction->Get( 1289 bool ok = leveldb_transaction->Get(
1270 LevelDBSlice(key_generator_current_number_key), data, found); 1290 LevelDBSlice(key_generator_current_number_key), &data, found);
1271 if (!ok) { 1291 if (!ok) {
1272 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER); 1292 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER);
1273 return false; 1293 return false;
1274 } 1294 }
1275 if (found) { 1295 if (found && !data.empty()) {
1276 key_generator_current_number = DecodeInt(data.begin(), data.end()); 1296 StringPiece slice(data);
1277 } else { 1297 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) {
1278 // Previously, the key generator state was not stored explicitly 1298 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER);
1279 // but derived from the maximum numeric key present in existing 1299 return false;
1280 // data. This violates the spec as the data may be cleared but the
1281 // key generator state must be preserved.
1282 // TODO(jsbell): Fix this for all stores on database open?
1283 const std::vector<char> start_key =
1284 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
1285 const std::vector<char> stop_key =
1286 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
1287
1288 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1289 int64 max_numeric_key = 0;
1290
1291 for (it->Seek(LevelDBSlice(start_key));
1292 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0;
1293 it->Next()) {
1294 const char* p = it->Key().begin();
1295 const char* limit = it->Key().end();
1296
1297 ObjectStoreDataKey data_key;
1298 p = ObjectStoreDataKey::Decode(p, limit, &data_key);
1299 DCHECK(p);
1300
1301 scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
1302 if (user_key->type() == WebKit::WebIDBKey::NumberType) {
1303 int64 n = static_cast<int64>(user_key->number());
1304 if (n > max_numeric_key)
1305 max_numeric_key = n;
1306 }
1307 } 1300 }
1308 1301 return true;
1309 key_generator_current_number = max_numeric_key + 1;
1310 } 1302 }
1311 1303
1304 // Previously, the key generator state was not stored explicitly
1305 // but derived from the maximum numeric key present in existing
1306 // data. This violates the spec as the data may be cleared but the
1307 // key generator state must be preserved.
1308 // TODO(jsbell): Fix this for all stores on database open?
1309 const std::vector<char> start_key =
1310 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
1311 const std::vector<char> stop_key =
1312 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
1313
1314 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1315 int64 max_numeric_key = 0;
1316
1317 for (it->Seek(LevelDBSlice(start_key));
1318 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0;
1319 it->Next()) {
1320 const char* p = it->Key().begin();
1321 const char* limit = it->Key().end();
1322
1323 ObjectStoreDataKey data_key;
1324 p = ObjectStoreDataKey::Decode(p, limit, &data_key);
1325 DCHECK(p);
1326
1327 scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
1328 if (user_key->type() == WebKit::WebIDBKey::NumberType) {
1329 int64 n = static_cast<int64>(user_key->number());
1330 if (n > max_numeric_key)
1331 max_numeric_key = n;
1332 }
1333 }
1334
1335 key_generator_current_number = max_numeric_key + 1;
1312 return true; 1336 return true;
1313 } 1337 }
1314 1338
1315 bool IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber( 1339 bool IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
1316 IndexedDBBackingStore::Transaction* transaction, 1340 IndexedDBBackingStore::Transaction* transaction,
1317 int64 database_id, 1341 int64 database_id,
1318 int64 object_store_id, 1342 int64 object_store_id,
1319 int64 new_number, 1343 int64 new_number,
1320 bool check_current) { 1344 bool check_current) {
1321 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1345 if (!KeyPrefix::ValidIds(database_id, object_store_id))
(...skipping 30 matching lines...) Expand all
1352 RecordIdentifier* found_record_identifier, 1376 RecordIdentifier* found_record_identifier,
1353 bool& found) { 1377 bool& found) {
1354 IDB_TRACE("IndexedDBBackingStore::key_exists_in_object_store"); 1378 IDB_TRACE("IndexedDBBackingStore::key_exists_in_object_store");
1355 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1379 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1356 return false; 1380 return false;
1357 found = false; 1381 found = false;
1358 LevelDBTransaction* leveldb_transaction = 1382 LevelDBTransaction* leveldb_transaction =
1359 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1383 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1360 const std::vector<char> leveldb_key = 1384 const std::vector<char> leveldb_key =
1361 ObjectStoreDataKey::Encode(database_id, object_store_id, key); 1385 ObjectStoreDataKey::Encode(database_id, object_store_id, key);
1362 std::vector<char> data; 1386 std::string data;
1363 1387
1364 bool ok = leveldb_transaction->Get(LevelDBSlice(leveldb_key), data, found); 1388 bool ok = leveldb_transaction->Get(LevelDBSlice(leveldb_key), &data, found);
1365 if (!ok) { 1389 if (!ok) {
1366 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE); 1390 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE);
1367 return false; 1391 return false;
1368 } 1392 }
1369 if (!found) 1393 if (!found)
1370 return true; 1394 return true;
1371 if (!data.size()) { 1395 if (!data.size()) {
1372 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE); 1396 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE);
1373 return false; 1397 return false;
1374 } 1398 }
1375 1399
1376 int64 version; 1400 int64 version;
1377 if (DecodeVarInt(&*data.begin(), &*data.rbegin() + 1, version) == 0) 1401 StringPiece slice(data);
1402 if (!DecodeVarInt(&slice, &version))
1378 return false; 1403 return false;
1379 1404
1380 found_record_identifier->Reset(EncodeIDBKey(key), version); 1405 std::vector<char> encoded_key;
1406 EncodeIDBKey(key, &encoded_key);
1407 found_record_identifier->Reset(encoded_key, version);
1381 return true; 1408 return true;
1382 } 1409 }
1383 1410
1384 static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it, 1411 static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it,
1385 const std::vector<char>& stop_key, 1412 const std::vector<char>& stop_key,
1386 int64 index_id, 1413 int64 index_id,
1387 unsigned char meta_data_type) { 1414 unsigned char meta_data_type) {
1388 if (!it->IsValid() || CompareKeys(it->Key(), LevelDBSlice(stop_key)) >= 0) 1415 if (!it->IsValid() || CompareKeys(it->Key(), LevelDBSlice(stop_key)) >= 0)
1389 return false; 1416 return false;
1390 1417
1391 IndexMetaDataKey meta_data_key; 1418 IndexMetaDataKey meta_data_key;
1392 const char* p = IndexMetaDataKey::Decode( 1419 const char* p = IndexMetaDataKey::Decode(
1393 it->Key().begin(), it->Key().end(), &meta_data_key); 1420 it->Key().begin(), it->Key().end(), &meta_data_key);
1394 DCHECK(p); 1421 DCHECK(p);
1395 if (meta_data_key.IndexId() != index_id) 1422 if (meta_data_key.IndexId() != index_id)
1396 return false; 1423 return false;
1397 if (meta_data_key.meta_data_type() != meta_data_type) 1424 if (meta_data_key.meta_data_type() != meta_data_type)
1398 return false; 1425 return false;
1399 return true; 1426 return true;
1400 } 1427 }
1401 1428
1402 // TODO(jsbell): This should do some error handling rather than plowing ahead 1429 // TODO(jsbell): This should do some error handling rather than plowing ahead
1403 // when bad 1430 // when bad data is encountered.
1404 // data is encountered.
1405 bool IndexedDBBackingStore::GetIndexes( 1431 bool IndexedDBBackingStore::GetIndexes(
1406 int64 database_id, 1432 int64 database_id,
1407 int64 object_store_id, 1433 int64 object_store_id,
1408 IndexedDBObjectStoreMetadata::IndexMap* indexes) { 1434 IndexedDBObjectStoreMetadata::IndexMap* indexes) {
1409 IDB_TRACE("IndexedDBBackingStore::get_indexes"); 1435 IDB_TRACE("IndexedDBBackingStore::get_indexes");
1410 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1436 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1411 return false; 1437 return false;
1412 const std::vector<char> start_key = 1438 const std::vector<char> start_key =
1413 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0); 1439 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0);
1414 const std::vector<char> stop_key = 1440 const std::vector<char> stop_key =
(...skipping 15 matching lines...) Expand all
1430 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1456 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1431 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail 1457 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail
1432 // the load. 1458 // the load.
1433 it->Next(); 1459 it->Next();
1434 continue; 1460 continue;
1435 } 1461 }
1436 1462
1437 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1463 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1438 // simplify. 1464 // simplify.
1439 int64 index_id = meta_data_key.IndexId(); 1465 int64 index_id = meta_data_key.IndexId();
1440 string16 index_name = DecodeString(it->Value().begin(), it->Value().end()); 1466 string16 index_name;
1467 {
1468 StringPiece slice(it->Value().AsStringPiece());
1469 if (!DecodeString(&slice, &index_name) || !slice.empty())
1470 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1471 }
1441 1472
1442 it->Next(); // unique flag 1473 it->Next(); // unique flag
1443 if (!CheckIndexAndMetaDataKey( 1474 if (!CheckIndexAndMetaDataKey(
1444 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { 1475 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) {
1445 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1476 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1446 break; 1477 break;
1447 } 1478 }
1448 bool index_unique = DecodeBool(it->Value().begin(), it->Value().end()); 1479 bool index_unique;
1480 {
1481 StringPiece slice(it->Value().AsStringPiece());
1482 if (!DecodeBool(&slice, &index_unique) || !slice.empty())
1483 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1484 }
1449 1485
1450 it->Next(); // key_path 1486 it->Next(); // key_path
1451 if (!CheckIndexAndMetaDataKey( 1487 if (!CheckIndexAndMetaDataKey(
1452 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { 1488 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) {
1453 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1489 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1454 break; 1490 break;
1455 } 1491 }
1456 IndexedDBKeyPath key_path = 1492 IndexedDBKeyPath key_path;
1457 DecodeIDBKeyPath(it->Value().begin(), it->Value().end()); 1493 {
1494 StringPiece slice(it->Value().AsStringPiece());
1495 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1496 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1497 }
1458 1498
1459 it->Next(); // [optional] multi_entry flag 1499 it->Next(); // [optional] multi_entry flag
1460 bool index_multi_entry = false; 1500 bool index_multi_entry = false;
1461 if (CheckIndexAndMetaDataKey( 1501 if (CheckIndexAndMetaDataKey(
1462 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { 1502 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) {
1463 index_multi_entry = DecodeBool(it->Value().begin(), it->Value().end()); 1503 StringPiece slice(it->Value().AsStringPiece());
1504 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty())
1505 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1506
1464 it->Next(); 1507 it->Next();
1465 } 1508 }
1466 1509
1467 (*indexes)[index_id] = IndexedDBIndexMetadata( 1510 (*indexes)[index_id] = IndexedDBIndexMetadata(
1468 index_name, index_id, key_path, index_unique, index_multi_entry); 1511 index_name, index_id, key_path, index_unique, index_multi_entry);
1469 } 1512 }
1470 return true; 1513 return true;
1471 } 1514 }
1472 1515
1473 WARN_UNUSED_RESULT static bool SetMaxIndexId(LevelDBTransaction* transaction, 1516 WARN_UNUSED_RESULT static bool SetMaxIndexId(LevelDBTransaction* transaction,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 int64 index_id, 1605 int64 index_id,
1563 const IndexedDBKey& key, 1606 const IndexedDBKey& key,
1564 const RecordIdentifier& record_identifier) { 1607 const RecordIdentifier& record_identifier) {
1565 IDB_TRACE("IndexedDBBackingStore::put_index_data_for_record"); 1608 IDB_TRACE("IndexedDBBackingStore::put_index_data_for_record");
1566 DCHECK(key.IsValid()); 1609 DCHECK(key.IsValid());
1567 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1610 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1568 return false; 1611 return false;
1569 1612
1570 LevelDBTransaction* leveldb_transaction = 1613 LevelDBTransaction* leveldb_transaction =
1571 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1614 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1615
1616 std::vector<char> encoded_key;
1617 EncodeIDBKey(key, &encoded_key);
1618
1572 const std::vector<char> index_data_key = 1619 const std::vector<char> index_data_key =
1573 IndexDataKey::Encode(database_id, 1620 IndexDataKey::Encode(database_id,
1574 object_store_id, 1621 object_store_id,
1575 index_id, 1622 index_id,
1576 EncodeIDBKey(key), 1623 encoded_key,
1577 record_identifier.primary_key()); 1624 record_identifier.primary_key());
1578 1625
1579 std::vector<char> data; 1626 std::vector<char> data;
1580 EncodeVarInt(record_identifier.version(), &data); 1627 EncodeVarInt(record_identifier.version(), &data);
1581 const std::vector<char>& primary_key = record_identifier.primary_key(); 1628 const std::vector<char>& primary_key = record_identifier.primary_key();
1582 data.insert(data.end(), primary_key.begin(), primary_key.end()); 1629 data.insert(data.end(), primary_key.begin(), primary_key.end());
1583 1630
1584 leveldb_transaction->Put(LevelDBSlice(index_data_key), data); 1631 leveldb_transaction->Put(LevelDBSlice(index_data_key), data);
1585 return true; 1632 return true;
1586 } 1633 }
(...skipping 27 matching lines...) Expand all
1614 } 1661 }
1615 1662
1616 static bool VersionExists(LevelDBTransaction* transaction, 1663 static bool VersionExists(LevelDBTransaction* transaction,
1617 int64 database_id, 1664 int64 database_id,
1618 int64 object_store_id, 1665 int64 object_store_id,
1619 int64 version, 1666 int64 version,
1620 const std::vector<char>& encoded_primary_key, 1667 const std::vector<char>& encoded_primary_key,
1621 bool& exists) { 1668 bool& exists) {
1622 const std::vector<char> key = 1669 const std::vector<char> key =
1623 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key); 1670 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key);
1624 std::vector<char> data; 1671 std::string data;
1625 1672
1626 bool ok = transaction->Get(LevelDBSlice(key), data, exists); 1673 bool ok = transaction->Get(LevelDBSlice(key), &data, exists);
1627 if (!ok) { 1674 if (!ok) {
1628 INTERNAL_READ_ERROR(VERSION_EXISTS); 1675 INTERNAL_READ_ERROR(VERSION_EXISTS);
1629 return false; 1676 return false;
1630 } 1677 }
1631 if (!exists) 1678 if (!exists)
1632 return true; 1679 return true;
1633 1680
1634 exists = (DecodeInt(data.begin(), data.end()) == version); 1681 StringPiece slice(data);
1682 int64 decoded;
1683 if (!DecodeInt(&slice, &decoded) || !slice.empty())
1684 return false;
1685 exists = (decoded == version);
1635 return true; 1686 return true;
1636 } 1687 }
1637 1688
1638 bool IndexedDBBackingStore::FindKeyInIndex( 1689 bool IndexedDBBackingStore::FindKeyInIndex(
1639 IndexedDBBackingStore::Transaction* transaction, 1690 IndexedDBBackingStore::Transaction* transaction,
1640 int64 database_id, 1691 int64 database_id,
1641 int64 object_store_id, 1692 int64 object_store_id,
1642 int64 index_id, 1693 int64 index_id,
1643 const IndexedDBKey& key, 1694 const IndexedDBKey& key,
1644 std::vector<char>& found_encoded_primary_key, 1695 std::vector<char>& found_encoded_primary_key,
(...skipping 10 matching lines...) Expand all
1655 IndexDataKey::Encode(database_id, object_store_id, index_id, key); 1706 IndexDataKey::Encode(database_id, object_store_id, index_id, key);
1656 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1707 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1657 it->Seek(LevelDBSlice(leveldb_key)); 1708 it->Seek(LevelDBSlice(leveldb_key));
1658 1709
1659 for (;;) { 1710 for (;;) {
1660 if (!it->IsValid()) 1711 if (!it->IsValid())
1661 return true; 1712 return true;
1662 if (CompareIndexKeys(it->Key(), LevelDBSlice(leveldb_key)) > 0) 1713 if (CompareIndexKeys(it->Key(), LevelDBSlice(leveldb_key)) > 0)
1663 return true; 1714 return true;
1664 1715
1716 StringPiece slice(it->Value().AsStringPiece());
1717
1665 int64 version; 1718 int64 version;
1666 const char* p = 1719 if (!DecodeVarInt(&slice, &version)) {
1667 DecodeVarInt(it->Value().begin(), it->Value().end(), version);
1668 if (!p) {
1669 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX); 1720 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX);
1670 return false; 1721 return false;
1671 } 1722 }
1672 found_encoded_primary_key.insert( 1723 found_encoded_primary_key.insert(
1673 found_encoded_primary_key.end(), p, it->Value().end()); 1724 found_encoded_primary_key.end(), slice.begin(), slice.end());
1674 1725
1675 bool exists = false; 1726 bool exists = false;
1676 bool ok = VersionExists(leveldb_transaction, 1727 bool ok = VersionExists(leveldb_transaction,
1677 database_id, 1728 database_id,
1678 object_store_id, 1729 object_store_id,
1679 version, 1730 version,
1680 found_encoded_primary_key, 1731 found_encoded_primary_key,
1681 exists); 1732 exists);
1682 if (!ok) 1733 if (!ok)
1683 return false; 1734 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1767 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX);
1717 return false; 1768 return false;
1718 } 1769 }
1719 if (!found) 1770 if (!found)
1720 return true; 1771 return true;
1721 if (!found_encoded_primary_key.size()) { 1772 if (!found_encoded_primary_key.size()) {
1722 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1773 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX);
1723 return false; 1774 return false;
1724 } 1775 }
1725 1776
1726 DecodeIDBKey(&*found_encoded_primary_key.begin(), 1777 StringPiece slice(&*found_encoded_primary_key.begin(),
1727 &*found_encoded_primary_key.rbegin() + 1, 1778 found_encoded_primary_key.size());
1728 primary_key); 1779 return DecodeIDBKey(&slice, primary_key) && slice.empty();
1729 return true;
1730 } 1780 }
1731 1781
1732 bool IndexedDBBackingStore::KeyExistsInIndex( 1782 bool IndexedDBBackingStore::KeyExistsInIndex(
1733 IndexedDBBackingStore::Transaction* transaction, 1783 IndexedDBBackingStore::Transaction* transaction,
1734 int64 database_id, 1784 int64 database_id,
1735 int64 object_store_id, 1785 int64 object_store_id,
1736 int64 index_id, 1786 int64 index_id,
1737 const IndexedDBKey& index_key, 1787 const IndexedDBKey& index_key,
1738 scoped_ptr<IndexedDBKey>* found_primary_key, 1788 scoped_ptr<IndexedDBKey>* found_primary_key,
1739 bool& exists) { 1789 bool& exists) {
(...skipping 14 matching lines...) Expand all
1754 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1804 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX);
1755 return false; 1805 return false;
1756 } 1806 }
1757 if (!exists) 1807 if (!exists)
1758 return true; 1808 return true;
1759 if (!found_encoded_primary_key.size()) { 1809 if (!found_encoded_primary_key.size()) {
1760 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1810 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX);
1761 return false; 1811 return false;
1762 } 1812 }
1763 1813
1764 DecodeIDBKey(&*found_encoded_primary_key.begin(), 1814 StringPiece slice(&*found_encoded_primary_key.begin(),
1765 &*found_encoded_primary_key.rbegin() + 1, 1815 found_encoded_primary_key.size());
1766 found_primary_key); 1816 return DecodeIDBKey(&slice, found_primary_key) && slice.empty();
1767 return true;
1768 } 1817 }
1769 1818
1770 IndexedDBBackingStore::Cursor::Cursor( 1819 IndexedDBBackingStore::Cursor::Cursor(
1771 const IndexedDBBackingStore::Cursor* other) 1820 const IndexedDBBackingStore::Cursor* other)
1772 : transaction_(other->transaction_), 1821 : transaction_(other->transaction_),
1773 cursor_options_(other->cursor_options_), 1822 cursor_options_(other->cursor_options_),
1774 current_key_(new IndexedDBKey(*other->current_key_)) { 1823 current_key_(new IndexedDBKey(*other->current_key_)) {
1775 if (other->iterator_) { 1824 if (other->iterator_) {
1776 iterator_ = transaction_->CreateIterator(); 1825 iterator_ = transaction_->CreateIterator();
1777 1826
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 key_position = ObjectStoreDataKey::Decode( 2035 key_position = ObjectStoreDataKey::Decode(
1987 key_position, key_limit, &object_store_data_key); 2036 key_position, key_limit, &object_store_data_key);
1988 if (!key_position) { 2037 if (!key_position) {
1989 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2038 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
1990 return false; 2039 return false;
1991 } 2040 }
1992 2041
1993 current_key_ = object_store_data_key.user_key(); 2042 current_key_ = object_store_data_key.user_key();
1994 2043
1995 int64 version; 2044 int64 version;
1996 const char* value_position = DecodeVarInt( 2045 StringPiece slice(iterator_->Value().AsStringPiece());
1997 iterator_->Value().begin(), iterator_->Value().end(), version); 2046 if (!DecodeVarInt(&slice, &version)) {
1998 if (!value_position) {
1999 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2047 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2000 return false; 2048 return false;
2001 } 2049 }
2002 2050
2003 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2051 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2004 record_identifier_.Reset(EncodeIDBKey(*current_key_), version); 2052 std::vector<char> encoded_key;
2053 EncodeIDBKey(*current_key_, &encoded_key);
2054 record_identifier_.Reset(encoded_key, version);
2005 2055
2006 return true; 2056 return true;
2007 } 2057 }
2008 2058
2009 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { 2059 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
2010 public: 2060 public:
2011 ObjectStoreCursorImpl( 2061 ObjectStoreCursorImpl(
2012 LevelDBTransaction* transaction, 2062 LevelDBTransaction* transaction,
2013 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2063 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2014 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2064 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
(...skipping 26 matching lines...) Expand all
2041 key_position = ObjectStoreDataKey::Decode( 2091 key_position = ObjectStoreDataKey::Decode(
2042 key_position, key_limit, &object_store_data_key); 2092 key_position, key_limit, &object_store_data_key);
2043 if (!key_position) { 2093 if (!key_position) {
2044 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2094 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2045 return false; 2095 return false;
2046 } 2096 }
2047 2097
2048 current_key_ = object_store_data_key.user_key(); 2098 current_key_ = object_store_data_key.user_key();
2049 2099
2050 int64 version; 2100 int64 version;
2051 const char* value_position = DecodeVarInt( 2101 StringPiece slice(iterator_->Value().AsStringPiece());
2052 iterator_->Value().begin(), iterator_->Value().end(), version); 2102 if (!DecodeVarInt(&slice, &version)) {
2053 if (!value_position) {
2054 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2103 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2055 return false; 2104 return false;
2056 } 2105 }
2057 2106
2058 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2107 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2059 record_identifier_.Reset(EncodeIDBKey(*current_key_), version); 2108 std::vector<char> encoded_key;
2109 EncodeIDBKey(*current_key_, &encoded_key);
2110 record_identifier_.Reset(encoded_key, version);
2060 2111
2061 std::vector<char> value; 2112 std::vector<char> value;
2062 value.insert(value.end(), value_position, iterator_->Value().end()); 2113 value.insert(value.end(), slice.begin(), slice.end());
2063 current_value_.swap(value); 2114 current_value_.swap(value);
2064 return true; 2115 return true;
2065 } 2116 }
2066 2117
2067 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { 2118 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2068 public: 2119 public:
2069 IndexKeyCursorImpl( 2120 IndexKeyCursorImpl(
2070 LevelDBTransaction* transaction, 2121 LevelDBTransaction* transaction,
2071 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2122 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2072 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2123 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 bool IndexKeyCursorImpl::LoadCurrentRow() { 2158 bool IndexKeyCursorImpl::LoadCurrentRow() {
2108 const char* key_position = iterator_->Key().begin(); 2159 const char* key_position = iterator_->Key().begin();
2109 const char* key_limit = iterator_->Key().end(); 2160 const char* key_limit = iterator_->Key().end();
2110 2161
2111 IndexDataKey index_data_key; 2162 IndexDataKey index_data_key;
2112 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key); 2163 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key);
2113 2164
2114 current_key_ = index_data_key.user_key(); 2165 current_key_ = index_data_key.user_key();
2115 DCHECK(current_key_); 2166 DCHECK(current_key_);
2116 2167
2168 StringPiece slice(iterator_->Value().AsStringPiece());
2117 int64 index_data_version; 2169 int64 index_data_version;
2118 const char* value_position = DecodeVarInt( 2170 if (!DecodeVarInt(&slice, &index_data_version)) {
2119 iterator_->Value().begin(), iterator_->Value().end(), index_data_version);
2120 if (!value_position) {
2121 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2171 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2122 return false; 2172 return false;
2123 } 2173 }
2124 2174
2125 value_position = 2175 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) {
2126 DecodeIDBKey(value_position, iterator_->Value().end(), &primary_key_);
2127 if (!value_position) {
2128 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2176 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2129 return false; 2177 return false;
2130 } 2178 }
2131 2179
2132 std::vector<char> primary_leveldb_key = 2180 std::vector<char> primary_leveldb_key =
2133 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2181 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2134 index_data_key.ObjectStoreId(), 2182 index_data_key.ObjectStoreId(),
2135 *primary_key_); 2183 *primary_key_);
2136 2184
2137 std::vector<char> result; 2185 std::string result;
2138 bool found = false; 2186 bool found = false;
2139 bool ok = transaction_->Get(LevelDBSlice(primary_leveldb_key), result, found); 2187 bool ok =
2188 transaction_->Get(LevelDBSlice(primary_leveldb_key), &result, found);
2140 if (!ok) { 2189 if (!ok) {
2141 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2190 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2142 return false; 2191 return false;
2143 } 2192 }
2144 if (!found) { 2193 if (!found) {
2145 transaction_->Remove(iterator_->Key()); 2194 transaction_->Remove(iterator_->Key());
2146 return false; 2195 return false;
2147 } 2196 }
2148 if (!result.size()) { 2197 if (!result.size()) {
2149 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2198 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2150 return false; 2199 return false;
2151 } 2200 }
2152 2201
2153 int64 object_store_data_version; 2202 int64 object_store_data_version;
2154 const char* t = DecodeVarInt( 2203 slice = StringPiece(result);
2155 &*result.begin(), &*result.rbegin() + 1, object_store_data_version); 2204 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2156 if (!t) {
2157 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2205 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2158 return false; 2206 return false;
2159 } 2207 }
2160 2208
2161 if (object_store_data_version != index_data_version) { 2209 if (object_store_data_version != index_data_version) {
2162 transaction_->Remove(iterator_->Key()); 2210 transaction_->Remove(iterator_->Key());
2163 return false; 2211 return false;
2164 } 2212 }
2165 2213
2166 return true; 2214 return true;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2210 bool IndexCursorImpl::LoadCurrentRow() { 2258 bool IndexCursorImpl::LoadCurrentRow() {
2211 const char* key_position = iterator_->Key().begin(); 2259 const char* key_position = iterator_->Key().begin();
2212 const char* key_limit = iterator_->Key().end(); 2260 const char* key_limit = iterator_->Key().end();
2213 2261
2214 IndexDataKey index_data_key; 2262 IndexDataKey index_data_key;
2215 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key); 2263 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key);
2216 2264
2217 current_key_ = index_data_key.user_key(); 2265 current_key_ = index_data_key.user_key();
2218 DCHECK(current_key_); 2266 DCHECK(current_key_);
2219 2267
2220 const char* value_position = iterator_->Value().begin(); 2268 StringPiece slice(iterator_->Value().AsStringPiece());
2221 const char* value_limit = iterator_->Value().end();
2222
2223 int64 index_data_version; 2269 int64 index_data_version;
2224 value_position = 2270 if (!DecodeVarInt(&slice, &index_data_version)) {
2225 DecodeVarInt(value_position, value_limit, index_data_version);
2226 if (!value_position) {
2227 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2271 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2228 return false; 2272 return false;
2229 } 2273 }
2230 value_position = DecodeIDBKey(value_position, value_limit, &primary_key_); 2274 if (!DecodeIDBKey(&slice, &primary_key_)) {
2231 if (!value_position) {
2232 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2275 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2233 return false; 2276 return false;
2234 } 2277 }
2235 2278
2236 primary_leveldb_key_ = 2279 primary_leveldb_key_ =
2237 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2280 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2238 index_data_key.ObjectStoreId(), 2281 index_data_key.ObjectStoreId(),
2239 *primary_key_); 2282 *primary_key_);
2240 2283
2241 std::vector<char> result; 2284 std::string result;
2242 bool found = false; 2285 bool found = false;
2243 bool ok = 2286 bool ok =
2244 transaction_->Get(LevelDBSlice(primary_leveldb_key_), result, found); 2287 transaction_->Get(LevelDBSlice(primary_leveldb_key_), &result, found);
2245 if (!ok) { 2288 if (!ok) {
2246 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2289 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2247 return false; 2290 return false;
2248 } 2291 }
2249 if (!found) { 2292 if (!found) {
2250 transaction_->Remove(iterator_->Key()); 2293 transaction_->Remove(iterator_->Key());
2251 return false; 2294 return false;
2252 } 2295 }
2253 if (!result.size()) { 2296 if (!result.size()) {
2254 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2297 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2255 return false; 2298 return false;
2256 } 2299 }
2257 2300
2258 int64 object_store_data_version; 2301 int64 object_store_data_version;
2259 value_position = DecodeVarInt( 2302 slice = StringPiece(result);
2260 &*result.begin(), &*result.rbegin() + 1, object_store_data_version); 2303 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2261 if (!value_position) {
2262 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2304 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2263 return false; 2305 return false;
2264 } 2306 }
2265 2307
2266 if (object_store_data_version != index_data_version) { 2308 if (object_store_data_version != index_data_version) {
2267 transaction_->Remove(iterator_->Key()); 2309 transaction_->Remove(iterator_->Key());
2268 return false; 2310 return false;
2269 } 2311 }
2270 2312
2271 // TODO(jsbell): Make value_position an iterator. 2313 current_value_.clear();
2272 std::vector<char> value; 2314 current_value_.insert(current_value_.end(), slice.begin(), slice.end());
2273 value.insert(value.end(),
2274 value_position,
2275 static_cast<const char*>(&*result.rbegin()) + 1);
2276 current_value_.swap(value);
2277 return true; 2315 return true;
2278 } 2316 }
2279 2317
2280 bool ObjectStoreCursorOptions( 2318 bool ObjectStoreCursorOptions(
2281 LevelDBTransaction* transaction, 2319 LevelDBTransaction* transaction,
2282 int64 database_id, 2320 int64 database_id,
2283 int64 object_store_id, 2321 int64 object_store_id,
2284 const IndexedDBKeyRange& range, 2322 const IndexedDBKeyRange& range,
2285 indexed_db::CursorDirection direction, 2323 indexed_db::CursorDirection direction,
2286 IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) { 2324 IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 } 2584 }
2547 2585
2548 void IndexedDBBackingStore::Transaction::Rollback() { 2586 void IndexedDBBackingStore::Transaction::Rollback() {
2549 IDB_TRACE("IndexedDBBackingStore::Transaction::rollback"); 2587 IDB_TRACE("IndexedDBBackingStore::Transaction::rollback");
2550 DCHECK(transaction_); 2588 DCHECK(transaction_);
2551 transaction_->Rollback(); 2589 transaction_->Rollback();
2552 transaction_ = NULL; 2590 transaction_ = NULL;
2553 } 2591 }
2554 2592
2555 } // namespace content 2593 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/indexed_db/indexed_db_backing_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698