1 // Copyright 2016 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.
4
5 #include "content/browser/indexed_db/database_impl.h"
6
7 #include <set>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "base/numerics/safe_math.h"
13 #include "base/sequence_checker.h"
14 #include "base/sequenced_task_runner.h"
15 #include "content/browser/indexed_db/indexed_db_callback_helpers.h"
16 #include "content/browser/indexed_db/indexed_db_connection.h"
17 #include "content/browser/indexed_db/indexed_db_context_impl.h"
18 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
19 #include "content/browser/indexed_db/indexed_db_factory_impl.h"
20 #include "content/browser/indexed_db/indexed_db_transaction.h"
21 #include "content/browser/indexed_db/transaction_impl.h"
22 #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
23
24 using blink::IndexedDBIndexKeys;
25 using blink::IndexedDBKey;
26 using blink::IndexedDBKeyPath;
27 using blink::IndexedDBKeyRange;
28 using std::swap;
29
30 namespace blink {
31 class IndexedDBKeyRange;
32 }
33
34 namespace content {
35 namespace {
36
37 const char kBadTransactionMode[] = "Bad transaction mode";
38 const char kTransactionAlreadyExists[] = "Transaction already exists";
39
40 } // namespace
41
DatabaseImpl(std::unique_ptr<IndexedDBConnection> connection,const url::Origin & origin,IndexedDBDispatcherHost * dispatcher_host,scoped_refptr<base::SequencedTaskRunner> idb_runner)42 DatabaseImpl::DatabaseImpl(std::unique_ptr<IndexedDBConnection> connection,
43 const url::Origin& origin,
44 IndexedDBDispatcherHost* dispatcher_host,
45 scoped_refptr<base::SequencedTaskRunner> idb_runner)
46 : dispatcher_host_(dispatcher_host),
47 indexed_db_context_(dispatcher_host->context()),
48 connection_(std::move(connection)),
49 origin_(origin),
50 idb_runner_(std::move(idb_runner)) {
51 DCHECK(idb_runner_->RunsTasksInCurrentSequence());
52 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
53 DCHECK(connection_);
54 indexed_db_context_->ConnectionOpened(origin_, connection_.get());
55 }
56
~DatabaseImpl()57 DatabaseImpl::~DatabaseImpl() {
58 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
59 leveldb::Status status;
60 if (connection_->IsConnected()) {
61 status = connection_->AbortTransactionsAndClose(
62 IndexedDBConnection::CloseErrorHandling::kAbortAllReturnLastError);
63 }
64 indexed_db_context_->ConnectionClosed(origin_, connection_.get());
65 if (!status.ok()) {
66 indexed_db_context_->GetIDBFactory()->OnDatabaseError(
67 origin_, status, "Error during rollbacks.");
68 }
69 }
70
RenameObjectStore(int64_t transaction_id,int64_t object_store_id,const base::string16 & new_name)71 void DatabaseImpl::RenameObjectStore(int64_t transaction_id,
72 int64_t object_store_id,
73 const base::string16& new_name) {
74 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
75 if (!connection_->IsConnected())
76 return;
77
78 IndexedDBTransaction* transaction =
79 connection_->GetTransaction(transaction_id);
80 if (!transaction)
81 return;
82
83 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange) {
84 mojo::ReportBadMessage(
85 "RenameObjectStore must be called from a version change transaction.");
86 return;
87 }
88
89 transaction->ScheduleTask(
90 blink::mojom::IDBTaskType::Preemptive,
91 BindWeakOperation(&IndexedDBDatabase::RenameObjectStoreOperation,
92 connection_->database()->AsWeakPtr(), object_store_id,
93 new_name));
94 }
95
CreateTransaction(mojo::PendingAssociatedReceiver<blink::mojom::IDBTransaction> transaction_receiver,int64_t transaction_id,const std::vector<int64_t> & object_store_ids,blink::mojom::IDBTransactionMode mode,blink::mojom::IDBTransactionDurability durability)96 void DatabaseImpl::CreateTransaction(
97 mojo::PendingAssociatedReceiver<blink::mojom::IDBTransaction>
98 transaction_receiver,
99 int64_t transaction_id,
100 const std::vector<int64_t>& object_store_ids,
101 blink::mojom::IDBTransactionMode mode,
102 blink::mojom::IDBTransactionDurability durability) {
103 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
104 if (!connection_->IsConnected())
105 return;
106
107 if (mode != blink::mojom::IDBTransactionMode::ReadOnly &&
108 mode != blink::mojom::IDBTransactionMode::ReadWrite) {
109 mojo::ReportBadMessage(kBadTransactionMode);
110 return;
111 }
112
113 if (connection_->GetTransaction(transaction_id)) {
114 mojo::ReportBadMessage(kTransactionAlreadyExists);
115 return;
116 }
117
118 IndexedDBTransaction* transaction = connection_->CreateTransaction(
119 transaction_id,
120 std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode,
121 new IndexedDBBackingStore::Transaction(
122 connection_->database()->backing_store()->AsWeakPtr(), durability,
123 mode));
124 connection_->database()->RegisterAndScheduleTransaction(transaction);
125
126 dispatcher_host_->CreateAndBindTransactionImpl(
127 std::move(transaction_receiver), origin_, transaction->AsWeakPtr());
128 }
129
Close()130 void DatabaseImpl::Close() {
131 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
132 if (!connection_->IsConnected())
133 return;
134
135 leveldb::Status status = connection_->AbortTransactionsAndClose(
136 IndexedDBConnection::CloseErrorHandling::kReturnOnFirstError);
137
138 if (!status.ok()) {
139 indexed_db_context_->GetIDBFactory()->OnDatabaseError(
140 origin_, status, "Error during rollbacks.");
141 }
142 }
143
VersionChangeIgnored()144 void DatabaseImpl::VersionChangeIgnored() {
145 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
146 if (!connection_->IsConnected())
147 return;
148
149 connection_->VersionChangeIgnored();
150 }
151
AddObserver(int64_t transaction_id,int32_t observer_id,bool include_transaction,bool no_records,bool values,uint32_t operation_types)152 void DatabaseImpl::AddObserver(int64_t transaction_id,
153 int32_t observer_id,
154 bool include_transaction,
155 bool no_records,
156 bool values,
157 uint32_t operation_types) {
158 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
159 if (!connection_->IsConnected())
160 return;
161
162 IndexedDBTransaction* transaction =
163 connection_->GetTransaction(transaction_id);
164 if (!transaction)
165 return;
166
167 IndexedDBObserver::Options options(include_transaction, no_records, values,
168 operation_types);
169 connection_->database()->AddPendingObserver(transaction, observer_id,
170 options);
171 }
172
RemoveObservers(const std::vector<int32_t> & observers)173 void DatabaseImpl::RemoveObservers(const std::vector<int32_t>& observers) {
174 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
175 if (!connection_->IsConnected())
176 return;
177
178 connection_->RemoveObservers(observers);
179 }
180
Get(int64_t transaction_id,int64_t object_store_id,int64_t index_id,const IndexedDBKeyRange & key_range,bool key_only,blink::mojom::IDBDatabase::GetCallback callback)181 void DatabaseImpl::Get(int64_t transaction_id,
182 int64_t object_store_id,
183 int64_t index_id,
184 const IndexedDBKeyRange& key_range,
185 bool key_only,
186 blink::mojom::IDBDatabase::GetCallback callback) {
187 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
188 if (!connection_->IsConnected()) {
189 IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
190 "Not connected.");
191 std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult(
192 blink::mojom::IDBError::New(error.code(), error.message())));
193 return;
194 }
195
196 IndexedDBTransaction* transaction =
197 connection_->GetTransaction(transaction_id);
198 if (!transaction) {
199 IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
200 "Unknown transaction.");
201 std::move(callback).Run(blink::mojom::IDBDatabaseGetResult::NewErrorResult(
202 blink::mojom::IDBError::New(error.code(), error.message())));
203 return;
204 }
205
206 blink::mojom::IDBDatabase::GetCallback aborting_callback =
207 CreateCallbackAbortOnDestruct<blink::mojom::IDBDatabase::GetCallback,
208 blink::mojom::IDBDatabaseGetResultPtr>(
209 std::move(callback), transaction->AsWeakPtr());
210
211 transaction->ScheduleTask(BindWeakOperation(
212 &IndexedDBDatabase::GetOperation, connection_->database()->AsWeakPtr(),
213 dispatcher_host_->AsWeakPtr(), object_store_id, index_id,
214 std::make_unique<IndexedDBKeyRange>(key_range),
215 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
216 std::move(aborting_callback)));
217 }
218
GetAll(int64_t transaction_id,int64_t object_store_id,int64_t index_id,const IndexedDBKeyRange & key_range,bool key_only,int64_t max_count,blink::mojom::IDBDatabase::GetAllCallback callback)219 void DatabaseImpl::GetAll(int64_t transaction_id,
220 int64_t object_store_id,
221 int64_t index_id,
222 const IndexedDBKeyRange& key_range,
223 bool key_only,
224 int64_t max_count,
225 blink::mojom::IDBDatabase::GetAllCallback callback) {
226 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
227 if (!connection_->IsConnected()) {
228 IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
229 "Not connected.");
230 std::move(callback).Run(
231 blink::mojom::IDBDatabaseGetAllResult::NewErrorResult(
232 blink::mojom::IDBError::New(error.code(), error.message())));
233 return;
234 }
235
236 IndexedDBTransaction* transaction =
237 connection_->GetTransaction(transaction_id);
238 if (!transaction) {
239 IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
240 "Unknown transaction.");
241 std::move(callback).Run(
242 blink::mojom::IDBDatabaseGetAllResult::NewErrorResult(
243 blink::mojom::IDBError::New(error.code(), error.message())));
244 return;
245 }
246
247 blink::mojom::IDBDatabase::GetAllCallback aborting_callback =
248 CreateCallbackAbortOnDestruct<blink::mojom::IDBDatabase::GetAllCallback,
249 blink::mojom::IDBDatabaseGetAllResultPtr>(
250 std::move(callback), transaction->AsWeakPtr());
251
252 transaction->ScheduleTask(BindWeakOperation(
253 &IndexedDBDatabase::GetAllOperation, connection_->database()->AsWeakPtr(),
254 dispatcher_host_->AsWeakPtr(), object_store_id, index_id,
255 std::make_unique<IndexedDBKeyRange>(key_range),
256 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE,
257 max_count, std::move(aborting_callback)));
258 }
259
SetIndexKeys(int64_t transaction_id,int64_t object_store_id,const IndexedDBKey & primary_key,const std::vector<IndexedDBIndexKeys> & index_keys)260 void DatabaseImpl::SetIndexKeys(
261 int64_t transaction_id,
262 int64_t object_store_id,
263 const IndexedDBKey& primary_key,
264 const std::vector<IndexedDBIndexKeys>& index_keys) {
265 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
266 if (!connection_->IsConnected())
267 return;
268
269 IndexedDBTransaction* transaction =
270 connection_->GetTransaction(transaction_id);
271 if (!transaction)
272 return;
273
274 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange) {
275 mojo::ReportBadMessage(
276 "SetIndexKeys must be called from a version change transaction.");
277 return;
278 }
279
280 transaction->ScheduleTask(
281 blink::mojom::IDBTaskType::Preemptive,
282 BindWeakOperation(&IndexedDBDatabase::SetIndexKeysOperation,
283 connection_->database()->AsWeakPtr(), object_store_id,
284 std::make_unique<IndexedDBKey>(primary_key),
285 index_keys));
286 }
287
SetIndexesReady(int64_t transaction_id,int64_t object_store_id,const std::vector<int64_t> & index_ids)288 void DatabaseImpl::SetIndexesReady(int64_t transaction_id,
289 int64_t object_store_id,
290 const std::vector<int64_t>& index_ids) {
291 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
292 if (!connection_->IsConnected())
293 return;
294
295 IndexedDBTransaction* transaction =
296 connection_->GetTransaction(transaction_id);
297 if (!transaction)
298 return;
299
300 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange) {
301 mojo::ReportBadMessage(
302 "SetIndexesReady must be called from a version change transaction.");
303 return;
304 }
305
306 transaction->ScheduleTask(
307 blink::mojom::IDBTaskType::Preemptive,
308 BindWeakOperation(&IndexedDBDatabase::SetIndexesReadyOperation,
309 connection_->database()->AsWeakPtr(),
310 index_ids.size()));
311 }
312
OpenCursor(int64_t transaction_id,int64_t object_store_id,int64_t index_id,const IndexedDBKeyRange & key_range,blink::mojom::IDBCursorDirection direction,bool key_only,blink::mojom::IDBTaskType task_type,blink::mojom::IDBDatabase::OpenCursorCallback callback)313 void DatabaseImpl::OpenCursor(
314 int64_t transaction_id,
315 int64_t object_store_id,
316 int64_t index_id,
317 const IndexedDBKeyRange& key_range,
318 blink::mojom::IDBCursorDirection direction,
319 bool key_only,
320 blink::mojom::IDBTaskType task_type,
321 blink::mojom::IDBDatabase::OpenCursorCallback callback) {
322 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
323 if (!connection_->IsConnected()) {
324 IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
325 "Not connected.");
326 std::move(callback).Run(
327 blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult(
328 blink::mojom::IDBError::New(error.code(), error.message())));
329 return;
330 }
331
332 IndexedDBTransaction* transaction =
333 connection_->GetTransaction(transaction_id);
334 if (!transaction) {
335 IndexedDBDatabaseError error(blink::mojom::IDBException::kUnknownError,
336 "Unknown transaction.");
337 std::move(callback).Run(
338 blink::mojom::IDBDatabaseOpenCursorResult::NewErrorResult(
339 blink::mojom::IDBError::New(error.code(), error.message())));
340 return;
341 }
342
343 blink::mojom::IDBDatabase::OpenCursorCallback aborting_callback =
344 CreateCallbackAbortOnDestruct<
345 blink::mojom::IDBDatabase::OpenCursorCallback,
346 blink::mojom::IDBDatabaseOpenCursorResultPtr>(
347 std::move(callback), transaction->AsWeakPtr());
348
349 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange &&
350 task_type == blink::mojom::IDBTaskType::Preemptive) {
351 mojo::ReportBadMessage(
352 "OpenCursor with |Preemptive| task type must be called from a version "
353 "change transaction.");
354 return;
355 }
356
357 std::unique_ptr<IndexedDBDatabase::OpenCursorOperationParams> params(
358 std::make_unique<IndexedDBDatabase::OpenCursorOperationParams>());
359 params->object_store_id = object_store_id;
360 params->index_id = index_id;
361 params->key_range = std::make_unique<IndexedDBKeyRange>(key_range);
362 params->direction = direction;
363 params->cursor_type =
364 key_only ? indexed_db::CURSOR_KEY_ONLY : indexed_db::CURSOR_KEY_AND_VALUE;
365 params->task_type = task_type;
366 params->callback = std::move(aborting_callback);
367 transaction->ScheduleTask(
368 BindWeakOperation(&IndexedDBDatabase::OpenCursorOperation,
369 connection_->database()->AsWeakPtr(), std::move(params),
370 origin_, dispatcher_host_->AsWeakPtr()));
371 }
372
Count(int64_t transaction_id,int64_t object_store_id,int64_t index_id,const IndexedDBKeyRange & key_range,mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> pending_callbacks)373 void DatabaseImpl::Count(
374 int64_t transaction_id,
375 int64_t object_store_id,
376 int64_t index_id,
377 const IndexedDBKeyRange& key_range,
378 mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks>
379 pending_callbacks) {
380 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
381 scoped_refptr<IndexedDBCallbacks> callbacks(
382 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
383 std::move(pending_callbacks), idb_runner_));
384 if (!connection_->IsConnected())
385 return;
386
387 IndexedDBTransaction* transaction =
388 connection_->GetTransaction(transaction_id);
389 if (!transaction)
390 return;
391
392 transaction->ScheduleTask(BindWeakOperation(
393 &IndexedDBDatabase::CountOperation, connection_->database()->AsWeakPtr(),
394 object_store_id, index_id,
395 std::make_unique<blink::IndexedDBKeyRange>(key_range),
396 std::move(callbacks)));
397 }
398
DeleteRange(int64_t transaction_id,int64_t object_store_id,const IndexedDBKeyRange & key_range,mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> pending_callbacks)399 void DatabaseImpl::DeleteRange(
400 int64_t transaction_id,
401 int64_t object_store_id,
402 const IndexedDBKeyRange& key_range,
403 mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks>
404 pending_callbacks) {
405 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
406 scoped_refptr<IndexedDBCallbacks> callbacks(
407 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
408 std::move(pending_callbacks), idb_runner_));
409 if (!connection_->IsConnected())
410 return;
411
412 IndexedDBTransaction* transaction =
413 connection_->GetTransaction(transaction_id);
414 if (!transaction)
415 return;
416
417 transaction->ScheduleTask(BindWeakOperation(
418 &IndexedDBDatabase::DeleteRangeOperation,
419 connection_->database()->AsWeakPtr(), object_store_id,
420 std::make_unique<IndexedDBKeyRange>(key_range), std::move(callbacks)));
421 }
422
GetKeyGeneratorCurrentNumber(int64_t transaction_id,int64_t object_store_id,mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> pending_callbacks)423 void DatabaseImpl::GetKeyGeneratorCurrentNumber(
424 int64_t transaction_id,
425 int64_t object_store_id,
426 mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks>
427 pending_callbacks) {
428 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
429 scoped_refptr<IndexedDBCallbacks> callbacks(
430 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
431 std::move(pending_callbacks), idb_runner_));
432 if (!connection_->IsConnected())
433 return;
434
435 IndexedDBTransaction* transaction =
436 connection_->GetTransaction(transaction_id);
437 if (!transaction)
438 return;
439
440 transaction->ScheduleTask(BindWeakOperation(
441 &IndexedDBDatabase::GetKeyGeneratorCurrentNumberOperation,
442 connection_->database()->AsWeakPtr(), object_store_id,
443 std::move(callbacks)));
444 }
445
Clear(int64_t transaction_id,int64_t object_store_id,mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> pending_callbacks)446 void DatabaseImpl::Clear(
447 int64_t transaction_id,
448 int64_t object_store_id,
449 mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks>
450 pending_callbacks) {
451 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
452 scoped_refptr<IndexedDBCallbacks> callbacks(
453 new IndexedDBCallbacks(dispatcher_host_->AsWeakPtr(), origin_,
454 std::move(pending_callbacks), idb_runner_));
455 if (!connection_->IsConnected())
456 return;
457
458 IndexedDBTransaction* transaction =
459 connection_->GetTransaction(transaction_id);
460 if (!transaction)
461 return;
462
463 transaction->ScheduleTask(BindWeakOperation(
464 &IndexedDBDatabase::ClearOperation, connection_->database()->AsWeakPtr(),
465 object_store_id, std::move(callbacks)));
466 }
467
CreateIndex(int64_t transaction_id,int64_t object_store_id,int64_t index_id,const base::string16 & name,const IndexedDBKeyPath & key_path,bool unique,bool multi_entry)468 void DatabaseImpl::CreateIndex(int64_t transaction_id,
469 int64_t object_store_id,
470 int64_t index_id,
471 const base::string16& name,
472 const IndexedDBKeyPath& key_path,
473 bool unique,
474 bool multi_entry) {
475 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
476 if (!connection_->IsConnected())
477 return;
478
479 IndexedDBTransaction* transaction =
480 connection_->GetTransaction(transaction_id);
481 if (!transaction)
482 return;
483
484 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange) {
485 mojo::ReportBadMessage(
486 "CreateIndex must be called from a version change transaction.");
487 return;
488 }
489
490 transaction->ScheduleTask(
491 blink::mojom::IDBTaskType::Preemptive,
492 BindWeakOperation(&IndexedDBDatabase::CreateIndexOperation,
493 connection_->database()->AsWeakPtr(), object_store_id,
494 index_id, name, key_path, unique, multi_entry));
495 }
496
DeleteIndex(int64_t transaction_id,int64_t object_store_id,int64_t index_id)497 void DatabaseImpl::DeleteIndex(int64_t transaction_id,
498 int64_t object_store_id,
499 int64_t index_id) {
500 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
501 if (!connection_->IsConnected())
502 return;
503
504 IndexedDBTransaction* transaction =
505 connection_->GetTransaction(transaction_id);
506 if (!transaction)
507 return;
508
509 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange) {
510 mojo::ReportBadMessage(
511 "DeleteIndex must be called from a version change transaction.");
512 return;
513 }
514
515 transaction->ScheduleTask(BindWeakOperation(
516 &IndexedDBDatabase::DeleteIndexOperation,
517 connection_->database()->AsWeakPtr(), object_store_id, index_id));
518 }
519
RenameIndex(int64_t transaction_id,int64_t object_store_id,int64_t index_id,const base::string16 & new_name)520 void DatabaseImpl::RenameIndex(int64_t transaction_id,
521 int64_t object_store_id,
522 int64_t index_id,
523 const base::string16& new_name) {
524 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
525 if (!connection_->IsConnected())
526 return;
527
528 IndexedDBTransaction* transaction =
529 connection_->GetTransaction(transaction_id);
530 if (!transaction)
531 return;
532
533 if (transaction->mode() != blink::mojom::IDBTransactionMode::VersionChange) {
534 mojo::ReportBadMessage(
535 "RenameIndex must be called from a version change transaction.");
536 return;
537 }
538
539 transaction->ScheduleTask(
540 BindWeakOperation(&IndexedDBDatabase::RenameIndexOperation,
541 connection_->database()->AsWeakPtr(), object_store_id,
542 index_id, new_name));
543 }
544
Abort(int64_t transaction_id)545 void DatabaseImpl::Abort(int64_t transaction_id) {
546 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
547 if (!connection_->IsConnected())
548 return;
549
550 IndexedDBTransaction* transaction =
551 connection_->GetTransaction(transaction_id);
552 if (!transaction)
553 return;
554
555 connection_->AbortTransactionAndTearDownOnError(
556 transaction,
557 IndexedDBDatabaseError(blink::mojom::IDBException::kAbortError,
558 "Transaction aborted by user."));
559 }
560
561 } // namespace content
562