| // Copyright 2025 The Chromium Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "components/persistent_cache/sqlite/backend_storage_delegate.h" | |
| #include <memory> | |
| #include <utility> | |
| #include "base/files/file_path.h" | |
| #include "base/numerics/clamped_math.h" | |
| #include "base/types/expected_macros.h" | |
| #include "components/persistent_cache/pending_backend.h" | |
| #include "components/persistent_cache/sqlite/sqlite_backend_impl.h" | |
| #include "components/persistent_cache/sqlite/vfs_util.h" | |
| #include "components/sqlite_vfs/client.h" | |
| #include "components/sqlite_vfs/file_set_error.h" | |
| #include "components/sqlite_vfs/pending_file_set.h" | |
| #include "components/sqlite_vfs/sqlite_database_vfs_file_set.h" | |
| #include "components/sqlite_vfs/vfs_utils.h" | |
| namespace persistent_cache::sqlite { | |
| namespace { | |
| TransactionError FileSetErrorToTransactionError( | |
| sqlite_vfs::FileSetError error) { | |
| switch (error) { | |
| case sqlite_vfs::FileSetError::kTransient: | |
| return TransactionError::kTransient; | |
| case sqlite_vfs::FileSetError::kPermanent: | |
| return TransactionError::kConnectionError; | |
| case sqlite_vfs::FileSetError::kPermanentRequireDeletion: | |
| return TransactionError::kPermanent; | |
| } | |
| } | |
| } // namespace | |
| base::expected<PendingBackend, TransactionError> | |
| BackendStorageDelegate::MakePendingBackend(Client client, | |
| const base::FilePath& directory, | |
| const base::FilePath& base_name, | |
| bool single_connection, | |
| bool journal_mode_wal) { | |
| ASSIGN_OR_RETURN(auto pending_file_set, | |
| sqlite_vfs::MakePendingFileSet( | |
| VfsClientFromClient(client), directory, base_name, | |
| single_connection, journal_mode_wal), | |
| &FileSetErrorToTransactionError); | |
| return PendingBackend(std::move(pending_file_set)); | |
| } | |
| base::expected<std::unique_ptr<Backend>, TransactionError> | |
| BackendStorageDelegate::MakeBackend(Client client, | |
| const base::FilePath& directory, | |
| const base::FilePath& base_name, | |
| bool single_connection, | |
| bool journal_mode_wal) { | |
| ASSIGN_OR_RETURN(auto pending_backend, | |
| MakePendingBackend(client, directory, base_name, | |
| single_connection, journal_mode_wal)); | |
| return SqliteBackendImpl::Bind(std::move(pending_backend), client); | |
| } | |
| std::optional<PendingBackend> BackendStorageDelegate::ShareReadOnlyConnection( | |
| const base::FilePath& directory, | |
| const base::FilePath& base_name, | |
| const Backend& backend) { | |
| ASSIGN_OR_RETURN( | |
| auto pending_file_set, | |
| sqlite_vfs::ShareConnection( | |
| directory, base_name, | |
| static_cast<const SqliteBackendImpl&>(backend).file_set(), | |
| /*read_write=*/false), | |
| [](sqlite_vfs::FileSetError) { return std::nullopt; }); | |
| return PendingBackend(std::move(pending_file_set)); | |
| } | |
| std::optional<PendingBackend> BackendStorageDelegate::ShareReadWriteConnection( | |
| const base::FilePath& directory, | |
| const base::FilePath& base_name, | |
| const Backend& backend) { | |
| ASSIGN_OR_RETURN( | |
| auto pending_file_set, | |
| sqlite_vfs::ShareConnection( | |
| directory, base_name, | |
| static_cast<const SqliteBackendImpl&>(backend).file_set(), | |
| /*read_write=*/true), | |
| [](sqlite_vfs::FileSetError) { return std::nullopt; }); | |
| return PendingBackend(std::move(pending_file_set)); | |
| } | |
| base::FilePath BackendStorageDelegate::GetBaseName(const base::FilePath& file) { | |
| return sqlite_vfs::GetBaseName(file); | |
| } | |
| int64_t BackendStorageDelegate::DeleteFiles(Client client, | |
| const base::FilePath& directory, | |
| const base::FilePath& base_name) { | |
| return sqlite_vfs::DeleteFiles(VfsClientFromClient(client), directory, | |
| base_name); | |
| } | |
| } // namespace persistent_cache::sqlite |