| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 5 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 6 | 6 |
| 7 #include <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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 3802 ¤t_value_); | 3803 ¤t_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 Loading... |
| 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 |
| OLD | NEW |