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

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: Rebased 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
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());
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());
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());
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());
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());
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());
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
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1430 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1457 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1431 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail 1458 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail
1432 // the load. 1459 // the load.
1433 it->Next(); 1460 it->Next();
1434 continue; 1461 continue;
1435 } 1462 }
1436 1463
1437 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1464 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1438 // simplify. 1465 // simplify.
1439 int64 index_id = meta_data_key.IndexId(); 1466 int64 index_id = meta_data_key.IndexId();
1440 string16 index_name = DecodeString(it->Value().begin(), it->Value().end()); 1467 string16 index_name;
1468 {
1469 StringPiece slice(it->Value());
1470 if (!DecodeString(&slice, &index_name) || !slice.empty())
1471 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1472 }
1441 1473
1442 it->Next(); // unique flag 1474 it->Next(); // unique flag
1443 if (!CheckIndexAndMetaDataKey( 1475 if (!CheckIndexAndMetaDataKey(
1444 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { 1476 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) {
1445 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1477 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1446 break; 1478 break;
1447 } 1479 }
1448 bool index_unique = DecodeBool(it->Value().begin(), it->Value().end()); 1480 bool index_unique;
1481 {
1482 StringPiece slice(it->Value());
1483 if (!DecodeBool(&slice, &index_unique) || !slice.empty())
1484 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1485 }
1449 1486
1450 it->Next(); // key_path 1487 it->Next(); // key_path
1451 if (!CheckIndexAndMetaDataKey( 1488 if (!CheckIndexAndMetaDataKey(
1452 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { 1489 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) {
1453 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1490 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1454 break; 1491 break;
1455 } 1492 }
1456 IndexedDBKeyPath key_path = 1493 IndexedDBKeyPath key_path;
1457 DecodeIDBKeyPath(it->Value().begin(), it->Value().end()); 1494 {
1495 StringPiece slice(it->Value());
1496 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1497 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1498 }
1458 1499
1459 it->Next(); // [optional] multi_entry flag 1500 it->Next(); // [optional] multi_entry flag
1460 bool index_multi_entry = false; 1501 bool index_multi_entry = false;
1461 if (CheckIndexAndMetaDataKey( 1502 if (CheckIndexAndMetaDataKey(
1462 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { 1503 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) {
1463 index_multi_entry = DecodeBool(it->Value().begin(), it->Value().end()); 1504 StringPiece slice(it->Value());
1505 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty())
1506 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1507
1464 it->Next(); 1508 it->Next();
1465 } 1509 }
1466 1510
1467 (*indexes)[index_id] = IndexedDBIndexMetadata( 1511 (*indexes)[index_id] = IndexedDBIndexMetadata(
1468 index_name, index_id, key_path, index_unique, index_multi_entry); 1512 index_name, index_id, key_path, index_unique, index_multi_entry);
1469 } 1513 }
1470 return true; 1514 return true;
1471 } 1515 }
1472 1516
1473 WARN_UNUSED_RESULT static bool SetMaxIndexId(LevelDBTransaction* transaction, 1517 WARN_UNUSED_RESULT static bool SetMaxIndexId(LevelDBTransaction* transaction,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1562 int64 index_id, 1606 int64 index_id,
1563 const IndexedDBKey& key, 1607 const IndexedDBKey& key,
1564 const RecordIdentifier& record_identifier) { 1608 const RecordIdentifier& record_identifier) {
1565 IDB_TRACE("IndexedDBBackingStore::put_index_data_for_record"); 1609 IDB_TRACE("IndexedDBBackingStore::put_index_data_for_record");
1566 DCHECK(key.IsValid()); 1610 DCHECK(key.IsValid());
1567 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1611 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1568 return false; 1612 return false;
1569 1613
1570 LevelDBTransaction* leveldb_transaction = 1614 LevelDBTransaction* leveldb_transaction =
1571 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1615 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1616
1617 std::vector<char> encoded_key;
1618 EncodeIDBKey(key, &encoded_key);
1619
1572 const std::vector<char> index_data_key = 1620 const std::vector<char> index_data_key =
1573 IndexDataKey::Encode(database_id, 1621 IndexDataKey::Encode(database_id,
1574 object_store_id, 1622 object_store_id,
1575 index_id, 1623 index_id,
1576 EncodeIDBKey(key), 1624 encoded_key,
1577 record_identifier.primary_key()); 1625 record_identifier.primary_key());
1578 1626
1579 std::vector<char> data; 1627 std::vector<char> data;
1580 EncodeVarInt(record_identifier.version(), &data); 1628 EncodeVarInt(record_identifier.version(), &data);
1581 const std::vector<char>& primary_key = record_identifier.primary_key(); 1629 const std::vector<char>& primary_key = record_identifier.primary_key();
1582 data.insert(data.end(), primary_key.begin(), primary_key.end()); 1630 data.insert(data.end(), primary_key.begin(), primary_key.end());
1583 1631
1584 leveldb_transaction->Put(LevelDBSlice(index_data_key), data); 1632 leveldb_transaction->Put(LevelDBSlice(index_data_key), data);
1585 return true; 1633 return true;
1586 } 1634 }
(...skipping 27 matching lines...) Expand all
1614 } 1662 }
1615 1663
1616 static bool VersionExists(LevelDBTransaction* transaction, 1664 static bool VersionExists(LevelDBTransaction* transaction,
1617 int64 database_id, 1665 int64 database_id,
1618 int64 object_store_id, 1666 int64 object_store_id,
1619 int64 version, 1667 int64 version,
1620 const std::vector<char>& encoded_primary_key, 1668 const std::vector<char>& encoded_primary_key,
1621 bool& exists) { 1669 bool& exists) {
1622 const std::vector<char> key = 1670 const std::vector<char> key =
1623 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key); 1671 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key);
1624 std::vector<char> data; 1672 std::string data;
1625 1673
1626 bool ok = transaction->Get(LevelDBSlice(key), data, exists); 1674 bool ok = transaction->Get(LevelDBSlice(key), &data, exists);
1627 if (!ok) { 1675 if (!ok) {
1628 INTERNAL_READ_ERROR(VERSION_EXISTS); 1676 INTERNAL_READ_ERROR(VERSION_EXISTS);
1629 return false; 1677 return false;
1630 } 1678 }
1631 if (!exists) 1679 if (!exists)
1632 return true; 1680 return true;
1633 1681
1634 exists = (DecodeInt(data.begin(), data.end()) == version); 1682 StringPiece slice(data);
1683 int64 decoded;
1684 if (!DecodeInt(&slice, &decoded) || !slice.empty())
1685 return false;
1686 exists = (decoded == version);
1635 return true; 1687 return true;
1636 } 1688 }
1637 1689
1638 bool IndexedDBBackingStore::FindKeyInIndex( 1690 bool IndexedDBBackingStore::FindKeyInIndex(
1639 IndexedDBBackingStore::Transaction* transaction, 1691 IndexedDBBackingStore::Transaction* transaction,
1640 int64 database_id, 1692 int64 database_id,
1641 int64 object_store_id, 1693 int64 object_store_id,
1642 int64 index_id, 1694 int64 index_id,
1643 const IndexedDBKey& key, 1695 const IndexedDBKey& key,
1644 std::vector<char>& found_encoded_primary_key, 1696 std::vector<char>& found_encoded_primary_key,
(...skipping 10 matching lines...) Expand all
1655 IndexDataKey::Encode(database_id, object_store_id, index_id, key); 1707 IndexDataKey::Encode(database_id, object_store_id, index_id, key);
1656 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1708 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1657 it->Seek(LevelDBSlice(leveldb_key)); 1709 it->Seek(LevelDBSlice(leveldb_key));
1658 1710
1659 for (;;) { 1711 for (;;) {
1660 if (!it->IsValid()) 1712 if (!it->IsValid())
1661 return true; 1713 return true;
1662 if (CompareIndexKeys(it->Key(), LevelDBSlice(leveldb_key)) > 0) 1714 if (CompareIndexKeys(it->Key(), LevelDBSlice(leveldb_key)) > 0)
1663 return true; 1715 return true;
1664 1716
1717 StringPiece slice(it->Value());
1718
1665 int64 version; 1719 int64 version;
1666 const char* p = 1720 if (!DecodeVarInt(&slice, &version)) {
1667 DecodeVarInt(it->Value().begin(), it->Value().end(), version);
1668 if (!p) {
1669 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX); 1721 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX);
1670 return false; 1722 return false;
1671 } 1723 }
1672 found_encoded_primary_key.insert( 1724 found_encoded_primary_key.insert(
1673 found_encoded_primary_key.end(), p, it->Value().end()); 1725 found_encoded_primary_key.end(), slice.begin(), slice.end());
1674 1726
1675 bool exists = false; 1727 bool exists = false;
1676 bool ok = VersionExists(leveldb_transaction, 1728 bool ok = VersionExists(leveldb_transaction,
1677 database_id, 1729 database_id,
1678 object_store_id, 1730 object_store_id,
1679 version, 1731 version,
1680 found_encoded_primary_key, 1732 found_encoded_primary_key,
1681 exists); 1733 exists);
1682 if (!ok) 1734 if (!ok)
1683 return false; 1735 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1716 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1768 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX);
1717 return false; 1769 return false;
1718 } 1770 }
1719 if (!found) 1771 if (!found)
1720 return true; 1772 return true;
1721 if (!found_encoded_primary_key.size()) { 1773 if (!found_encoded_primary_key.size()) {
1722 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1774 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX);
1723 return false; 1775 return false;
1724 } 1776 }
1725 1777
1726 DecodeIDBKey(&*found_encoded_primary_key.begin(), 1778 StringPiece slice(&*found_encoded_primary_key.begin(),
1727 &*found_encoded_primary_key.rbegin() + 1, 1779 found_encoded_primary_key.size());
1728 primary_key); 1780 return DecodeIDBKey(&slice, primary_key) && slice.empty();
1729 return true;
1730 } 1781 }
1731 1782
1732 bool IndexedDBBackingStore::KeyExistsInIndex( 1783 bool IndexedDBBackingStore::KeyExistsInIndex(
1733 IndexedDBBackingStore::Transaction* transaction, 1784 IndexedDBBackingStore::Transaction* transaction,
1734 int64 database_id, 1785 int64 database_id,
1735 int64 object_store_id, 1786 int64 object_store_id,
1736 int64 index_id, 1787 int64 index_id,
1737 const IndexedDBKey& index_key, 1788 const IndexedDBKey& index_key,
1738 scoped_ptr<IndexedDBKey>* found_primary_key, 1789 scoped_ptr<IndexedDBKey>* found_primary_key,
1739 bool& exists) { 1790 bool& exists) {
(...skipping 14 matching lines...) Expand all
1754 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1805 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX);
1755 return false; 1806 return false;
1756 } 1807 }
1757 if (!exists) 1808 if (!exists)
1758 return true; 1809 return true;
1759 if (!found_encoded_primary_key.size()) { 1810 if (!found_encoded_primary_key.size()) {
1760 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1811 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX);
1761 return false; 1812 return false;
1762 } 1813 }
1763 1814
1764 DecodeIDBKey(&*found_encoded_primary_key.begin(), 1815 StringPiece slice(&*found_encoded_primary_key.begin(),
1765 &*found_encoded_primary_key.rbegin() + 1, 1816 found_encoded_primary_key.size());
1766 found_primary_key); 1817 return DecodeIDBKey(&slice, found_primary_key) && slice.empty();
alecflett 2013/06/03 21:22:53 This pattern makes me think we might also want som
jsbell 2013/06/03 21:37:09 Here there is the && slice.empty() at the end that
1767 return true;
1768 } 1818 }
1769 1819
1770 IndexedDBBackingStore::Cursor::Cursor( 1820 IndexedDBBackingStore::Cursor::Cursor(
1771 const IndexedDBBackingStore::Cursor* other) 1821 const IndexedDBBackingStore::Cursor* other)
1772 : transaction_(other->transaction_), 1822 : transaction_(other->transaction_),
1773 cursor_options_(other->cursor_options_), 1823 cursor_options_(other->cursor_options_),
1774 current_key_(new IndexedDBKey(*other->current_key_)) { 1824 current_key_(new IndexedDBKey(*other->current_key_)) {
1775 if (other->iterator_) { 1825 if (other->iterator_) {
1776 iterator_ = transaction_->CreateIterator(); 1826 iterator_ = transaction_->CreateIterator();
1777 1827
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
1986 key_position = ObjectStoreDataKey::Decode( 2036 key_position = ObjectStoreDataKey::Decode(
1987 key_position, key_limit, &object_store_data_key); 2037 key_position, key_limit, &object_store_data_key);
1988 if (!key_position) { 2038 if (!key_position) {
1989 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2039 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
1990 return false; 2040 return false;
1991 } 2041 }
1992 2042
1993 current_key_ = object_store_data_key.user_key(); 2043 current_key_ = object_store_data_key.user_key();
1994 2044
1995 int64 version; 2045 int64 version;
1996 const char* value_position = DecodeVarInt( 2046 StringPiece slice(iterator_->Value());
1997 iterator_->Value().begin(), iterator_->Value().end(), version); 2047 if (!DecodeVarInt(&slice, &version)) {
1998 if (!value_position) {
1999 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2048 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2000 return false; 2049 return false;
2001 } 2050 }
2002 2051
2003 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2052 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2004 record_identifier_.Reset(EncodeIDBKey(*current_key_), version); 2053 std::vector<char> encoded_key;
2054 EncodeIDBKey(*current_key_, &encoded_key);
2055 record_identifier_.Reset(encoded_key, version);
2005 2056
2006 return true; 2057 return true;
2007 } 2058 }
2008 2059
2009 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { 2060 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
2010 public: 2061 public:
2011 ObjectStoreCursorImpl( 2062 ObjectStoreCursorImpl(
2012 LevelDBTransaction* transaction, 2063 LevelDBTransaction* transaction,
2013 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2064 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2014 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2065 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
(...skipping 26 matching lines...) Expand all
2041 key_position = ObjectStoreDataKey::Decode( 2092 key_position = ObjectStoreDataKey::Decode(
2042 key_position, key_limit, &object_store_data_key); 2093 key_position, key_limit, &object_store_data_key);
2043 if (!key_position) { 2094 if (!key_position) {
2044 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2095 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2045 return false; 2096 return false;
2046 } 2097 }
2047 2098
2048 current_key_ = object_store_data_key.user_key(); 2099 current_key_ = object_store_data_key.user_key();
2049 2100
2050 int64 version; 2101 int64 version;
2051 const char* value_position = DecodeVarInt( 2102 StringPiece slice(iterator_->Value());
2052 iterator_->Value().begin(), iterator_->Value().end(), version); 2103 if (!DecodeVarInt(&slice, &version)) {
2053 if (!value_position) {
2054 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2104 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2055 return false; 2105 return false;
2056 } 2106 }
2057 2107
2058 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2108 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2059 record_identifier_.Reset(EncodeIDBKey(*current_key_), version); 2109 std::vector<char> encoded_key;
2110 EncodeIDBKey(*current_key_, &encoded_key);
2111 record_identifier_.Reset(encoded_key, version);
2060 2112
2061 std::vector<char> value; 2113 std::vector<char> value;
2062 value.insert(value.end(), value_position, iterator_->Value().end()); 2114 value.insert(value.end(), slice.begin(), slice.end());
2063 current_value_.swap(value); 2115 current_value_.swap(value);
2064 return true; 2116 return true;
2065 } 2117 }
2066 2118
2067 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { 2119 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2068 public: 2120 public:
2069 IndexKeyCursorImpl( 2121 IndexKeyCursorImpl(
2070 LevelDBTransaction* transaction, 2122 LevelDBTransaction* transaction,
2071 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2123 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2072 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2124 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 bool IndexKeyCursorImpl::LoadCurrentRow() { 2159 bool IndexKeyCursorImpl::LoadCurrentRow() {
2108 const char* key_position = iterator_->Key().begin(); 2160 const char* key_position = iterator_->Key().begin();
2109 const char* key_limit = iterator_->Key().end(); 2161 const char* key_limit = iterator_->Key().end();
2110 2162
2111 IndexDataKey index_data_key; 2163 IndexDataKey index_data_key;
2112 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key); 2164 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key);
2113 2165
2114 current_key_ = index_data_key.user_key(); 2166 current_key_ = index_data_key.user_key();
2115 DCHECK(current_key_); 2167 DCHECK(current_key_);
2116 2168
2169 StringPiece slice(iterator_->Value());
2117 int64 index_data_version; 2170 int64 index_data_version;
2118 const char* value_position = DecodeVarInt( 2171 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); 2172 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2122 return false; 2173 return false;
2123 } 2174 }
2124 2175
2125 value_position = 2176 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); 2177 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2129 return false; 2178 return false;
2130 } 2179 }
2131 2180
2132 std::vector<char> primary_leveldb_key = 2181 std::vector<char> primary_leveldb_key =
2133 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2182 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2134 index_data_key.ObjectStoreId(), 2183 index_data_key.ObjectStoreId(),
2135 *primary_key_); 2184 *primary_key_);
2136 2185
2137 std::vector<char> result; 2186 std::string result;
2138 bool found = false; 2187 bool found = false;
2139 bool ok = transaction_->Get(LevelDBSlice(primary_leveldb_key), result, found); 2188 bool ok =
2189 transaction_->Get(LevelDBSlice(primary_leveldb_key), &result, found);
2140 if (!ok) { 2190 if (!ok) {
2141 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2191 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2142 return false; 2192 return false;
2143 } 2193 }
2144 if (!found) { 2194 if (!found) {
2145 transaction_->Remove(iterator_->Key()); 2195 transaction_->Remove(iterator_->Key());
2146 return false; 2196 return false;
2147 } 2197 }
2148 if (!result.size()) { 2198 if (!result.size()) {
2149 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2199 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2150 return false; 2200 return false;
2151 } 2201 }
2152 2202
2153 int64 object_store_data_version; 2203 int64 object_store_data_version;
2154 const char* t = DecodeVarInt( 2204 slice = StringPiece(result);
2155 &*result.begin(), &*result.rbegin() + 1, object_store_data_version); 2205 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2156 if (!t) {
2157 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2206 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2158 return false; 2207 return false;
2159 } 2208 }
2160 2209
2161 if (object_store_data_version != index_data_version) { 2210 if (object_store_data_version != index_data_version) {
2162 transaction_->Remove(iterator_->Key()); 2211 transaction_->Remove(iterator_->Key());
2163 return false; 2212 return false;
2164 } 2213 }
2165 2214
2166 return true; 2215 return true;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2210 bool IndexCursorImpl::LoadCurrentRow() { 2259 bool IndexCursorImpl::LoadCurrentRow() {
2211 const char* key_position = iterator_->Key().begin(); 2260 const char* key_position = iterator_->Key().begin();
2212 const char* key_limit = iterator_->Key().end(); 2261 const char* key_limit = iterator_->Key().end();
2213 2262
2214 IndexDataKey index_data_key; 2263 IndexDataKey index_data_key;
2215 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key); 2264 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key);
2216 2265
2217 current_key_ = index_data_key.user_key(); 2266 current_key_ = index_data_key.user_key();
2218 DCHECK(current_key_); 2267 DCHECK(current_key_);
2219 2268
2220 const char* value_position = iterator_->Value().begin(); 2269 StringPiece slice(iterator_->Value());
2221 const char* value_limit = iterator_->Value().end();
2222
2223 int64 index_data_version; 2270 int64 index_data_version;
2224 value_position = 2271 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); 2272 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2228 return false; 2273 return false;
2229 } 2274 }
2230 value_position = DecodeIDBKey(value_position, value_limit, &primary_key_); 2275 if (!DecodeIDBKey(&slice, &primary_key_)) {
2231 if (!value_position) {
2232 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2276 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2233 return false; 2277 return false;
2234 } 2278 }
2235 2279
2236 primary_leveldb_key_ = 2280 primary_leveldb_key_ =
2237 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2281 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2238 index_data_key.ObjectStoreId(), 2282 index_data_key.ObjectStoreId(),
2239 *primary_key_); 2283 *primary_key_);
2240 2284
2241 std::vector<char> result; 2285 std::string result;
2242 bool found = false; 2286 bool found = false;
2243 bool ok = 2287 bool ok =
2244 transaction_->Get(LevelDBSlice(primary_leveldb_key_), result, found); 2288 transaction_->Get(LevelDBSlice(primary_leveldb_key_), &result, found);
2245 if (!ok) { 2289 if (!ok) {
2246 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2290 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2247 return false; 2291 return false;
2248 } 2292 }
2249 if (!found) { 2293 if (!found) {
2250 transaction_->Remove(iterator_->Key()); 2294 transaction_->Remove(iterator_->Key());
2251 return false; 2295 return false;
2252 } 2296 }
2253 if (!result.size()) { 2297 if (!result.size()) {
2254 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2298 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2255 return false; 2299 return false;
2256 } 2300 }
2257 2301
2258 int64 object_store_data_version; 2302 int64 object_store_data_version;
2259 value_position = DecodeVarInt( 2303 slice = StringPiece(result);
2260 &*result.begin(), &*result.rbegin() + 1, object_store_data_version); 2304 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2261 if (!value_position) {
2262 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2305 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2263 return false; 2306 return false;
2264 } 2307 }
2265 2308
2266 if (object_store_data_version != index_data_version) { 2309 if (object_store_data_version != index_data_version) {
2267 transaction_->Remove(iterator_->Key()); 2310 transaction_->Remove(iterator_->Key());
2268 return false; 2311 return false;
2269 } 2312 }
2270 2313
2271 // TODO(jsbell): Make value_position an iterator. 2314 current_value_.clear();
2272 std::vector<char> value; 2315 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; 2316 return true;
2278 } 2317 }
2279 2318
2280 bool ObjectStoreCursorOptions( 2319 bool ObjectStoreCursorOptions(
2281 LevelDBTransaction* transaction, 2320 LevelDBTransaction* transaction,
2282 int64 database_id, 2321 int64 database_id,
2283 int64 object_store_id, 2322 int64 object_store_id,
2284 const IndexedDBKeyRange& range, 2323 const IndexedDBKeyRange& range,
2285 indexed_db::CursorDirection direction, 2324 indexed_db::CursorDirection direction,
2286 IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) { 2325 IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
2546 } 2585 }
2547 2586
2548 void IndexedDBBackingStore::Transaction::Rollback() { 2587 void IndexedDBBackingStore::Transaction::Rollback() {
2549 IDB_TRACE("IndexedDBBackingStore::Transaction::rollback"); 2588 IDB_TRACE("IndexedDBBackingStore::Transaction::rollback");
2550 DCHECK(transaction_); 2589 DCHECK(transaction_);
2551 transaction_->Rollback(); 2590 transaction_->Rollback();
2552 transaction_ = NULL; 2591 transaction_ = NULL;
2553 } 2592 }
2554 2593
2555 } // namespace content 2594 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698