5#include "../SqlConnection.hpp"
6#include "../SqlError.hpp"
7#include "SqlBackup.hpp"
17 #pragma clang diagnostic push
18 #pragma clang diagnostic ignored "-Wnullability-extension"
22 #pragma clang diagnostic pop
25namespace Lightweight::SqlBackup::detail
31constexpr size_t MaxBinaryLobBufferSize = 16 * 1024 * 1024;
52bool IsTransientError(SqlErrorInfo
const& error);
59std::chrono::milliseconds CalculateRetryDelay(
unsigned attempt, RetrySettings
const& settings)
noexcept;
69bool ConnectWithRetry(SqlConnection& conn,
70 SqlConnectionString
const& connectionString,
71 RetrySettings
const& settings,
72 ProgressManager& progress,
73 std::string
const& operation);
84template <
typename Func>
85auto RetryOnTransientError(Func&& func,
86 RetrySettings
const& settings,
87 ProgressManager& progress,
88 std::string
const& operation) ->
decltype(func())
90 unsigned attempts = 0;
98 catch (SqlException
const& e)
100 if (!IsTransientError(e.info()) || attempts >= settings.maxRetries)
105 { .state = Progress::State::Warning,
106 .tableName = operation,
108 .totalRows = std::nullopt,
109 .message = std::format(
"Transient error, retry {}/{}: {}", attempts, settings.maxRetries, e.what()) });
111 std::this_thread::sleep_for(CalculateRetryDelay(attempts - 1, settings));
119std::string CurrentDateTime();
128template <
typename Container>
129Container ReadZipEntry(zip_t* zip, zip_int64_t index, zip_uint64_t size)
131 zip_file_t* file = zip_fopen_index(zip,
static_cast<zip_uint64_t
>(index), 0);
138 zip_int64_t bytesRead = zip_fread(file, data.data(), size);
141 if (bytesRead < 0 || std::cmp_not_equal(bytesRead, size))
152std::string FormatTableName(std::string_view schema, std::string_view table);
161bool DropTableIfExists(SqlConnection& conn,
162 std::string
const& schema,
163 std::string
const& tableName,
164 ProgressManager& progress);