1use crate::database::backup::models::BackupData;
7use crate::errors::AppError;
8use chrono::Utc;
9use rusqlite::{params, Connection};
10
11pub fn restore_backup_data(conn: &Connection, backup: &BackupData) -> Result<String, AppError> {
13 conn.execute("BEGIN IMMEDIATE TRANSACTION", [])?;
15
16 let mut game_stmt = conn.prepare(
18 "INSERT OR REPLACE INTO games (id, name, cover_url, platform, platform_game_id, installed, import_confidence, install_path, executable_path, launch_args, user_rating, favorite, status, playtime, last_played, added_at, alternative_names)
19 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17)"
20 )?;
21
22 let mut details_stmt = conn.prepare(
23 "INSERT OR REPLACE INTO game_details (
24 game_id, steam_app_id, developer, publisher, release_date, genres, tags, series,
25 description_raw, description_ptbr, background_image, critic_score, steam_review_label,
26 steam_review_count, steam_review_score, steam_review_updated_at, esrb_rating, is_adult,
27 adult_tags, external_links, median_playtime, estimated_playtime, updated_at
28 )
29 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23)"
30 )?;
31
32 let mut wishlist_stmt = conn.prepare(
33 "INSERT OR REPLACE INTO wishlist (id, name, cover_url, store_url, store_platform, current_price, normal_price, lowest_price, currency, on_sale, voucher, added_at, itad_id)
34 VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)"
35 )?;
36
37 for game in &backup.games {
38 let alt_names_json = game
39 .alternative_names
40 .as_ref()
41 .and_then(|v| serde_json::to_string(v).ok());
42
43 game_stmt.execute(params![
44 game.id,
45 game.name,
46 game.cover_url,
47 game.platform.to_string(),
48 game.platform_game_id,
49 game.installed,
50 game.import_confidence.as_ref().map(|ic| ic.to_string()),
51 game.install_path,
52 game.executable_path,
53 game.launch_args,
54 game.user_rating,
55 game.favorite,
56 game.status,
57 game.playtime,
58 game.last_played,
59 game.added_at,
60 alt_names_json
61 ])?;
62 }
63
64 for detail in &backup.game_details {
65 let links_json = detail
66 .external_links
67 .as_ref()
68 .and_then(|links| serde_json::to_string(links).ok());
69
70 let tags_json = detail
71 .tags
72 .as_ref()
73 .and_then(|tags| crate::database::serialize_tags(tags).ok());
74
75 details_stmt.execute(params![
76 detail.game_id,
77 detail.steam_app_id,
78 detail.developer,
79 detail.publisher,
80 detail.release_date,
81 detail.genres,
82 tags_json,
83 detail.series,
84 detail.description_raw,
85 detail.description_ptbr,
86 detail.background_image,
87 detail.critic_score,
88 detail.steam_review_label,
89 detail.steam_review_count,
90 detail.steam_review_score,
91 detail.steam_review_updated_at,
92 detail.esrb_rating,
93 detail.is_adult,
94 detail.adult_tags,
95 links_json,
96 detail.median_playtime,
97 detail.estimated_playtime,
98 detail.updated_at
99 ])?;
100 }
101
102 for item in &backup.wishlist_game {
103 wishlist_stmt.execute(params![
104 item.id,
105 item.name,
106 item.cover_url,
107 item.store_url,
108 item.store_platform,
109 item.current_price,
110 item.normal_price,
111 item.lowest_price,
112 item.currency,
113 item.on_sale,
114 item.voucher,
115 item.added_at,
116 item.itad_id
117 ])?;
118 }
119
120 let mut extras_stmt = conn.prepare(
121 "INSERT OR REPLACE INTO game_extras (
122 steam_app_id, pcgw_page_id, pcgw_page_name, engine,
123 available_on,
124 dx_versions, vulkan_versions, opengl_versions,
125 win64, linux64, macos_arm, macos_intel64,
126 ray_tracing, upscaling, frame_gen,
127 ultrawidescreen, four_k_support, hdr, high_fps, fov, borderless_windowed, color_blind,
128 controller_support, full_controller, playstation_controllers, xinput_controllers,
129 surround_sound, subtitles, closed_captions,
130 has_save_data, has_config_data,
131 languages_interface, languages_audio, languages_subtitles,
132 fetched_at
133 ) VALUES (
134 ?1, ?2, ?3, ?4,
135 ?5,
136 ?6, ?7, ?8,
137 ?9, ?10, ?11, ?12,
138 ?13, ?14, ?15,
139 ?16, ?17, ?18, ?19, ?20, ?21, ?22,
140 ?23, ?24, ?25, ?26,
141 ?27, ?28, ?29,
142 ?30, ?31,
143 ?32, ?33, ?34,
144 ?35
145 )",
146 )?;
147
148 let mut sysreq_stmt = conn.prepare(
149 "INSERT INTO system_requirements (
150 steam_app_id, os_family, tier_title, target,
151 min_os, min_cpu, min_cpu2, min_ram, min_gpu, min_gpu2, min_vram, min_dx, min_storage,
152 rec_os, rec_cpu, rec_cpu2, rec_ram, rec_gpu, rec_gpu2, rec_vram, rec_dx, rec_storage,
153 fetched_at
154 ) VALUES (
155 ?1, ?2, ?3, ?4,
156 ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13,
157 ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22,
158 ?23
159 )",
160 )?;
161
162 let mut paths_stmt = conn.prepare(
163 "INSERT INTO game_data_paths (steam_app_id, kind, os, raw_path, fetched_at)
164 VALUES (?1, ?2, ?3, ?4, ?5)",
165 )?;
166
167 let serialize_vec = |v: &Option<Vec<String>>| -> Option<String> {
168 v.as_ref().and_then(|list| serde_json::to_string(list).ok())
169 };
170
171 let now = Utc::now().to_rfc3339();
172
173 conn.execute("DELETE FROM system_requirements", [])?;
175 conn.execute("DELETE FROM game_data_paths", [])?;
176
177 for extras in &backup.game_extras {
178 extras_stmt.execute(params![
179 extras.steam_app_id,
180 extras.pcgw_page_id,
181 extras.pcgw_page_name,
182 extras.engine,
183 extras.available_on,
184 extras.dx_versions,
185 extras.vulkan_versions,
186 extras.opengl_versions,
187 extras.win64,
188 extras.linux64,
189 extras.macos_arm,
190 extras.macos_intel64,
191 extras.ray_tracing,
192 extras.upscaling,
193 extras.frame_gen,
194 extras.ultrawidescreen,
195 extras.four_k_support,
196 extras.hdr,
197 extras.high_fps,
198 extras.fov,
199 extras.borderless_windowed,
200 extras.color_blind,
201 extras.controller_support,
202 extras.full_controller,
203 extras.playstation_controllers,
204 extras.xinput_controllers,
205 extras.surround_sound,
206 extras.subtitles,
207 extras.closed_captions,
208 extras.has_save_data,
209 extras.has_config_data,
210 serialize_vec(&extras.languages_interface),
211 serialize_vec(&extras.languages_audio),
212 serialize_vec(&extras.languages_subtitles),
213 extras.fetched_at,
214 ])?;
215 }
216
217 for req in &backup.system_requirements {
218 sysreq_stmt.execute(params![
219 req.steam_app_id,
220 req.os_family,
221 req.tier_title,
222 req.target,
223 req.min_os,
224 req.min_cpu,
225 req.min_cpu2,
226 req.min_ram,
227 req.min_gpu,
228 req.min_gpu2,
229 req.min_vram,
230 req.min_dx,
231 req.min_storage,
232 req.rec_os,
233 req.rec_cpu,
234 req.rec_cpu2,
235 req.rec_ram,
236 req.rec_gpu,
237 req.rec_gpu2,
238 req.rec_vram,
239 req.rec_dx,
240 req.rec_storage,
241 now,
242 ])?;
243 }
244
245 for path in &backup.game_data_paths {
246 paths_stmt.execute(params![
247 path.steam_app_id,
248 path.kind,
249 path.os,
250 path.raw_path,
251 now,
252 ])?;
253 }
254
255 conn.execute("COMMIT", [])?;
256
257 Ok(format!(
258 "Backup restaurado! {} jogos, {} detalhes, {} itens da wishlist, {} dados técnicos, {} requisitos de sistema e {} caminhos.",
259 backup.games.len(),
260 backup.game_details.len(),
261 backup.wishlist_game.len(),
262 backup.game_extras.len(),
263 backup.system_requirements.len(),
264 backup.game_data_paths.len(),
265 ))
266}