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_cursor.h" | 5 #include "content/browser/indexed_db/indexed_db_cursor.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "content/browser/indexed_db/indexed_db_callbacks.h" | 13 #include "content/browser/indexed_db/indexed_db_callbacks.h" |
14 #include "content/browser/indexed_db/indexed_db_database_error.h" | 14 #include "content/browser/indexed_db/indexed_db_database_error.h" |
15 #include "content/browser/indexed_db/indexed_db_tracing.h" | 15 #include "content/browser/indexed_db/indexed_db_tracing.h" |
16 #include "content/browser/indexed_db/indexed_db_transaction.h" | 16 #include "content/browser/indexed_db/indexed_db_transaction.h" |
17 #include "content/browser/indexed_db/indexed_db_value.h" | 17 #include "content/browser/indexed_db/indexed_db_value.h" |
18 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" | 18 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" |
19 | 19 |
20 namespace content { | 20 namespace content { |
21 namespace { | |
22 // This should never be script visible: the cursor should either be closed when | |
23 // it hits the end of the range (and script throws an error before the call | |
24 // could be made), if the transaction has finished (ditto), or if there's an | |
25 // incoming request from the front end but the transaction has aborted on the | |
26 // back end; in that case the tx will already have sent an abort to the request | |
27 // so this would be ignored. | |
28 IndexedDBDatabaseError CreateCursorClosedError() { | |
29 return IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | |
30 "The cursor has been closed."); | |
31 } | |
32 | |
33 leveldb::Status InvokeOrSucceed(base::WeakPtr<IndexedDBCursor> weak_cursor, | |
34 IndexedDBTransaction::Operation operation, | |
35 IndexedDBTransaction* transaction) { | |
36 if (weak_cursor) | |
37 return operation.Run(transaction); | |
38 return leveldb::Status::OK(); | |
39 } | |
40 | |
41 // This allows us to bind a function with a return value to a weak ptr, and if | |
42 // the weak pointer is invalidated then we just return a default (success). | |
43 template <typename Functor, typename... Args> | |
44 IndexedDBTransaction::Operation BindWeakOperation( | |
45 Functor&& functor, | |
46 base::WeakPtr<IndexedDBCursor> weak_cursor, | |
47 Args&&... args) { | |
48 DCHECK(weak_cursor); | |
49 IndexedDBCursor* cursor_ptr = weak_cursor.get(); | |
50 return base::Bind( | |
51 &InvokeOrSucceed, std::move(weak_cursor), | |
52 base::Bind(std::forward<Functor>(functor), base::Unretained(cursor_ptr), | |
53 std::forward<Args>(args)...)); | |
54 } | |
55 | |
56 } // namespace | |
21 | 57 |
22 IndexedDBCursor::IndexedDBCursor( | 58 IndexedDBCursor::IndexedDBCursor( |
23 std::unique_ptr<IndexedDBBackingStore::Cursor> cursor, | 59 std::unique_ptr<IndexedDBBackingStore::Cursor> cursor, |
24 indexed_db::CursorType cursor_type, | 60 indexed_db::CursorType cursor_type, |
25 blink::WebIDBTaskType task_type, | 61 blink::WebIDBTaskType task_type, |
26 IndexedDBTransaction* transaction) | 62 IndexedDBTransaction* transaction) |
27 : task_type_(task_type), | 63 : task_type_(task_type), |
28 cursor_type_(cursor_type), | 64 cursor_type_(cursor_type), |
29 transaction_(transaction), | 65 transaction_(transaction), |
30 cursor_(std::move(cursor)), | 66 cursor_(std::move(cursor)), |
31 closed_(false) { | 67 closed_(false), |
32 transaction_->RegisterOpenCursor(this); | 68 ptr_factory_(this) {} |
33 } | |
34 | 69 |
35 IndexedDBCursor::~IndexedDBCursor() { | 70 IndexedDBCursor::~IndexedDBCursor() {} |
36 transaction_->UnregisterOpenCursor(this); | |
37 } | |
38 | 71 |
39 void IndexedDBCursor::Continue(std::unique_ptr<IndexedDBKey> key, | 72 void IndexedDBCursor::Continue(std::unique_ptr<IndexedDBKey> key, |
40 std::unique_ptr<IndexedDBKey> primary_key, | 73 std::unique_ptr<IndexedDBKey> primary_key, |
41 scoped_refptr<IndexedDBCallbacks> callbacks) { | 74 scoped_refptr<IndexedDBCallbacks> callbacks) { |
42 IDB_TRACE("IndexedDBCursor::Continue"); | 75 IDB_TRACE("IndexedDBCursor::Continue"); |
43 | 76 |
44 if (closed_) { | 77 if (closed_) { |
45 callbacks->OnError( | 78 callbacks->OnError(CreateCursorClosedError()); |
46 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | |
47 "The cursor has been closed.")); | |
48 return; | 79 return; |
49 } | 80 } |
50 | 81 |
51 transaction_->ScheduleTask( | 82 transaction_->ScheduleTask( |
52 task_type_, | 83 task_type_, |
53 base::Bind(&IndexedDBCursor::CursorIterationOperation, | 84 BindWeakOperation(&IndexedDBCursor::CursorIterationOperation, |
54 this, | 85 ptr_factory_.GetWeakPtr(), base::Passed(&key), |
55 base::Passed(&key), | 86 base::Passed(&primary_key), callbacks)); |
56 base::Passed(&primary_key), | |
57 callbacks)); | |
58 } | 87 } |
59 | 88 |
60 void IndexedDBCursor::Advance(uint32_t count, | 89 void IndexedDBCursor::Advance(uint32_t count, |
61 scoped_refptr<IndexedDBCallbacks> callbacks) { | 90 scoped_refptr<IndexedDBCallbacks> callbacks) { |
62 IDB_TRACE("IndexedDBCursor::Advance"); | 91 IDB_TRACE("IndexedDBCursor::Advance"); |
63 | 92 |
64 if (closed_) { | 93 if (closed_) { |
65 callbacks->OnError( | 94 callbacks->OnError(CreateCursorClosedError()); |
66 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | |
67 "The cursor has been closed.")); | |
68 return; | 95 return; |
69 } | 96 } |
70 | 97 |
71 transaction_->ScheduleTask( | 98 transaction_->ScheduleTask( |
72 task_type_, | 99 task_type_, |
73 base::Bind( | 100 BindWeakOperation(&IndexedDBCursor::CursorAdvanceOperation, |
74 &IndexedDBCursor::CursorAdvanceOperation, this, count, callbacks)); | 101 ptr_factory_.GetWeakPtr(), count, callbacks)); |
102 } | |
103 | |
104 void IndexedDBCursor::Close() { | |
105 IDB_TRACE("IndexedDBCursor::Close"); | |
106 closed_ = true; | |
107 cursor_.reset(); | |
108 saved_cursor_.reset(); | |
109 transaction_ = nullptr; | |
110 } | |
111 | |
112 void IndexedDBCursor::RemoveCursorFromTransaction() { | |
113 if (transaction_) | |
114 transaction_->UnregisterOpenCursor(this); | |
75 } | 115 } |
76 | 116 |
77 leveldb::Status IndexedDBCursor::CursorAdvanceOperation( | 117 leveldb::Status IndexedDBCursor::CursorAdvanceOperation( |
78 uint32_t count, | 118 uint32_t count, |
79 scoped_refptr<IndexedDBCallbacks> callbacks, | 119 scoped_refptr<IndexedDBCallbacks> callbacks, |
80 IndexedDBTransaction* /*transaction*/) { | 120 IndexedDBTransaction* /*transaction*/) { |
81 IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation"); | 121 IDB_TRACE("IndexedDBCursor::CursorAdvanceOperation"); |
82 leveldb::Status s = leveldb::Status::OK(); | 122 leveldb::Status s = leveldb::Status::OK(); |
83 | 123 |
84 if (!cursor_ || !cursor_->Advance(count, &s)) { | 124 if (!cursor_ || !cursor_->Advance(count, &s)) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 callbacks->OnSuccess(this->key(), this->primary_key(), Value()); | 164 callbacks->OnSuccess(this->key(), this->primary_key(), Value()); |
125 return s; | 165 return s; |
126 } | 166 } |
127 | 167 |
128 void IndexedDBCursor::PrefetchContinue( | 168 void IndexedDBCursor::PrefetchContinue( |
129 int number_to_fetch, | 169 int number_to_fetch, |
130 scoped_refptr<IndexedDBCallbacks> callbacks) { | 170 scoped_refptr<IndexedDBCallbacks> callbacks) { |
131 IDB_TRACE("IndexedDBCursor::PrefetchContinue"); | 171 IDB_TRACE("IndexedDBCursor::PrefetchContinue"); |
132 | 172 |
133 if (closed_) { | 173 if (closed_) { |
134 callbacks->OnError( | 174 callbacks->OnError(CreateCursorClosedError()); |
135 IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | |
136 "The cursor has been closed.")); | |
137 return; | 175 return; |
138 } | 176 } |
139 | 177 |
140 transaction_->ScheduleTask( | 178 transaction_->ScheduleTask( |
141 task_type_, | 179 task_type_, |
142 base::Bind(&IndexedDBCursor::CursorPrefetchIterationOperation, | 180 BindWeakOperation(&IndexedDBCursor::CursorPrefetchIterationOperation, |
143 this, | 181 ptr_factory_.GetWeakPtr(), number_to_fetch, callbacks)); |
144 number_to_fetch, | |
145 callbacks)); | |
146 } | 182 } |
147 | 183 |
148 leveldb::Status IndexedDBCursor::CursorPrefetchIterationOperation( | 184 leveldb::Status IndexedDBCursor::CursorPrefetchIterationOperation( |
149 int number_to_fetch, | 185 int number_to_fetch, |
150 scoped_refptr<IndexedDBCallbacks> callbacks, | 186 scoped_refptr<IndexedDBCallbacks> callbacks, |
151 IndexedDBTransaction* /*transaction*/) { | 187 IndexedDBTransaction* /*transaction*/) { |
152 IDB_TRACE("IndexedDBCursor::CursorPrefetchIterationOperation"); | 188 IDB_TRACE("IndexedDBCursor::CursorPrefetchIterationOperation"); |
153 leveldb::Status s = leveldb::Status::OK(); | 189 leveldb::Status s = leveldb::Status::OK(); |
154 | 190 |
155 std::vector<IndexedDBKey> found_keys; | 191 std::vector<IndexedDBKey> found_keys; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 DCHECK_GT(used_prefetches, 0); | 268 DCHECK_GT(used_prefetches, 0); |
233 for (int i = 0; i < used_prefetches - 1; ++i) { | 269 for (int i = 0; i < used_prefetches - 1; ++i) { |
234 bool ok = cursor_->Continue(&s); | 270 bool ok = cursor_->Continue(&s); |
235 DCHECK(ok); | 271 DCHECK(ok); |
236 } | 272 } |
237 } | 273 } |
238 | 274 |
239 return s; | 275 return s; |
240 } | 276 } |
241 | 277 |
242 void IndexedDBCursor::Close() { | |
cmumford
2016/12/01 19:14:51
Any reason to move Close()? git-blame works better
dmurph
2016/12/01 21:12:23
Just trying to put it in header order. Moved back.
| |
243 IDB_TRACE("IndexedDBCursor::Close"); | |
244 closed_ = true; | |
245 cursor_.reset(); | |
246 saved_cursor_.reset(); | |
247 } | |
248 | |
249 } // namespace content | 278 } // namespace content |
OLD | NEW |