Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Evan Stade | 1a8d9d4 | 2024-09-10 19:37:19 | [diff] [blame] | 5 | #ifndef CONTENT_BROWSER_INDEXED_DB_INSTANCE_DATABASE_H_ |
| 6 | #define CONTENT_BROWSER_INDEXED_DB_INSTANCE_DATABASE_H_ |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 7 | |
avi | b734894 | 2015-12-25 20:57:10 | [diff] [blame] | 8 | #include <stddef.h> |
| 9 | #include <stdint.h> |
| 10 | |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 11 | #include <map> |
jsbell | 1964420 | 2016-07-15 22:27:08 | [diff] [blame] | 12 | #include <memory> |
Abhishek Shanthkumar | 88ce490 | 2025-06-26 16:00:00 | [diff] [blame] | 13 | #include <set> |
[email protected] | d5516bfe | 2013-07-10 01:31:56 | [diff] [blame] | 14 | #include <string> |
[email protected] | f243eacf | 2014-01-16 23:55:09 | [diff] [blame] | 15 | #include <utility> |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 16 | #include <vector> |
| 17 | |
Brett Wilson | cc8623d | 2017-09-12 03:28:10 | [diff] [blame] | 18 | #include "base/containers/queue.h" |
Avi Drissman | adac2199 | 2023-01-11 23:46:39 | [diff] [blame] | 19 | #include "base/functional/callback.h" |
dmurph | 497e676f1 | 2017-04-25 20:29:57 | [diff] [blame] | 20 | #include "base/gtest_prod_util.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 21 | #include "base/memory/raw_ptr.h" |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 22 | #include "base/memory/ref_counted.h" |
Mingyu Lei | 0fe8df7 | 2022-12-16 06:44:48 | [diff] [blame] | 23 | #include "base/memory/scoped_refptr.h" |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 24 | #include "base/memory/weak_ptr.h" |
Nathan Memmott | aecdf345 | 2022-10-10 17:53:37 | [diff] [blame] | 25 | #include "components/services/storage/indexed_db/locks/partitioned_lock_manager.h" |
Ari Chivukula | 65a987e | 2022-04-26 19:04:12 | [diff] [blame] | 26 | #include "components/services/storage/public/cpp/buckets/bucket_locator.h" |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 27 | #include "content/browser/indexed_db/indexed_db_value.h" |
Evan Stade | d9529ea5 | 2025-04-11 17:02:50 | [diff] [blame] | 28 | #include "content/browser/indexed_db/instance/backing_store.h" |
Evan Stade | 1a8d9d4 | 2024-09-10 19:37:19 | [diff] [blame] | 29 | #include "content/browser/indexed_db/instance/connection_coordinator.h" |
| 30 | #include "content/browser/indexed_db/instance/factory_client.h" |
| 31 | #include "content/browser/indexed_db/instance/pending_connection.h" |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 32 | #include "content/browser/indexed_db/list_set.h" |
Daniel Murphy | d36cedf | 2017-10-12 00:04:54 | [diff] [blame] | 33 | #include "content/common/content_export.h" |
Chase Phillips | 68ecf551 | 2018-08-16 01:59:13 | [diff] [blame] | 34 | #include "third_party/blink/public/common/indexeddb/indexeddb_key.h" |
Henrique Ferreiro | da0a55c | 2019-11-12 14:06:04 | [diff] [blame] | 35 | #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-forward.h" |
jsbell | bebef32 | 2016-04-15 16:46:20 | [diff] [blame] | 36 | |
Chase Phillips | 850b96f7 | 2018-08-24 19:44:16 | [diff] [blame] | 37 | namespace blink { |
Chase Phillips | 33d161d6 | 2018-08-28 19:44:12 | [diff] [blame] | 38 | class IndexedDBKeyRange; |
| 39 | struct IndexedDBDatabaseMetadata; |
Chase Phillips | 33d161d6 | 2018-08-28 19:44:12 | [diff] [blame] | 40 | } // namespace blink |
Chase Phillips | 850b96f7 | 2018-08-24 19:44:16 | [diff] [blame] | 41 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 42 | namespace content::indexed_db { |
| 43 | class BucketContext; |
| 44 | class Connection; |
| 45 | class DatabaseCallbacks; |
| 46 | class Transaction; |
Evan Stade | 6265dcd | 2024-02-27 20:50:04 | [diff] [blame] | 47 | enum class CursorType; |
Evan Stade | 6265dcd | 2024-02-27 20:50:04 | [diff] [blame] | 48 | |
Evan Stade | 1a8d9d4 | 2024-09-10 19:37:19 | [diff] [blame] | 49 | // This class maps to a single IDB database: |
| 50 | // https://www.w3.org/TR/IndexedDB/#database |
| 51 | // |
| 52 | // It is created and operated on a bucket thread. |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 53 | class CONTENT_EXPORT Database { |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 54 | public: |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 55 | // Used to report irrecoverable backend errors. The second argument can be |
| 56 | // null. |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 57 | using ErrorCallback = base::RepeatingCallback<void(Status, const char*)>; |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 58 | |
Abhishek Shanthkumar | 88ce490 | 2025-06-26 16:00:00 | [diff] [blame] | 59 | Database(uint32_t id_for_locks, |
| 60 | const std::u16string& name, |
| 61 | BucketContext& bucket_context); |
Evan Stade | 6a314fe | 2023-09-25 21:24:12 | [diff] [blame] | 62 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 63 | Database(const Database&) = delete; |
| 64 | Database& operator=(const Database&) = delete; |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 65 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 66 | virtual ~Database(); |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 67 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 68 | BackingStore* backing_store(); |
Evan Stade | 2fbd453 | 2025-04-30 10:19:22 | [diff] [blame] | 69 | BackingStore::Database* backing_store_db() { return backing_store_db_.get(); } |
Evan Stade | 22f9c264 | 2024-02-04 00:35:28 | [diff] [blame] | 70 | PartitionedLockManager& lock_manager(); |
[email protected] | 59057f8 | 2013-09-11 20:52:24 | [diff] [blame] | 71 | |
Evan Stade | 2fbd453 | 2025-04-30 10:19:22 | [diff] [blame] | 72 | const blink::IndexedDBDatabaseMetadata& metadata() const { |
| 73 | return backing_store_db_->GetMetadata(); |
Ari Chivukula | 664bf8d | 2022-04-27 23:28:18 | [diff] [blame] | 74 | } |
Evan Stade | 2fbd453 | 2025-04-30 10:19:22 | [diff] [blame] | 75 | const std::u16string& name() const { return name_; } |
| 76 | int64_t version() const; |
| 77 | bool IsInitialized() const; |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 78 | |
Evan Stade | e2a6816 | 2025-07-08 17:22:54 | [diff] [blame] | 79 | // Called to permanently delete the database wrapped by `this`. Will call |
| 80 | // `on_complete` and release `locks` when done. This may be called more than |
| 81 | // once, in which case latter calls are a no-op, and `on_complete` will not be |
| 82 | // called. Returns an error, or the latest version of the deleted database |
| 83 | // if successful, or 0 if the database had already been deleted. |
| 84 | StatusOr<int64_t> DeleteDatabase(std::vector<PartitionedLock> locks, |
| 85 | base::OnceClosure on_complete); |
| 86 | |
Abhishek Shanthkumar | 88ce490 | 2025-06-26 16:00:00 | [diff] [blame] | 87 | // Builds the set of lock requests for the given transaction `mode` and |
| 88 | // `scope`. `scope` is used iff `mode` is not `VersionChange`. |
| 89 | std::vector<PartitionedLockManager::PartitionedLockRequest> |
| 90 | BuildLockRequestsForTransaction(blink::mojom::IDBTransactionMode mode, |
| 91 | const std::set<int64_t>& scope) const; |
| 92 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 93 | const list_set<Connection*>& connections() const { return connections_; } |
jsbell | 7017da4 | 2016-08-16 13:07:15 | [diff] [blame] | 94 | |
Evan Stade | 4c8bfd6 | 2025-05-08 15:52:36 | [diff] [blame] | 95 | Status RunTasks(); |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 96 | void RegisterAndScheduleTransaction(Transaction* transaction); |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 97 | |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 98 | // The database object (this object) must be kept alive for the duration of |
Ari Chivukula | 8d3ecea | 2021-06-18 18:55:48 | [diff] [blame] | 99 | // this call. This means the caller should own an |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 100 | // BucketContextHandle while calling this methods. |
Mingyu Lei | 87210bc | 2025-04-17 09:35:50 | [diff] [blame] | 101 | Status ForceCloseAndRunTasks(const std::string& message); |
[email protected] | 75a854a | 2014-07-07 15:57:36 | [diff] [blame] | 102 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 103 | void ScheduleOpenConnection(std::unique_ptr<PendingConnection> connection); |
Mingyu Lei | 0fe8df7 | 2022-12-16 06:44:48 | [diff] [blame] | 104 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 105 | void ScheduleDeleteDatabase(std::unique_ptr<FactoryClient> factory_client, |
| 106 | base::OnceClosure on_deletion_complete); |
Daniel Murphy | 48b6b3a | 2019-08-07 20:38:25 | [diff] [blame] | 107 | |
[email protected] | 8df07d2 | 2013-07-22 17:57:43 | [diff] [blame] | 108 | // Number of connections that have progressed passed initial open call. |
Daniel Murphy | 7c75043 | 2019-08-20 01:39:47 | [diff] [blame] | 109 | size_t ConnectionCount() const { return connections_.size(); } |
jsbell | 1964420 | 2016-07-15 22:27:08 | [diff] [blame] | 110 | |
| 111 | // Number of active open/delete calls (running or blocked on other |
| 112 | // connections). |
Daniel Murphy | ede9159 | 2019-08-12 19:50:22 | [diff] [blame] | 113 | size_t ActiveOpenDeleteCount() const { |
| 114 | return connection_coordinator_.ActiveOpenDeleteCount(); |
| 115 | } |
jsbell | 1964420 | 2016-07-15 22:27:08 | [diff] [blame] | 116 | |
| 117 | // Number of open/delete calls that are waiting their turn. |
Daniel Murphy | ede9159 | 2019-08-12 19:50:22 | [diff] [blame] | 118 | size_t PendingOpenDeleteCount() const { |
| 119 | return connection_coordinator_.PendingOpenDeleteCount(); |
| 120 | } |
[email protected] | 8df07d2 | 2013-07-22 17:57:43 | [diff] [blame] | 121 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 122 | Status VersionChangeOperation(int64_t version, Transaction* transaction); |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 123 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 124 | Status GetOperation(int64_t object_store_id, |
| 125 | int64_t index_id, |
Evan Stade | ca999b1 | 2025-05-09 19:09:11 | [diff] [blame] | 126 | blink::IndexedDBKeyRange key_range, |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 127 | indexed_db::CursorType cursor_type, |
| 128 | blink::mojom::IDBDatabase::GetCallback callback, |
| 129 | Transaction* transaction); |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 130 | |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 131 | struct OpenCursorOperationParams { |
| 132 | OpenCursorOperationParams(); |
Peter Boström | 828b902 | 2021-09-21 02:28:43 | [diff] [blame] | 133 | |
| 134 | OpenCursorOperationParams(const OpenCursorOperationParams&) = delete; |
| 135 | OpenCursorOperationParams& operator=(const OpenCursorOperationParams&) = |
| 136 | delete; |
| 137 | |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 138 | ~OpenCursorOperationParams(); |
| 139 | int64_t object_store_id; |
| 140 | int64_t index_id; |
Evan Stade | ca999b1 | 2025-05-09 19:09:11 | [diff] [blame] | 141 | blink::IndexedDBKeyRange key_range; |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 142 | blink::mojom::IDBCursorDirection direction; |
| 143 | indexed_db::CursorType cursor_type; |
| 144 | blink::mojom::IDBTaskType task_type; |
| 145 | blink::mojom::IDBDatabase::OpenCursorCallback callback; |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 146 | }; |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 147 | Status OpenCursorOperation(std::unique_ptr<OpenCursorOperationParams> params, |
| 148 | const storage::BucketLocator& bucket_locator, |
| 149 | Transaction* transaction); |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 150 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 151 | Status CountOperation(int64_t object_store_id, |
| 152 | int64_t index_id, |
Evan Stade | ca999b1 | 2025-05-09 19:09:11 | [diff] [blame] | 153 | blink::IndexedDBKeyRange key_range, |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 154 | blink::mojom::IDBDatabase::CountCallback callback, |
| 155 | Transaction* transaction); |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 156 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 157 | Status DeleteRangeOperation( |
dmurph | 50ab051b3 | 2016-11-29 22:13:30 | [diff] [blame] | 158 | int64_t object_store_id, |
Evan Stade | ca999b1 | 2025-05-09 19:09:11 | [diff] [blame] | 159 | blink::IndexedDBKeyRange key_range, |
Evan Stade | ad03d76 | 2023-06-01 16:37:58 | [diff] [blame] | 160 | blink::mojom::IDBDatabase::DeleteRangeCallback success_callback, |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 161 | Transaction* transaction); |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 162 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 163 | Status GetKeyGeneratorCurrentNumberOperation( |
Harley Li | 20add69 | 2019-02-15 22:54:12 | [diff] [blame] | 164 | int64_t object_store_id, |
Evan Stade | dc38e971 | 2023-07-14 02:04:54 | [diff] [blame] | 165 | blink::mojom::IDBDatabase::GetKeyGeneratorCurrentNumberCallback callback, |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 166 | Transaction* transaction); |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 167 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 168 | Status ClearOperation(int64_t object_store_id, |
| 169 | blink::mojom::IDBDatabase::ClearCallback callback, |
| 170 | Transaction* transaction); |
[email protected] | 65880a8 | 2013-08-16 21:30:08 | [diff] [blame] | 171 | |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 172 | // Use this factory function for GetAll instead of creating the operation |
| 173 | // directly. |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 174 | base::OnceCallback<Status(Transaction*)> CreateGetAllOperation( |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 175 | int64_t object_store_id, |
| 176 | int64_t index_id, |
Evan Stade | ca999b1 | 2025-05-09 19:09:11 | [diff] [blame] | 177 | blink::IndexedDBKeyRange key_range, |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 178 | blink::mojom::IDBGetAllResultType result_type, |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 179 | int64_t max_count, |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 180 | blink::mojom::IDBCursorDirection direction, |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 181 | blink::mojom::IDBDatabase::GetAllCallback callback, |
| 182 | Transaction* transaction); |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 183 | |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 184 | bool IsObjectStoreIdInMetadata(int64_t object_store_id) const; |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 185 | bool IsObjectStoreIdAndMaybeIndexIdInMetadata(int64_t object_store_id, |
| 186 | int64_t index_id) const; |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 187 | |
Brad Triebwasser | fe45f3f | 2024-06-03 19:20:29 | [diff] [blame] | 188 | // Returns metadata relevant to idb-internals. |
| 189 | storage::mojom::IdbDatabaseMetadataPtr GetIdbInternalsMetadata() const; |
Brad Triebwasser | 88b84af | 2024-06-04 19:36:55 | [diff] [blame] | 190 | // Called when the data used to populate the struct in |
| 191 | // `GetIdbInternalsMetadata` is changed in a significant way. |
| 192 | void NotifyOfIdbInternalsRelevantChange(); |
Brad Triebwasser | fe45f3f | 2024-06-03 19:20:29 | [diff] [blame] | 193 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 194 | base::WeakPtr<Database> AsWeakPtr() { return weak_factory_.GetWeakPtr(); } |
Daniel Murphy | 7c75043 | 2019-08-20 01:39:47 | [diff] [blame] | 195 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 196 | void AddConnectionForTesting(Connection* connection) { |
Evan Stade | 2fbd453 | 2025-04-30 10:19:22 | [diff] [blame] | 197 | if (connections_.empty()) { |
| 198 | OpenInternal(); |
| 199 | } |
Daniel Murphy | 7c75043 | 2019-08-20 01:39:47 | [diff] [blame] | 200 | connections_.insert(connection); |
| 201 | } |
Daniel Murphy | 0240b78 | 2019-08-14 21:15:09 | [diff] [blame] | 202 | |
Evan Stade | 4c8bfd6 | 2025-05-08 15:52:36 | [diff] [blame] | 203 | bool CanBeDestroyed(); |
| 204 | |
jsbell | 341d558 | 2015-08-27 17:58:27 | [diff] [blame] | 205 | protected: |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 206 | friend class Transaction; |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 207 | friend class ConnectionCoordinator::ConnectionRequest; |
| 208 | friend class ConnectionCoordinator::OpenRequest; |
| 209 | friend class ConnectionCoordinator::DeleteRequest; |
dmurph | 50ab051b3 | 2016-11-29 22:13:30 | [diff] [blame] | 210 | |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 211 | private: |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 212 | FRIEND_TEST_ALL_PREFIXES(DatabaseTest, OpenDeleteClear); |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 213 | FRIEND_TEST_ALL_PREFIXES(DatabaseOperationTest, |
| 214 | ObjectStoreGetAllKeysWithInvalidObjectStoreId); |
| 215 | FRIEND_TEST_ALL_PREFIXES(DatabaseOperationTest, |
| 216 | IndexGetAllKeysWithInvalidIndexId); |
| 217 | friend class DatabaseOperationTest; |
dmurph | 497e676f1 | 2017-04-25 20:29:57 | [diff] [blame] | 218 | |
| 219 | void CallUpgradeTransactionStartedForTesting(int64_t old_version); |
| 220 | |
jsbell | ef26d19b | 2016-07-29 22:03:20 | [diff] [blame] | 221 | class ConnectionRequest; |
jsbell | 1964420 | 2016-07-15 22:27:08 | [diff] [blame] | 222 | class OpenRequest; |
| 223 | class DeleteRequest; |
jsbell | 0a918e69 | 2014-08-23 21:35:56 | [diff] [blame] | 224 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 225 | Status OpenInternal(); |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 226 | |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 227 | // This class informs its result sink of an error if a `GetAllOperation` is |
| 228 | // deleted without being run. This functionality mimics that of |
| 229 | // AbortOnDestruct callbacks. `GetAll()` cannot easily be shoe-horned into the |
| 230 | // abort-on-destruct callback templating. |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 231 | class CONTENT_EXPORT GetAllResultSinkWrapper { |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 232 | public: |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 233 | GetAllResultSinkWrapper(base::WeakPtr<Transaction> transaction, |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 234 | blink::mojom::IDBDatabase::GetAllCallback callback); |
| 235 | ~GetAllResultSinkWrapper(); |
| 236 | |
| 237 | mojo::AssociatedRemote<blink::mojom::IDBDatabaseGetAllResultSink>& Get(); |
| 238 | |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 239 | // An override for unit tests to bind the associated receiver successfully |
| 240 | // without a pre-existing endpoint entanglement. |
| 241 | void UseDedicatedReceiverForTesting() { |
| 242 | use_dedicated_receiver_for_testing_ = true; |
| 243 | } |
| 244 | |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 245 | private: |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 246 | base::WeakPtr<Transaction> transaction_; |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 247 | blink::mojom::IDBDatabase::GetAllCallback callback_; |
| 248 | mojo::AssociatedRemote<blink::mojom::IDBDatabaseGetAllResultSink> |
| 249 | result_sink_; |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 250 | bool use_dedicated_receiver_for_testing_ = false; |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 251 | }; |
| 252 | |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 253 | Status GetAllOperation(int64_t object_store_id, |
| 254 | int64_t index_id, |
Evan Stade | ca999b1 | 2025-05-09 19:09:11 | [diff] [blame] | 255 | blink::IndexedDBKeyRange key_range, |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 256 | blink::mojom::IDBGetAllResultType result_type, |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 257 | int64_t max_count, |
Steve Becker | 4848af3 | 2024-10-29 22:57:19 | [diff] [blame] | 258 | blink::mojom::IDBCursorDirection direction, |
Mike Wasserman | 0d5da52 | 2024-09-27 07:47:03 | [diff] [blame] | 259 | std::unique_ptr<GetAllResultSinkWrapper> result_sink, |
| 260 | Transaction* transaction); |
Evan Stade | 4202b1f | 2024-06-12 16:10:54 | [diff] [blame] | 261 | |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 262 | // If there is no active request, grab a new one from the pending queue and |
| 263 | // start it. Afterwards, possibly release the database by calling |
| 264 | // MaybeReleaseDatabase(). |
| 265 | void ProcessRequestQueueAndMaybeRelease(); |
| 266 | |
| 267 | // If there are no connections, pending requests, or an active request, then |
Ari Chivukula | fae9b808 | 2022-04-14 22:27:29 | [diff] [blame] | 268 | // this function will call `destroy_me_`, which can destruct this object. |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 269 | void MaybeReleaseDatabase(); |
[email protected] | 907a8bc5 | 2013-06-07 16:32:34 | [diff] [blame] | 270 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 271 | std::unique_ptr<Connection> CreateConnection( |
| 272 | std::unique_ptr<DatabaseCallbacks> database_callbacks, |
Evan Stade | 9f5e401c | 2024-01-04 23:58:35 | [diff] [blame] | 273 | mojo::Remote<storage::mojom::IndexedDBClientStateChecker> |
Evan Stade | 2db7aa7 | 2024-02-01 17:07:27 | [diff] [blame] | 274 | client_state_checker, |
Evan Stade | 8e75d40 | 2024-09-04 00:42:43 | [diff] [blame] | 275 | base::UnguessableToken client_token, |
| 276 | int scheduling_priority); |
[email protected] | d29650c | 2014-03-18 01:20:59 | [diff] [blame] | 277 | |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 278 | // Ack that one of the connections notified with a "versionchange" event did |
| 279 | // not promptly close. Therefore a "blocked" event should be fired at the |
| 280 | // pending connection. |
| 281 | void VersionChangeIgnored(); |
| 282 | |
Daniel Murphy | 7bc96c2 | 2019-05-28 22:47:21 | [diff] [blame] | 283 | bool HasNoConnections() const; |
| 284 | |
| 285 | void SendVersionChangeToAllConnections(int64_t old_version, |
| 286 | int64_t new_version); |
| 287 | |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 288 | // This can only be called when the given connection is closed and no longer |
| 289 | // has any transaction objects. |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 290 | void ConnectionClosed(Connection* connection); |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 291 | |
Evan Stade | 8c6ddfd | 2025-01-06 17:41:10 | [diff] [blame] | 292 | // In rare cases there are a very large number of queued |
| 293 | // requests/transactions, so calculations related to blocking or blocked |
| 294 | // clients can be expensive. See crbug.com/384476946. This method is used for |
| 295 | // shortcutting such operations when there's only a single client. Also |
| 296 | // returns true for zero clients. |
| 297 | bool OnlyHasOneClient() const; |
| 298 | |
Mingyu Lei | 5cff96b | 2023-01-13 17:09:51 | [diff] [blame] | 299 | // Find the transactions that block `current_transaction` from acquiring the |
| 300 | // locks, and ensure that the clients with blocking transactions are active. |
| 301 | void RequireBlockingTransactionClientsToBeActive( |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 302 | Transaction* current_transaction, |
Mingyu Lei | 5cff96b | 2023-01-13 17:09:51 | [diff] [blame] | 303 | std::vector<PartitionedLockManager::PartitionedLockRequest>& |
| 304 | lock_requests); |
| 305 | |
Evan Stade | caa7d18 | 2025-04-30 17:42:12 | [diff] [blame] | 306 | // Gets metadata for the given object store ID, asserting that the object |
| 307 | // store exists. |
| 308 | const blink::IndexedDBObjectStoreMetadata& GetObjectStoreMetadata( |
| 309 | int64_t object_store_id) const; |
| 310 | |
Evan Stade | e24c007 | 2025-06-18 18:29:17 | [diff] [blame] | 311 | // This ID uniquely identifies this database within this process. It's not |
Abhishek Shanthkumar | 88ce490 | 2025-06-26 16:00:00 | [diff] [blame] | 312 | // persisted anywhere. Only used when the backing store is SQLite. |
Evan Stade | e24c007 | 2025-06-18 18:29:17 | [diff] [blame] | 313 | uint32_t id_for_locks_; |
Evan Stade | 2fbd453 | 2025-04-30 10:19:22 | [diff] [blame] | 314 | std::u16string name_; |
Evan Stade | a35e272 | 2023-09-05 22:53:42 | [diff] [blame] | 315 | |
| 316 | // The object that owns `this`. |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 317 | raw_ref<BucketContext> bucket_context_; |
Evan Stade | a35e272 | 2023-09-05 22:53:42 | [diff] [blame] | 318 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 319 | list_set<Connection*> connections_; |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 320 | |
Evan Stade | 6b4d5a6 | 2025-05-29 20:53:53 | [diff] [blame] | 321 | // True once `ForceCloseAndRunTasks()` is called. |
Daniel Murphy | 7c75043 | 2019-08-20 01:39:47 | [diff] [blame] | 322 | bool force_closing_ = false; |
Daniel Murphy | 4c0f9c1 | 2019-05-23 01:14:35 | [diff] [blame] | 323 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 324 | ConnectionCoordinator connection_coordinator_; |
jsbell | 1964420 | 2016-07-15 22:27:08 | [diff] [blame] | 325 | |
Evan Stade | e2a6816 | 2025-07-08 17:22:54 | [diff] [blame] | 326 | // Null until `OpenInternal()` is called successfully, as well as after the |
| 327 | // database has been deleted via `DeleteDatabase()`. |
Evan Stade | 2fbd453 | 2025-04-30 10:19:22 | [diff] [blame] | 328 | std::unique_ptr<BackingStore::Database> backing_store_db_; |
| 329 | |
Ari Chivukula | fae9b808 | 2022-04-14 22:27:29 | [diff] [blame] | 330 | // `weak_factory_` is used for all callback uses. |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 331 | base::WeakPtrFactory<Database> weak_factory_{this}; |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 332 | }; |
| 333 | |
Evan Stade | cbb1e00 | 2024-09-13 20:06:57 | [diff] [blame] | 334 | } // namespace content::indexed_db |
[email protected] | 72a4183d | 2013-05-31 18:33:10 | [diff] [blame] | 335 | |
Evan Stade | 1a8d9d4 | 2024-09-10 19:37:19 | [diff] [blame] | 336 | #endif // CONTENT_BROWSER_INDEXED_DB_INSTANCE_DATABASE_H_ |