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

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

Issue 18075008: IndexedDB: Switch key/value handling from vector<char> to std::string (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove C++11ism Created 7 years, 5 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>
8
9 #include "base/file_util.h" 7 #include "base/file_util.h"
10 #include "base/logging.h" 8 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
12 #include "base/strings/string_piece.h" 10 #include "base/strings/string_piece.h"
13 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
14 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h" 12 #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
15 #include "content/browser/indexed_db/indexed_db_metadata.h" 13 #include "content/browser/indexed_db/indexed_db_metadata.h"
16 #include "content/browser/indexed_db/indexed_db_tracing.h" 14 #include "content/browser/indexed_db/indexed_db_tracing.h"
17 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 15 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
18 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 16 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
19 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 17 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
20 #include "content/browser/indexed_db/leveldb/leveldb_slice.h"
21 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 18 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
22 #include "content/common/indexed_db/indexed_db_key.h" 19 #include "content/common/indexed_db/indexed_db_key.h"
23 #include "content/common/indexed_db/indexed_db_key_path.h" 20 #include "content/common/indexed_db/indexed_db_key_path.h"
24 #include "content/common/indexed_db/indexed_db_key_range.h" 21 #include "content/common/indexed_db/indexed_db_key_range.h"
25 #include "third_party/WebKit/public/platform/WebIDBKey.h" 22 #include "third_party/WebKit/public/platform/WebIDBKey.h"
26 #include "third_party/WebKit/public/platform/WebIDBKeyPath.h" 23 #include "third_party/WebKit/public/platform/WebIDBKeyPath.h"
27 24
28 using base::StringPiece; 25 using base::StringPiece;
29 26
30 // TODO(jsbell): Make blink push the version during the open() call. 27 // TODO(jsbell): Make blink push the version during the open() call.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 NOTREACHED(); \ 78 NOTREACHED(); \
82 RecordInternalError(type, location); \ 79 RecordInternalError(type, location); \
83 } while (0) 80 } while (0)
84 81
85 #define INTERNAL_READ_ERROR(location) REPORT_ERROR("Read", location) 82 #define INTERNAL_READ_ERROR(location) REPORT_ERROR("Read", location)
86 #define INTERNAL_CONSISTENCY_ERROR(location) \ 83 #define INTERNAL_CONSISTENCY_ERROR(location) \
87 REPORT_ERROR("Consistency", location) 84 REPORT_ERROR("Consistency", location)
88 #define INTERNAL_WRITE_ERROR(location) REPORT_ERROR("Write", location) 85 #define INTERNAL_WRITE_ERROR(location) REPORT_ERROR("Write", location)
89 86
90 static void PutBool(LevelDBTransaction* transaction, 87 static void PutBool(LevelDBTransaction* transaction,
91 const LevelDBSlice& key, 88 const StringPiece& key,
92 bool value) { 89 bool value) {
93 std::vector<char> buffer; 90 std::string buffer;
94 EncodeBool(value, &buffer); 91 EncodeBool(value, &buffer);
95 transaction->Put(key, &buffer); 92 transaction->Put(key, &buffer);
96 } 93 }
97 94
98 template <typename DBOrTransaction> 95 template <typename DBOrTransaction>
99 static bool GetInt(DBOrTransaction* db, 96 static bool GetInt(DBOrTransaction* db,
100 const LevelDBSlice& key, 97 const StringPiece& key,
101 int64* found_int, 98 int64* found_int,
102 bool* found) { 99 bool* found) {
103 std::string result; 100 std::string result;
104 bool ok = db->Get(key, &result, found); 101 bool ok = db->Get(key, &result, found);
105 if (!ok) 102 if (!ok)
106 return false; 103 return false;
107 if (!*found) 104 if (!*found)
108 return true; 105 return true;
109 StringPiece slice(result); 106 StringPiece slice(result);
110 return DecodeInt(&slice, found_int) && slice.empty(); 107 return DecodeInt(&slice, found_int) && slice.empty();
111 } 108 }
112 109
113 static void PutInt(LevelDBTransaction* transaction, 110 static void PutInt(LevelDBTransaction* transaction,
114 const LevelDBSlice& key, 111 const StringPiece& key,
115 int64 value) { 112 int64 value) {
116 DCHECK_GE(value, 0); 113 DCHECK_GE(value, 0);
117 std::vector<char> buffer; 114 std::string buffer;
118 EncodeInt(value, &buffer); 115 EncodeInt(value, &buffer);
119 transaction->Put(key, &buffer); 116 transaction->Put(key, &buffer);
120 } 117 }
121 118
122 template <typename DBOrTransaction> 119 template <typename DBOrTransaction>
123 WARN_UNUSED_RESULT static bool GetVarInt(DBOrTransaction* db, 120 WARN_UNUSED_RESULT static bool GetVarInt(DBOrTransaction* db,
124 const LevelDBSlice& key, 121 const StringPiece& key,
125 int64* found_int, 122 int64* found_int,
126 bool* found) { 123 bool* found) {
127 std::string result; 124 std::string result;
128 bool ok = db->Get(key, &result, found); 125 bool ok = db->Get(key, &result, found);
129 if (!ok) 126 if (!ok)
130 return false; 127 return false;
131 if (!*found) 128 if (!*found)
132 return true; 129 return true;
133 StringPiece slice(result); 130 StringPiece slice(result);
134 return DecodeVarInt(&slice, found_int) && slice.empty(); 131 return DecodeVarInt(&slice, found_int) && slice.empty();
135 } 132 }
136 133
137 static void PutVarInt(LevelDBTransaction* transaction, 134 static void PutVarInt(LevelDBTransaction* transaction,
138 const LevelDBSlice& key, 135 const StringPiece& key,
139 int64 value) { 136 int64 value) {
140 std::vector<char> buffer; 137 std::string buffer;
141 EncodeVarInt(value, &buffer); 138 EncodeVarInt(value, &buffer);
142 transaction->Put(key, &buffer); 139 transaction->Put(key, &buffer);
143 } 140 }
144 141
145 template <typename DBOrTransaction> 142 template <typename DBOrTransaction>
146 WARN_UNUSED_RESULT static bool GetString(DBOrTransaction* db, 143 WARN_UNUSED_RESULT static bool GetString(DBOrTransaction* db,
147 const LevelDBSlice& key, 144 const StringPiece& key,
148 string16* found_string, 145 string16* found_string,
149 bool* found) { 146 bool* found) {
150 std::string result; 147 std::string result;
151 *found = false; 148 *found = false;
152 bool ok = db->Get(key, &result, found); 149 bool ok = db->Get(key, &result, found);
153 if (!ok) 150 if (!ok)
154 return false; 151 return false;
155 if (!*found) 152 if (!*found)
156 return true; 153 return true;
157 StringPiece slice(result); 154 StringPiece slice(result);
158 return DecodeString(&slice, found_string) && slice.empty(); 155 return DecodeString(&slice, found_string) && slice.empty();
159 } 156 }
160 157
161 static void PutString(LevelDBTransaction* transaction, 158 static void PutString(LevelDBTransaction* transaction,
162 const LevelDBSlice& key, 159 const StringPiece& key,
163 const string16& value) { 160 const string16& value) {
164 std::vector<char> buffer; 161 std::string buffer;
165 EncodeString(value, &buffer); 162 EncodeString(value, &buffer);
166 transaction->Put(key, &buffer); 163 transaction->Put(key, &buffer);
167 } 164 }
168 165
169 static void PutIDBKeyPath(LevelDBTransaction* transaction, 166 static void PutIDBKeyPath(LevelDBTransaction* transaction,
170 const LevelDBSlice& key, 167 const StringPiece& key,
171 const IndexedDBKeyPath& value) { 168 const IndexedDBKeyPath& value) {
172 std::vector<char> buffer; 169 std::string buffer;
173 EncodeIDBKeyPath(value, &buffer); 170 EncodeIDBKeyPath(value, &buffer);
174 transaction->Put(key, &buffer); 171 transaction->Put(key, &buffer);
175 } 172 }
176 173
177 static int CompareKeys(const LevelDBSlice& a, const LevelDBSlice& b) { 174 static int CompareKeys(const StringPiece& a, const StringPiece& b) {
178 return Compare(a, b, false /*index_keys*/); 175 return Compare(a, b, false /*index_keys*/);
179 } 176 }
180 177
181 static int CompareIndexKeys(const LevelDBSlice& a, const LevelDBSlice& b) { 178 static int CompareIndexKeys(const StringPiece& a, const StringPiece& b) {
182 return Compare(a, b, true /*index_keys*/); 179 return Compare(a, b, true /*index_keys*/);
183 } 180 }
184 181
185 class Comparator : public LevelDBComparator { 182 class Comparator : public LevelDBComparator {
186 public: 183 public:
187 virtual int Compare(const LevelDBSlice& a, const LevelDBSlice& b) const 184 virtual int Compare(const StringPiece& a, const StringPiece& b) const
188 OVERRIDE { 185 OVERRIDE {
189 return content::Compare(a, b, false /*index_keys*/); 186 return content::Compare(a, b, false /*index_keys*/);
190 } 187 }
191 virtual const char* Name() const OVERRIDE { return "idb_cmp1"; } 188 virtual const char* Name() const OVERRIDE { return "idb_cmp1"; }
192 }; 189 };
193 190
194 // 0 - Initial version. 191 // 0 - Initial version.
195 // 1 - Adds UserIntVersion to DatabaseMetaData. 192 // 1 - Adds UserIntVersion to DatabaseMetaData.
196 // 2 - Adds DataVersion to to global metadata. 193 // 2 - Adds DataVersion to to global metadata.
197 static const int64 kLatestKnownSchemaVersion = 2; 194 static const int64 kLatestKnownSchemaVersion = 2;
198 WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) { 195 WARN_UNUSED_RESULT static bool IsSchemaKnown(LevelDBDatabase* db, bool* known) {
199 int64 db_schema_version = 0; 196 int64 db_schema_version = 0;
200 bool found = false; 197 bool found = false;
201 bool ok = GetInt( 198 bool ok = GetInt(db, SchemaVersionKey::Encode(), &db_schema_version, &found);
202 db, LevelDBSlice(SchemaVersionKey::Encode()), &db_schema_version, &found);
203 if (!ok) 199 if (!ok)
204 return false; 200 return false;
205 if (!found) { 201 if (!found) {
206 *known = true; 202 *known = true;
207 return true; 203 return true;
208 } 204 }
209 if (db_schema_version > kLatestKnownSchemaVersion) { 205 if (db_schema_version > kLatestKnownSchemaVersion) {
210 *known = false; 206 *known = false;
211 return true; 207 return true;
212 } 208 }
213 209
214 const uint32 latest_known_data_version = kWireVersion; 210 const uint32 latest_known_data_version = kWireVersion;
215 int64 db_data_version = 0; 211 int64 db_data_version = 0;
216 ok = GetInt( 212 ok = GetInt(db, DataVersionKey::Encode(), &db_data_version, &found);
217 db, LevelDBSlice(DataVersionKey::Encode()), &db_data_version, &found);
218 if (!ok) 213 if (!ok)
219 return false; 214 return false;
220 if (!found) { 215 if (!found) {
221 *known = true; 216 *known = true;
222 return true; 217 return true;
223 } 218 }
224 219
225 if (db_data_version > latest_known_data_version) { 220 if (db_data_version > latest_known_data_version) {
226 *known = false; 221 *known = false;
227 return true; 222 return true;
228 } 223 }
229 224
230 *known = true; 225 *known = true;
231 return true; 226 return true;
232 } 227 }
233 228
234 WARN_UNUSED_RESULT static bool SetUpMetadata( 229 WARN_UNUSED_RESULT static bool SetUpMetadata(
235 LevelDBDatabase* db, 230 LevelDBDatabase* db,
236 const std::string& origin_identifier) { 231 const std::string& origin_identifier) {
237 const uint32 latest_known_data_version = kWireVersion; 232 const uint32 latest_known_data_version = kWireVersion;
238 const std::vector<char> schema_version_key = SchemaVersionKey::Encode(); 233 const std::string schema_version_key = SchemaVersionKey::Encode();
239 const std::vector<char> data_version_key = DataVersionKey::Encode(); 234 const std::string data_version_key = DataVersionKey::Encode();
240 235
241 scoped_refptr<LevelDBTransaction> transaction = 236 scoped_refptr<LevelDBTransaction> transaction =
242 LevelDBTransaction::Create(db); 237 LevelDBTransaction::Create(db);
243 238
244 int64 db_schema_version = 0; 239 int64 db_schema_version = 0;
245 int64 db_data_version = 0; 240 int64 db_data_version = 0;
246 bool found = false; 241 bool found = false;
247 bool ok = GetInt(transaction.get(), 242 bool ok =
248 LevelDBSlice(schema_version_key), 243 GetInt(transaction.get(), schema_version_key, &db_schema_version, &found);
249 &db_schema_version,
250 &found);
251 if (!ok) { 244 if (!ok) {
252 INTERNAL_READ_ERROR(SET_UP_METADATA); 245 INTERNAL_READ_ERROR(SET_UP_METADATA);
253 return false; 246 return false;
254 } 247 }
255 if (!found) { 248 if (!found) {
256 // Initialize new backing store. 249 // Initialize new backing store.
257 db_schema_version = kLatestKnownSchemaVersion; 250 db_schema_version = kLatestKnownSchemaVersion;
258 PutInt( 251 PutInt(transaction.get(), schema_version_key, db_schema_version);
259 transaction.get(), LevelDBSlice(schema_version_key), db_schema_version);
260 db_data_version = latest_known_data_version; 252 db_data_version = latest_known_data_version;
261 PutInt(transaction.get(), LevelDBSlice(data_version_key), db_data_version); 253 PutInt(transaction.get(), data_version_key, db_data_version);
262 } else { 254 } else {
263 // Upgrade old backing store. 255 // Upgrade old backing store.
264 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion); 256 DCHECK_LE(db_schema_version, kLatestKnownSchemaVersion);
265 if (db_schema_version < 1) { 257 if (db_schema_version < 1) {
266 db_schema_version = 1; 258 db_schema_version = 1;
267 PutInt(transaction.get(), 259 PutInt(transaction.get(), schema_version_key, db_schema_version);
268 LevelDBSlice(schema_version_key), 260 const std::string start_key =
269 db_schema_version);
270 const std::vector<char> start_key =
271 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier); 261 DatabaseNameKey::EncodeMinKeyForOrigin(origin_identifier);
272 const std::vector<char> stop_key = 262 const std::string stop_key =
273 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier); 263 DatabaseNameKey::EncodeStopKeyForOrigin(origin_identifier);
274 scoped_ptr<LevelDBIterator> it = db->CreateIterator(); 264 scoped_ptr<LevelDBIterator> it = db->CreateIterator();
275 for (it->Seek(LevelDBSlice(start_key)); 265 for (it->Seek(start_key);
276 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; 266 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
277 it->Next()) { 267 it->Next()) {
278 int64 database_id = 0; 268 int64 database_id = 0;
279 found = false; 269 found = false;
280 bool ok = GetInt(transaction.get(), it->Key(), &database_id, &found); 270 bool ok = GetInt(transaction.get(), it->Key(), &database_id, &found);
281 if (!ok) { 271 if (!ok) {
282 INTERNAL_READ_ERROR(SET_UP_METADATA); 272 INTERNAL_READ_ERROR(SET_UP_METADATA);
283 return false; 273 return false;
284 } 274 }
285 if (!found) { 275 if (!found) {
286 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA); 276 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
287 return false; 277 return false;
288 } 278 }
289 std::vector<char> int_version_key = DatabaseMetaDataKey::Encode( 279 std::string int_version_key = DatabaseMetaDataKey::Encode(
290 database_id, DatabaseMetaDataKey::USER_INT_VERSION); 280 database_id, DatabaseMetaDataKey::USER_INT_VERSION);
291 PutVarInt(transaction.get(), 281 PutVarInt(transaction.get(),
292 LevelDBSlice(int_version_key), 282 int_version_key,
293 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); 283 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION);
294 } 284 }
295 } 285 }
296 if (db_schema_version < 2) { 286 if (db_schema_version < 2) {
297 db_schema_version = 2; 287 db_schema_version = 2;
298 PutInt(transaction.get(), 288 PutInt(transaction.get(), schema_version_key, db_schema_version);
299 LevelDBSlice(schema_version_key),
300 db_schema_version);
301 db_data_version = kWireVersion; 289 db_data_version = kWireVersion;
302 PutInt( 290 PutInt(transaction.get(), data_version_key, db_data_version);
303 transaction.get(), LevelDBSlice(data_version_key), db_data_version);
304 } 291 }
305 } 292 }
306 293
307 // All new values will be written using this serialization version. 294 // All new values will be written using this serialization version.
308 found = false; 295 found = false;
309 ok = GetInt(transaction.get(), 296 ok = GetInt(transaction.get(), data_version_key, &db_data_version, &found);
310 LevelDBSlice(data_version_key),
311 &db_data_version,
312 &found);
313 if (!ok) { 297 if (!ok) {
314 INTERNAL_READ_ERROR(SET_UP_METADATA); 298 INTERNAL_READ_ERROR(SET_UP_METADATA);
315 return false; 299 return false;
316 } 300 }
317 if (!found) { 301 if (!found) {
318 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA); 302 INTERNAL_CONSISTENCY_ERROR(SET_UP_METADATA);
319 return false; 303 return false;
320 } 304 }
321 if (db_data_version < latest_known_data_version) { 305 if (db_data_version < latest_known_data_version) {
322 db_data_version = latest_known_data_version; 306 db_data_version = latest_known_data_version;
323 PutInt(transaction.get(), LevelDBSlice(data_version_key), db_data_version); 307 PutInt(transaction.get(), data_version_key, db_data_version);
324 } 308 }
325 309
326 DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion); 310 DCHECK_EQ(db_schema_version, kLatestKnownSchemaVersion);
327 DCHECK_EQ(db_data_version, latest_known_data_version); 311 DCHECK_EQ(db_data_version, latest_known_data_version);
328 312
329 if (!transaction->Commit()) { 313 if (!transaction->Commit()) {
330 INTERNAL_WRITE_ERROR(SET_UP_METADATA); 314 INTERNAL_WRITE_ERROR(SET_UP_METADATA);
331 return false; 315 return false;
332 } 316 }
333 return true; 317 return true;
334 } 318 }
335 319
336 template <typename DBOrTransaction> 320 template <typename DBOrTransaction>
337 WARN_UNUSED_RESULT static bool GetMaxObjectStoreId(DBOrTransaction* db, 321 WARN_UNUSED_RESULT static bool GetMaxObjectStoreId(DBOrTransaction* db,
338 int64 database_id, 322 int64 database_id,
339 int64* max_object_store_id) { 323 int64* max_object_store_id) {
340 const std::vector<char> max_object_store_id_key = DatabaseMetaDataKey::Encode( 324 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
341 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); 325 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
342 bool ok = 326 bool ok =
343 GetMaxObjectStoreId(db, max_object_store_id_key, max_object_store_id); 327 GetMaxObjectStoreId(db, max_object_store_id_key, max_object_store_id);
344 return ok; 328 return ok;
345 } 329 }
346 330
347 template <typename DBOrTransaction> 331 template <typename DBOrTransaction>
348 WARN_UNUSED_RESULT static bool GetMaxObjectStoreId( 332 WARN_UNUSED_RESULT static bool GetMaxObjectStoreId(
349 DBOrTransaction* db, 333 DBOrTransaction* db,
350 const std::vector<char>& max_object_store_id_key, 334 const std::string& max_object_store_id_key,
351 int64* max_object_store_id) { 335 int64* max_object_store_id) {
352 *max_object_store_id = -1; 336 *max_object_store_id = -1;
353 bool found = false; 337 bool found = false;
354 bool ok = GetInt( 338 bool ok = GetInt(db, max_object_store_id_key, max_object_store_id, &found);
355 db, LevelDBSlice(max_object_store_id_key), max_object_store_id, &found);
356 if (!ok) 339 if (!ok)
357 return false; 340 return false;
358 if (!found) 341 if (!found)
359 *max_object_store_id = 0; 342 *max_object_store_id = 0;
360 343
361 DCHECK_GE(*max_object_store_id, 0); 344 DCHECK_GE(*max_object_store_id, 0);
362 return true; 345 return true;
363 } 346 }
364 347
365 class DefaultLevelDBFactory : public LevelDBFactory { 348 class DefaultLevelDBFactory : public LevelDBFactory {
(...skipping 18 matching lines...) Expand all
384 comparator_(comparator.Pass()), 367 comparator_(comparator.Pass()),
385 weak_factory_(this) {} 368 weak_factory_(this) {}
386 369
387 IndexedDBBackingStore::~IndexedDBBackingStore() { 370 IndexedDBBackingStore::~IndexedDBBackingStore() {
388 // db_'s destructor uses comparator_. The order of destruction is important. 371 // db_'s destructor uses comparator_. The order of destruction is important.
389 db_.reset(); 372 db_.reset();
390 comparator_.reset(); 373 comparator_.reset();
391 } 374 }
392 375
393 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier( 376 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier(
394 const std::vector<char>& primary_key, 377 const std::string& primary_key,
395 int64 version) 378 int64 version)
396 : primary_key_(primary_key), version_(version) { 379 : primary_key_(primary_key), version_(version) {
397 DCHECK(!primary_key.empty()); 380 DCHECK(!primary_key.empty());
398 } 381 }
399 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier() 382 IndexedDBBackingStore::RecordIdentifier::RecordIdentifier()
400 : primary_key_(), version_(-1) {} 383 : primary_key_(), version_(-1) {}
401 IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() {} 384 IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() {}
402 385
403 IndexedDBBackingStore::Cursor::CursorOptions::CursorOptions() {} 386 IndexedDBBackingStore::Cursor::CursorOptions::CursorOptions() {}
404 IndexedDBBackingStore::Cursor::CursorOptions::~CursorOptions() {} 387 IndexedDBBackingStore::Cursor::CursorOptions::~CursorOptions() {}
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", 444 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus",
462 1, 445 1,
463 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, 446 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX,
464 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, 447 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1,
465 base::HistogramBase::kUmaTargetedHistogramFlag) 448 base::HistogramBase::kUmaTargetedHistogramFlag)
466 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY); 449 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_FAILED_DIRECTORY);
467 return scoped_refptr<IndexedDBBackingStore>(); 450 return scoped_refptr<IndexedDBBackingStore>();
468 } 451 }
469 452
470 base::FilePath identifier_path = 453 base::FilePath identifier_path =
471 base::FilePath().AppendASCII(origin_identifier). 454 base::FilePath().AppendASCII(origin_identifier)
472 AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb")); 455 .AddExtension(FILE_PATH_LITERAL(".indexeddb.leveldb"));
473 456
474 int limit = file_util::GetMaximumPathComponentLength(path_base); 457 int limit = file_util::GetMaximumPathComponentLength(path_base);
475 if (limit == -1) { 458 if (limit == -1) {
476 DLOG(WARNING) << "GetMaximumPathComponentLength returned -1"; 459 DLOG(WARNING) << "GetMaximumPathComponentLength returned -1";
477 // In limited testing, ChromeOS returns 143, other OSes 255. 460 // In limited testing, ChromeOS returns 143, other OSes 255.
478 #if defined(OS_CHROMEOS) 461 #if defined(OS_CHROMEOS)
479 limit = 143; 462 limit = 143;
480 #else 463 #else
481 limit = 255; 464 limit = 255;
482 #endif 465 #endif
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 525
543 if (db) { 526 if (db) {
544 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus", 527 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus",
545 1, 528 1,
546 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, 529 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX,
547 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, 530 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1,
548 base::HistogramBase::kUmaTargetedHistogramFlag) 531 base::HistogramBase::kUmaTargetedHistogramFlag)
549 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_SUCCESS); 532 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_SUCCESS);
550 } else if (is_disk_full) { 533 } else if (is_disk_full) {
551 LOG(ERROR) << "Unable to open backing store - disk is full."; 534 LOG(ERROR) << "Unable to open backing store - disk is full.";
552 base::Histogram::FactoryGet( 535 base::Histogram::FactoryGet("WebCore.IndexedDB.BackingStore.OpenStatus",
553 "WebCore.IndexedDB.BackingStore.OpenStatus", 536 1,
554 1, 537 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX,
555 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX, 538 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1,
556 INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_MAX + 1, 539 base::HistogramBase::kUmaTargetedHistogramFlag)
557 base::HistogramBase::kUmaTargetedHistogramFlag)
558 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_DISK_FULL); 540 ->Add(INDEXED_DB_LEVEL_DB_BACKING_STORE_OPEN_DISK_FULL);
559 return scoped_refptr<IndexedDBBackingStore>(); 541 return scoped_refptr<IndexedDBBackingStore>();
560 } else { 542 } else {
561 LOG(ERROR) << "IndexedDB backing store open failed, attempting cleanup"; 543 LOG(ERROR) << "IndexedDB backing store open failed, attempting cleanup";
562 *data_loss = WebKit::WebIDBCallbacks::DataLossTotal; 544 *data_loss = WebKit::WebIDBCallbacks::DataLossTotal;
563 bool success = leveldb_factory->DestroyLevelDB(file_path); 545 bool success = leveldb_factory->DestroyLevelDB(file_path);
564 if (!success) { 546 if (!success) {
565 LOG(ERROR) << "IndexedDB backing store cleanup failed"; 547 LOG(ERROR) << "IndexedDB backing store cleanup failed";
566 base::Histogram::FactoryGet( 548 base::Histogram::FactoryGet(
567 "WebCore.IndexedDB.BackingStore.OpenStatus", 549 "WebCore.IndexedDB.BackingStore.OpenStatus",
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 new IndexedDBBackingStore(identifier, db.Pass(), comparator.Pass())); 633 new IndexedDBBackingStore(identifier, db.Pass(), comparator.Pass()));
652 634
653 if (!SetUpMetadata(backing_store->db_.get(), identifier)) 635 if (!SetUpMetadata(backing_store->db_.get(), identifier))
654 return scoped_refptr<IndexedDBBackingStore>(); 636 return scoped_refptr<IndexedDBBackingStore>();
655 637
656 return backing_store; 638 return backing_store;
657 } 639 }
658 640
659 std::vector<string16> IndexedDBBackingStore::GetDatabaseNames() { 641 std::vector<string16> IndexedDBBackingStore::GetDatabaseNames() {
660 std::vector<string16> found_names; 642 std::vector<string16> found_names;
661 const std::vector<char> start_key = 643 const std::string start_key =
662 DatabaseNameKey::EncodeMinKeyForOrigin(identifier_); 644 DatabaseNameKey::EncodeMinKeyForOrigin(identifier_);
663 const std::vector<char> stop_key = 645 const std::string stop_key =
664 DatabaseNameKey::EncodeStopKeyForOrigin(identifier_); 646 DatabaseNameKey::EncodeStopKeyForOrigin(identifier_);
665 647
666 DCHECK(found_names.empty()); 648 DCHECK(found_names.empty());
667 649
668 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 650 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
669 for (it->Seek(LevelDBSlice(start_key)); 651 for (it->Seek(start_key);
670 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; 652 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
671 it->Next()) { 653 it->Next()) {
672 const char* p = it->Key().begin(); 654 const char* p = it->Key().begin();
673 const char* limit = it->Key().end(); 655 const char* limit = it->Key().end();
674 656
675 DatabaseNameKey database_name_key; 657 DatabaseNameKey database_name_key;
676 p = DatabaseNameKey::Decode(p, limit, &database_name_key); 658 p = DatabaseNameKey::Decode(p, limit, &database_name_key);
677 DCHECK(p); 659 DCHECK(p);
678 660
679 found_names.push_back(database_name_key.database_name()); 661 found_names.push_back(database_name_key.database_name());
680 } 662 }
681 return found_names; 663 return found_names;
682 } 664 }
683 665
684 bool IndexedDBBackingStore::GetIDBDatabaseMetaData( 666 bool IndexedDBBackingStore::GetIDBDatabaseMetaData(
685 const string16& name, 667 const string16& name,
686 IndexedDBDatabaseMetadata* metadata, 668 IndexedDBDatabaseMetadata* metadata,
687 bool* found) { 669 bool* found) {
688 const std::vector<char> key = DatabaseNameKey::Encode(identifier_, name); 670 const std::string key = DatabaseNameKey::Encode(identifier_, name);
689 *found = false; 671 *found = false;
690 672
691 bool ok = GetInt(db_.get(), LevelDBSlice(key), &metadata->id, found); 673 bool ok = GetInt(db_.get(), key, &metadata->id, found);
692 if (!ok) { 674 if (!ok) {
693 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 675 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA);
694 return false; 676 return false;
695 } 677 }
696 if (!*found) 678 if (!*found)
697 return true; 679 return true;
698 680
699 ok = GetString(db_.get(), 681 ok = GetString(db_.get(),
700 LevelDBSlice(DatabaseMetaDataKey::Encode( 682 DatabaseMetaDataKey::Encode(metadata->id,
701 metadata->id, DatabaseMetaDataKey::USER_VERSION)), 683 DatabaseMetaDataKey::USER_VERSION),
702 &metadata->version, 684 &metadata->version,
703 found); 685 found);
704 if (!ok) { 686 if (!ok) {
705 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 687 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA);
706 return false; 688 return false;
707 } 689 }
708 if (!*found) { 690 if (!*found) {
709 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA); 691 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA);
710 return false; 692 return false;
711 } 693 }
712 694
713 ok = GetVarInt(db_.get(), 695 ok = GetVarInt(db_.get(),
714 LevelDBSlice(DatabaseMetaDataKey::Encode( 696 DatabaseMetaDataKey::Encode(
715 metadata->id, DatabaseMetaDataKey::USER_INT_VERSION)), 697 metadata->id, DatabaseMetaDataKey::USER_INT_VERSION),
716 &metadata->int_version, 698 &metadata->int_version,
717 found); 699 found);
718 if (!ok) { 700 if (!ok) {
719 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA); 701 INTERNAL_READ_ERROR(GET_IDBDATABASE_METADATA);
720 return false; 702 return false;
721 } 703 }
722 if (!*found) { 704 if (!*found) {
723 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA); 705 INTERNAL_CONSISTENCY_ERROR(GET_IDBDATABASE_METADATA);
724 return false; 706 return false;
725 } 707 }
(...skipping 12 matching lines...) Expand all
738 } 720 }
739 721
740 WARN_UNUSED_RESULT static bool GetNewDatabaseId(LevelDBDatabase* db, 722 WARN_UNUSED_RESULT static bool GetNewDatabaseId(LevelDBDatabase* db,
741 int64* new_id) { 723 int64* new_id) {
742 scoped_refptr<LevelDBTransaction> transaction = 724 scoped_refptr<LevelDBTransaction> transaction =
743 LevelDBTransaction::Create(db); 725 LevelDBTransaction::Create(db);
744 726
745 *new_id = -1; 727 *new_id = -1;
746 int64 max_database_id = -1; 728 int64 max_database_id = -1;
747 bool found = false; 729 bool found = false;
748 bool ok = GetInt(transaction.get(), 730 bool ok = GetInt(
749 LevelDBSlice(MaxDatabaseIdKey::Encode()), 731 transaction.get(), MaxDatabaseIdKey::Encode(), &max_database_id, &found);
750 &max_database_id,
751 &found);
752 if (!ok) { 732 if (!ok) {
753 INTERNAL_READ_ERROR(GET_NEW_DATABASE_ID); 733 INTERNAL_READ_ERROR(GET_NEW_DATABASE_ID);
754 return false; 734 return false;
755 } 735 }
756 if (!found) 736 if (!found)
757 max_database_id = 0; 737 max_database_id = 0;
758 738
759 DCHECK_GE(max_database_id, 0); 739 DCHECK_GE(max_database_id, 0);
760 740
761 int64 database_id = max_database_id + 1; 741 int64 database_id = max_database_id + 1;
762 PutInt( 742 PutInt(transaction.get(), MaxDatabaseIdKey::Encode(), database_id);
763 transaction.get(), LevelDBSlice(MaxDatabaseIdKey::Encode()), database_id);
764 if (!transaction->Commit()) { 743 if (!transaction->Commit()) {
765 INTERNAL_WRITE_ERROR(GET_NEW_DATABASE_ID); 744 INTERNAL_WRITE_ERROR(GET_NEW_DATABASE_ID);
766 return false; 745 return false;
767 } 746 }
768 *new_id = database_id; 747 *new_id = database_id;
769 return true; 748 return true;
770 } 749 }
771 750
772 bool IndexedDBBackingStore::CreateIDBDatabaseMetaData(const string16& name, 751 bool IndexedDBBackingStore::CreateIDBDatabaseMetaData(const string16& name,
773 const string16& version, 752 const string16& version,
774 int64 int_version, 753 int64 int_version,
775 int64* row_id) { 754 int64* row_id) {
776 bool ok = GetNewDatabaseId(db_.get(), row_id); 755 bool ok = GetNewDatabaseId(db_.get(), row_id);
777 if (!ok) 756 if (!ok)
778 return false; 757 return false;
779 DCHECK_GE(*row_id, 0); 758 DCHECK_GE(*row_id, 0);
780 759
781 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) 760 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
782 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; 761 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
783 762
784 scoped_refptr<LevelDBTransaction> transaction = 763 scoped_refptr<LevelDBTransaction> transaction =
785 LevelDBTransaction::Create(db_.get()); 764 LevelDBTransaction::Create(db_.get());
786 PutInt(transaction.get(), 765 PutInt(
787 LevelDBSlice(DatabaseNameKey::Encode(identifier_, name)), 766 transaction.get(), DatabaseNameKey::Encode(identifier_, name), *row_id);
788 *row_id); 767 PutString(
789 PutString(transaction.get(), 768 transaction.get(),
790 LevelDBSlice(DatabaseMetaDataKey::Encode( 769 DatabaseMetaDataKey::Encode(*row_id, DatabaseMetaDataKey::USER_VERSION),
791 *row_id, DatabaseMetaDataKey::USER_VERSION)), 770 version);
792 version);
793 PutVarInt(transaction.get(), 771 PutVarInt(transaction.get(),
794 LevelDBSlice(DatabaseMetaDataKey::Encode( 772 DatabaseMetaDataKey::Encode(*row_id,
795 *row_id, DatabaseMetaDataKey::USER_INT_VERSION)), 773 DatabaseMetaDataKey::USER_INT_VERSION),
796 int_version); 774 int_version);
797 if (!transaction->Commit()) { 775 if (!transaction->Commit()) {
798 INTERNAL_WRITE_ERROR(CREATE_IDBDATABASE_METADATA); 776 INTERNAL_WRITE_ERROR(CREATE_IDBDATABASE_METADATA);
799 return false; 777 return false;
800 } 778 }
801 return true; 779 return true;
802 } 780 }
803 781
804 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( 782 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion(
805 IndexedDBBackingStore::Transaction* transaction, 783 IndexedDBBackingStore::Transaction* transaction,
806 int64 row_id, 784 int64 row_id,
807 int64 int_version) { 785 int64 int_version) {
808 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION) 786 if (int_version == IndexedDBDatabaseMetadata::NO_INT_VERSION)
809 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION; 787 int_version = IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION;
810 DCHECK_GE(int_version, 0) << "int_version was " << int_version; 788 DCHECK_GE(int_version, 0) << "int_version was " << int_version;
811 PutVarInt(Transaction::LevelDBTransactionFrom(transaction), 789 PutVarInt(Transaction::LevelDBTransactionFrom(transaction),
812 LevelDBSlice(DatabaseMetaDataKey::Encode( 790 DatabaseMetaDataKey::Encode(row_id,
813 row_id, DatabaseMetaDataKey::USER_INT_VERSION)), 791 DatabaseMetaDataKey::USER_INT_VERSION),
814 int_version); 792 int_version);
815 return true; 793 return true;
816 } 794 }
817 795
818 bool IndexedDBBackingStore::UpdateIDBDatabaseMetaData( 796 bool IndexedDBBackingStore::UpdateIDBDatabaseMetaData(
819 IndexedDBBackingStore::Transaction* transaction, 797 IndexedDBBackingStore::Transaction* transaction,
820 int64 row_id, 798 int64 row_id,
821 const string16& version) { 799 const string16& version) {
822 PutString(Transaction::LevelDBTransactionFrom(transaction), 800 PutString(
823 LevelDBSlice(DatabaseMetaDataKey::Encode( 801 Transaction::LevelDBTransactionFrom(transaction),
824 row_id, DatabaseMetaDataKey::USER_VERSION)), 802 DatabaseMetaDataKey::Encode(row_id, DatabaseMetaDataKey::USER_VERSION),
825 version); 803 version);
826 return true; 804 return true;
827 } 805 }
828 806
829 static void DeleteRange(LevelDBTransaction* transaction, 807 static void DeleteRange(LevelDBTransaction* transaction,
830 const std::vector<char>& begin, 808 const std::string& begin,
831 const std::vector<char>& end) { 809 const std::string& end) {
832 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 810 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
833 for (it->Seek(LevelDBSlice(begin)); 811 for (it->Seek(begin); it->IsValid() && CompareKeys(it->Key(), end) < 0;
834 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(end)) < 0;
835 it->Next()) 812 it->Next())
836 transaction->Remove(it->Key()); 813 transaction->Remove(it->Key());
837 } 814 }
838 815
839 bool IndexedDBBackingStore::DeleteDatabase(const string16& name) { 816 bool IndexedDBBackingStore::DeleteDatabase(const string16& name) {
840 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase"); 817 IDB_TRACE("IndexedDBBackingStore::DeleteDatabase");
841 scoped_ptr<LevelDBWriteOnlyTransaction> transaction = 818 scoped_ptr<LevelDBWriteOnlyTransaction> transaction =
842 LevelDBWriteOnlyTransaction::Create(db_.get()); 819 LevelDBWriteOnlyTransaction::Create(db_.get());
843 820
844 IndexedDBDatabaseMetadata metadata; 821 IndexedDBDatabaseMetadata metadata;
845 bool success = false; 822 bool success = false;
846 bool ok = GetIDBDatabaseMetaData(name, &metadata, &success); 823 bool ok = GetIDBDatabaseMetaData(name, &metadata, &success);
847 if (!ok) 824 if (!ok)
848 return false; 825 return false;
849 if (!success) 826 if (!success)
850 return true; 827 return true;
851 828
852 const std::vector<char> start_key = DatabaseMetaDataKey::Encode( 829 const std::string start_key = DatabaseMetaDataKey::Encode(
853 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME); 830 metadata.id, DatabaseMetaDataKey::ORIGIN_NAME);
854 const std::vector<char> stop_key = DatabaseMetaDataKey::Encode( 831 const std::string stop_key = DatabaseMetaDataKey::Encode(
855 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME); 832 metadata.id + 1, DatabaseMetaDataKey::ORIGIN_NAME);
856 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 833 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
857 for (it->Seek(LevelDBSlice(start_key)); 834 for (it->Seek(start_key);
858 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; 835 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
859 it->Next()) 836 it->Next())
860 transaction->Remove(it->Key()); 837 transaction->Remove(it->Key());
861 838
862 const std::vector<char> key = DatabaseNameKey::Encode(identifier_, name); 839 const std::string key = DatabaseNameKey::Encode(identifier_, name);
863 transaction->Remove(LevelDBSlice(key)); 840 transaction->Remove(key);
864 841
865 if (!transaction->Commit()) { 842 if (!transaction->Commit()) {
866 INTERNAL_WRITE_ERROR(DELETE_DATABASE); 843 INTERNAL_WRITE_ERROR(DELETE_DATABASE);
867 return false; 844 return false;
868 } 845 }
869 return true; 846 return true;
870 } 847 }
871 848
872 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it, 849 static bool CheckObjectStoreAndMetaDataType(const LevelDBIterator* it,
873 const std::vector<char>& stop_key, 850 const std::string& stop_key,
874 int64 object_store_id, 851 int64 object_store_id,
875 int64 meta_data_type) { 852 int64 meta_data_type) {
876 if (!it->IsValid() || CompareKeys(it->Key(), LevelDBSlice(stop_key)) >= 0) 853 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0)
877 return false; 854 return false;
878 855
879 ObjectStoreMetaDataKey meta_data_key; 856 ObjectStoreMetaDataKey meta_data_key;
880 const char* p = ObjectStoreMetaDataKey::Decode( 857 const char* p = ObjectStoreMetaDataKey::Decode(
881 it->Key().begin(), it->Key().end(), &meta_data_key); 858 it->Key().begin(), it->Key().end(), &meta_data_key);
882 DCHECK(p); 859 DCHECK(p);
883 if (meta_data_key.ObjectStoreId() != object_store_id) 860 if (meta_data_key.ObjectStoreId() != object_store_id)
884 return false; 861 return false;
885 if (meta_data_key.MetaDataType() != meta_data_type) 862 if (meta_data_key.MetaDataType() != meta_data_type)
886 return false; 863 return false;
887 return true; 864 return true;
888 } 865 }
889 866
890 // TODO(jsbell): This should do some error handling rather than 867 // TODO(jsbell): This should do some error handling rather than
891 // plowing ahead when bad data is encountered. 868 // plowing ahead when bad data is encountered.
892 bool IndexedDBBackingStore::GetObjectStores( 869 bool IndexedDBBackingStore::GetObjectStores(
893 int64 database_id, 870 int64 database_id,
894 IndexedDBDatabaseMetadata::ObjectStoreMap* object_stores) { 871 IndexedDBDatabaseMetadata::ObjectStoreMap* object_stores) {
895 IDB_TRACE("IndexedDBBackingStore::GetObjectStores"); 872 IDB_TRACE("IndexedDBBackingStore::GetObjectStores");
896 if (!KeyPrefix::IsValidDatabaseId(database_id)) 873 if (!KeyPrefix::IsValidDatabaseId(database_id))
897 return false; 874 return false;
898 const std::vector<char> start_key = 875 const std::string start_key =
899 ObjectStoreMetaDataKey::Encode(database_id, 1, 0); 876 ObjectStoreMetaDataKey::Encode(database_id, 1, 0);
900 const std::vector<char> stop_key = 877 const std::string stop_key =
901 ObjectStoreMetaDataKey::EncodeMaxKey(database_id); 878 ObjectStoreMetaDataKey::EncodeMaxKey(database_id);
902 879
903 DCHECK(object_stores->empty()); 880 DCHECK(object_stores->empty());
904 881
905 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 882 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
906 it->Seek(LevelDBSlice(start_key)); 883 it->Seek(start_key);
907 while (it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0) { 884 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
908 const char* p = it->Key().begin(); 885 const char* p = it->Key().begin();
909 const char* limit = it->Key().end(); 886 const char* limit = it->Key().end();
910 887
911 ObjectStoreMetaDataKey meta_data_key; 888 ObjectStoreMetaDataKey meta_data_key;
912 p = ObjectStoreMetaDataKey::Decode(p, limit, &meta_data_key); 889 p = ObjectStoreMetaDataKey::Decode(p, limit, &meta_data_key);
913 DCHECK(p); 890 DCHECK(p);
914 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) { 891 if (meta_data_key.MetaDataType() != ObjectStoreMetaDataKey::NAME) {
915 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 892 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
916 // Possible stale metadata, but don't fail the load. 893 // Possible stale metadata, but don't fail the load.
917 it->Next(); 894 it->Next();
918 continue; 895 continue;
919 } 896 }
920 897
921 int64 object_store_id = meta_data_key.ObjectStoreId(); 898 int64 object_store_id = meta_data_key.ObjectStoreId();
922 899
923 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 900 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
924 // simplify. 901 // simplify.
925 string16 object_store_name; 902 string16 object_store_name;
926 { 903 {
927 StringPiece slice(it->Value().AsStringPiece()); 904 StringPiece slice(it->Value());
928 if (!DecodeString(&slice, &object_store_name) || !slice.empty()) 905 if (!DecodeString(&slice, &object_store_name) || !slice.empty())
929 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 906 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
930 } 907 }
931 908
932 it->Next(); 909 it->Next();
933 if (!CheckObjectStoreAndMetaDataType(it.get(), 910 if (!CheckObjectStoreAndMetaDataType(it.get(),
934 stop_key, 911 stop_key,
935 object_store_id, 912 object_store_id,
936 ObjectStoreMetaDataKey::KEY_PATH)) { 913 ObjectStoreMetaDataKey::KEY_PATH)) {
937 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 914 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
938 break; 915 break;
939 } 916 }
940 IndexedDBKeyPath key_path; 917 IndexedDBKeyPath key_path;
941 { 918 {
942 StringPiece slice(it->Value().AsStringPiece()); 919 StringPiece slice(it->Value());
943 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 920 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
944 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 921 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
945 } 922 }
946 923
947 it->Next(); 924 it->Next();
948 if (!CheckObjectStoreAndMetaDataType( 925 if (!CheckObjectStoreAndMetaDataType(
949 it.get(), 926 it.get(),
950 stop_key, 927 stop_key,
951 object_store_id, 928 object_store_id,
952 ObjectStoreMetaDataKey::AUTO_INCREMENT)) { 929 ObjectStoreMetaDataKey::AUTO_INCREMENT)) {
953 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 930 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
954 break; 931 break;
955 } 932 }
956 bool auto_increment; 933 bool auto_increment;
957 { 934 {
958 StringPiece slice(it->Value().AsStringPiece()); 935 StringPiece slice(it->Value());
959 if (!DecodeBool(&slice, &auto_increment) || !slice.empty()) 936 if (!DecodeBool(&slice, &auto_increment) || !slice.empty())
960 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 937 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
961 } 938 }
962 939
963 it->Next(); // Is evicatble. 940 it->Next(); // Is evicatble.
964 if (!CheckObjectStoreAndMetaDataType(it.get(), 941 if (!CheckObjectStoreAndMetaDataType(it.get(),
965 stop_key, 942 stop_key,
966 object_store_id, 943 object_store_id,
967 ObjectStoreMetaDataKey::EVICTABLE)) { 944 ObjectStoreMetaDataKey::EVICTABLE)) {
968 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 945 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
(...skipping 14 matching lines...) Expand all
983 if (!CheckObjectStoreAndMetaDataType( 960 if (!CheckObjectStoreAndMetaDataType(
984 it.get(), 961 it.get(),
985 stop_key, 962 stop_key,
986 object_store_id, 963 object_store_id,
987 ObjectStoreMetaDataKey::MAX_INDEX_ID)) { 964 ObjectStoreMetaDataKey::MAX_INDEX_ID)) {
988 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 965 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
989 break; 966 break;
990 } 967 }
991 int64 max_index_id; 968 int64 max_index_id;
992 { 969 {
993 StringPiece slice(it->Value().AsStringPiece()); 970 StringPiece slice(it->Value());
994 if (!DecodeInt(&slice, &max_index_id) || !slice.empty()) 971 if (!DecodeInt(&slice, &max_index_id) || !slice.empty())
995 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 972 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
996 } 973 }
997 974
998 it->Next(); // [optional] has key path (is not null) 975 it->Next(); // [optional] has key path (is not null)
999 if (CheckObjectStoreAndMetaDataType(it.get(), 976 if (CheckObjectStoreAndMetaDataType(it.get(),
1000 stop_key, 977 stop_key,
1001 object_store_id, 978 object_store_id,
1002 ObjectStoreMetaDataKey::HAS_KEY_PATH)) { 979 ObjectStoreMetaDataKey::HAS_KEY_PATH)) {
1003 bool has_key_path; 980 bool has_key_path;
1004 { 981 {
1005 StringPiece slice(it->Value().AsStringPiece()); 982 StringPiece slice(it->Value());
1006 if (!DecodeBool(&slice, &has_key_path)) 983 if (!DecodeBool(&slice, &has_key_path))
1007 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 984 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
1008 } 985 }
1009 // This check accounts for two layers of legacy coding: 986 // This check accounts for two layers of legacy coding:
1010 // (1) Initially, has_key_path was added to distinguish null vs. string. 987 // (1) Initially, has_key_path was added to distinguish null vs. string.
1011 // (2) Later, null vs. string vs. array was stored in the key_path itself. 988 // (2) Later, null vs. string vs. array was stored in the key_path itself.
1012 // So this check is only relevant for string-type key_paths. 989 // So this check is only relevant for string-type key_paths.
1013 if (!has_key_path && 990 if (!has_key_path &&
1014 (key_path.type() == WebKit::WebIDBKeyPath::StringType && 991 (key_path.type() == WebKit::WebIDBKeyPath::StringType &&
1015 !key_path.string().empty())) { 992 !key_path.string().empty())) {
1016 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 993 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
1017 break; 994 break;
1018 } 995 }
1019 if (!has_key_path) 996 if (!has_key_path)
1020 key_path = IndexedDBKeyPath(); 997 key_path = IndexedDBKeyPath();
1021 it->Next(); 998 it->Next();
1022 } 999 }
1023 1000
1024 int64 key_generator_current_number = -1; 1001 int64 key_generator_current_number = -1;
1025 if (CheckObjectStoreAndMetaDataType( 1002 if (CheckObjectStoreAndMetaDataType(
1026 it.get(), 1003 it.get(),
1027 stop_key, 1004 stop_key,
1028 object_store_id, 1005 object_store_id,
1029 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) { 1006 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER)) {
1030 StringPiece slice(it->Value().AsStringPiece()); 1007 StringPiece slice(it->Value());
1031 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty()) 1008 if (!DecodeInt(&slice, &key_generator_current_number) || !slice.empty())
1032 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES); 1009 INTERNAL_CONSISTENCY_ERROR(GET_OBJECT_STORES);
1033 1010
1034 // TODO(jsbell): Return key_generator_current_number, cache in 1011 // TODO(jsbell): Return key_generator_current_number, cache in
1035 // object store, and write lazily to backing store. For now, 1012 // object store, and write lazily to backing store. For now,
1036 // just assert that if it was written it was valid. 1013 // just assert that if it was written it was valid.
1037 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber); 1014 DCHECK_GE(key_generator_current_number, kKeyGeneratorInitialNumber);
1038 it->Next(); 1015 it->Next();
1039 } 1016 }
1040 1017
1041 IndexedDBObjectStoreMetadata metadata(object_store_name, 1018 IndexedDBObjectStoreMetadata metadata(object_store_name,
1042 object_store_id, 1019 object_store_id,
1043 key_path, 1020 key_path,
1044 auto_increment, 1021 auto_increment,
1045 max_index_id); 1022 max_index_id);
1046 if (!GetIndexes(database_id, object_store_id, &metadata.indexes)) 1023 if (!GetIndexes(database_id, object_store_id, &metadata.indexes))
1047 return false; 1024 return false;
1048 (*object_stores)[object_store_id] = metadata; 1025 (*object_stores)[object_store_id] = metadata;
1049 } 1026 }
1050 return true; 1027 return true;
1051 } 1028 }
1052 1029
1053 WARN_UNUSED_RESULT static bool SetMaxObjectStoreId( 1030 WARN_UNUSED_RESULT static bool SetMaxObjectStoreId(
1054 LevelDBTransaction* transaction, 1031 LevelDBTransaction* transaction,
1055 int64 database_id, 1032 int64 database_id,
1056 int64 object_store_id) { 1033 int64 object_store_id) {
1057 const std::vector<char> max_object_store_id_key = DatabaseMetaDataKey::Encode( 1034 const std::string max_object_store_id_key = DatabaseMetaDataKey::Encode(
1058 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID); 1035 database_id, DatabaseMetaDataKey::MAX_OBJECT_STORE_ID);
1059 int64 max_object_store_id = -1; 1036 int64 max_object_store_id = -1;
1060 bool ok = GetMaxObjectStoreId( 1037 bool ok = GetMaxObjectStoreId(
1061 transaction, max_object_store_id_key, &max_object_store_id); 1038 transaction, max_object_store_id_key, &max_object_store_id);
1062 if (!ok) { 1039 if (!ok) {
1063 INTERNAL_READ_ERROR(SET_MAX_OBJECT_STORE_ID); 1040 INTERNAL_READ_ERROR(SET_MAX_OBJECT_STORE_ID);
1064 return false; 1041 return false;
1065 } 1042 }
1066 1043
1067 if (object_store_id <= max_object_store_id) { 1044 if (object_store_id <= max_object_store_id) {
1068 INTERNAL_CONSISTENCY_ERROR(SET_MAX_OBJECT_STORE_ID); 1045 INTERNAL_CONSISTENCY_ERROR(SET_MAX_OBJECT_STORE_ID);
1069 return false; 1046 return false;
1070 } 1047 }
1071 PutInt(transaction, LevelDBSlice(max_object_store_id_key), object_store_id); 1048 PutInt(transaction, max_object_store_id_key, object_store_id);
1072 return true; 1049 return true;
1073 } 1050 }
1074 1051
1075 bool IndexedDBBackingStore::CreateObjectStore( 1052 bool IndexedDBBackingStore::CreateObjectStore(
1076 IndexedDBBackingStore::Transaction* transaction, 1053 IndexedDBBackingStore::Transaction* transaction,
1077 int64 database_id, 1054 int64 database_id,
1078 int64 object_store_id, 1055 int64 object_store_id,
1079 const string16& name, 1056 const string16& name,
1080 const IndexedDBKeyPath& key_path, 1057 const IndexedDBKeyPath& key_path,
1081 bool auto_increment) { 1058 bool auto_increment) {
1082 IDB_TRACE("IndexedDBBackingStore::CreateObjectStore"); 1059 IDB_TRACE("IndexedDBBackingStore::CreateObjectStore");
1083 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1060 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1084 return false; 1061 return false;
1085 LevelDBTransaction* leveldb_transaction = 1062 LevelDBTransaction* leveldb_transaction =
1086 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1063 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1087 if (!SetMaxObjectStoreId(leveldb_transaction, database_id, object_store_id)) 1064 if (!SetMaxObjectStoreId(leveldb_transaction, database_id, object_store_id))
1088 return false; 1065 return false;
1089 1066
1090 const std::vector<char> name_key = ObjectStoreMetaDataKey::Encode( 1067 const std::string name_key = ObjectStoreMetaDataKey::Encode(
1091 database_id, object_store_id, ObjectStoreMetaDataKey::NAME); 1068 database_id, object_store_id, ObjectStoreMetaDataKey::NAME);
1092 const std::vector<char> key_path_key = ObjectStoreMetaDataKey::Encode( 1069 const std::string key_path_key = ObjectStoreMetaDataKey::Encode(
1093 database_id, object_store_id, ObjectStoreMetaDataKey::KEY_PATH); 1070 database_id, object_store_id, ObjectStoreMetaDataKey::KEY_PATH);
1094 const std::vector<char> auto_increment_key = ObjectStoreMetaDataKey::Encode( 1071 const std::string auto_increment_key = ObjectStoreMetaDataKey::Encode(
1095 database_id, object_store_id, ObjectStoreMetaDataKey::AUTO_INCREMENT); 1072 database_id, object_store_id, ObjectStoreMetaDataKey::AUTO_INCREMENT);
1096 const std::vector<char> evictable_key = ObjectStoreMetaDataKey::Encode( 1073 const std::string evictable_key = ObjectStoreMetaDataKey::Encode(
1097 database_id, object_store_id, ObjectStoreMetaDataKey::EVICTABLE); 1074 database_id, object_store_id, ObjectStoreMetaDataKey::EVICTABLE);
1098 const std::vector<char> last_version_key = ObjectStoreMetaDataKey::Encode( 1075 const std::string last_version_key = ObjectStoreMetaDataKey::Encode(
1099 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); 1076 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
1100 const std::vector<char> max_index_id_key = ObjectStoreMetaDataKey::Encode( 1077 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode(
1101 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); 1078 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID);
1102 const std::vector<char> has_key_path_key = ObjectStoreMetaDataKey::Encode( 1079 const std::string has_key_path_key = ObjectStoreMetaDataKey::Encode(
1103 database_id, object_store_id, ObjectStoreMetaDataKey::HAS_KEY_PATH); 1080 database_id, object_store_id, ObjectStoreMetaDataKey::HAS_KEY_PATH);
1104 const std::vector<char> key_generator_current_number_key = 1081 const std::string key_generator_current_number_key =
1105 ObjectStoreMetaDataKey::Encode( 1082 ObjectStoreMetaDataKey::Encode(
1106 database_id, 1083 database_id,
1107 object_store_id, 1084 object_store_id,
1108 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); 1085 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER);
1109 const std::vector<char> names_key = 1086 const std::string names_key = ObjectStoreNamesKey::Encode(database_id, name);
1110 ObjectStoreNamesKey::Encode(database_id, name);
1111 1087
1112 PutString(leveldb_transaction, LevelDBSlice(name_key), name); 1088 PutString(leveldb_transaction, name_key, name);
1113 PutIDBKeyPath(leveldb_transaction, LevelDBSlice(key_path_key), key_path); 1089 PutIDBKeyPath(leveldb_transaction, key_path_key, key_path);
1114 PutInt(leveldb_transaction, LevelDBSlice(auto_increment_key), auto_increment); 1090 PutInt(leveldb_transaction, auto_increment_key, auto_increment);
1115 PutInt(leveldb_transaction, LevelDBSlice(evictable_key), false); 1091 PutInt(leveldb_transaction, evictable_key, false);
1116 PutInt(leveldb_transaction, LevelDBSlice(last_version_key), 1); 1092 PutInt(leveldb_transaction, last_version_key, 1);
1117 PutInt(leveldb_transaction, LevelDBSlice(max_index_id_key), kMinimumIndexId); 1093 PutInt(leveldb_transaction, max_index_id_key, kMinimumIndexId);
1118 PutBool( 1094 PutBool(leveldb_transaction, has_key_path_key, !key_path.IsNull());
1119 leveldb_transaction, LevelDBSlice(has_key_path_key), !key_path.IsNull());
1120 PutInt(leveldb_transaction, 1095 PutInt(leveldb_transaction,
1121 LevelDBSlice(key_generator_current_number_key), 1096 key_generator_current_number_key,
1122 kKeyGeneratorInitialNumber); 1097 kKeyGeneratorInitialNumber);
1123 PutInt(leveldb_transaction, LevelDBSlice(names_key), object_store_id); 1098 PutInt(leveldb_transaction, names_key, object_store_id);
1124 return true; 1099 return true;
1125 } 1100 }
1126 1101
1127 bool IndexedDBBackingStore::DeleteObjectStore( 1102 bool IndexedDBBackingStore::DeleteObjectStore(
1128 IndexedDBBackingStore::Transaction* transaction, 1103 IndexedDBBackingStore::Transaction* transaction,
1129 int64 database_id, 1104 int64 database_id,
1130 int64 object_store_id) { 1105 int64 object_store_id) {
1131 IDB_TRACE("IndexedDBBackingStore::DeleteObjectStore"); 1106 IDB_TRACE("IndexedDBBackingStore::DeleteObjectStore");
1132 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1107 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1133 return false; 1108 return false;
1134 LevelDBTransaction* leveldb_transaction = 1109 LevelDBTransaction* leveldb_transaction =
1135 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1110 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1136 1111
1137 string16 object_store_name; 1112 string16 object_store_name;
1138 bool found = false; 1113 bool found = false;
1139 bool ok = GetString( 1114 bool ok = GetString(
1140 leveldb_transaction, 1115 leveldb_transaction,
1141 LevelDBSlice(ObjectStoreMetaDataKey::Encode( 1116 ObjectStoreMetaDataKey::Encode(
1142 database_id, object_store_id, ObjectStoreMetaDataKey::NAME)), 1117 database_id, object_store_id, ObjectStoreMetaDataKey::NAME),
1143 &object_store_name, 1118 &object_store_name,
1144 &found); 1119 &found);
1145 if (!ok) { 1120 if (!ok) {
1146 INTERNAL_READ_ERROR(DELETE_OBJECT_STORE); 1121 INTERNAL_READ_ERROR(DELETE_OBJECT_STORE);
1147 return false; 1122 return false;
1148 } 1123 }
1149 if (!found) { 1124 if (!found) {
1150 INTERNAL_CONSISTENCY_ERROR(DELETE_OBJECT_STORE); 1125 INTERNAL_CONSISTENCY_ERROR(DELETE_OBJECT_STORE);
1151 return false; 1126 return false;
1152 } 1127 }
1153 1128
1154 DeleteRange( 1129 DeleteRange(
1155 leveldb_transaction, 1130 leveldb_transaction,
1156 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0), 1131 ObjectStoreMetaDataKey::Encode(database_id, object_store_id, 0),
1157 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1132 ObjectStoreMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1158 1133
1159 leveldb_transaction->Remove(LevelDBSlice( 1134 leveldb_transaction->Remove(
1160 ObjectStoreNamesKey::Encode(database_id, object_store_name))); 1135 ObjectStoreNamesKey::Encode(database_id, object_store_name));
1161 1136
1162 DeleteRange(leveldb_transaction, 1137 DeleteRange(leveldb_transaction,
1163 IndexFreeListKey::Encode(database_id, object_store_id, 0), 1138 IndexFreeListKey::Encode(database_id, object_store_id, 0),
1164 IndexFreeListKey::EncodeMaxKey(database_id, object_store_id)); 1139 IndexFreeListKey::EncodeMaxKey(database_id, object_store_id));
1165 DeleteRange(leveldb_transaction, 1140 DeleteRange(leveldb_transaction,
1166 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0), 1141 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0),
1167 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id)); 1142 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id));
1168 1143
1169 return ClearObjectStore(transaction, database_id, object_store_id); 1144 return ClearObjectStore(transaction, database_id, object_store_id);
1170 } 1145 }
1171 1146
1172 bool IndexedDBBackingStore::GetRecord( 1147 bool IndexedDBBackingStore::GetRecord(
1173 IndexedDBBackingStore::Transaction* transaction, 1148 IndexedDBBackingStore::Transaction* transaction,
1174 int64 database_id, 1149 int64 database_id,
1175 int64 object_store_id, 1150 int64 object_store_id,
1176 const IndexedDBKey& key, 1151 const IndexedDBKey& key,
1177 std::vector<char>* record) { 1152 std::string* record) {
1178 IDB_TRACE("IndexedDBBackingStore::GetRecord"); 1153 IDB_TRACE("IndexedDBBackingStore::GetRecord");
1179 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1154 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1180 return false; 1155 return false;
1181 LevelDBTransaction* leveldb_transaction = 1156 LevelDBTransaction* leveldb_transaction =
1182 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1157 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1183 1158
1184 const std::vector<char> leveldb_key = 1159 const std::string leveldb_key =
1185 ObjectStoreDataKey::Encode(database_id, object_store_id, key); 1160 ObjectStoreDataKey::Encode(database_id, object_store_id, key);
1186 std::string data; 1161 std::string data;
1187 1162
1188 record->clear(); 1163 record->clear();
1189 1164
1190 bool found = false; 1165 bool found = false;
1191 bool ok = leveldb_transaction->Get(LevelDBSlice(leveldb_key), &data, &found); 1166 bool ok = leveldb_transaction->Get(leveldb_key, &data, &found);
1192 if (!ok) { 1167 if (!ok) {
1193 INTERNAL_READ_ERROR(GET_RECORD); 1168 INTERNAL_READ_ERROR(GET_RECORD);
1194 return false; 1169 return false;
1195 } 1170 }
1196 if (!found) 1171 if (!found)
1197 return true; 1172 return true;
1198 if (data.empty()) { 1173 if (data.empty()) {
1199 INTERNAL_READ_ERROR(GET_RECORD); 1174 INTERNAL_READ_ERROR(GET_RECORD);
1200 return false; 1175 return false;
1201 } 1176 }
1202 1177
1203 int64 version; 1178 int64 version;
1204 StringPiece slice(data); 1179 StringPiece slice(data);
1205 if (!DecodeVarInt(&slice, &version)) { 1180 if (!DecodeVarInt(&slice, &version)) {
1206 INTERNAL_READ_ERROR(GET_RECORD); 1181 INTERNAL_READ_ERROR(GET_RECORD);
1207 return false; 1182 return false;
1208 } 1183 }
1209 1184
1210 record->insert(record->end(), slice.begin(), slice.end()); 1185 *record = slice.as_string();
1211 return true; 1186 return true;
1212 } 1187 }
1213 1188
1214 WARN_UNUSED_RESULT static bool GetNewVersionNumber( 1189 WARN_UNUSED_RESULT static bool GetNewVersionNumber(
1215 LevelDBTransaction* transaction, 1190 LevelDBTransaction* transaction,
1216 int64 database_id, 1191 int64 database_id,
1217 int64 object_store_id, 1192 int64 object_store_id,
1218 int64* new_version_number) { 1193 int64* new_version_number) {
1219 const std::vector<char> last_version_key = ObjectStoreMetaDataKey::Encode( 1194 const std::string last_version_key = ObjectStoreMetaDataKey::Encode(
1220 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION); 1195 database_id, object_store_id, ObjectStoreMetaDataKey::LAST_VERSION);
1221 1196
1222 *new_version_number = -1; 1197 *new_version_number = -1;
1223 int64 last_version = -1; 1198 int64 last_version = -1;
1224 bool found = false; 1199 bool found = false;
1225 bool ok = GetInt( 1200 bool ok = GetInt(transaction, last_version_key, &last_version, &found);
1226 transaction, LevelDBSlice(last_version_key), &last_version, &found);
1227 if (!ok) { 1201 if (!ok) {
1228 INTERNAL_READ_ERROR(GET_NEW_VERSION_NUMBER); 1202 INTERNAL_READ_ERROR(GET_NEW_VERSION_NUMBER);
1229 return false; 1203 return false;
1230 } 1204 }
1231 if (!found) 1205 if (!found)
1232 last_version = 0; 1206 last_version = 0;
1233 1207
1234 DCHECK_GE(last_version, 0); 1208 DCHECK_GE(last_version, 0);
1235 1209
1236 int64 version = last_version + 1; 1210 int64 version = last_version + 1;
1237 PutInt(transaction, LevelDBSlice(last_version_key), version); 1211 PutInt(transaction, last_version_key, version);
1238 1212
1239 // TODO(jsbell): Think about how we want to handle the overflow scenario. 1213 // TODO(jsbell): Think about how we want to handle the overflow scenario.
1240 DCHECK(version > last_version); 1214 DCHECK(version > last_version);
1241 1215
1242 *new_version_number = version; 1216 *new_version_number = version;
1243 return true; 1217 return true;
1244 } 1218 }
1245 1219
1246 bool IndexedDBBackingStore::PutRecord( 1220 bool IndexedDBBackingStore::PutRecord(
1247 IndexedDBBackingStore::Transaction* transaction, 1221 IndexedDBBackingStore::Transaction* transaction,
1248 int64 database_id, 1222 int64 database_id,
1249 int64 object_store_id, 1223 int64 object_store_id,
1250 const IndexedDBKey& key, 1224 const IndexedDBKey& key,
1251 const std::vector<char>& value, 1225 const std::string& value,
1252 RecordIdentifier* record_identifier) { 1226 RecordIdentifier* record_identifier) {
1253 IDB_TRACE("IndexedDBBackingStore::PutRecord"); 1227 IDB_TRACE("IndexedDBBackingStore::PutRecord");
1254 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1228 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1255 return false; 1229 return false;
1256 DCHECK(key.IsValid()); 1230 DCHECK(key.IsValid());
1257 1231
1258 LevelDBTransaction* leveldb_transaction = 1232 LevelDBTransaction* leveldb_transaction =
1259 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1233 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1260 int64 version = -1; 1234 int64 version = -1;
1261 bool ok = GetNewVersionNumber( 1235 bool ok = GetNewVersionNumber(
1262 leveldb_transaction, database_id, object_store_id, &version); 1236 leveldb_transaction, database_id, object_store_id, &version);
1263 if (!ok) 1237 if (!ok)
1264 return false; 1238 return false;
1265 DCHECK_GE(version, 0); 1239 DCHECK_GE(version, 0);
1266 const std::vector<char> object_storedata_key = 1240 const std::string object_storedata_key =
1267 ObjectStoreDataKey::Encode(database_id, object_store_id, key); 1241 ObjectStoreDataKey::Encode(database_id, object_store_id, key);
1268 1242
1269 std::vector<char> v; 1243 std::string v;
1270 EncodeVarInt(version, &v); 1244 EncodeVarInt(version, &v);
1271 v.insert(v.end(), value.begin(), value.end()); 1245 v.append(value);
1272 1246
1273 leveldb_transaction->Put(LevelDBSlice(object_storedata_key), &v); 1247 leveldb_transaction->Put(object_storedata_key, &v);
1274 1248
1275 const std::vector<char> exists_entry_key = 1249 const std::string exists_entry_key =
1276 ExistsEntryKey::Encode(database_id, object_store_id, key); 1250 ExistsEntryKey::Encode(database_id, object_store_id, key);
1277 std::vector<char> version_encoded; 1251 std::string version_encoded;
1278 EncodeInt(version, &version_encoded); 1252 EncodeInt(version, &version_encoded);
1279 leveldb_transaction->Put(LevelDBSlice(exists_entry_key), &version_encoded); 1253 leveldb_transaction->Put(exists_entry_key, &version_encoded);
1280 1254
1281 std::vector<char> key_encoded; 1255 std::string key_encoded;
1282 EncodeIDBKey(key, &key_encoded); 1256 EncodeIDBKey(key, &key_encoded);
1283 record_identifier->Reset(key_encoded, version); 1257 record_identifier->Reset(key_encoded, version);
1284 return true; 1258 return true;
1285 } 1259 }
1286 1260
1287 bool IndexedDBBackingStore::ClearObjectStore( 1261 bool IndexedDBBackingStore::ClearObjectStore(
1288 IndexedDBBackingStore::Transaction* transaction, 1262 IndexedDBBackingStore::Transaction* transaction,
1289 int64 database_id, 1263 int64 database_id,
1290 int64 object_store_id) { 1264 int64 object_store_id) {
1291 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore"); 1265 IDB_TRACE("IndexedDBBackingStore::ClearObjectStore");
1292 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1266 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1293 return false; 1267 return false;
1294 LevelDBTransaction* leveldb_transaction = 1268 LevelDBTransaction* leveldb_transaction =
1295 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1269 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1296 const std::vector<char> start_key = 1270 const std::string start_key =
1297 KeyPrefix(database_id, object_store_id).Encode(); 1271 KeyPrefix(database_id, object_store_id).Encode();
1298 const std::vector<char> stop_key = 1272 const std::string stop_key =
1299 KeyPrefix(database_id, object_store_id + 1).Encode(); 1273 KeyPrefix(database_id, object_store_id + 1).Encode();
1300 1274
1301 DeleteRange(leveldb_transaction, start_key, stop_key); 1275 DeleteRange(leveldb_transaction, start_key, stop_key);
1302 return true; 1276 return true;
1303 } 1277 }
1304 1278
1305 bool IndexedDBBackingStore::DeleteRecord( 1279 bool IndexedDBBackingStore::DeleteRecord(
1306 IndexedDBBackingStore::Transaction* transaction, 1280 IndexedDBBackingStore::Transaction* transaction,
1307 int64 database_id, 1281 int64 database_id,
1308 int64 object_store_id, 1282 int64 object_store_id,
1309 const RecordIdentifier& record_identifier) { 1283 const RecordIdentifier& record_identifier) {
1310 IDB_TRACE("IndexedDBBackingStore::DeleteRecord"); 1284 IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
1311 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1285 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1312 return false; 1286 return false;
1313 LevelDBTransaction* leveldb_transaction = 1287 LevelDBTransaction* leveldb_transaction =
1314 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1288 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1315 1289
1316 const std::vector<char> object_store_data_key = ObjectStoreDataKey::Encode( 1290 const std::string object_store_data_key = ObjectStoreDataKey::Encode(
1317 database_id, object_store_id, record_identifier.primary_key()); 1291 database_id, object_store_id, record_identifier.primary_key());
1318 leveldb_transaction->Remove(LevelDBSlice(object_store_data_key)); 1292 leveldb_transaction->Remove(object_store_data_key);
1319 1293
1320 const std::vector<char> exists_entry_key = ExistsEntryKey::Encode( 1294 const std::string exists_entry_key = ExistsEntryKey::Encode(
1321 database_id, object_store_id, record_identifier.primary_key()); 1295 database_id, object_store_id, record_identifier.primary_key());
1322 leveldb_transaction->Remove(LevelDBSlice(exists_entry_key)); 1296 leveldb_transaction->Remove(exists_entry_key);
1323 return true; 1297 return true;
1324 } 1298 }
1325 1299
1326 bool IndexedDBBackingStore::GetKeyGeneratorCurrentNumber( 1300 bool IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
1327 IndexedDBBackingStore::Transaction* transaction, 1301 IndexedDBBackingStore::Transaction* transaction,
1328 int64 database_id, 1302 int64 database_id,
1329 int64 object_store_id, 1303 int64 object_store_id,
1330 int64* key_generator_current_number) { 1304 int64* key_generator_current_number) {
1331 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1305 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1332 return false; 1306 return false;
1333 LevelDBTransaction* leveldb_transaction = 1307 LevelDBTransaction* leveldb_transaction =
1334 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1308 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1335 1309
1336 const std::vector<char> key_generator_current_number_key = 1310 const std::string key_generator_current_number_key =
1337 ObjectStoreMetaDataKey::Encode( 1311 ObjectStoreMetaDataKey::Encode(
1338 database_id, 1312 database_id,
1339 object_store_id, 1313 object_store_id,
1340 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); 1314 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER);
1341 1315
1342 *key_generator_current_number = -1; 1316 *key_generator_current_number = -1;
1343 std::string data; 1317 std::string data;
1344 1318
1345 bool found = false; 1319 bool found = false;
1346 bool ok = leveldb_transaction->Get( 1320 bool ok =
1347 LevelDBSlice(key_generator_current_number_key), &data, &found); 1321 leveldb_transaction->Get(key_generator_current_number_key, &data, &found);
1348 if (!ok) { 1322 if (!ok) {
1349 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER); 1323 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER);
1350 return false; 1324 return false;
1351 } 1325 }
1352 if (found && !data.empty()) { 1326 if (found && !data.empty()) {
1353 StringPiece slice(data); 1327 StringPiece slice(data);
1354 if (!DecodeInt(&slice, key_generator_current_number) || !slice.empty()) { 1328 if (!DecodeInt(&slice, key_generator_current_number) || !slice.empty()) {
1355 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER); 1329 INTERNAL_READ_ERROR(GET_KEY_GENERATOR_CURRENT_NUMBER);
1356 return false; 1330 return false;
1357 } 1331 }
1358 return true; 1332 return true;
1359 } 1333 }
1360 1334
1361 // Previously, the key generator state was not stored explicitly 1335 // Previously, the key generator state was not stored explicitly
1362 // but derived from the maximum numeric key present in existing 1336 // but derived from the maximum numeric key present in existing
1363 // data. This violates the spec as the data may be cleared but the 1337 // data. This violates the spec as the data may be cleared but the
1364 // key generator state must be preserved. 1338 // key generator state must be preserved.
1365 // TODO(jsbell): Fix this for all stores on database open? 1339 // TODO(jsbell): Fix this for all stores on database open?
1366 const std::vector<char> start_key = 1340 const std::string start_key =
1367 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 1341 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
1368 const std::vector<char> stop_key = 1342 const std::string stop_key =
1369 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 1343 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
1370 1344
1371 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1345 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1372 int64 max_numeric_key = 0; 1346 int64 max_numeric_key = 0;
1373 1347
1374 for (it->Seek(LevelDBSlice(start_key)); 1348 for (it->Seek(start_key);
1375 it->IsValid() && CompareKeys(it->Key(), LevelDBSlice(stop_key)) < 0; 1349 it->IsValid() && CompareKeys(it->Key(), stop_key) < 0;
1376 it->Next()) { 1350 it->Next()) {
1377 const char* p = it->Key().begin(); 1351 const char* p = it->Key().begin();
1378 const char* limit = it->Key().end(); 1352 const char* limit = it->Key().end();
1379 1353
1380 ObjectStoreDataKey data_key; 1354 ObjectStoreDataKey data_key;
1381 p = ObjectStoreDataKey::Decode(p, limit, &data_key); 1355 p = ObjectStoreDataKey::Decode(p, limit, &data_key);
1382 DCHECK(p); 1356 DCHECK(p);
1383 1357
1384 scoped_ptr<IndexedDBKey> user_key = data_key.user_key(); 1358 scoped_ptr<IndexedDBKey> user_key = data_key.user_key();
1385 if (user_key->type() == WebKit::WebIDBKey::NumberType) { 1359 if (user_key->type() == WebKit::WebIDBKey::NumberType) {
(...skipping 21 matching lines...) Expand all
1407 if (check_current) { 1381 if (check_current) {
1408 int64 current_number; 1382 int64 current_number;
1409 bool ok = GetKeyGeneratorCurrentNumber( 1383 bool ok = GetKeyGeneratorCurrentNumber(
1410 transaction, database_id, object_store_id, &current_number); 1384 transaction, database_id, object_store_id, &current_number);
1411 if (!ok) 1385 if (!ok)
1412 return false; 1386 return false;
1413 if (new_number <= current_number) 1387 if (new_number <= current_number)
1414 return true; 1388 return true;
1415 } 1389 }
1416 1390
1417 const std::vector<char> key_generator_current_number_key = 1391 const std::string key_generator_current_number_key =
1418 ObjectStoreMetaDataKey::Encode( 1392 ObjectStoreMetaDataKey::Encode(
1419 database_id, 1393 database_id,
1420 object_store_id, 1394 object_store_id,
1421 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER); 1395 ObjectStoreMetaDataKey::KEY_GENERATOR_CURRENT_NUMBER);
1422 PutInt(leveldb_transaction, 1396 PutInt(leveldb_transaction, key_generator_current_number_key, new_number);
1423 LevelDBSlice(key_generator_current_number_key),
1424 new_number);
1425 return true; 1397 return true;
1426 } 1398 }
1427 1399
1428 bool IndexedDBBackingStore::KeyExistsInObjectStore( 1400 bool IndexedDBBackingStore::KeyExistsInObjectStore(
1429 IndexedDBBackingStore::Transaction* transaction, 1401 IndexedDBBackingStore::Transaction* transaction,
1430 int64 database_id, 1402 int64 database_id,
1431 int64 object_store_id, 1403 int64 object_store_id,
1432 const IndexedDBKey& key, 1404 const IndexedDBKey& key,
1433 RecordIdentifier* found_record_identifier, 1405 RecordIdentifier* found_record_identifier,
1434 bool* found) { 1406 bool* found) {
1435 IDB_TRACE("IndexedDBBackingStore::KeyExistsInObjectStore"); 1407 IDB_TRACE("IndexedDBBackingStore::KeyExistsInObjectStore");
1436 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1408 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1437 return false; 1409 return false;
1438 *found = false; 1410 *found = false;
1439 LevelDBTransaction* leveldb_transaction = 1411 LevelDBTransaction* leveldb_transaction =
1440 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1412 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1441 const std::vector<char> leveldb_key = 1413 const std::string leveldb_key =
1442 ObjectStoreDataKey::Encode(database_id, object_store_id, key); 1414 ObjectStoreDataKey::Encode(database_id, object_store_id, key);
1443 std::string data; 1415 std::string data;
1444 1416
1445 bool ok = leveldb_transaction->Get(LevelDBSlice(leveldb_key), &data, found); 1417 bool ok = leveldb_transaction->Get(leveldb_key, &data, found);
1446 if (!ok) { 1418 if (!ok) {
1447 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE); 1419 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE);
1448 return false; 1420 return false;
1449 } 1421 }
1450 if (!*found) 1422 if (!*found)
1451 return true; 1423 return true;
1452 if (!data.size()) { 1424 if (!data.size()) {
1453 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE); 1425 INTERNAL_READ_ERROR(KEY_EXISTS_IN_OBJECT_STORE);
1454 return false; 1426 return false;
1455 } 1427 }
1456 1428
1457 int64 version; 1429 int64 version;
1458 StringPiece slice(data); 1430 StringPiece slice(data);
1459 if (!DecodeVarInt(&slice, &version)) 1431 if (!DecodeVarInt(&slice, &version))
1460 return false; 1432 return false;
1461 1433
1462 std::vector<char> encoded_key; 1434 std::string encoded_key;
1463 EncodeIDBKey(key, &encoded_key); 1435 EncodeIDBKey(key, &encoded_key);
1464 found_record_identifier->Reset(encoded_key, version); 1436 found_record_identifier->Reset(encoded_key, version);
1465 return true; 1437 return true;
1466 } 1438 }
1467 1439
1468 static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it, 1440 static bool CheckIndexAndMetaDataKey(const LevelDBIterator* it,
1469 const std::vector<char>& stop_key, 1441 const std::string& stop_key,
1470 int64 index_id, 1442 int64 index_id,
1471 unsigned char meta_data_type) { 1443 unsigned char meta_data_type) {
1472 if (!it->IsValid() || CompareKeys(it->Key(), LevelDBSlice(stop_key)) >= 0) 1444 if (!it->IsValid() || CompareKeys(it->Key(), stop_key) >= 0)
1473 return false; 1445 return false;
1474 1446
1475 IndexMetaDataKey meta_data_key; 1447 IndexMetaDataKey meta_data_key;
1476 const char* p = IndexMetaDataKey::Decode( 1448 const char* p = IndexMetaDataKey::Decode(
1477 it->Key().begin(), it->Key().end(), &meta_data_key); 1449 it->Key().begin(), it->Key().end(), &meta_data_key);
1478 DCHECK(p); 1450 DCHECK(p);
1479 if (meta_data_key.IndexId() != index_id) 1451 if (meta_data_key.IndexId() != index_id)
1480 return false; 1452 return false;
1481 if (meta_data_key.meta_data_type() != meta_data_type) 1453 if (meta_data_key.meta_data_type() != meta_data_type)
1482 return false; 1454 return false;
1483 return true; 1455 return true;
1484 } 1456 }
1485 1457
1486 // TODO(jsbell): This should do some error handling rather than plowing ahead 1458 // TODO(jsbell): This should do some error handling rather than plowing ahead
1487 // when bad data is encountered. 1459 // when bad data is encountered.
1488 bool IndexedDBBackingStore::GetIndexes( 1460 bool IndexedDBBackingStore::GetIndexes(
1489 int64 database_id, 1461 int64 database_id,
1490 int64 object_store_id, 1462 int64 object_store_id,
1491 IndexedDBObjectStoreMetadata::IndexMap* indexes) { 1463 IndexedDBObjectStoreMetadata::IndexMap* indexes) {
1492 IDB_TRACE("IndexedDBBackingStore::GetIndexes"); 1464 IDB_TRACE("IndexedDBBackingStore::GetIndexes");
1493 if (!KeyPrefix::ValidIds(database_id, object_store_id)) 1465 if (!KeyPrefix::ValidIds(database_id, object_store_id))
1494 return false; 1466 return false;
1495 const std::vector<char> start_key = 1467 const std::string start_key =
1496 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0); 1468 IndexMetaDataKey::Encode(database_id, object_store_id, 0, 0);
1497 const std::vector<char> stop_key = 1469 const std::string stop_key =
1498 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0); 1470 IndexMetaDataKey::Encode(database_id, object_store_id + 1, 0, 0);
1499 1471
1500 DCHECK(indexes->empty()); 1472 DCHECK(indexes->empty());
1501 1473
1502 scoped_ptr<LevelDBIterator> it = db_->CreateIterator(); 1474 scoped_ptr<LevelDBIterator> it = db_->CreateIterator();
1503 it->Seek(LevelDBSlice(start_key)); 1475 it->Seek(start_key);
1504 while (it->IsValid() && 1476 while (it->IsValid() && CompareKeys(it->Key(), stop_key) < 0) {
1505 CompareKeys(LevelDBSlice(it->Key()), LevelDBSlice(stop_key)) < 0) {
1506 const char* p = it->Key().begin(); 1477 const char* p = it->Key().begin();
1507 const char* limit = it->Key().end(); 1478 const char* limit = it->Key().end();
1508 1479
1509 IndexMetaDataKey meta_data_key; 1480 IndexMetaDataKey meta_data_key;
1510 p = IndexMetaDataKey::Decode(p, limit, &meta_data_key); 1481 p = IndexMetaDataKey::Decode(p, limit, &meta_data_key);
1511 DCHECK(p); 1482 DCHECK(p);
1512 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) { 1483 if (meta_data_key.meta_data_type() != IndexMetaDataKey::NAME) {
1513 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1484 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1514 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail 1485 // Possible stale metadata due to http://webkit.org/b/85557 but don't fail
1515 // the load. 1486 // the load.
1516 it->Next(); 1487 it->Next();
1517 continue; 1488 continue;
1518 } 1489 }
1519 1490
1520 // TODO(jsbell): Do this by direct key lookup rather than iteration, to 1491 // TODO(jsbell): Do this by direct key lookup rather than iteration, to
1521 // simplify. 1492 // simplify.
1522 int64 index_id = meta_data_key.IndexId(); 1493 int64 index_id = meta_data_key.IndexId();
1523 string16 index_name; 1494 string16 index_name;
1524 { 1495 {
1525 StringPiece slice(it->Value().AsStringPiece()); 1496 StringPiece slice(it->Value());
1526 if (!DecodeString(&slice, &index_name) || !slice.empty()) 1497 if (!DecodeString(&slice, &index_name) || !slice.empty())
1527 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1498 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1528 } 1499 }
1529 1500
1530 it->Next(); // unique flag 1501 it->Next(); // unique flag
1531 if (!CheckIndexAndMetaDataKey( 1502 if (!CheckIndexAndMetaDataKey(
1532 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) { 1503 it.get(), stop_key, index_id, IndexMetaDataKey::UNIQUE)) {
1533 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1504 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1534 break; 1505 break;
1535 } 1506 }
1536 bool index_unique; 1507 bool index_unique;
1537 { 1508 {
1538 StringPiece slice(it->Value().AsStringPiece()); 1509 StringPiece slice(it->Value());
1539 if (!DecodeBool(&slice, &index_unique) || !slice.empty()) 1510 if (!DecodeBool(&slice, &index_unique) || !slice.empty())
1540 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1511 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1541 } 1512 }
1542 1513
1543 it->Next(); // key_path 1514 it->Next(); // key_path
1544 if (!CheckIndexAndMetaDataKey( 1515 if (!CheckIndexAndMetaDataKey(
1545 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) { 1516 it.get(), stop_key, index_id, IndexMetaDataKey::KEY_PATH)) {
1546 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1517 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1547 break; 1518 break;
1548 } 1519 }
1549 IndexedDBKeyPath key_path; 1520 IndexedDBKeyPath key_path;
1550 { 1521 {
1551 StringPiece slice(it->Value().AsStringPiece()); 1522 StringPiece slice(it->Value());
1552 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty()) 1523 if (!DecodeIDBKeyPath(&slice, &key_path) || !slice.empty())
1553 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1524 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1554 } 1525 }
1555 1526
1556 it->Next(); // [optional] multi_entry flag 1527 it->Next(); // [optional] multi_entry flag
1557 bool index_multi_entry = false; 1528 bool index_multi_entry = false;
1558 if (CheckIndexAndMetaDataKey( 1529 if (CheckIndexAndMetaDataKey(
1559 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) { 1530 it.get(), stop_key, index_id, IndexMetaDataKey::MULTI_ENTRY)) {
1560 StringPiece slice(it->Value().AsStringPiece()); 1531 StringPiece slice(it->Value());
1561 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty()) 1532 if (!DecodeBool(&slice, &index_multi_entry) || !slice.empty())
1562 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES); 1533 INTERNAL_CONSISTENCY_ERROR(GET_INDEXES);
1563 1534
1564 it->Next(); 1535 it->Next();
1565 } 1536 }
1566 1537
1567 (*indexes)[index_id] = IndexedDBIndexMetadata( 1538 (*indexes)[index_id] = IndexedDBIndexMetadata(
1568 index_name, index_id, key_path, index_unique, index_multi_entry); 1539 index_name, index_id, key_path, index_unique, index_multi_entry);
1569 } 1540 }
1570 return true; 1541 return true;
1571 } 1542 }
1572 1543
1573 WARN_UNUSED_RESULT static bool SetMaxIndexId(LevelDBTransaction* transaction, 1544 WARN_UNUSED_RESULT static bool SetMaxIndexId(LevelDBTransaction* transaction,
1574 int64 database_id, 1545 int64 database_id,
1575 int64 object_store_id, 1546 int64 object_store_id,
1576 int64 index_id) { 1547 int64 index_id) {
1577 int64 max_index_id = -1; 1548 int64 max_index_id = -1;
1578 const std::vector<char> max_index_id_key = ObjectStoreMetaDataKey::Encode( 1549 const std::string max_index_id_key = ObjectStoreMetaDataKey::Encode(
1579 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID); 1550 database_id, object_store_id, ObjectStoreMetaDataKey::MAX_INDEX_ID);
1580 bool found = false; 1551 bool found = false;
1581 bool ok = GetInt( 1552 bool ok = GetInt(transaction, max_index_id_key, &max_index_id, &found);
1582 transaction, LevelDBSlice(max_index_id_key), &max_index_id, &found);
1583 if (!ok) { 1553 if (!ok) {
1584 INTERNAL_READ_ERROR(SET_MAX_INDEX_ID); 1554 INTERNAL_READ_ERROR(SET_MAX_INDEX_ID);
1585 return false; 1555 return false;
1586 } 1556 }
1587 if (!found) 1557 if (!found)
1588 max_index_id = kMinimumIndexId; 1558 max_index_id = kMinimumIndexId;
1589 1559
1590 if (index_id <= max_index_id) { 1560 if (index_id <= max_index_id) {
1591 INTERNAL_CONSISTENCY_ERROR(SET_MAX_INDEX_ID); 1561 INTERNAL_CONSISTENCY_ERROR(SET_MAX_INDEX_ID);
1592 return false; 1562 return false;
1593 } 1563 }
1594 1564
1595 PutInt(transaction, LevelDBSlice(max_index_id_key), index_id); 1565 PutInt(transaction, max_index_id_key, index_id);
1596 return true; 1566 return true;
1597 } 1567 }
1598 1568
1599 bool IndexedDBBackingStore::CreateIndex( 1569 bool IndexedDBBackingStore::CreateIndex(
1600 IndexedDBBackingStore::Transaction* transaction, 1570 IndexedDBBackingStore::Transaction* transaction,
1601 int64 database_id, 1571 int64 database_id,
1602 int64 object_store_id, 1572 int64 object_store_id,
1603 int64 index_id, 1573 int64 index_id,
1604 const string16& name, 1574 const string16& name,
1605 const IndexedDBKeyPath& key_path, 1575 const IndexedDBKeyPath& key_path,
1606 bool is_unique, 1576 bool is_unique,
1607 bool is_multi_entry) { 1577 bool is_multi_entry) {
1608 IDB_TRACE("IndexedDBBackingStore::CreateIndex"); 1578 IDB_TRACE("IndexedDBBackingStore::CreateIndex");
1609 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1579 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1610 return false; 1580 return false;
1611 LevelDBTransaction* leveldb_transaction = 1581 LevelDBTransaction* leveldb_transaction =
1612 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1582 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1613 if (!SetMaxIndexId( 1583 if (!SetMaxIndexId(
1614 leveldb_transaction, database_id, object_store_id, index_id)) 1584 leveldb_transaction, database_id, object_store_id, index_id))
1615 return false; 1585 return false;
1616 1586
1617 const std::vector<char> name_key = IndexMetaDataKey::Encode( 1587 const std::string name_key = IndexMetaDataKey::Encode(
1618 database_id, object_store_id, index_id, IndexMetaDataKey::NAME); 1588 database_id, object_store_id, index_id, IndexMetaDataKey::NAME);
1619 const std::vector<char> unique_key = IndexMetaDataKey::Encode( 1589 const std::string unique_key = IndexMetaDataKey::Encode(
1620 database_id, object_store_id, index_id, IndexMetaDataKey::UNIQUE); 1590 database_id, object_store_id, index_id, IndexMetaDataKey::UNIQUE);
1621 const std::vector<char> key_path_key = IndexMetaDataKey::Encode( 1591 const std::string key_path_key = IndexMetaDataKey::Encode(
1622 database_id, object_store_id, index_id, IndexMetaDataKey::KEY_PATH); 1592 database_id, object_store_id, index_id, IndexMetaDataKey::KEY_PATH);
1623 const std::vector<char> multi_entry_key = IndexMetaDataKey::Encode( 1593 const std::string multi_entry_key = IndexMetaDataKey::Encode(
1624 database_id, object_store_id, index_id, IndexMetaDataKey::MULTI_ENTRY); 1594 database_id, object_store_id, index_id, IndexMetaDataKey::MULTI_ENTRY);
1625 1595
1626 PutString(leveldb_transaction, LevelDBSlice(name_key), name); 1596 PutString(leveldb_transaction, name_key, name);
1627 PutBool(leveldb_transaction, LevelDBSlice(unique_key), is_unique); 1597 PutBool(leveldb_transaction, unique_key, is_unique);
1628 PutIDBKeyPath(leveldb_transaction, LevelDBSlice(key_path_key), key_path); 1598 PutIDBKeyPath(leveldb_transaction, key_path_key, key_path);
1629 PutBool(leveldb_transaction, LevelDBSlice(multi_entry_key), is_multi_entry); 1599 PutBool(leveldb_transaction, multi_entry_key, is_multi_entry);
1630 return true; 1600 return true;
1631 } 1601 }
1632 1602
1633 bool IndexedDBBackingStore::DeleteIndex( 1603 bool IndexedDBBackingStore::DeleteIndex(
1634 IndexedDBBackingStore::Transaction* transaction, 1604 IndexedDBBackingStore::Transaction* transaction,
1635 int64 database_id, 1605 int64 database_id,
1636 int64 object_store_id, 1606 int64 object_store_id,
1637 int64 index_id) { 1607 int64 index_id) {
1638 IDB_TRACE("IndexedDBBackingStore::DeleteIndex"); 1608 IDB_TRACE("IndexedDBBackingStore::DeleteIndex");
1639 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1609 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1640 return false; 1610 return false;
1641 LevelDBTransaction* leveldb_transaction = 1611 LevelDBTransaction* leveldb_transaction =
1642 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1612 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1643 1613
1644 const std::vector<char> index_meta_data_start = 1614 const std::string index_meta_data_start =
1645 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0); 1615 IndexMetaDataKey::Encode(database_id, object_store_id, index_id, 0);
1646 const std::vector<char> index_meta_data_end = 1616 const std::string index_meta_data_end =
1647 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 1617 IndexMetaDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
1648 DeleteRange(leveldb_transaction, index_meta_data_start, index_meta_data_end); 1618 DeleteRange(leveldb_transaction, index_meta_data_start, index_meta_data_end);
1649 1619
1650 const std::vector<char> index_data_start = 1620 const std::string index_data_start =
1651 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); 1621 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id);
1652 const std::vector<char> index_data_end = 1622 const std::string index_data_end =
1653 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 1623 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
1654 DeleteRange(leveldb_transaction, index_data_start, index_data_end); 1624 DeleteRange(leveldb_transaction, index_data_start, index_data_end);
1655 return true; 1625 return true;
1656 } 1626 }
1657 1627
1658 bool IndexedDBBackingStore::PutIndexDataForRecord( 1628 bool IndexedDBBackingStore::PutIndexDataForRecord(
1659 IndexedDBBackingStore::Transaction* transaction, 1629 IndexedDBBackingStore::Transaction* transaction,
1660 int64 database_id, 1630 int64 database_id,
1661 int64 object_store_id, 1631 int64 object_store_id,
1662 int64 index_id, 1632 int64 index_id,
1663 const IndexedDBKey& key, 1633 const IndexedDBKey& key,
1664 const RecordIdentifier& record_identifier) { 1634 const RecordIdentifier& record_identifier) {
1665 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord"); 1635 IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord");
1666 DCHECK(key.IsValid()); 1636 DCHECK(key.IsValid());
1667 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1637 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1668 return false; 1638 return false;
1669 1639
1670 LevelDBTransaction* leveldb_transaction = 1640 LevelDBTransaction* leveldb_transaction =
1671 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1641 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1672 1642
1673 std::vector<char> encoded_key; 1643 std::string encoded_key;
1674 EncodeIDBKey(key, &encoded_key); 1644 EncodeIDBKey(key, &encoded_key);
1675 1645
1676 const std::vector<char> index_data_key = 1646 const std::string index_data_key =
1677 IndexDataKey::Encode(database_id, 1647 IndexDataKey::Encode(database_id,
1678 object_store_id, 1648 object_store_id,
1679 index_id, 1649 index_id,
1680 encoded_key, 1650 encoded_key,
1681 record_identifier.primary_key(), 1651 record_identifier.primary_key(),
1682 0); 1652 0);
1683 1653
1684 std::vector<char> data; 1654 std::string data;
1685 EncodeVarInt(record_identifier.version(), &data); 1655 EncodeVarInt(record_identifier.version(), &data);
1686 const std::vector<char>& primary_key = record_identifier.primary_key(); 1656 data.append(record_identifier.primary_key());
1687 data.insert(data.end(), primary_key.begin(), primary_key.end());
1688 1657
1689 leveldb_transaction->Put(LevelDBSlice(index_data_key), &data); 1658 leveldb_transaction->Put(index_data_key, &data);
1690 return true; 1659 return true;
1691 } 1660 }
1692 1661
1693 static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction, 1662 static bool FindGreatestKeyLessThanOrEqual(LevelDBTransaction* transaction,
1694 const std::vector<char>& target, 1663 const std::string& target,
1695 std::vector<char>* found_key) { 1664 std::string* found_key) {
1696 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 1665 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
1697 it->Seek(LevelDBSlice(target)); 1666 it->Seek(target);
1698 1667
1699 if (!it->IsValid()) { 1668 if (!it->IsValid()) {
1700 it->SeekToLast(); 1669 it->SeekToLast();
1701 if (!it->IsValid()) 1670 if (!it->IsValid())
1702 return false; 1671 return false;
1703 } 1672 }
1704 1673
1705 while (CompareIndexKeys(LevelDBSlice(it->Key()), LevelDBSlice(target)) > 0) { 1674 while (CompareIndexKeys(it->Key(), target) > 0) {
1706 it->Prev(); 1675 it->Prev();
1707 if (!it->IsValid()) 1676 if (!it->IsValid())
1708 return false; 1677 return false;
1709 } 1678 }
1710 1679
1711 do { 1680 do {
1712 found_key->assign(it->Key().begin(), it->Key().end()); 1681 *found_key = it->Key().as_string();
1713 1682
1714 // There can be several index keys that compare equal. We want the last one. 1683 // There can be several index keys that compare equal. We want the last one.
1715 it->Next(); 1684 it->Next();
1716 } while (it->IsValid() && !CompareIndexKeys(it->Key(), LevelDBSlice(target))); 1685 } while (it->IsValid() && !CompareIndexKeys(it->Key(), target));
1717 1686
1718 return true; 1687 return true;
1719 } 1688 }
1720 1689
1721 static bool VersionExists(LevelDBTransaction* transaction, 1690 static bool VersionExists(LevelDBTransaction* transaction,
1722 int64 database_id, 1691 int64 database_id,
1723 int64 object_store_id, 1692 int64 object_store_id,
1724 int64 version, 1693 int64 version,
1725 const std::vector<char>& encoded_primary_key, 1694 const std::string& encoded_primary_key,
1726 bool* exists) { 1695 bool* exists) {
1727 const std::vector<char> key = 1696 const std::string key =
1728 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key); 1697 ExistsEntryKey::Encode(database_id, object_store_id, encoded_primary_key);
1729 std::string data; 1698 std::string data;
1730 1699
1731 bool ok = transaction->Get(LevelDBSlice(key), &data, exists); 1700 bool ok = transaction->Get(key, &data, exists);
1732 if (!ok) { 1701 if (!ok) {
1733 INTERNAL_READ_ERROR(VERSION_EXISTS); 1702 INTERNAL_READ_ERROR(VERSION_EXISTS);
1734 return false; 1703 return false;
1735 } 1704 }
1736 if (!*exists) 1705 if (!*exists)
1737 return true; 1706 return true;
1738 1707
1739 StringPiece slice(data); 1708 StringPiece slice(data);
1740 int64 decoded; 1709 int64 decoded;
1741 if (!DecodeInt(&slice, &decoded) || !slice.empty()) 1710 if (!DecodeInt(&slice, &decoded) || !slice.empty())
1742 return false; 1711 return false;
1743 *exists = (decoded == version); 1712 *exists = (decoded == version);
1744 return true; 1713 return true;
1745 } 1714 }
1746 1715
1747 bool IndexedDBBackingStore::FindKeyInIndex( 1716 bool IndexedDBBackingStore::FindKeyInIndex(
1748 IndexedDBBackingStore::Transaction* transaction, 1717 IndexedDBBackingStore::Transaction* transaction,
1749 int64 database_id, 1718 int64 database_id,
1750 int64 object_store_id, 1719 int64 object_store_id,
1751 int64 index_id, 1720 int64 index_id,
1752 const IndexedDBKey& key, 1721 const IndexedDBKey& key,
1753 std::vector<char>* found_encoded_primary_key, 1722 std::string* found_encoded_primary_key,
1754 bool* found) { 1723 bool* found) {
1755 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex"); 1724 IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex");
1756 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id)); 1725 DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id));
1757 1726
1758 DCHECK(found_encoded_primary_key->empty()); 1727 DCHECK(found_encoded_primary_key->empty());
1759 *found = false; 1728 *found = false;
1760 1729
1761 LevelDBTransaction* leveldb_transaction = 1730 LevelDBTransaction* leveldb_transaction =
1762 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction); 1731 IndexedDBBackingStore::Transaction::LevelDBTransactionFrom(transaction);
1763 const std::vector<char> leveldb_key = 1732 const std::string leveldb_key =
1764 IndexDataKey::Encode(database_id, object_store_id, index_id, key); 1733 IndexDataKey::Encode(database_id, object_store_id, index_id, key);
1765 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator(); 1734 scoped_ptr<LevelDBIterator> it = leveldb_transaction->CreateIterator();
1766 it->Seek(LevelDBSlice(leveldb_key)); 1735 it->Seek(leveldb_key);
1767 1736
1768 for (;;) { 1737 for (;;) {
1769 if (!it->IsValid()) 1738 if (!it->IsValid())
1770 return true; 1739 return true;
1771 if (CompareIndexKeys(it->Key(), LevelDBSlice(leveldb_key)) > 0) 1740 if (CompareIndexKeys(it->Key(), leveldb_key) > 0)
1772 return true; 1741 return true;
1773 1742
1774 StringPiece slice(it->Value().AsStringPiece()); 1743 StringPiece slice(it->Value());
1775 1744
1776 int64 version; 1745 int64 version;
1777 if (!DecodeVarInt(&slice, &version)) { 1746 if (!DecodeVarInt(&slice, &version)) {
1778 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX); 1747 INTERNAL_READ_ERROR(FIND_KEY_IN_INDEX);
1779 return false; 1748 return false;
1780 } 1749 }
1781 found_encoded_primary_key->insert( 1750 *found_encoded_primary_key = slice.as_string();
1782 found_encoded_primary_key->end(), slice.begin(), slice.end());
1783 1751
1784 bool exists = false; 1752 bool exists = false;
1785 bool ok = VersionExists(leveldb_transaction, 1753 bool ok = VersionExists(leveldb_transaction,
1786 database_id, 1754 database_id,
1787 object_store_id, 1755 object_store_id,
1788 version, 1756 version,
1789 *found_encoded_primary_key, 1757 *found_encoded_primary_key,
1790 &exists); 1758 &exists);
1791 if (!ok) 1759 if (!ok)
1792 return false; 1760 return false;
(...skipping 13 matching lines...) Expand all
1806 int64 database_id, 1774 int64 database_id,
1807 int64 object_store_id, 1775 int64 object_store_id,
1808 int64 index_id, 1776 int64 index_id,
1809 const IndexedDBKey& key, 1777 const IndexedDBKey& key,
1810 scoped_ptr<IndexedDBKey>* primary_key) { 1778 scoped_ptr<IndexedDBKey>* primary_key) {
1811 IDB_TRACE("IndexedDBBackingStore::GetPrimaryKeyViaIndex"); 1779 IDB_TRACE("IndexedDBBackingStore::GetPrimaryKeyViaIndex");
1812 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1780 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1813 return false; 1781 return false;
1814 1782
1815 bool found = false; 1783 bool found = false;
1816 std::vector<char> found_encoded_primary_key; 1784 std::string found_encoded_primary_key;
1817 bool ok = FindKeyInIndex(transaction, 1785 bool ok = FindKeyInIndex(transaction,
1818 database_id, 1786 database_id,
1819 object_store_id, 1787 object_store_id,
1820 index_id, 1788 index_id,
1821 key, 1789 key,
1822 &found_encoded_primary_key, 1790 &found_encoded_primary_key,
1823 &found); 1791 &found);
1824 if (!ok) { 1792 if (!ok) {
1825 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1793 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX);
1826 return false; 1794 return false;
1827 } 1795 }
1828 if (!found) 1796 if (!found)
1829 return true; 1797 return true;
1830 if (!found_encoded_primary_key.size()) { 1798 if (!found_encoded_primary_key.size()) {
1831 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX); 1799 INTERNAL_READ_ERROR(GET_PRIMARY_KEY_VIA_INDEX);
1832 return false; 1800 return false;
1833 } 1801 }
1834 1802
1835 StringPiece slice(&*found_encoded_primary_key.begin(), 1803 StringPiece slice(found_encoded_primary_key);
1836 found_encoded_primary_key.size());
1837 return DecodeIDBKey(&slice, primary_key) && slice.empty(); 1804 return DecodeIDBKey(&slice, primary_key) && slice.empty();
1838 } 1805 }
1839 1806
1840 bool IndexedDBBackingStore::KeyExistsInIndex( 1807 bool IndexedDBBackingStore::KeyExistsInIndex(
1841 IndexedDBBackingStore::Transaction* transaction, 1808 IndexedDBBackingStore::Transaction* transaction,
1842 int64 database_id, 1809 int64 database_id,
1843 int64 object_store_id, 1810 int64 object_store_id,
1844 int64 index_id, 1811 int64 index_id,
1845 const IndexedDBKey& index_key, 1812 const IndexedDBKey& index_key,
1846 scoped_ptr<IndexedDBKey>* found_primary_key, 1813 scoped_ptr<IndexedDBKey>* found_primary_key,
1847 bool* exists) { 1814 bool* exists) {
1848 IDB_TRACE("IndexedDBBackingStore::KeyExistsInIndex"); 1815 IDB_TRACE("IndexedDBBackingStore::KeyExistsInIndex");
1849 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 1816 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
1850 return false; 1817 return false;
1851 1818
1852 *exists = false; 1819 *exists = false;
1853 std::vector<char> found_encoded_primary_key; 1820 std::string found_encoded_primary_key;
1854 bool ok = FindKeyInIndex(transaction, 1821 bool ok = FindKeyInIndex(transaction,
1855 database_id, 1822 database_id,
1856 object_store_id, 1823 object_store_id,
1857 index_id, 1824 index_id,
1858 index_key, 1825 index_key,
1859 &found_encoded_primary_key, 1826 &found_encoded_primary_key,
1860 exists); 1827 exists);
1861 if (!ok) { 1828 if (!ok) {
1862 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1829 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX);
1863 return false; 1830 return false;
1864 } 1831 }
1865 if (!*exists) 1832 if (!*exists)
1866 return true; 1833 return true;
1867 if (found_encoded_primary_key.empty()) { 1834 if (found_encoded_primary_key.empty()) {
1868 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX); 1835 INTERNAL_READ_ERROR(KEY_EXISTS_IN_INDEX);
1869 return false; 1836 return false;
1870 } 1837 }
1871 1838
1872 StringPiece slice(&*found_encoded_primary_key.begin(), 1839 StringPiece slice(found_encoded_primary_key);
1873 found_encoded_primary_key.size());
1874 return DecodeIDBKey(&slice, found_primary_key) && slice.empty(); 1840 return DecodeIDBKey(&slice, found_primary_key) && slice.empty();
1875 } 1841 }
1876 1842
1877 IndexedDBBackingStore::Cursor::Cursor( 1843 IndexedDBBackingStore::Cursor::Cursor(
1878 const IndexedDBBackingStore::Cursor* other) 1844 const IndexedDBBackingStore::Cursor* other)
1879 : transaction_(other->transaction_), 1845 : transaction_(other->transaction_),
1880 cursor_options_(other->cursor_options_), 1846 cursor_options_(other->cursor_options_),
1881 current_key_(new IndexedDBKey(*other->current_key_)) { 1847 current_key_(new IndexedDBKey(*other->current_key_)) {
1882 if (other->iterator_) { 1848 if (other->iterator_) {
1883 iterator_ = transaction_->CreateIterator(); 1849 iterator_ = transaction_->CreateIterator();
1884 1850
1885 if (other->iterator_->IsValid()) { 1851 if (other->iterator_->IsValid()) {
1886 iterator_->Seek(other->iterator_->Key()); 1852 iterator_->Seek(other->iterator_->Key());
1887 DCHECK(iterator_->IsValid()); 1853 DCHECK(iterator_->IsValid());
1888 } 1854 }
1889 } 1855 }
1890 } 1856 }
1891 1857
1892 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction, 1858 IndexedDBBackingStore::Cursor::Cursor(LevelDBTransaction* transaction,
1893 const CursorOptions& cursor_options) 1859 const CursorOptions& cursor_options)
1894 : transaction_(transaction), cursor_options_(cursor_options) {} 1860 : transaction_(transaction), cursor_options_(cursor_options) {}
1895 IndexedDBBackingStore::Cursor::~Cursor() {} 1861 IndexedDBBackingStore::Cursor::~Cursor() {}
1896 1862
1897 bool IndexedDBBackingStore::Cursor::FirstSeek() { 1863 bool IndexedDBBackingStore::Cursor::FirstSeek() {
1898 iterator_ = transaction_->CreateIterator(); 1864 iterator_ = transaction_->CreateIterator();
1899 if (cursor_options_.forward) 1865 if (cursor_options_.forward)
1900 iterator_->Seek(LevelDBSlice(cursor_options_.low_key)); 1866 iterator_->Seek(cursor_options_.low_key);
1901 else 1867 else
1902 iterator_->Seek(LevelDBSlice(cursor_options_.high_key)); 1868 iterator_->Seek(cursor_options_.high_key);
1903 1869
1904 return ContinueFunction(0, READY); 1870 return ContinueFunction(0, READY);
1905 } 1871 }
1906 1872
1907 bool IndexedDBBackingStore::Cursor::Advance(uint32 count) { 1873 bool IndexedDBBackingStore::Cursor::Advance(uint32 count) {
1908 while (count--) { 1874 while (count--) {
1909 if (!ContinueFunction()) 1875 if (!ContinueFunction())
1910 return false; 1876 return false;
1911 } 1877 }
1912 return true; 1878 return true;
(...skipping 10 matching lines...) Expand all
1923 // value we yield for each key is the first duplicate in forwards 1889 // value we yield for each key is the first duplicate in forwards
1924 // order. 1890 // order.
1925 IndexedDBKey last_duplicate_key; 1891 IndexedDBKey last_duplicate_key;
1926 1892
1927 bool forward = cursor_options_.forward; 1893 bool forward = cursor_options_.forward;
1928 1894
1929 for (;;) { 1895 for (;;) {
1930 if (next_state == SEEK) { 1896 if (next_state == SEEK) {
1931 // TODO(jsbell): Optimize seeking for reverse cursors as well. 1897 // TODO(jsbell): Optimize seeking for reverse cursors as well.
1932 if (first_iteration && key && key->IsValid() && forward) { 1898 if (first_iteration && key && key->IsValid() && forward) {
1933 iterator_->Seek(LevelDBSlice(EncodeKey(*key))); 1899 iterator_->Seek(EncodeKey(*key));
1934 first_iteration = false; 1900 first_iteration = false;
1935 } else if (forward) { 1901 } else if (forward) {
1936 iterator_->Next(); 1902 iterator_->Next();
1937 } else { 1903 } else {
1938 iterator_->Prev(); 1904 iterator_->Prev();
1939 } 1905 }
1940 } else { 1906 } else {
1941 next_state = SEEK; // for subsequent iterations 1907 next_state = SEEK; // for subsequent iterations
1942 } 1908 }
1943 1909
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2008 break; 1974 break;
2009 } 1975 }
2010 1976
2011 DCHECK(!last_duplicate_key.IsValid() || 1977 DCHECK(!last_duplicate_key.IsValid() ||
2012 (forward && last_duplicate_key.IsEqual(*current_key_))); 1978 (forward && last_duplicate_key.IsEqual(*current_key_)));
2013 return true; 1979 return true;
2014 } 1980 }
2015 1981
2016 bool IndexedDBBackingStore::Cursor::HaveEnteredRange() const { 1982 bool IndexedDBBackingStore::Cursor::HaveEnteredRange() const {
2017 if (cursor_options_.forward) { 1983 if (cursor_options_.forward) {
2018 int compare = CompareIndexKeys(iterator_->Key(), 1984 int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.low_key);
2019 LevelDBSlice(cursor_options_.low_key));
2020 if (cursor_options_.low_open) { 1985 if (cursor_options_.low_open) {
2021 return compare > 0; 1986 return compare > 0;
2022 } 1987 }
2023 return compare >= 0; 1988 return compare >= 0;
2024 } 1989 }
2025 int compare = CompareIndexKeys(iterator_->Key(), 1990 int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.high_key);
2026 LevelDBSlice(cursor_options_.high_key));
2027 if (cursor_options_.high_open) { 1991 if (cursor_options_.high_open) {
2028 return compare < 0; 1992 return compare < 0;
2029 } 1993 }
2030 return compare <= 0; 1994 return compare <= 0;
2031 } 1995 }
2032 1996
2033 bool IndexedDBBackingStore::Cursor::IsPastBounds() const { 1997 bool IndexedDBBackingStore::Cursor::IsPastBounds() const {
2034 if (cursor_options_.forward) { 1998 if (cursor_options_.forward) {
2035 int compare = CompareIndexKeys(iterator_->Key(), 1999 int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.high_key);
2036 LevelDBSlice(cursor_options_.high_key));
2037 if (cursor_options_.high_open) { 2000 if (cursor_options_.high_open) {
2038 return compare >= 0; 2001 return compare >= 0;
2039 } 2002 }
2040 return compare > 0; 2003 return compare > 0;
2041 } 2004 }
2042 int compare = 2005 int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.low_key);
2043 CompareIndexKeys(iterator_->Key(), LevelDBSlice(cursor_options_.low_key));
2044 if (cursor_options_.low_open) { 2006 if (cursor_options_.low_open) {
2045 return compare <= 0; 2007 return compare <= 0;
2046 } 2008 }
2047 return compare < 0; 2009 return compare < 0;
2048 } 2010 }
2049 2011
2050 const IndexedDBKey& IndexedDBBackingStore::Cursor::primary_key() const { 2012 const IndexedDBKey& IndexedDBBackingStore::Cursor::primary_key() const {
2051 return *current_key_; 2013 return *current_key_;
2052 } 2014 }
2053 2015
2054 const IndexedDBBackingStore::RecordIdentifier& 2016 const IndexedDBBackingStore::RecordIdentifier&
2055 IndexedDBBackingStore::Cursor::record_identifier() const { 2017 IndexedDBBackingStore::Cursor::record_identifier() const {
2056 return record_identifier_; 2018 return record_identifier_;
2057 } 2019 }
2058 2020
2059 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { 2021 class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2060 public: 2022 public:
2061 ObjectStoreKeyCursorImpl( 2023 ObjectStoreKeyCursorImpl(
2062 LevelDBTransaction* transaction, 2024 LevelDBTransaction* transaction,
2063 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2025 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2064 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2026 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
2065 2027
2066 virtual Cursor* Clone() OVERRIDE { 2028 virtual Cursor* Clone() OVERRIDE {
2067 return new ObjectStoreKeyCursorImpl(this); 2029 return new ObjectStoreKeyCursorImpl(this);
2068 } 2030 }
2069 2031
2070 // IndexedDBBackingStore::Cursor 2032 // IndexedDBBackingStore::Cursor
2071 virtual std::vector<char>* Value() OVERRIDE { 2033 virtual std::string* Value() OVERRIDE {
2072 NOTREACHED(); 2034 NOTREACHED();
2073 return NULL; 2035 return NULL;
2074 } 2036 }
2075 virtual bool LoadCurrentRow() OVERRIDE; 2037 virtual bool LoadCurrentRow() OVERRIDE;
2076 2038
2077 protected: 2039 protected:
2078 virtual std::vector<char> EncodeKey(const IndexedDBKey& key) OVERRIDE { 2040 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE {
2079 return ObjectStoreDataKey::Encode( 2041 return ObjectStoreDataKey::Encode(
2080 cursor_options_.database_id, cursor_options_.object_store_id, key); 2042 cursor_options_.database_id, cursor_options_.object_store_id, key);
2081 } 2043 }
2082 2044
2083 private: 2045 private:
2084 explicit ObjectStoreKeyCursorImpl(const ObjectStoreKeyCursorImpl* other) 2046 explicit ObjectStoreKeyCursorImpl(const ObjectStoreKeyCursorImpl* other)
2085 : IndexedDBBackingStore::Cursor(other) {} 2047 : IndexedDBBackingStore::Cursor(other) {}
2086 }; 2048 };
2087 2049
2088 bool ObjectStoreKeyCursorImpl::LoadCurrentRow() { 2050 bool ObjectStoreKeyCursorImpl::LoadCurrentRow() {
2089 const char* key_position = iterator_->Key().begin(); 2051 const char* key_position = iterator_->Key().begin();
2090 const char* key_limit = iterator_->Key().end(); 2052 const char* key_limit = iterator_->Key().end();
2091 2053
2092 ObjectStoreDataKey object_store_data_key; 2054 ObjectStoreDataKey object_store_data_key;
2093 key_position = ObjectStoreDataKey::Decode( 2055 key_position = ObjectStoreDataKey::Decode(
2094 key_position, key_limit, &object_store_data_key); 2056 key_position, key_limit, &object_store_data_key);
2095 if (!key_position) { 2057 if (!key_position) {
2096 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2058 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2097 return false; 2059 return false;
2098 } 2060 }
2099 2061
2100 current_key_ = object_store_data_key.user_key(); 2062 current_key_ = object_store_data_key.user_key();
2101 2063
2102 int64 version; 2064 int64 version;
2103 StringPiece slice(iterator_->Value().AsStringPiece()); 2065 StringPiece slice(iterator_->Value());
2104 if (!DecodeVarInt(&slice, &version)) { 2066 if (!DecodeVarInt(&slice, &version)) {
2105 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2067 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2106 return false; 2068 return false;
2107 } 2069 }
2108 2070
2109 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2071 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2110 std::vector<char> encoded_key; 2072 std::string encoded_key;
2111 EncodeIDBKey(*current_key_, &encoded_key); 2073 EncodeIDBKey(*current_key_, &encoded_key);
2112 record_identifier_.Reset(encoded_key, version); 2074 record_identifier_.Reset(encoded_key, version);
2113 2075
2114 return true; 2076 return true;
2115 } 2077 }
2116 2078
2117 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { 2079 class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
2118 public: 2080 public:
2119 ObjectStoreCursorImpl( 2081 ObjectStoreCursorImpl(
2120 LevelDBTransaction* transaction, 2082 LevelDBTransaction* transaction,
2121 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2083 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2122 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2084 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
2123 2085
2124 virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); } 2086 virtual Cursor* Clone() OVERRIDE { return new ObjectStoreCursorImpl(this); }
2125 2087
2126 // IndexedDBBackingStore::Cursor 2088 // IndexedDBBackingStore::Cursor
2127 virtual std::vector<char>* Value() OVERRIDE { return &current_value_; } 2089 virtual std::string* Value() OVERRIDE { return &current_value_; }
2128 virtual bool LoadCurrentRow() OVERRIDE; 2090 virtual bool LoadCurrentRow() OVERRIDE;
2129 2091
2130 protected: 2092 protected:
2131 virtual std::vector<char> EncodeKey(const IndexedDBKey& key) OVERRIDE { 2093 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE {
2132 return ObjectStoreDataKey::Encode( 2094 return ObjectStoreDataKey::Encode(
2133 cursor_options_.database_id, cursor_options_.object_store_id, key); 2095 cursor_options_.database_id, cursor_options_.object_store_id, key);
2134 } 2096 }
2135 2097
2136 private: 2098 private:
2137 explicit ObjectStoreCursorImpl(const ObjectStoreCursorImpl* other) 2099 explicit ObjectStoreCursorImpl(const ObjectStoreCursorImpl* other)
2138 : IndexedDBBackingStore::Cursor(other), 2100 : IndexedDBBackingStore::Cursor(other),
2139 current_value_(other->current_value_) {} 2101 current_value_(other->current_value_) {}
2140 2102
2141 std::vector<char> current_value_; 2103 std::string current_value_;
2142 }; 2104 };
2143 2105
2144 bool ObjectStoreCursorImpl::LoadCurrentRow() { 2106 bool ObjectStoreCursorImpl::LoadCurrentRow() {
2145 const char* key_position = iterator_->Key().begin(); 2107 const char* key_position = iterator_->Key().begin();
2146 const char* key_limit = iterator_->Key().end(); 2108 const char* key_limit = iterator_->Key().end();
2147 2109
2148 ObjectStoreDataKey object_store_data_key; 2110 ObjectStoreDataKey object_store_data_key;
2149 key_position = ObjectStoreDataKey::Decode( 2111 key_position = ObjectStoreDataKey::Decode(
2150 key_position, key_limit, &object_store_data_key); 2112 key_position, key_limit, &object_store_data_key);
2151 if (!key_position) { 2113 if (!key_position) {
2152 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2114 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2153 return false; 2115 return false;
2154 } 2116 }
2155 2117
2156 current_key_ = object_store_data_key.user_key(); 2118 current_key_ = object_store_data_key.user_key();
2157 2119
2158 int64 version; 2120 int64 version;
2159 StringPiece slice(iterator_->Value().AsStringPiece()); 2121 StringPiece slice(iterator_->Value());
2160 if (!DecodeVarInt(&slice, &version)) { 2122 if (!DecodeVarInt(&slice, &version)) {
2161 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2123 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2162 return false; 2124 return false;
2163 } 2125 }
2164 2126
2165 // TODO(jsbell): This re-encodes what was just decoded; try and optimize. 2127 // TODO(jsbell): This re-encodes what was just decoded; try and optimize.
2166 std::vector<char> encoded_key; 2128 std::string encoded_key;
2167 EncodeIDBKey(*current_key_, &encoded_key); 2129 EncodeIDBKey(*current_key_, &encoded_key);
2168 record_identifier_.Reset(encoded_key, version); 2130 record_identifier_.Reset(encoded_key, version);
2169 2131
2170 std::vector<char> value; 2132 current_value_ = slice.as_string();
2171 value.insert(value.end(), slice.begin(), slice.end());
2172 current_value_.swap(value);
2173 return true; 2133 return true;
2174 } 2134 }
2175 2135
2176 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { 2136 class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
2177 public: 2137 public:
2178 IndexKeyCursorImpl( 2138 IndexKeyCursorImpl(
2179 LevelDBTransaction* transaction, 2139 LevelDBTransaction* transaction,
2180 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2140 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2181 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2141 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
2182 2142
2183 virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); } 2143 virtual Cursor* Clone() OVERRIDE { return new IndexKeyCursorImpl(this); }
2184 2144
2185 // IndexedDBBackingStore::Cursor 2145 // IndexedDBBackingStore::Cursor
2186 virtual std::vector<char>* Value() OVERRIDE { 2146 virtual std::string* Value() OVERRIDE {
2187 NOTREACHED(); 2147 NOTREACHED();
2188 return NULL; 2148 return NULL;
2189 } 2149 }
2190 virtual const IndexedDBKey& primary_key() const OVERRIDE { 2150 virtual const IndexedDBKey& primary_key() const OVERRIDE {
2191 return *primary_key_; 2151 return *primary_key_;
2192 } 2152 }
2193 virtual const IndexedDBBackingStore::RecordIdentifier& RecordIdentifier() 2153 virtual const IndexedDBBackingStore::RecordIdentifier& RecordIdentifier()
2194 const { 2154 const {
2195 NOTREACHED(); 2155 NOTREACHED();
2196 return record_identifier_; 2156 return record_identifier_;
2197 } 2157 }
2198 virtual bool LoadCurrentRow() OVERRIDE; 2158 virtual bool LoadCurrentRow() OVERRIDE;
2199 2159
2200 protected: 2160 protected:
2201 virtual std::vector<char> EncodeKey(const IndexedDBKey& key) OVERRIDE { 2161 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE {
2202 return IndexDataKey::Encode(cursor_options_.database_id, 2162 return IndexDataKey::Encode(cursor_options_.database_id,
2203 cursor_options_.object_store_id, 2163 cursor_options_.object_store_id,
2204 cursor_options_.index_id, 2164 cursor_options_.index_id,
2205 key); 2165 key);
2206 } 2166 }
2207 2167
2208 private: 2168 private:
2209 explicit IndexKeyCursorImpl(const IndexKeyCursorImpl* other) 2169 explicit IndexKeyCursorImpl(const IndexKeyCursorImpl* other)
2210 : IndexedDBBackingStore::Cursor(other), 2170 : IndexedDBBackingStore::Cursor(other),
2211 primary_key_(new IndexedDBKey(*other->primary_key_)) {} 2171 primary_key_(new IndexedDBKey(*other->primary_key_)) {}
2212 2172
2213 scoped_ptr<IndexedDBKey> primary_key_; 2173 scoped_ptr<IndexedDBKey> primary_key_;
2214 }; 2174 };
2215 2175
2216 bool IndexKeyCursorImpl::LoadCurrentRow() { 2176 bool IndexKeyCursorImpl::LoadCurrentRow() {
2217 const char* key_position = iterator_->Key().begin(); 2177 const char* key_position = iterator_->Key().begin();
2218 const char* key_limit = iterator_->Key().end(); 2178 const char* key_limit = iterator_->Key().end();
2219 2179
2220 IndexDataKey index_data_key; 2180 IndexDataKey index_data_key;
2221 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key); 2181 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key);
2222 2182
2223 current_key_ = index_data_key.user_key(); 2183 current_key_ = index_data_key.user_key();
2224 DCHECK(current_key_); 2184 DCHECK(current_key_);
2225 2185
2226 StringPiece slice(iterator_->Value().AsStringPiece()); 2186 StringPiece slice(iterator_->Value());
2227 int64 index_data_version; 2187 int64 index_data_version;
2228 if (!DecodeVarInt(&slice, &index_data_version)) { 2188 if (!DecodeVarInt(&slice, &index_data_version)) {
2229 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2189 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2230 return false; 2190 return false;
2231 } 2191 }
2232 2192
2233 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) { 2193 if (!DecodeIDBKey(&slice, &primary_key_) || !slice.empty()) {
2234 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2194 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2235 return false; 2195 return false;
2236 } 2196 }
2237 2197
2238 std::vector<char> primary_leveldb_key = 2198 std::string primary_leveldb_key =
2239 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2199 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2240 index_data_key.ObjectStoreId(), 2200 index_data_key.ObjectStoreId(),
2241 *primary_key_); 2201 *primary_key_);
2242 2202
2243 std::string result; 2203 std::string result;
2244 bool found = false; 2204 bool found = false;
2245 bool ok = 2205 bool ok = transaction_->Get(primary_leveldb_key, &result, &found);
2246 transaction_->Get(LevelDBSlice(primary_leveldb_key), &result, &found);
2247 if (!ok) { 2206 if (!ok) {
2248 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2207 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2249 return false; 2208 return false;
2250 } 2209 }
2251 if (!found) { 2210 if (!found) {
2252 transaction_->Remove(iterator_->Key()); 2211 transaction_->Remove(iterator_->Key());
2253 return false; 2212 return false;
2254 } 2213 }
2255 if (!result.size()) { 2214 if (!result.size()) {
2256 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2215 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
(...skipping 18 matching lines...) Expand all
2275 class IndexCursorImpl : public IndexedDBBackingStore::Cursor { 2234 class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
2276 public: 2235 public:
2277 IndexCursorImpl( 2236 IndexCursorImpl(
2278 LevelDBTransaction* transaction, 2237 LevelDBTransaction* transaction,
2279 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) 2238 const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
2280 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {} 2239 : IndexedDBBackingStore::Cursor(transaction, cursor_options) {}
2281 2240
2282 virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); } 2241 virtual Cursor* Clone() OVERRIDE { return new IndexCursorImpl(this); }
2283 2242
2284 // IndexedDBBackingStore::Cursor 2243 // IndexedDBBackingStore::Cursor
2285 virtual std::vector<char>* Value() OVERRIDE { return &current_value_; } 2244 virtual std::string* Value() OVERRIDE { return &current_value_; }
2286 virtual const IndexedDBKey& primary_key() const OVERRIDE { 2245 virtual const IndexedDBKey& primary_key() const OVERRIDE {
2287 return *primary_key_; 2246 return *primary_key_;
2288 } 2247 }
2289 virtual const IndexedDBBackingStore::RecordIdentifier& RecordIdentifier() 2248 virtual const IndexedDBBackingStore::RecordIdentifier& RecordIdentifier()
2290 const { 2249 const {
2291 NOTREACHED(); 2250 NOTREACHED();
2292 return record_identifier_; 2251 return record_identifier_;
2293 } 2252 }
2294 virtual bool LoadCurrentRow() OVERRIDE; 2253 virtual bool LoadCurrentRow() OVERRIDE;
2295 2254
2296 protected: 2255 protected:
2297 virtual std::vector<char> EncodeKey(const IndexedDBKey& key) OVERRIDE { 2256 virtual std::string EncodeKey(const IndexedDBKey& key) OVERRIDE {
2298 return IndexDataKey::Encode(cursor_options_.database_id, 2257 return IndexDataKey::Encode(cursor_options_.database_id,
2299 cursor_options_.object_store_id, 2258 cursor_options_.object_store_id,
2300 cursor_options_.index_id, 2259 cursor_options_.index_id,
2301 key); 2260 key);
2302 } 2261 }
2303 2262
2304 private: 2263 private:
2305 explicit IndexCursorImpl(const IndexCursorImpl* other) 2264 explicit IndexCursorImpl(const IndexCursorImpl* other)
2306 : IndexedDBBackingStore::Cursor(other), 2265 : IndexedDBBackingStore::Cursor(other),
2307 primary_key_(new IndexedDBKey(*other->primary_key_)), 2266 primary_key_(new IndexedDBKey(*other->primary_key_)),
2308 current_value_(other->current_value_), 2267 current_value_(other->current_value_),
2309 primary_leveldb_key_(other->primary_leveldb_key_) {} 2268 primary_leveldb_key_(other->primary_leveldb_key_) {}
2310 2269
2311 scoped_ptr<IndexedDBKey> primary_key_; 2270 scoped_ptr<IndexedDBKey> primary_key_;
2312 std::vector<char> current_value_; 2271 std::string current_value_;
2313 std::vector<char> primary_leveldb_key_; 2272 std::string primary_leveldb_key_;
2314 }; 2273 };
2315 2274
2316 bool IndexCursorImpl::LoadCurrentRow() { 2275 bool IndexCursorImpl::LoadCurrentRow() {
2317 const char* key_position = iterator_->Key().begin(); 2276 const char* key_position = iterator_->Key().begin();
2318 const char* key_limit = iterator_->Key().end(); 2277 const char* key_limit = iterator_->Key().end();
2319 2278
2320 IndexDataKey index_data_key; 2279 IndexDataKey index_data_key;
2321 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key); 2280 key_position = IndexDataKey::Decode(key_position, key_limit, &index_data_key);
2322 2281
2323 current_key_ = index_data_key.user_key(); 2282 current_key_ = index_data_key.user_key();
2324 DCHECK(current_key_); 2283 DCHECK(current_key_);
2325 2284
2326 StringPiece slice(iterator_->Value().AsStringPiece()); 2285 StringPiece slice(iterator_->Value());
2327 int64 index_data_version; 2286 int64 index_data_version;
2328 if (!DecodeVarInt(&slice, &index_data_version)) { 2287 if (!DecodeVarInt(&slice, &index_data_version)) {
2329 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2288 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2330 return false; 2289 return false;
2331 } 2290 }
2332 if (!DecodeIDBKey(&slice, &primary_key_)) { 2291 if (!DecodeIDBKey(&slice, &primary_key_)) {
2333 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2292 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2334 return false; 2293 return false;
2335 } 2294 }
2336 2295
2337 primary_leveldb_key_ = 2296 primary_leveldb_key_ =
2338 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(), 2297 ObjectStoreDataKey::Encode(index_data_key.DatabaseId(),
2339 index_data_key.ObjectStoreId(), 2298 index_data_key.ObjectStoreId(),
2340 *primary_key_); 2299 *primary_key_);
2341 2300
2342 std::string result; 2301 std::string result;
2343 bool found = false; 2302 bool found = false;
2344 bool ok = 2303 bool ok = transaction_->Get(primary_leveldb_key_, &result, &found);
2345 transaction_->Get(LevelDBSlice(primary_leveldb_key_), &result, &found);
2346 if (!ok) { 2304 if (!ok) {
2347 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2305 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2348 return false; 2306 return false;
2349 } 2307 }
2350 if (!found) { 2308 if (!found) {
2351 transaction_->Remove(iterator_->Key()); 2309 transaction_->Remove(iterator_->Key());
2352 return false; 2310 return false;
2353 } 2311 }
2354 if (!result.size()) { 2312 if (!result.size()) {
2355 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2313 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2356 return false; 2314 return false;
2357 } 2315 }
2358 2316
2359 int64 object_store_data_version; 2317 int64 object_store_data_version;
2360 slice = StringPiece(result); 2318 slice = StringPiece(result);
2361 if (!DecodeVarInt(&slice, &object_store_data_version)) { 2319 if (!DecodeVarInt(&slice, &object_store_data_version)) {
2362 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW); 2320 INTERNAL_READ_ERROR(LOAD_CURRENT_ROW);
2363 return false; 2321 return false;
2364 } 2322 }
2365 2323
2366 if (object_store_data_version != index_data_version) { 2324 if (object_store_data_version != index_data_version) {
2367 transaction_->Remove(iterator_->Key()); 2325 transaction_->Remove(iterator_->Key());
2368 return false; 2326 return false;
2369 } 2327 }
2370 2328
2371 current_value_.clear(); 2329 current_value_ = slice.as_string();
2372 current_value_.insert(current_value_.end(), slice.begin(), slice.end());
2373 return true; 2330 return true;
2374 } 2331 }
2375 2332
2376 bool ObjectStoreCursorOptions( 2333 bool ObjectStoreCursorOptions(
2377 LevelDBTransaction* transaction, 2334 LevelDBTransaction* transaction,
2378 int64 database_id, 2335 int64 database_id,
2379 int64 object_store_id, 2336 int64 object_store_id,
2380 const IndexedDBKeyRange& range, 2337 const IndexedDBKeyRange& range,
2381 indexed_db::CursorDirection direction, 2338 indexed_db::CursorDirection direction,
2382 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { 2339 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2414 return false; 2371 return false;
2415 cursor_options->high_open = false; 2372 cursor_options->high_open = false;
2416 } 2373 }
2417 } else { 2374 } else {
2418 cursor_options->high_key = 2375 cursor_options->high_key =
2419 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper()); 2376 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper());
2420 cursor_options->high_open = range.upperOpen(); 2377 cursor_options->high_open = range.upperOpen();
2421 2378
2422 if (!cursor_options->forward) { 2379 if (!cursor_options->forward) {
2423 // For reverse cursors, we need a key that exists. 2380 // For reverse cursors, we need a key that exists.
2424 std::vector<char> found_high_key; 2381 std::string found_high_key;
2425 if (!FindGreatestKeyLessThanOrEqual( 2382 if (!FindGreatestKeyLessThanOrEqual(
2426 transaction, cursor_options->high_key, &found_high_key)) 2383 transaction, cursor_options->high_key, &found_high_key))
2427 return false; 2384 return false;
2428 2385
2429 // If the target key should not be included, but we end up with a smaller 2386 // If the target key should not be included, but we end up with a smaller
2430 // key, we should include that. 2387 // key, we should include that.
2431 if (cursor_options->high_open && 2388 if (cursor_options->high_open &&
2432 CompareIndexKeys(LevelDBSlice(found_high_key), 2389 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
2433 LevelDBSlice(cursor_options->high_key)) <
2434 0)
2435 cursor_options->high_open = false; 2390 cursor_options->high_open = false;
2436 2391
2437 cursor_options->high_key = found_high_key; 2392 cursor_options->high_key = found_high_key;
2438 } 2393 }
2439 } 2394 }
2440 2395
2441 return true; 2396 return true;
2442 } 2397 }
2443 2398
2444 bool IndexCursorOptions( 2399 bool IndexCursorOptions(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 if (!FindGreatestKeyLessThanOrEqual( 2439 if (!FindGreatestKeyLessThanOrEqual(
2485 transaction, cursor_options->high_key, &cursor_options->high_key)) 2440 transaction, cursor_options->high_key, &cursor_options->high_key))
2486 return false; 2441 return false;
2487 cursor_options->high_open = false; 2442 cursor_options->high_open = false;
2488 } 2443 }
2489 } else { 2444 } else {
2490 cursor_options->high_key = IndexDataKey::Encode( 2445 cursor_options->high_key = IndexDataKey::Encode(
2491 database_id, object_store_id, index_id, range.upper()); 2446 database_id, object_store_id, index_id, range.upper());
2492 cursor_options->high_open = range.upperOpen(); 2447 cursor_options->high_open = range.upperOpen();
2493 2448
2494 std::vector<char> found_high_key; 2449 std::string found_high_key;
2495 // Seek to the *last* key in the set of non-unique keys 2450 // Seek to the *last* key in the set of non-unique keys
2496 if (!FindGreatestKeyLessThanOrEqual( 2451 if (!FindGreatestKeyLessThanOrEqual(
2497 transaction, cursor_options->high_key, &found_high_key)) 2452 transaction, cursor_options->high_key, &found_high_key))
2498 return false; 2453 return false;
2499 2454
2500 // If the target key should not be included, but we end up with a smaller 2455 // If the target key should not be included, but we end up with a smaller
2501 // key, we should include that. 2456 // key, we should include that.
2502 if (cursor_options->high_open && 2457 if (cursor_options->high_open &&
2503 CompareIndexKeys(LevelDBSlice(found_high_key), 2458 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
2504 LevelDBSlice(cursor_options->high_key)) <
2505 0)
2506 cursor_options->high_open = false; 2459 cursor_options->high_open = false;
2507 2460
2508 cursor_options->high_key = found_high_key; 2461 cursor_options->high_key = found_high_key;
2509 } 2462 }
2510 2463
2511 return true; 2464 return true;
2512 } 2465 }
2513 2466
2514 scoped_ptr<IndexedDBBackingStore::Cursor> 2467 scoped_ptr<IndexedDBBackingStore::Cursor>
2515 IndexedDBBackingStore::OpenObjectStoreCursor( 2468 IndexedDBBackingStore::OpenObjectStoreCursor(
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 } 2595 }
2643 2596
2644 void IndexedDBBackingStore::Transaction::Rollback() { 2597 void IndexedDBBackingStore::Transaction::Rollback() {
2645 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); 2598 IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
2646 DCHECK(transaction_.get()); 2599 DCHECK(transaction_.get());
2647 transaction_->Rollback(); 2600 transaction_->Rollback();
2648 transaction_ = NULL; 2601 transaction_ = NULL;
2649 } 2602 }
2650 2603
2651 } // namespace content 2604 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_backing_store.h ('k') | 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