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

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

Issue 2506773002: [IndexedDB] Integrating failures and corruption with transaction (Closed)
Patch Set: removed extra log statements Created 4 years 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
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 <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
(...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 DatabaseMetaDataKey::Encode( 1332 DatabaseMetaDataKey::Encode(
1333 *row_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER), 1333 *row_id, DatabaseMetaDataKey::BLOB_KEY_GENERATOR_CURRENT_NUMBER),
1334 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber); 1334 DatabaseMetaDataKey::kBlobKeyGeneratorInitialNumber);
1335 1335
1336 s = transaction->Commit(); 1336 s = transaction->Commit();
1337 if (!s.ok()) 1337 if (!s.ok())
1338 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA); 1338 INTERNAL_WRITE_ERROR_UNTESTED(CREATE_IDBDATABASE_METADATA);
1339 return s; 1339 return s;
1340 } 1340 }
1341 1341
1342 bool IndexedDBBackingStore::UpdateIDBDatabaseIntVersion( 1342 void IndexedDBBackingStore::UpdateIDBDatabaseIntVersion(
1343 IndexedDBBackingStore::Transaction* transaction, 1343 IndexedDBBackingStore::Transaction* transaction,
1344 int64_t row_id, 1344 int64_t row_id,
1345 int64_t version) { 1345 int64_t version) {
1346 if (version == IndexedDBDatabaseMetadata::NO_VERSION) 1346 if (version == IndexedDBDatabaseMetadata::NO_VERSION)
1347 version = IndexedDBDatabaseMetadata::DEFAULT_VERSION; 1347 version = IndexedDBDatabaseMetadata::DEFAULT_VERSION;
1348 DCHECK_GE(version, 0) << "version was " << version; 1348 DCHECK_GE(version, 0) << "version was " << version;
1349 PutVarInt( 1349 PutVarInt(
1350 transaction->transaction(), 1350 transaction->transaction(),
1351 DatabaseMetaDataKey::Encode(row_id, DatabaseMetaDataKey::USER_VERSION), 1351 DatabaseMetaDataKey::Encode(row_id, DatabaseMetaDataKey::USER_VERSION),
1352 version); 1352 version);
1353 return true;
1354 } 1353 }
1355 1354
1356 // If you're deleting a range that contains user keys that have blob info, this 1355 // If you're deleting a range that contains user keys that have blob info, this
1357 // won't clean up the blobs. 1356 // won't clean up the blobs.
1358 static leveldb::Status DeleteRangeBasic(LevelDBTransaction* transaction, 1357 static leveldb::Status DeleteRangeBasic(LevelDBTransaction* transaction,
1359 const std::string& begin, 1358 const std::string& begin,
1360 const std::string& end, 1359 const std::string& end,
1361 bool upper_open, 1360 bool upper_open,
1362 size_t* delete_count) { 1361 size_t* delete_count) {
1363 DCHECK(delete_count); 1362 DCHECK(delete_count);
(...skipping 1830 matching lines...) Expand 10 before | Expand all | Expand 10 after
3194 return true; 3193 return true;
3195 } 3194 }
3196 3195
3197 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key, 3196 bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key,
3198 const IndexedDBKey* primary_key, 3197 const IndexedDBKey* primary_key,
3199 IteratorState next_state, 3198 IteratorState next_state,
3200 leveldb::Status* s) { 3199 leveldb::Status* s) {
3201 DCHECK(!key || next_state == SEEK); 3200 DCHECK(!key || next_state == SEEK);
3202 3201
3203 if (cursor_options_.forward) 3202 if (cursor_options_.forward)
3204 return ContinueNext(key, primary_key, next_state, s); 3203 return ContinueNext(key, primary_key, next_state, s) ==
3204 ContinueResult::DONE;
3205 else 3205 else
3206 return ContinuePrevious(key, primary_key, next_state, s); 3206 return ContinuePrevious(key, primary_key, next_state, s) ==
3207 ContinueResult::DONE;
3207 } 3208 }
3208 3209
3209 bool IndexedDBBackingStore::Cursor::ContinueNext( 3210 IndexedDBBackingStore::Cursor::ContinueResult
3210 const IndexedDBKey* key, 3211 IndexedDBBackingStore::Cursor::ContinueNext(const IndexedDBKey* key,
3211 const IndexedDBKey* primary_key, 3212 const IndexedDBKey* primary_key,
3212 IteratorState next_state, 3213 IteratorState next_state,
3213 leveldb::Status* s) { 3214 leveldb::Status* s) {
3214 DCHECK(cursor_options_.forward); 3215 DCHECK(cursor_options_.forward);
3215 DCHECK(!key || key->IsValid()); 3216 DCHECK(!key || key->IsValid());
3216 DCHECK(!primary_key || primary_key->IsValid()); 3217 DCHECK(!primary_key || primary_key->IsValid());
3217 *s = leveldb::Status::OK(); 3218 *s = leveldb::Status::OK();
3218 3219
3219 // TODO(alecflett): avoid a copy here? 3220 // TODO(alecflett): avoid a copy here?
3220 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey(); 3221 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey();
3221 3222
3222 // If seeking to a particular key (or key and primary key), skip the cursor 3223 // If seeking to a particular key (or key and primary key), skip the cursor
3223 // forward rather than iterating it. 3224 // forward rather than iterating it.
3224 if (next_state == SEEK && key) { 3225 if (next_state == SEEK && key) {
3225 std::string leveldb_key = 3226 std::string leveldb_key =
3226 primary_key ? EncodeKey(*key, *primary_key) : EncodeKey(*key); 3227 primary_key ? EncodeKey(*key, *primary_key) : EncodeKey(*key);
3227 *s = iterator_->Seek(leveldb_key); 3228 *s = iterator_->Seek(leveldb_key);
3228 if (!s->ok()) 3229 if (!s->ok())
3229 return false; 3230 return ContinueResult::LEVELDB_ERROR;
3230 // Cursor is at the next value already; don't advance it again below. 3231 // Cursor is at the next value already; don't advance it again below.
3231 next_state = READY; 3232 next_state = READY;
3232 } 3233 }
3233 3234
3234 for (;;) { 3235 for (;;) {
3235 // Only advance the cursor if it was not set to position already, either 3236 // Only advance the cursor if it was not set to position already, either
3236 // because it is newly opened (and positioned at start of range) or 3237 // because it is newly opened (and positioned at start of range) or
3237 // skipped forward by continue with a specific key. 3238 // skipped forward by continue with a specific key.
3238 if (next_state == SEEK) { 3239 if (next_state == SEEK) {
3239 *s = iterator_->Next(); 3240 *s = iterator_->Next();
3240 if (!s->ok()) 3241 if (!s->ok())
3241 return false; 3242 return ContinueResult::LEVELDB_ERROR;
3242 } else { 3243 } else {
3243 next_state = SEEK; 3244 next_state = SEEK;
3244 } 3245 }
3245 3246
3246 // Fail if we've run out of data or gone past the cursor's bounds. 3247 // Fail if we've run out of data or gone past the cursor's bounds.
3247 if (!iterator_->IsValid() || IsPastBounds()) 3248 if (!iterator_->IsValid() || IsPastBounds())
3248 return false; 3249 return ContinueResult::OUT_OF_BOUNDS;
3249 3250
3250 // TODO(jsbell): Document why this might be false. When do we ever not 3251 // TODO(jsbell): Document why this might be false. When do we ever not
3251 // seek into the range before starting cursor iteration? 3252 // seek into the range before starting cursor iteration?
3252 if (!HaveEnteredRange()) 3253 if (!HaveEnteredRange())
3253 continue; 3254 continue;
3254 3255
3255 // The row may not load because there's a stale entry in the index. If no 3256 // The row may not load because there's a stale entry in the index. If no
3256 // error then not fatal. 3257 // error then not fatal.
3257 if (!LoadCurrentRow(s)) { 3258 if (!LoadCurrentRow(s)) {
3258 if (!s->ok()) 3259 if (!s->ok())
3259 return false; 3260 return ContinueResult::LEVELDB_ERROR;
3260 continue; 3261 continue;
3261 } 3262 }
3262 3263
3263 // Cursor is now positioned at a non-stale record in range. 3264 // Cursor is now positioned at a non-stale record in range.
3264 3265
3265 // "Unique" cursors should continue seeking until a new key value is seen. 3266 // "Unique" cursors should continue seeking until a new key value is seen.
3266 if (cursor_options_.unique && previous_key.IsValid() && 3267 if (cursor_options_.unique && previous_key.IsValid() &&
3267 current_key_->Equals(previous_key)) { 3268 current_key_->Equals(previous_key)) {
3268 continue; 3269 continue;
3269 } 3270 }
3270 3271
3271 break; 3272 break;
3272 } 3273 }
3273 3274
3274 return true; 3275 return ContinueResult::DONE;
3275 } 3276 }
3276 3277
3277 bool IndexedDBBackingStore::Cursor::ContinuePrevious( 3278 IndexedDBBackingStore::Cursor::ContinueResult
3278 const IndexedDBKey* key, 3279 IndexedDBBackingStore::Cursor::ContinuePrevious(const IndexedDBKey* key,
3279 const IndexedDBKey* primary_key, 3280 const IndexedDBKey* primary_key,
3280 IteratorState next_state, 3281 IteratorState next_state,
3281 leveldb::Status* s) { 3282 leveldb::Status* s) {
3282 DCHECK(!cursor_options_.forward); 3283 DCHECK(!cursor_options_.forward);
3283 DCHECK(!key || key->IsValid()); 3284 DCHECK(!key || key->IsValid());
3284 DCHECK(!primary_key || primary_key->IsValid()); 3285 DCHECK(!primary_key || primary_key->IsValid());
3285 *s = leveldb::Status::OK(); 3286 *s = leveldb::Status::OK();
3286 3287
3287 // TODO(alecflett): avoid a copy here? 3288 // TODO(alecflett): avoid a copy here?
3288 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey(); 3289 IndexedDBKey previous_key = current_key_ ? *current_key_ : IndexedDBKey();
3289 3290
3290 // When iterating with PrevNoDuplicate, spec requires that the value we 3291 // When iterating with PrevNoDuplicate, spec requires that the value we
3291 // yield for each key is the *first* duplicate in forwards order. We do this 3292 // yield for each key is the *first* duplicate in forwards order. We do this
3292 // by remembering the duplicate key (implicitly, the first record seen with 3293 // by remembering the duplicate key (implicitly, the first record seen with
3293 // a new key), keeping track of the earliest duplicate seen, and continuing 3294 // a new key), keeping track of the earliest duplicate seen, and continuing
3294 // until yet another new key is seen, at which point the earliest duplicate 3295 // until yet another new key is seen, at which point the earliest duplicate
3295 // is the correct cursor position. 3296 // is the correct cursor position.
3296 IndexedDBKey duplicate_key; 3297 IndexedDBKey duplicate_key;
3297 std::string earliest_duplicate; 3298 std::string earliest_duplicate;
3298 3299
3299 // TODO(jsbell): Optimize continuing to a specific key (or key and primary 3300 // TODO(jsbell): Optimize continuing to a specific key (or key and primary
3300 // key) for reverse cursors as well. See Seek() optimization at the start of 3301 // key) for reverse cursors as well. See Seek() optimization at the start of
3301 // ContinueNext() for an example. 3302 // ContinueNext() for an example.
3302 3303
3303 for (;;) { 3304 for (;;) {
3304 if (next_state == SEEK) { 3305 if (next_state == SEEK) {
3305 *s = iterator_->Prev(); 3306 *s = iterator_->Prev();
3306 if (!s->ok()) 3307 if (!s->ok())
3307 return false; 3308 return ContinueResult::LEVELDB_ERROR;
3308 } else { 3309 } else {
3309 next_state = SEEK; // for subsequent iterations 3310 next_state = SEEK; // for subsequent iterations
3310 } 3311 }
3311 3312
3312 // If we've run out of data or gone past the cursor's bounds. 3313 // If we've run out of data or gone past the cursor's bounds.
3313 if (!iterator_->IsValid() || IsPastBounds()) { 3314 if (!iterator_->IsValid() || IsPastBounds()) {
3314 if (duplicate_key.IsValid()) 3315 if (duplicate_key.IsValid())
3315 break; 3316 break;
3316 return false; 3317 return ContinueResult::OUT_OF_BOUNDS;
3317 } 3318 }
3318 3319
3319 // TODO(jsbell): Document why this might be false. When do we ever not 3320 // TODO(jsbell): Document why this might be false. When do we ever not
3320 // seek into the range before starting cursor iteration? 3321 // seek into the range before starting cursor iteration?
3321 if (!HaveEnteredRange()) 3322 if (!HaveEnteredRange())
3322 continue; 3323 continue;
3323 3324
3324 // The row may not load because there's a stale entry in the index. If no 3325 // The row may not load because there's a stale entry in the index. If no
3325 // error then not fatal. 3326 // error then not fatal.
3326 if (!LoadCurrentRow(s)) { 3327 if (!LoadCurrentRow(s)) {
3327 if (!s->ok()) 3328 if (!s->ok())
3328 return false; 3329 return ContinueResult::LEVELDB_ERROR;
3329 continue; 3330 continue;
3330 } 3331 }
3331 3332
3332 // If seeking to a key (or key and primary key), continue until found. 3333 // If seeking to a key (or key and primary key), continue until found.
3333 // TODO(jsbell): If Seek() optimization is added above, remove this. 3334 // TODO(jsbell): If Seek() optimization is added above, remove this.
3334 if (key) { 3335 if (key) {
3335 if (primary_key && key->Equals(*current_key_) && 3336 if (primary_key && key->Equals(*current_key_) &&
3336 primary_key->IsLessThan(this->primary_key())) 3337 primary_key->IsLessThan(this->primary_key()))
3337 continue; 3338 continue;
3338 if (key->IsLessThan(*current_key_)) 3339 if (key->IsLessThan(*current_key_))
(...skipping 26 matching lines...) Expand all
3365 3366
3366 break; 3367 break;
3367 } 3368 }
3368 3369
3369 if (cursor_options_.unique) { 3370 if (cursor_options_.unique) {
3370 DCHECK(duplicate_key.IsValid()); 3371 DCHECK(duplicate_key.IsValid());
3371 DCHECK(!earliest_duplicate.empty()); 3372 DCHECK(!earliest_duplicate.empty());
3372 3373
3373 *s = iterator_->Seek(earliest_duplicate); 3374 *s = iterator_->Seek(earliest_duplicate);
3374 if (!s->ok()) 3375 if (!s->ok())
3375 return false; 3376 return ContinueResult::LEVELDB_ERROR;
3376 if (!LoadCurrentRow(s)) { 3377 if (!LoadCurrentRow(s)) {
3377 DCHECK(!s->ok()); 3378 DCHECK(!s->ok());
3378 return false; 3379 return ContinueResult::LEVELDB_ERROR;
3379 } 3380 }
3380 } 3381 }
3381 3382
3382 return true; 3383 return ContinueResult::DONE;
3383 } 3384 }
3384 3385
3385 bool IndexedDBBackingStore::Cursor::HaveEnteredRange() const { 3386 bool IndexedDBBackingStore::Cursor::HaveEnteredRange() const {
3386 if (cursor_options_.forward) { 3387 if (cursor_options_.forward) {
3387 int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.low_key); 3388 int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.low_key);
3388 if (cursor_options_.low_open) { 3389 if (cursor_options_.low_open) {
3389 return compare > 0; 3390 return compare > 0;
3390 } 3391 }
3391 return compare >= 0; 3392 return compare >= 0;
3392 } 3393 }
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
3802 &current_value_); 3803 &current_value_);
3803 return s->ok(); 3804 return s->ok();
3804 } 3805 }
3805 3806
3806 bool ObjectStoreCursorOptions( 3807 bool ObjectStoreCursorOptions(
3807 LevelDBTransaction* transaction, 3808 LevelDBTransaction* transaction,
3808 int64_t database_id, 3809 int64_t database_id,
3809 int64_t object_store_id, 3810 int64_t object_store_id,
3810 const IndexedDBKeyRange& range, 3811 const IndexedDBKeyRange& range,
3811 blink::WebIDBCursorDirection direction, 3812 blink::WebIDBCursorDirection direction,
3812 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { 3813 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options,
3814 leveldb::Status* status) {
3813 cursor_options->database_id = database_id; 3815 cursor_options->database_id = database_id;
3814 cursor_options->object_store_id = object_store_id; 3816 cursor_options->object_store_id = object_store_id;
3815 3817
3816 bool lower_bound = range.lower().IsValid(); 3818 bool lower_bound = range.lower().IsValid();
3817 bool upper_bound = range.upper().IsValid(); 3819 bool upper_bound = range.upper().IsValid();
3818 cursor_options->forward = 3820 cursor_options->forward =
3819 (direction == blink::WebIDBCursorDirectionNextNoDuplicate || 3821 (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
3820 direction == blink::WebIDBCursorDirectionNext); 3822 direction == blink::WebIDBCursorDirectionNext);
3821 cursor_options->unique = 3823 cursor_options->unique =
3822 (direction == blink::WebIDBCursorDirectionNextNoDuplicate || 3824 (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
3823 direction == blink::WebIDBCursorDirectionPrevNoDuplicate); 3825 direction == blink::WebIDBCursorDirectionPrevNoDuplicate);
3824 3826
3825 if (!lower_bound) { 3827 if (!lower_bound) {
3826 cursor_options->low_key = 3828 cursor_options->low_key =
3827 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey()); 3829 ObjectStoreDataKey::Encode(database_id, object_store_id, MinIDBKey());
3828 cursor_options->low_open = true; // Not included. 3830 cursor_options->low_open = true; // Not included.
3829 } else { 3831 } else {
3830 cursor_options->low_key = 3832 cursor_options->low_key =
3831 ObjectStoreDataKey::Encode(database_id, object_store_id, range.lower()); 3833 ObjectStoreDataKey::Encode(database_id, object_store_id, range.lower());
3832 cursor_options->low_open = range.lower_open(); 3834 cursor_options->low_open = range.lower_open();
3833 } 3835 }
3834 3836
3835 leveldb::Status s;
3836
3837 if (!upper_bound) { 3837 if (!upper_bound) {
3838 cursor_options->high_key = 3838 cursor_options->high_key =
3839 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey()); 3839 ObjectStoreDataKey::Encode(database_id, object_store_id, MaxIDBKey());
3840 3840
3841 if (cursor_options->forward) { 3841 if (cursor_options->forward) {
3842 cursor_options->high_open = true; // Not included. 3842 cursor_options->high_open = true; // Not included.
3843 } else { 3843 } else {
3844 // We need a key that exists. 3844 // We need a key that exists.
3845 // TODO(cmumford): Handle this error (crbug.com/363397) 3845 if (!FindGreatestKeyLessThanOrEqual(transaction, cursor_options->high_key,
3846 if (!FindGreatestKeyLessThanOrEqual(transaction, 3846 &cursor_options->high_key, status))
3847 cursor_options->high_key,
3848 &cursor_options->high_key,
3849 &s))
3850 return false; 3847 return false;
3851 cursor_options->high_open = false; 3848 cursor_options->high_open = false;
3852 } 3849 }
3853 } else { 3850 } else {
3854 cursor_options->high_key = 3851 cursor_options->high_key =
3855 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper()); 3852 ObjectStoreDataKey::Encode(database_id, object_store_id, range.upper());
3856 cursor_options->high_open = range.upper_open(); 3853 cursor_options->high_open = range.upper_open();
3857 3854
3858 if (!cursor_options->forward) { 3855 if (!cursor_options->forward) {
3859 // For reverse cursors, we need a key that exists. 3856 // For reverse cursors, we need a key that exists.
3860 std::string found_high_key; 3857 std::string found_high_key;
3861 // TODO(cmumford): Handle this error (crbug.com/363397) 3858 if (!FindGreatestKeyLessThanOrEqual(transaction, cursor_options->high_key,
3862 if (!FindGreatestKeyLessThanOrEqual( 3859 &found_high_key, status))
3863 transaction, cursor_options->high_key, &found_high_key, &s))
3864 return false; 3860 return false;
3865 3861
3866 // If the target key should not be included, but we end up with a smaller 3862 // If the target key should not be included, but we end up with a smaller
3867 // key, we should include that. 3863 // key, we should include that.
3868 if (cursor_options->high_open && 3864 if (cursor_options->high_open &&
3869 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0) 3865 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
3870 cursor_options->high_open = false; 3866 cursor_options->high_open = false;
3871 3867
3872 cursor_options->high_key = found_high_key; 3868 cursor_options->high_key = found_high_key;
3873 } 3869 }
3874 } 3870 }
3875 3871
3876 return true; 3872 return true;
3877 } 3873 }
3878 3874
3879 bool IndexCursorOptions( 3875 bool IndexCursorOptions(
3880 LevelDBTransaction* transaction, 3876 LevelDBTransaction* transaction,
3881 int64_t database_id, 3877 int64_t database_id,
3882 int64_t object_store_id, 3878 int64_t object_store_id,
3883 int64_t index_id, 3879 int64_t index_id,
3884 const IndexedDBKeyRange& range, 3880 const IndexedDBKeyRange& range,
3885 blink::WebIDBCursorDirection direction, 3881 blink::WebIDBCursorDirection direction,
3886 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options) { 3882 IndexedDBBackingStore::Cursor::CursorOptions* cursor_options,
3883 leveldb::Status* status) {
3887 DCHECK(transaction); 3884 DCHECK(transaction);
3888 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id)) 3885 if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
3889 return false; 3886 return false;
3890 3887
3891 cursor_options->database_id = database_id; 3888 cursor_options->database_id = database_id;
3892 cursor_options->object_store_id = object_store_id; 3889 cursor_options->object_store_id = object_store_id;
3893 cursor_options->index_id = index_id; 3890 cursor_options->index_id = index_id;
3894 3891
3895 bool lower_bound = range.lower().IsValid(); 3892 bool lower_bound = range.lower().IsValid();
3896 bool upper_bound = range.upper().IsValid(); 3893 bool upper_bound = range.upper().IsValid();
3897 cursor_options->forward = 3894 cursor_options->forward =
3898 (direction == blink::WebIDBCursorDirectionNextNoDuplicate || 3895 (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
3899 direction == blink::WebIDBCursorDirectionNext); 3896 direction == blink::WebIDBCursorDirectionNext);
3900 cursor_options->unique = 3897 cursor_options->unique =
3901 (direction == blink::WebIDBCursorDirectionNextNoDuplicate || 3898 (direction == blink::WebIDBCursorDirectionNextNoDuplicate ||
3902 direction == blink::WebIDBCursorDirectionPrevNoDuplicate); 3899 direction == blink::WebIDBCursorDirectionPrevNoDuplicate);
3903 3900
3904 if (!lower_bound) { 3901 if (!lower_bound) {
3905 cursor_options->low_key = 3902 cursor_options->low_key =
3906 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id); 3903 IndexDataKey::EncodeMinKey(database_id, object_store_id, index_id);
3907 cursor_options->low_open = false; // Included. 3904 cursor_options->low_open = false; // Included.
3908 } else { 3905 } else {
3909 cursor_options->low_key = IndexDataKey::Encode( 3906 cursor_options->low_key = IndexDataKey::Encode(
3910 database_id, object_store_id, index_id, range.lower()); 3907 database_id, object_store_id, index_id, range.lower());
3911 cursor_options->low_open = range.lower_open(); 3908 cursor_options->low_open = range.lower_open();
3912 } 3909 }
3913 3910
3914 leveldb::Status s;
3915
3916 if (!upper_bound) { 3911 if (!upper_bound) {
3917 cursor_options->high_key = 3912 cursor_options->high_key =
3918 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id); 3913 IndexDataKey::EncodeMaxKey(database_id, object_store_id, index_id);
3919 cursor_options->high_open = false; // Included. 3914 cursor_options->high_open = false; // Included.
3920 3915
3921 if (!cursor_options->forward) { // We need a key that exists. 3916 if (!cursor_options->forward) {
3922 if (!FindGreatestKeyLessThanOrEqual(transaction, 3917 // We need a key that exists.
3923 cursor_options->high_key, 3918 if (!FindGreatestKeyLessThanOrEqual(transaction, cursor_options->high_key,
3924 &cursor_options->high_key, 3919 &cursor_options->high_key, status))
3925 &s))
3926 return false; 3920 return false;
3927 cursor_options->high_open = false; 3921 cursor_options->high_open = false;
3928 } 3922 }
3929 } else { 3923 } else {
3930 cursor_options->high_key = IndexDataKey::Encode( 3924 cursor_options->high_key = IndexDataKey::Encode(
3931 database_id, object_store_id, index_id, range.upper()); 3925 database_id, object_store_id, index_id, range.upper());
3932 cursor_options->high_open = range.upper_open(); 3926 cursor_options->high_open = range.upper_open();
3933 3927
3934 std::string found_high_key; 3928 std::string found_high_key;
3935 // Seek to the *last* key in the set of non-unique keys 3929 // Seek to the *last* key in the set of non-unique keys
3936 // TODO(cmumford): Handle this error (crbug.com/363397) 3930 if (!FindGreatestKeyLessThanOrEqual(transaction, cursor_options->high_key,
3937 if (!FindGreatestKeyLessThanOrEqual( 3931 &found_high_key, status))
3938 transaction, cursor_options->high_key, &found_high_key, &s))
3939 return false; 3932 return false;
3940 3933
3941 // If the target key should not be included, but we end up with a smaller 3934 // If the target key should not be included, but we end up with a smaller
3942 // key, we should include that. 3935 // key, we should include that.
3943 if (cursor_options->high_open && 3936 if (cursor_options->high_open &&
3944 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0) 3937 CompareIndexKeys(found_high_key, cursor_options->high_key) < 0)
3945 cursor_options->high_open = false; 3938 cursor_options->high_open = false;
3946 3939
3947 cursor_options->high_key = found_high_key; 3940 cursor_options->high_key = found_high_key;
3948 } 3941 }
3949 3942
3950 return true; 3943 return true;
3951 } 3944 }
3952 3945
3953 std::unique_ptr<IndexedDBBackingStore::Cursor> 3946 std::unique_ptr<IndexedDBBackingStore::Cursor>
3954 IndexedDBBackingStore::OpenObjectStoreCursor( 3947 IndexedDBBackingStore::OpenObjectStoreCursor(
3955 IndexedDBBackingStore::Transaction* transaction, 3948 IndexedDBBackingStore::Transaction* transaction,
3956 int64_t database_id, 3949 int64_t database_id,
3957 int64_t object_store_id, 3950 int64_t object_store_id,
3958 const IndexedDBKeyRange& range, 3951 const IndexedDBKeyRange& range,
3959 blink::WebIDBCursorDirection direction, 3952 blink::WebIDBCursorDirection direction,
3960 leveldb::Status* s) { 3953 leveldb::Status* s) {
3961 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor"); 3954 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor");
3962 *s = leveldb::Status::OK();
3963 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3955 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3964 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3956 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3965 if (!ObjectStoreCursorOptions(leveldb_transaction, 3957 // TODO(cmumford): Handle this error (crbug.com/363397)
3966 database_id, 3958 if (!ObjectStoreCursorOptions(leveldb_transaction, database_id,
3967 object_store_id, 3959 object_store_id, range, direction,
3968 range, 3960 &cursor_options, s)) {
3969 direction,
3970 &cursor_options))
3971 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 3961 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
3962 }
3972 std::unique_ptr<ObjectStoreCursorImpl> cursor( 3963 std::unique_ptr<ObjectStoreCursorImpl> cursor(
3973 base::MakeUnique<ObjectStoreCursorImpl>(this, transaction, database_id, 3964 base::MakeUnique<ObjectStoreCursorImpl>(this, transaction, database_id,
3974 cursor_options)); 3965 cursor_options));
3975 if (!cursor->FirstSeek(s)) 3966 if (!cursor->FirstSeek(s))
3976 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 3967 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
3977 3968
3978 return std::move(cursor); 3969 return std::move(cursor);
3979 } 3970 }
3980 3971
3981 std::unique_ptr<IndexedDBBackingStore::Cursor> 3972 std::unique_ptr<IndexedDBBackingStore::Cursor>
3982 IndexedDBBackingStore::OpenObjectStoreKeyCursor( 3973 IndexedDBBackingStore::OpenObjectStoreKeyCursor(
3983 IndexedDBBackingStore::Transaction* transaction, 3974 IndexedDBBackingStore::Transaction* transaction,
3984 int64_t database_id, 3975 int64_t database_id,
3985 int64_t object_store_id, 3976 int64_t object_store_id,
3986 const IndexedDBKeyRange& range, 3977 const IndexedDBKeyRange& range,
3987 blink::WebIDBCursorDirection direction, 3978 blink::WebIDBCursorDirection direction,
3988 leveldb::Status* s) { 3979 leveldb::Status* s) {
3989 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor"); 3980 IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
3990 *s = leveldb::Status::OK();
3991 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 3981 LevelDBTransaction* leveldb_transaction = transaction->transaction();
3992 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 3982 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
3993 if (!ObjectStoreCursorOptions(leveldb_transaction, 3983 // TODO(cmumford): Handle this error (crbug.com/363397)
3994 database_id, 3984 if (!ObjectStoreCursorOptions(leveldb_transaction, database_id,
3995 object_store_id, 3985 object_store_id, range, direction,
3996 range, 3986 &cursor_options, s)) {
3997 direction,
3998 &cursor_options))
3999 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 3987 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
3988 }
4000 std::unique_ptr<ObjectStoreKeyCursorImpl> cursor( 3989 std::unique_ptr<ObjectStoreKeyCursorImpl> cursor(
4001 base::MakeUnique<ObjectStoreKeyCursorImpl>(this, transaction, database_id, 3990 base::MakeUnique<ObjectStoreKeyCursorImpl>(this, transaction, database_id,
4002 cursor_options)); 3991 cursor_options));
4003 if (!cursor->FirstSeek(s)) 3992 if (!cursor->FirstSeek(s))
4004 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 3993 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
4005 3994
4006 return std::move(cursor); 3995 return std::move(cursor);
4007 } 3996 }
4008 3997
4009 std::unique_ptr<IndexedDBBackingStore::Cursor> 3998 std::unique_ptr<IndexedDBBackingStore::Cursor>
4010 IndexedDBBackingStore::OpenIndexKeyCursor( 3999 IndexedDBBackingStore::OpenIndexKeyCursor(
4011 IndexedDBBackingStore::Transaction* transaction, 4000 IndexedDBBackingStore::Transaction* transaction,
4012 int64_t database_id, 4001 int64_t database_id,
4013 int64_t object_store_id, 4002 int64_t object_store_id,
4014 int64_t index_id, 4003 int64_t index_id,
4015 const IndexedDBKeyRange& range, 4004 const IndexedDBKeyRange& range,
4016 blink::WebIDBCursorDirection direction, 4005 blink::WebIDBCursorDirection direction,
4017 leveldb::Status* s) { 4006 leveldb::Status* s) {
4018 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor"); 4007 IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
4019 *s = leveldb::Status::OK(); 4008 *s = leveldb::Status::OK();
4020 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 4009 LevelDBTransaction* leveldb_transaction = transaction->transaction();
4021 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 4010 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
4022 if (!IndexCursorOptions(leveldb_transaction, 4011 if (!IndexCursorOptions(leveldb_transaction, database_id, object_store_id,
4023 database_id, 4012 index_id, range, direction, &cursor_options, s))
4024 object_store_id,
4025 index_id,
4026 range,
4027 direction,
4028 &cursor_options))
4029 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 4013 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
4030 std::unique_ptr<IndexKeyCursorImpl> cursor( 4014 std::unique_ptr<IndexKeyCursorImpl> cursor(
4031 base::MakeUnique<IndexKeyCursorImpl>(this, transaction, database_id, 4015 base::MakeUnique<IndexKeyCursorImpl>(this, transaction, database_id,
4032 cursor_options)); 4016 cursor_options));
4033 if (!cursor->FirstSeek(s)) 4017 if (!cursor->FirstSeek(s))
4034 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 4018 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
4035 4019
4036 return std::move(cursor); 4020 return std::move(cursor);
4037 } 4021 }
4038 4022
4039 std::unique_ptr<IndexedDBBackingStore::Cursor> 4023 std::unique_ptr<IndexedDBBackingStore::Cursor>
4040 IndexedDBBackingStore::OpenIndexCursor( 4024 IndexedDBBackingStore::OpenIndexCursor(
4041 IndexedDBBackingStore::Transaction* transaction, 4025 IndexedDBBackingStore::Transaction* transaction,
4042 int64_t database_id, 4026 int64_t database_id,
4043 int64_t object_store_id, 4027 int64_t object_store_id,
4044 int64_t index_id, 4028 int64_t index_id,
4045 const IndexedDBKeyRange& range, 4029 const IndexedDBKeyRange& range,
4046 blink::WebIDBCursorDirection direction, 4030 blink::WebIDBCursorDirection direction,
4047 leveldb::Status* s) { 4031 leveldb::Status* s) {
4048 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor"); 4032 IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
4049 LevelDBTransaction* leveldb_transaction = transaction->transaction(); 4033 LevelDBTransaction* leveldb_transaction = transaction->transaction();
4050 IndexedDBBackingStore::Cursor::CursorOptions cursor_options; 4034 IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
4051 if (!IndexCursorOptions(leveldb_transaction, 4035 if (!IndexCursorOptions(leveldb_transaction, database_id, object_store_id,
4052 database_id, 4036 index_id, range, direction, &cursor_options, s))
4053 object_store_id,
4054 index_id,
4055 range,
4056 direction,
4057 &cursor_options))
4058 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 4037 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
4059 std::unique_ptr<IndexCursorImpl> cursor( 4038 std::unique_ptr<IndexCursorImpl> cursor(
4060 new IndexCursorImpl(this, transaction, database_id, cursor_options)); 4039 new IndexCursorImpl(this, transaction, database_id, cursor_options));
4061 if (!cursor->FirstSeek(s)) 4040 if (!cursor->FirstSeek(s))
4062 return std::unique_ptr<IndexedDBBackingStore::Cursor>(); 4041 return std::unique_ptr<IndexedDBBackingStore::Cursor>();
4063 4042
4064 return std::move(cursor); 4043 return std::move(cursor);
4065 } 4044 }
4066 4045
4067 IndexedDBBackingStore::Transaction::Transaction( 4046 IndexedDBBackingStore::Transaction::Transaction(
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
4529 4508
4530 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor( 4509 IndexedDBBackingStore::Transaction::WriteDescriptor::WriteDescriptor(
4531 const WriteDescriptor& other) = default; 4510 const WriteDescriptor& other) = default;
4532 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() = 4511 IndexedDBBackingStore::Transaction::WriteDescriptor::~WriteDescriptor() =
4533 default; 4512 default;
4534 IndexedDBBackingStore::Transaction::WriteDescriptor& 4513 IndexedDBBackingStore::Transaction::WriteDescriptor&
4535 IndexedDBBackingStore::Transaction::WriteDescriptor:: 4514 IndexedDBBackingStore::Transaction::WriteDescriptor::
4536 operator=(const WriteDescriptor& other) = default; 4515 operator=(const WriteDescriptor& other) = default;
4537 4516
4538 } // namespace content 4517 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/indexed_db/indexed_db_backing_store.h ('k') | content/browser/indexed_db/indexed_db_cursor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698