blob: dad7889d7cb7f8e778a21cf4d7229d452ca76696 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2019 The Chromium Authors
Chase Phillips091007d2019-05-22 22:00:132// 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#ifndef CONTENT_BROWSER_INDEXED_DB_INSTANCE_CALLBACK_HELPERS_H_
6#define CONTENT_BROWSER_INDEXED_DB_INSTANCE_CALLBACK_HELPERS_H_
Chase Phillips091007d2019-05-22 22:00:137
8#include <memory>
Joshua Bell98475ae2019-08-15 01:43:369#include <utility>
Chase Phillips091007d2019-05-22 22:00:1310
Hans Wennborgf30ad802020-06-20 16:50:2011#include "base/check.h"
Chase Phillips091007d2019-05-22 22:00:1312#include "base/memory/weak_ptr.h"
Evan Stade1a8d9d42024-09-10 19:37:1913#include "content/browser/indexed_db/instance/transaction.h"
Henrique Ferreiroda0a55c2019-11-12 14:06:0414#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h"
Chase Phillips091007d2019-05-22 22:00:1315#include "third_party/leveldatabase/env_chromium.h"
16
17// Since functions in this file use templates, they must be in a header file
18// and can't be placed in a definition file. Please ensure any including file
19// is a definition file, itself, and never include this into a header file.
20
Evan Stadecbb1e002024-09-13 20:06:5721namespace content::indexed_db {
Chase Phillips091007d2019-05-22 22:00:1322namespace indexed_db_callback_helpers_internal {
23
24template <typename T>
Mike Wasserman0d5da522024-09-27 07:47:0325Status InvokeOrSucceed(base::WeakPtr<T> ptr,
26 Transaction::Operation operation,
27 Transaction* transaction) {
Evan Stade1a8d9d42024-09-10 19:37:1928 if (ptr) {
Chase Phillips091007d2019-05-22 22:00:1329 return std::move(operation).Run(transaction);
Evan Stade1a8d9d42024-09-10 19:37:1930 }
Mike Wasserman0d5da522024-09-27 07:47:0331 return Status::OK();
Chase Phillips091007d2019-05-22 22:00:1332}
33
34template <typename R>
Evan Stadecbb1e002024-09-13 20:06:5735R AbortCallback(base::WeakPtr<Transaction> transaction) {
Evan Stade1a8d9d42024-09-10 19:37:1936 if (transaction) {
Chase Phillips091007d2019-05-22 22:00:1337 transaction->IncrementNumErrorsSent();
Evan Stade1a8d9d42024-09-10 19:37:1938 }
Evan Stadecbb1e002024-09-13 20:06:5739 DatabaseError error(blink::mojom::IDBException::kIgnorableAbortError,
40 "Backend aborted error");
Chase Phillips091007d2019-05-22 22:00:1341 return R::Struct::NewErrorResult(
42 blink::mojom::IDBError::New(error.code(), error.message()));
43}
44
45template <typename R>
46base::OnceCallback<R()> CreateAbortCallback(
Evan Stadecbb1e002024-09-13 20:06:5747 base::WeakPtr<Transaction> transaction) {
Chase Phillips091007d2019-05-22 22:00:1348 return base::BindOnce(&AbortCallback<R>, std::move(transaction));
49}
50
51// CallbackAbortOnDestruct wraps a callback in a class with a destructor that
52// invokes that callback. When the CallbackAbortOnDestruct is instantiated,
53// it expects a separate callback that, when called at destruct, will return
54// the arguments that should be passed to the wrapped callback.
55//
56// This class is loosely based on //mojo/public/cpp/bindings/callback_helpers.h
57// WrapCallbackWithDefaultInvokeIfNotRun. The difference is that the destructor
58// calls |callback_| with args it gets on destruct rather than using static args
59// given when the wrapper is created.
60template <typename T, typename R>
61class CallbackAbortOnDestruct {
62 public:
Evan Stadecbb1e002024-09-13 20:06:5763 CallbackAbortOnDestruct(T callback, base::WeakPtr<Transaction> transaction)
Chase Phillips091007d2019-05-22 22:00:1364 : callback_(std::move(callback)),
65 args_at_destroy_(CreateAbortCallback<R>(transaction)),
66 called_(false) {}
Peter Boström828b9022021-09-21 02:28:4367
68 CallbackAbortOnDestruct(const CallbackAbortOnDestruct&) = delete;
69 CallbackAbortOnDestruct& operator=(const CallbackAbortOnDestruct&) = delete;
70
Chase Phillips091007d2019-05-22 22:00:1371 ~CallbackAbortOnDestruct() {
Evan Stade1a8d9d42024-09-10 19:37:1972 if (called_) {
Chase Phillips091007d2019-05-22 22:00:1373 return;
Evan Stade1a8d9d42024-09-10 19:37:1974 }
Chase Phillips091007d2019-05-22 22:00:1375 R args = std::move(args_at_destroy_).Run();
76 std::move(callback_).Run(std::move(args));
77 }
78
79 void Run(R ptr) {
80 called_ = true;
81 std::move(callback_).Run(std::move(ptr));
82 }
83
84 private:
85 T callback_;
86 base::OnceCallback<R()> args_at_destroy_;
87 bool called_;
Chase Phillips091007d2019-05-22 22:00:1388};
89
90} // namespace indexed_db_callback_helpers_internal
91
92// CreateCallbackAbortOnDestruct is a helper function to create an instance
93// of CallbackAbortOnDestruct that returns a callback. By using this helper
94// function, the wrapping callback can exist with the same type signature as
95// the wrapped callback.
96template <typename T, typename R>
Evan Stadecbb1e002024-09-13 20:06:5797T CreateCallbackAbortOnDestruct(T cb, base::WeakPtr<Transaction> transaction) {
Chase Phillips091007d2019-05-22 22:00:1398 return base::BindOnce(
99 &indexed_db_callback_helpers_internal::CallbackAbortOnDestruct<T, R>::Run,
100 std::make_unique<
101 indexed_db_callback_helpers_internal::CallbackAbortOnDestruct<T, R>>(
102 std::move(cb), std::move(transaction)));
103}
104
105// This allows us to bind a function with a return value to a weak ptr, and if
106// the weak pointer is invalidated then we just return a default (success).
107template <typename T, typename Functor, typename... Args>
Evan Stadecbb1e002024-09-13 20:06:57108Transaction::Operation BindWeakOperation(Functor&& functor,
109 base::WeakPtr<T> weak_ptr,
110 Args&&... args) {
Arthur Sonzognib9db7162023-04-19 07:39:31111 DCHECK(weak_ptr);
112 T* ptr = weak_ptr.get();
Chase Phillips091007d2019-05-22 22:00:13113 return base::BindOnce(
Arthur Sonzognib9db7162023-04-19 07:39:31114 &indexed_db_callback_helpers_internal::InvokeOrSucceed<T>,
115 std::move(weak_ptr),
116 base::BindOnce(std::forward<Functor>(functor), base::Unretained(ptr),
Chase Phillips091007d2019-05-22 22:00:13117 std::forward<Args>(args)...));
118}
119
Evan Stadecbb1e002024-09-13 20:06:57120} // namespace content::indexed_db
Chase Phillips091007d2019-05-22 22:00:13121
Evan Stade1a8d9d42024-09-10 19:37:19122#endif // CONTENT_BROWSER_INDEXED_DB_INSTANCE_CALLBACK_HELPERS_H_