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
3 // found in the LICENSE file.
5 #include "content/browser/indexed_db/indexed_db_cursor.h"
8 #include "base/logging.h"
9 #include "content/browser/indexed_db/indexed_db_callbacks.h"
10 #include "content/browser/indexed_db/indexed_db_database_error.h"
11 #include "content/browser/indexed_db/indexed_db_tracing.h"
12 #include "content/browser/indexed_db/indexed_db_transaction.h"
16 IndexedDBCursor::IndexedDBCursor(
17 scoped_ptr
<IndexedDBBackingStore::Cursor
> cursor
,
18 indexed_db::CursorType cursor_type
,
19 IndexedDBDatabase::TaskType task_type
,
20 IndexedDBTransaction
* transaction
)
21 : task_type_(task_type
),
22 cursor_type_(cursor_type
),
23 transaction_(transaction
),
24 cursor_(cursor
.Pass()),
26 transaction_
->RegisterOpenCursor(this);
29 IndexedDBCursor::~IndexedDBCursor() {
30 transaction_
->UnregisterOpenCursor(this);
33 void IndexedDBCursor::Continue(scoped_ptr
<IndexedDBKey
> key
,
34 scoped_refptr
<IndexedDBCallbacks
> callbacks
) {
35 IDB_TRACE("IndexedDBCursor::Continue");
37 transaction_
->ScheduleTask(
39 base::Bind(&IndexedDBCursor::CursorIterationOperation
,
45 void IndexedDBCursor::Advance(uint32 count
,
46 scoped_refptr
<IndexedDBCallbacks
> callbacks
) {
47 IDB_TRACE("IndexedDBCursor::Advance");
49 transaction_
->ScheduleTask(
52 &IndexedDBCursor::CursorAdvanceOperation
, this, count
, callbacks
));
55 void IndexedDBCursor::CursorAdvanceOperation(
57 scoped_refptr
<IndexedDBCallbacks
> callbacks
,
58 IndexedDBTransaction
* /*transaction*/) {
59 IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation");
60 if (!cursor_
|| !cursor_
->Advance(count
)) {
62 callbacks
->OnSuccess(static_cast<std::string
*>(NULL
));
66 callbacks
->OnSuccess(key(), primary_key(), Value());
69 void IndexedDBCursor::CursorIterationOperation(
70 scoped_ptr
<IndexedDBKey
> key
,
71 scoped_refptr
<IndexedDBCallbacks
> callbacks
,
72 IndexedDBTransaction
* /*transaction*/) {
73 IDB_TRACE("IndexedDBCursor::CursorIterationOperation");
75 !cursor_
->Continue(key
.get(), IndexedDBBackingStore::Cursor::SEEK
)) {
77 callbacks
->OnSuccess(static_cast<std::string
*>(NULL
));
81 callbacks
->OnSuccess(this->key(), primary_key(), Value());
84 void IndexedDBCursor::PrefetchContinue(
86 scoped_refptr
<IndexedDBCallbacks
> callbacks
) {
87 IDB_TRACE("IndexedDBCursor::PrefetchContinue");
89 transaction_
->ScheduleTask(
91 base::Bind(&IndexedDBCursor::CursorPrefetchIterationOperation
,
97 void IndexedDBCursor::CursorPrefetchIterationOperation(
99 scoped_refptr
<IndexedDBCallbacks
> callbacks
,
100 IndexedDBTransaction
* /*transaction*/) {
101 IDB_TRACE("IndexedDBCursor::CursorPrefetchIterationOperation");
103 std::vector
<IndexedDBKey
> found_keys
;
104 std::vector
<IndexedDBKey
> found_primary_keys
;
105 std::vector
<std::string
> found_values
;
108 saved_cursor_
.reset(cursor_
->Clone());
109 const size_t max_size_estimate
= 10 * 1024 * 1024;
110 size_t size_estimate
= 0;
112 for (int i
= 0; i
< number_to_fetch
; ++i
) {
113 if (!cursor_
|| !cursor_
->Continue()) {
118 found_keys
.push_back(cursor_
->key());
119 found_primary_keys
.push_back(cursor_
->primary_key());
121 switch (cursor_type_
) {
122 case indexed_db::CURSOR_KEY_ONLY
:
123 found_values
.push_back(std::string());
125 case indexed_db::CURSOR_KEY_AND_VALUE
: {
127 value
.swap(*cursor_
->Value());
128 size_estimate
+= value
.size();
129 found_values
.push_back(value
);
135 size_estimate
+= cursor_
->key().size_estimate();
136 size_estimate
+= cursor_
->primary_key().size_estimate();
138 if (size_estimate
> max_size_estimate
)
142 if (!found_keys
.size()) {
143 callbacks
->OnSuccess(static_cast<std::string
*>(NULL
));
147 callbacks
->OnSuccessWithPrefetch(
148 found_keys
, found_primary_keys
, found_values
);
151 void IndexedDBCursor::PrefetchReset(int used_prefetches
, int) {
152 IDB_TRACE("IndexedDBCursor::PrefetchReset");
153 cursor_
.swap(saved_cursor_
);
154 saved_cursor_
.reset();
159 for (int i
= 0; i
< used_prefetches
; ++i
) {
160 bool ok
= cursor_
->Continue();
166 void IndexedDBCursor::Close() {
167 IDB_TRACE("IndexedDBCursor::Close");
170 saved_cursor_
.reset();
173 } // namespace content