Lightweight 0.20251202.0
Loading...
Searching...
No Matches
Restore.hpp
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include "../SqlConnection.hpp"
6#include "Common.hpp"
7#include "SqlBackup.hpp"
8
9#include <atomic>
10#include <deque>
11#include <expected>
12#include <map>
13#include <memory>
14#include <mutex>
15#include <optional>
16#include <set>
17#include <string>
18#include <vector>
19
20#if defined(__clang__)
21 #pragma clang diagnostic push
22 #pragma clang diagnostic ignored "-Wnullability-extension"
23#endif
24#include <zip.h>
25#if defined(__clang__)
26 #pragma clang diagnostic pop
27#endif
28
29namespace Lightweight::SqlBackup::detail
30{
31
32/// Data required to restore a single chunk to the database.
33struct RestoreChunkInfo
34{
35 std::string tableName;
36 std::string chunkPath;
37 std::vector<uint8_t> content;
38 TableInfo const* tableInfo {};
39 std::optional<size_t> displayTotal;
40 bool isEndOfStream {}; ///< True when queue is empty and no more data is available.
41};
42
43/// Error information from FetchNextRestoreChunk.
44struct FetchChunkError
45{
46 std::string tableName; // Empty if table could not be determined
47 std::string message;
48};
49
50/// Context for restore operations, shared between restore workers.
51struct RestoreContext
52{
53 SqlConnectionString connectionString;
54 std::string schema;
55 std::map<std::string, TableInfo> const& tableMap;
56 std::deque<ZipEntryInfo>& dataQueue;
57 zip_t* zip;
58 std::mutex& queueMutex;
59 std::mutex& fileMutex;
60 ProgressManager& progress;
61 std::map<std::string, std::shared_ptr<std::atomic<size_t>>> tableProgress;
62 std::map<std::string, std::shared_ptr<std::atomic<size_t>>> chunksProcessed; // Per-table processed chunk count
63 std::map<std::string, size_t> totalChunks; // Per-table total chunk count
64 std::map<std::string, std::string> const* checksums; // entryName -> expected SHA-256 hash (optional)
65 RetrySettings const& retrySettings;
66 RestoreSettings restoreSettings;
67};
68
69/// Increments the chunk counter and reports completion status.
70///
71/// @param ctx The restore context.
72/// @param tableName The name of the table being restored.
73/// @param success Whether the chunk was restored successfully.
74void IncrementChunkCounter(RestoreContext& ctx, std::string const& tableName, bool success);
75
76/// Fetches the next chunk from the restore queue.
77///
78/// Handles dequeuing from the work queue, reading zip entry content,
79/// path parsing to extract table name, and checksum verification.
80///
81/// @param ctx The restore context.
82/// @return The chunk info on success (with isEndOfStream=true when queue is empty), or error details on failure.
83std::expected<RestoreChunkInfo, FetchChunkError> FetchNextRestoreChunk(RestoreContext& ctx);
84
85/// Restores chunk data to the database with retry logic.
86///
87/// Handles MSSQL identity insert handling, batch insertion with transaction management,
88/// SQLite intermediate commits, retry logic for transient errors, and progress tracking.
89///
90/// @param ctx The restore context.
91/// @param workerConn The database connection.
92/// @param chunk The chunk data to restore.
93/// @param batchCapacity The batch size for bulk inserts.
94/// @return true if chunk was restored successfully, false if errors occurred.
95bool RestoreChunkData(RestoreContext& ctx, SqlConnection& workerConn, RestoreChunkInfo const& chunk, size_t batchCapacity);
96
97/// Worker function that processes chunks from the restore queue.
98///
99/// This function processes restore chunks from the shared queue, using the helper functions
100/// FetchNextRestoreChunk() for I/O operations and RestoreChunkData() for database operations.
101///
102/// @param ctx The restore context containing queue, progress tracking, and settings.
103/// @param workerConn The database connection for this worker.
104void RestoreWorker(RestoreContext ctx, SqlConnection& workerConn);
105
106/// Restores indexes for all tables after data has been restored.
107///
108/// This function creates indexes that were backed up in the metadata.
109/// It is called after FK constraints are restored to ensure indexes are created
110/// on the final table structure.
111///
112/// @param connectionString The connection string to use.
113/// @param schema The schema name.
114/// @param tableMap Map of table names to their metadata including indexes.
115/// @param progress Progress manager for reporting status.
116void RestoreIndexes(SqlConnectionString const& connectionString,
117 std::string const& schema,
118 std::map<std::string, TableInfo> const& tableMap,
119 ProgressManager& progress);
120
121/// Applies foreign key constraints to all tables after data has been restored.
122///
123/// This function is called after data restoration to add FK constraints that
124/// were not included in the initial CREATE TABLE statements.
125///
126/// @param connectionString The connection string to use.
127/// @param schema The schema name.
128/// @param tableMap Map of table names to their metadata including foreign keys.
129/// @param progress Progress manager for reporting status.
130void ApplyDatabaseConstraints(SqlConnectionString const& connectionString,
131 std::string const& schema,
132 std::map<std::string, TableInfo> const& tableMap,
133 ProgressManager& progress);
134
135/// Recreates the database schema by dropping and creating tables from the backup metadata.
136///
137/// This function creates tables in dependency order for SQLite (to satisfy FK constraints on CREATE),
138/// or alphabetically for other databases (where FKs are added via ALTER TABLE later).
139///
140/// @param connectionString The connection string for the target database.
141/// @param schema The database schema name to create tables in.
142/// @param tableMap Map of table names to their metadata from the backup.
143/// @param progress Progress manager for reporting errors and status updates.
144/// @return Set of table names that were successfully created. Tables that fail to create
145/// (e.g., due to type incompatibilities) are excluded from the returned set,
146/// allowing the caller to skip data restoration for those tables.
147std::set<std::string> RecreateDatabaseSchema(SqlConnectionString const& connectionString,
148 std::string const& schema,
149 std::map<std::string, TableInfo> const& tableMap,
150 ProgressManager& progress);
151
152} // namespace Lightweight::SqlBackup::detail