blob: bb88f7d89d1b1b4975705966973f89244fac5b7a [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2013 The Chromium Authors
[email protected]72a4183d2013-05-31 18:33:102// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Evan Stade1a8d9d42024-09-10 19:37:195#include "content/browser/indexed_db/instance/cursor.h"
[email protected]72a4183d2013-05-31 18:33:106
avib7348942015-12-25 20:57:107#include <stddef.h>
Evan Stade1a8d9d42024-09-10 19:37:198
Evan Staded9529ea52025-04-11 17:02:509#include <cstdint>
10#include <memory>
dcheng36b6aec92015-12-26 06:16:3611#include <utility>
[email protected]4cfd02d2014-06-11 18:08:4012#include <vector>
13
Evan Staded9529ea52025-04-11 17:02:5014#include "base/check.h"
Hans Wennborg0917de892020-04-28 20:21:1515#include "base/check_op.h"
Evan Staded9529ea52025-04-11 17:02:5016#include "base/memory/ptr_util.h"
17#include "base/memory/weak_ptr.h"
Hans Wennborg0917de892020-04-28 20:21:1518#include "base/notreached.h"
Etienne Pierre-dorayfc7952f02025-06-06 00:04:3319#include "base/trace_event/trace_event.h"
[email protected]72a4183d2013-05-31 18:33:1020#include "content/browser/indexed_db/indexed_db_database_error.h"
Evan Staded9529ea52025-04-11 17:02:5021#include "content/browser/indexed_db/indexed_db_external_object.h"
[email protected]120875f2014-03-19 23:08:5222#include "content/browser/indexed_db/indexed_db_value.h"
Evan Stade1a8d9d42024-09-10 19:37:1923#include "content/browser/indexed_db/instance/callback_helpers.h"
24#include "content/browser/indexed_db/instance/transaction.h"
Evan Staded9529ea52025-04-11 17:02:5025#include "content/browser/indexed_db/status.h"
26#include "mojo/public/cpp/bindings/pending_associated_remote.h"
Evan Stadeb568dbdc2023-08-10 05:21:2427#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
Henrique Ferreiroda0a55c2019-11-12 14:06:0428#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
Etienne Pierre-doraye0fb4b162025-08-07 16:44:4829#include "third_party/perfetto/include/perfetto/tracing/track.h"
[email protected]72a4183d2013-05-31 18:33:1030
Chase Phillips68ecf5512018-08-16 01:59:1331using blink::IndexedDBKey;
32
Evan Stadecbb1e002024-09-13 20:06:5733namespace content::indexed_db {
dmurph9d00e05d2016-12-01 23:00:3434namespace {
35// This should never be script visible: the cursor should either be closed when
36// it hits the end of the range (and script throws an error before the call
37// could be made), if the transaction has finished (ditto), or if there's an
38// incoming request from the front end but the transaction has aborted on the
39// back end; in that case the tx will already have sent an abort to the request
40// so this would be ignored.
Evan Stadecbb1e002024-09-13 20:06:5741DatabaseError CreateCursorClosedError() {
42 return DatabaseError(blink::mojom::IDBException::kUnknownError,
43 "The cursor has been closed.");
dmurph9d00e05d2016-12-01 23:00:3444}
45
Evan Stadecbb1e002024-09-13 20:06:5746DatabaseError CreateError(blink::mojom::IDBException code,
47 const char* message,
48 base::WeakPtr<Transaction> transaction) {
Evan Stade1a8d9d42024-09-10 19:37:1949 if (transaction) {
Chase Phillips091007d2019-05-22 22:00:1350 transaction->IncrementNumErrorsSent();
Evan Stade1a8d9d42024-09-10 19:37:1951 }
Evan Stadecbb1e002024-09-13 20:06:5752 return DatabaseError(code, message);
Chase Phillipsd9377f2a2019-03-06 19:30:1053}
54
dmurph9d00e05d2016-12-01 23:00:3455} // namespace
[email protected]72a4183d2013-05-31 18:33:1056
Evan Stadeb568dbdc2023-08-10 05:21:2457// static
Evan Stadecbb1e002024-09-13 20:06:5758Cursor* Cursor::CreateAndBind(
Evan Staded9529ea52025-04-11 17:02:5059 std::unique_ptr<BackingStore::Cursor> cursor,
Evan Stadeb568dbdc2023-08-10 05:21:2460 indexed_db::CursorType cursor_type,
61 blink::mojom::IDBTaskType task_type,
Evan Stadecbb1e002024-09-13 20:06:5762 base::WeakPtr<Transaction> transaction,
Evan Stadeb568dbdc2023-08-10 05:21:2463 mojo::PendingAssociatedRemote<blink::mojom::IDBCursor>& pending_remote) {
Evan Stadecbb1e002024-09-13 20:06:5764 auto instance = base::WrapUnique(
65 new Cursor(std::move(cursor), cursor_type, task_type, transaction));
66 Cursor* instance_ptr = instance.get();
Evan Stadeb568dbdc2023-08-10 05:21:2467 mojo::MakeSelfOwnedAssociatedReceiver(
68 std::move(instance), pending_remote.InitWithNewEndpointAndPassReceiver());
69 return instance_ptr;
70}
71
Evan Staded9529ea52025-04-11 17:02:5072Cursor::Cursor(std::unique_ptr<BackingStore::Cursor> cursor,
Evan Stadecbb1e002024-09-13 20:06:5773 indexed_db::CursorType cursor_type,
74 blink::mojom::IDBTaskType task_type,
75 base::WeakPtr<Transaction> transaction)
Evan Stade5f29b6a92025-04-02 08:09:5376 : bucket_locator_(transaction->bucket_context()->bucket_locator()),
Marijn Kruisselbrink145f7592020-02-18 08:49:3177 task_type_(task_type),
[email protected]72a4183d2013-05-31 18:33:1078 cursor_type_(cursor_type),
Daniel Murphy17ee4e52019-04-29 21:40:2979 transaction_(std::move(transaction)),
Evan Stadeb568dbdc2023-08-10 05:21:2480 cursor_(std::move(cursor)) {
Etienne Pierre-doraye0fb4b162025-08-07 16:44:4881 TRACE_EVENT_BEGIN("IndexedDB", "Cursor::open",
82 perfetto::Track::FromPointer(this));
dmurph84f5e282017-03-30 00:58:5583}
[email protected]72a4183d2013-05-31 18:33:1084
Evan Stadecbb1e002024-09-13 20:06:5785Cursor::~Cursor() {
dmurph84f5e282017-03-30 00:58:5586 // Call to make sure we complete our lifetime trace.
87 Close();
88}
[email protected]72a4183d2013-05-31 18:33:1089
Evan Stadecbb1e002024-09-13 20:06:5790void Cursor::Advance(uint32_t count,
91 blink::mojom::IDBCursor::AdvanceCallback callback) {
92 TRACE_EVENT0("IndexedDB", "Cursor::Advance");
[email protected]72a4183d2013-05-31 18:33:1093
Evan Stade1a8d9d42024-09-10 19:37:1994 if (!transaction_) {
Daniel Murphy17ee4e52019-04-29 21:40:2995 Close();
Evan Stade1a8d9d42024-09-10 19:37:1996 }
dmurph50ab051b32016-11-29 22:13:3097 if (closed_) {
Evan Stadecbb1e002024-09-13 20:06:5798 const DatabaseError error(CreateCursorClosedError());
Chase Phillips284581e2019-05-22 21:56:4599 std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
100 blink::mojom::IDBError::New(error.code(), error.message())));
dmurph50ab051b32016-11-29 22:13:30101 return;
102 }
103
Chase Phillips091007d2019-05-22 22:00:13104 blink::mojom::IDBCursor::AdvanceCallback aborting_callback =
105 CreateCallbackAbortOnDestruct<blink::mojom::IDBCursor::AdvanceCallback,
106 blink::mojom::IDBCursorResultPtr>(
107 std::move(callback), transaction_);
108
Evan Stadecbb1e002024-09-13 20:06:57109 transaction_->ScheduleTask(
110 task_type_, BindWeakOperation<Cursor>(&Cursor::AdvanceOperation,
111 ptr_factory_.GetWeakPtr(), count,
112 std::move(aborting_callback)));
dmurph9d00e05d2016-12-01 23:00:34113}
114
Mike Wasserman0d5da522024-09-27 07:47:03115Status Cursor::AdvanceOperation(
avib7348942015-12-25 20:57:10116 uint32_t count,
Chase Phillips9a58b892019-01-11 22:04:27117 blink::mojom::IDBCursor::AdvanceCallback callback,
Evan Stadecbb1e002024-09-13 20:06:57118 Transaction* /*transaction*/) {
119 TRACE_EVENT0("IndexedDB", "Cursor::AdvanceOperation");
Evan Stade5dd95ec22025-06-10 23:47:26120
121 if (!cursor_) {
122 std::move(callback).Run(blink::mojom::IDBCursorResult::NewEmpty(true));
123 return Status::OK();
124 }
125
126 if (StatusOr<bool> result = cursor_->Advance(count);
127 !result.has_value() || !*result) {
[email protected]65880a82013-08-16 21:30:08128 cursor_.reset();
Chase Phillips77bf9a952019-02-21 02:07:09129
Evan Stade5dd95ec22025-06-10 23:47:26130 if (result.has_value()) {
Chase Phillips284581e2019-05-22 21:56:45131 std::move(callback).Run(blink::mojom::IDBCursorResult::NewEmpty(true));
Evan Stade5dd95ec22025-06-10 23:47:26132 return Status::OK();
dmurph50ab051b32016-11-29 22:13:30133 }
Chase Phillips9a58b892019-01-11 22:04:27134
Chase Phillipsd9377f2a2019-03-06 19:30:10135 // CreateError() needs to be called before calling Close() so
Chase Phillips77bf9a952019-02-21 02:07:09136 // |transaction_| is alive.
Henrique Ferreiroda0a55c2019-11-12 14:06:04137 auto error = CreateError(blink::mojom::IDBException::kUnknownError,
Chase Phillipsd9377f2a2019-03-06 19:30:10138 "Error advancing cursor", transaction_);
Chase Phillips77bf9a952019-02-21 02:07:09139 Close();
Chase Phillips284581e2019-05-22 21:56:45140 std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
141 blink::mojom::IDBError::New(error.code(), error.message())));
Evan Stade5dd95ec22025-06-10 23:47:26142 return result.error();
[email protected]72a4183d2013-05-31 18:33:10143 }
144
Chase Phillips77bf9a952019-02-21 02:07:09145 blink::mojom::IDBValuePtr mojo_value;
Chase Phillips77bf9a952019-02-21 02:07:09146 IndexedDBValue* value = Value();
147 if (value) {
Evan Stade822bdb42025-08-07 18:37:41148 mojo_value = transaction_->BuildMojoValue(std::move(*value));
Chase Phillips77bf9a952019-02-21 02:07:09149 } else {
150 mojo_value = blink::mojom::IDBValue::New();
151 }
Chase Phillips9a58b892019-01-11 22:04:27152
Evan Stadeca999b12025-05-09 19:09:11153 std::vector<IndexedDBKey> keys;
154 keys.emplace_back(key().Clone());
155 std::vector<IndexedDBKey> primary_keys;
156 primary_keys.emplace_back(primary_key().Clone());
Chase Phillips0e2035822019-03-13 18:03:56157 std::vector<blink::mojom::IDBValuePtr> values;
158 values.push_back(std::move(mojo_value));
Chase Phillips284581e2019-05-22 21:56:45159 std::move(callback).Run(blink::mojom::IDBCursorResult::NewValues(
Chase Phillips0e2035822019-03-13 18:03:56160 blink::mojom::IDBCursorValue::New(
Chase Phillips284581e2019-05-22 21:56:45161 std::move(keys), std::move(primary_keys), std::move(values))));
Evan Stade5dd95ec22025-06-10 23:47:26162 return Status::OK();
[email protected]72a4183d2013-05-31 18:33:10163}
164
Evan Stadeca999b12025-05-09 19:09:11165void Cursor::Continue(IndexedDBKey key,
166 IndexedDBKey primary_key,
Evan Stadecbb1e002024-09-13 20:06:57167 blink::mojom::IDBCursor::ContinueCallback callback) {
168 TRACE_EVENT0("IndexedDB", "Cursor::Continue");
Evan Stade1a8d9d42024-09-10 19:37:19169 if (!transaction_) {
Daniel Murphy17ee4e52019-04-29 21:40:29170 Close();
Evan Stade1a8d9d42024-09-10 19:37:19171 }
Chase Phillipsd9377f2a2019-03-06 19:30:10172 if (closed_) {
Evan Stadecbb1e002024-09-13 20:06:57173 const DatabaseError error(CreateCursorClosedError());
Chase Phillips284581e2019-05-22 21:56:45174 std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
175 blink::mojom::IDBError::New(error.code(), error.message())));
Chase Phillipsd9377f2a2019-03-06 19:30:10176 return;
177 }
178
Evan Stadeb568dbdc2023-08-10 05:21:24179 blink::mojom::IDBCursor::ContinueCallback aborting_callback =
180 CreateCallbackAbortOnDestruct<blink::mojom::IDBCursor::ContinueCallback,
181 blink::mojom::IDBCursorResultPtr>(
182 std::move(callback), transaction_);
Chase Phillips091007d2019-05-22 22:00:13183
Chase Phillipsd9377f2a2019-03-06 19:30:10184 transaction_->ScheduleTask(
185 task_type_,
Evan Stadecbb1e002024-09-13 20:06:57186 BindWeakOperation<Cursor>(
Evan Stadeca999b12025-05-09 19:09:11187 &Cursor::ContinueOperation, ptr_factory_.GetWeakPtr(), std::move(key),
188 std::move(primary_key), std::move(aborting_callback)));
Chase Phillipsd9377f2a2019-03-06 19:30:10189}
190
Mike Wasserman0d5da522024-09-27 07:47:03191Status Cursor::ContinueOperation(
Evan Stadeca999b12025-05-09 19:09:11192 IndexedDBKey key,
193 IndexedDBKey primary_key,
Evan Stadeb568dbdc2023-08-10 05:21:24194 blink::mojom::IDBCursor::ContinueCallback callback,
Evan Stadecbb1e002024-09-13 20:06:57195 Transaction* /*transaction*/) {
196 TRACE_EVENT0("IndexedDB", "Cursor::ContinueOperation");
Evan Stade5dd95ec22025-06-10 23:47:26197
198 if (!cursor_) {
199 std::move(callback).Run(blink::mojom::IDBCursorResult::NewEmpty(true));
200 return Status::OK();
201 }
202
203 if (StatusOr<bool> result = cursor_->Continue(key, primary_key);
204 !result.has_value() || !*result) {
[email protected]65880a82013-08-16 21:30:08205 cursor_.reset();
Evan Stade5dd95ec22025-06-10 23:47:26206 if (result.has_value()) {
dmurph50ab051b32016-11-29 22:13:30207 // This happens if we reach the end of the iterator and can't continue.
Chase Phillips284581e2019-05-22 21:56:45208 std::move(callback).Run(blink::mojom::IDBCursorResult::NewEmpty(true));
Evan Stade5dd95ec22025-06-10 23:47:26209 return Status::OK();
dmurph50ab051b32016-11-29 22:13:30210 }
Chase Phillipsd9377f2a2019-03-06 19:30:10211
212 // |transaction_| must be valid for CreateError(), so we can't call
213 // Close() until after calling CreateError().
Evan Stadecbb1e002024-09-13 20:06:57214 DatabaseError error = CreateError(blink::mojom::IDBException::kUnknownError,
215 "Error continuing cursor.", transaction_);
dmurph50ab051b32016-11-29 22:13:30216 Close();
Chase Phillips284581e2019-05-22 21:56:45217 std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
218 blink::mojom::IDBError::New(error.code(), error.message())));
Evan Stade5dd95ec22025-06-10 23:47:26219 return result.error();
[email protected]72a4183d2013-05-31 18:33:10220 }
221
Chase Phillipsd9377f2a2019-03-06 19:30:10222 blink::mojom::IDBValuePtr mojo_value;
Chase Phillipsd9377f2a2019-03-06 19:30:10223 IndexedDBValue* value = Value();
224 if (value) {
Evan Stade822bdb42025-08-07 18:37:41225 mojo_value = transaction_->BuildMojoValue(std::move(*value));
Chase Phillipsd9377f2a2019-03-06 19:30:10226 } else {
227 mojo_value = blink::mojom::IDBValue::New();
228 }
229
Evan Stadeca999b12025-05-09 19:09:11230 std::vector<IndexedDBKey> keys;
231 keys.emplace_back(this->key().Clone());
232 std::vector<IndexedDBKey> primary_keys;
233 primary_keys.emplace_back(this->primary_key().Clone());
Chase Phillips0e2035822019-03-13 18:03:56234 std::vector<blink::mojom::IDBValuePtr> values;
235 values.push_back(std::move(mojo_value));
Chase Phillips284581e2019-05-22 21:56:45236 std::move(callback).Run(blink::mojom::IDBCursorResult::NewValues(
Chase Phillips0e2035822019-03-13 18:03:56237 blink::mojom::IDBCursorValue::New(
Chase Phillips284581e2019-05-22 21:56:45238 std::move(keys), std::move(primary_keys), std::move(values))));
Evan Stade5dd95ec22025-06-10 23:47:26239 return Status::OK();
[email protected]72a4183d2013-05-31 18:33:10240}
241
Evan Stadecbb1e002024-09-13 20:06:57242void Cursor::Prefetch(int number_to_fetch,
243 blink::mojom::IDBCursor::PrefetchCallback callback) {
244 TRACE_EVENT0("IndexedDB", "Cursor::Prefetch");
[email protected]72a4183d2013-05-31 18:33:10245
Evan Stade1a8d9d42024-09-10 19:37:19246 if (!transaction_) {
Daniel Murphy17ee4e52019-04-29 21:40:29247 Close();
Evan Stade1a8d9d42024-09-10 19:37:19248 }
dmurph50ab051b32016-11-29 22:13:30249 if (closed_) {
Evan Stadecbb1e002024-09-13 20:06:57250 const DatabaseError error(CreateCursorClosedError());
Chase Phillips284581e2019-05-22 21:56:45251 std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
252 blink::mojom::IDBError::New(error.code(), error.message())));
dmurph50ab051b32016-11-29 22:13:30253 return;
254 }
255
Chase Phillips091007d2019-05-22 22:00:13256 blink::mojom::IDBCursor::PrefetchCallback aborting_callback =
257 CreateCallbackAbortOnDestruct<blink::mojom::IDBCursor::PrefetchCallback,
258 blink::mojom::IDBCursorResultPtr>(
259 std::move(callback), transaction_);
260
Evan Stadecbb1e002024-09-13 20:06:57261 transaction_->ScheduleTask(
262 task_type_,
263 BindWeakOperation<Cursor>(&Cursor::PrefetchIterationOperation,
264 ptr_factory_.GetWeakPtr(), number_to_fetch,
265 std::move(aborting_callback)));
[email protected]72a4183d2013-05-31 18:33:10266}
267
Mike Wasserman0d5da522024-09-27 07:47:03268Status Cursor::PrefetchIterationOperation(
[email protected]65880a82013-08-16 21:30:08269 int number_to_fetch,
Chase Phillipsf74e5172019-03-13 20:44:43270 blink::mojom::IDBCursor::PrefetchCallback callback,
Evan Stadecbb1e002024-09-13 20:06:57271 Transaction* /*transaction*/) {
272 TRACE_EVENT0("IndexedDB", "Cursor::PrefetchIterationOperation");
[email protected]72a4183d2013-05-31 18:33:10273
Mike Wasserman0d5da522024-09-27 07:47:03274 Status s = Status::OK();
[email protected]72a4183d2013-05-31 18:33:10275 std::vector<IndexedDBKey> found_keys;
276 std::vector<IndexedDBKey> found_primary_keys;
[email protected]120875f2014-03-19 23:08:52277 std::vector<IndexedDBValue> found_values;
[email protected]72a4183d2013-05-31 18:33:10278
Tom Sepez36c46c02025-07-11 21:43:56279 // TODO(cmumford): Use IPC::mojom::kChannelMaximumMessageSize
[email protected]72a4183d2013-05-31 18:33:10280 const size_t max_size_estimate = 10 * 1024 * 1024;
281 size_t size_estimate = 0;
282
[email protected]b05831e2014-04-16 18:32:19283 // TODO(cmumford): Handle this error (crbug.com/363397). Although this will
284 // properly fail, caller will not know why, and any corruption
285 // will be ignored.
[email protected]65880a82013-08-16 21:30:08286 for (int i = 0; i < number_to_fetch; ++i) {
Abhishek Shanthkumard9bed3af2025-07-01 08:37:03287 if (!cursor_ || reached_end_during_prefetch_) {
Evan Stade5dd95ec22025-06-10 23:47:26288 break;
289 }
290
Abhishek Shanthkumard9bed3af2025-07-01 08:37:03291 StatusOr<bool> result = cursor_->Continue();
292 if (!result.has_value()) {
[email protected]65880a82013-08-16 21:30:08293 cursor_.reset();
Chase Phillipsf74e5172019-03-13 20:44:43294 // |transaction_| must be valid for CreateError(), so we can't call
295 // Close() until after calling CreateError().
Evan Stadecbb1e002024-09-13 20:06:57296 DatabaseError error =
Henrique Ferreiroda0a55c2019-11-12 14:06:04297 CreateError(blink::mojom::IDBException::kUnknownError,
Andreas Butler32936e32019-01-26 00:21:32298 "Error continuing cursor.", transaction_);
299 Close();
Chase Phillips284581e2019-05-22 21:56:45300 std::move(callback).Run(blink::mojom::IDBCursorResult::NewErrorResult(
301 blink::mojom::IDBError::New(error.code(), error.message())));
Evan Stade5dd95ec22025-06-10 23:47:26302 return result.error();
[email protected]72a4183d2013-05-31 18:33:10303 }
304
Abhishek Shanthkumard9bed3af2025-07-01 08:37:03305 if (!*result) {
306 // We've reached the end, so just return what we have.
307 reached_end_during_prefetch_ = true;
308 break;
309 }
310
[email protected]9e215432014-01-07 22:55:04311 if (i == 0) {
312 // First prefetched result is always used, so that's the position
313 // a cursor should be reset to if the prefetch is invalidated.
Abhishek Shanthkumard9bed3af2025-07-01 08:37:03314 cursor_->SavePosition();
[email protected]9e215432014-01-07 22:55:04315 }
316
Evan Stadeca999b12025-05-09 19:09:11317 found_keys.emplace_back(cursor_->GetKey().Clone());
318 found_primary_keys.emplace_back(cursor_->GetPrimaryKey().Clone());
[email protected]72a4183d2013-05-31 18:33:10319
[email protected]65880a82013-08-16 21:30:08320 switch (cursor_type_) {
Evan Stade6265dcd2024-02-27 20:50:04321 case indexed_db::CursorType::kKeyOnly:
[email protected]120875f2014-03-19 23:08:52322 found_values.push_back(IndexedDBValue());
[email protected]72a4183d2013-05-31 18:33:10323 break;
Evan Stade6265dcd2024-02-27 20:50:04324 case indexed_db::CursorType::kKeyAndValue: {
Evan Stade46c8dab2025-05-07 17:05:14325 found_values.push_back(std::move(cursor_->GetValue()));
326 size_estimate += found_values.back().SizeEstimate();
[email protected]72a4183d2013-05-31 18:33:10327 break;
328 }
329 default:
Peter Boströmfc7ddc182024-10-31 19:37:21330 NOTREACHED();
[email protected]72a4183d2013-05-31 18:33:10331 }
Evan Staded9529ea52025-04-11 17:02:50332 size_estimate += cursor_->GetKey().size_estimate();
333 size_estimate += cursor_->GetPrimaryKey().size_estimate();
[email protected]72a4183d2013-05-31 18:33:10334
Evan Stade1a8d9d42024-09-10 19:37:19335 if (size_estimate > max_size_estimate) {
[email protected]72a4183d2013-05-31 18:33:10336 break;
Evan Stade1a8d9d42024-09-10 19:37:19337 }
[email protected]72a4183d2013-05-31 18:33:10338 }
339
thestig76ee1f42016-07-08 18:54:00340 if (found_keys.empty()) {
Chase Phillips284581e2019-05-22 21:56:45341 std::move(callback).Run(blink::mojom::IDBCursorResult::NewEmpty(true));
Evan Stade5dd95ec22025-06-10 23:47:26342 return Status::OK();
[email protected]72a4183d2013-05-31 18:33:10343 }
344
Chase Phillipsf74e5172019-03-13 20:44:43345 DCHECK_EQ(found_keys.size(), found_primary_keys.size());
346 DCHECK_EQ(found_keys.size(), found_values.size());
347
348 std::vector<blink::mojom::IDBValuePtr> mojo_values;
349 mojo_values.reserve(found_values.size());
Evan Stade2bc92e82025-06-04 19:07:36350 for (IndexedDBValue& value : found_values) {
Evan Stade822bdb42025-08-07 18:37:41351 mojo_values.emplace_back(transaction_->BuildMojoValue(std::move(value)));
Chase Phillipsbc461232019-05-09 22:35:14352 }
Chase Phillipsf74e5172019-03-13 20:44:43353
Chase Phillips284581e2019-05-22 21:56:45354 std::move(callback).Run(blink::mojom::IDBCursorResult::NewValues(
Chase Phillipsf74e5172019-03-13 20:44:43355 blink::mojom::IDBCursorValue::New(std::move(found_keys),
356 std::move(found_primary_keys),
Chase Phillips284581e2019-05-22 21:56:45357 std::move(mojo_values))));
Evan Stade5dd95ec22025-06-10 23:47:26358 return Status::OK();
[email protected]72a4183d2013-05-31 18:33:10359}
360
Evan Stadecbb1e002024-09-13 20:06:57361void Cursor::PrefetchReset(int used_prefetches) {
362 TRACE_EVENT0("IndexedDB", "Cursor::PrefetchReset");
Evan Stade1a8d9d42024-09-10 19:37:19363 if (closed_) {
Evan Stadeb568dbdc2023-08-10 05:21:24364 return;
Evan Stade1a8d9d42024-09-10 19:37:19365 }
Abhishek Shanthkumard9bed3af2025-07-01 08:37:03366
367 reached_end_during_prefetch_ = false;
368 if (!cursor_->TryResetToLastSavedPosition()) {
369 cursor_.reset();
370 }
371
dmurph50ab051b32016-11-29 22:13:30372 // First prefetched result is always used.
Joshua Bell98475ae2019-08-15 01:43:36373 if (cursor_) {
[email protected]9e215432014-01-07 22:55:04374 DCHECK_GT(used_prefetches, 0);
Abhishek Shanthkumard9bed3af2025-07-01 08:37:03375 if (used_prefetches > 1) {
376 auto result = cursor_->Advance(used_prefetches - 1);
377 DCHECK(!result.has_value() || result.value());
378 }
[email protected]72a4183d2013-05-31 18:33:10379 }
Chase Phillips4674aa342019-03-05 01:55:17380}
381
Evan Stadecbb1e002024-09-13 20:06:57382void Cursor::Close() {
Evan Stade1a8d9d42024-09-10 19:37:19383 if (closed_) {
dmurph84f5e282017-03-30 00:58:55384 return;
Evan Stade1a8d9d42024-09-10 19:37:19385 }
Etienne Pierre-doraye0fb4b162025-08-07 16:44:48386 // Corresponds to the TRACE_EVENT_BEGIN in the constructor.
387 TRACE_EVENT_END("IndexedDB", perfetto::Track::FromPointer(this));
Evan Stadecbb1e002024-09-13 20:06:57388 TRACE_EVENT0("IndexedDB", "Cursor::Close");
[email protected]72a4183d2013-05-31 18:33:10389 closed_ = true;
390 cursor_.reset();
Evan Stade1a8d9d42024-09-10 19:37:19391 if (transaction_) {
Victor Costan23303e6f12019-09-25 20:16:48392 transaction_->UnregisterOpenCursor(this);
Evan Stade1a8d9d42024-09-10 19:37:19393 }
Daniel Murphy17ee4e52019-04-29 21:40:29394 transaction_.reset();
[email protected]72a4183d2013-05-31 18:33:10395}
396
Evan Stadecbb1e002024-09-13 20:06:57397} // namespace content::indexed_db