Chromium Code Reviews| 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 |