game_manager_lib/database/backup/
auto.rs1use crate::database::backup::export_queries::fetch_backup_data;
4use crate::database::backup::models::BackupData;
5use crate::database::{self, AppState};
6use crate::errors::AppError;
7use chrono::Utc;
8use std::fs;
9use std::path::PathBuf;
10use tauri::{AppHandle, Manager};
11
12pub fn backup_if_major_update(
13 app: &AppHandle,
14 previous_version: &str,
15 current_version: &str,
16) -> Result<Option<PathBuf>, AppError> {
17 let parse_version = |v: &str| -> (u32, u32, u32) {
19 let parts: Vec<&str> = v.split('.').collect();
20 let major = parts.first().and_then(|s| s.parse().ok()).unwrap_or(0);
21 let minor = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(0);
22 let patch = parts.get(2).and_then(|s| s.parse().ok()).unwrap_or(0);
23 (major, minor, patch)
24 };
25
26 let (prev_major, _, _) = parse_version(previous_version);
27 let (curr_major, _, _) = parse_version(current_version);
28
29 if prev_major != curr_major && prev_major > 0 {
31 tracing::info!(
32 "Mudança de versão major detectada: v{} -> v{}",
33 previous_version,
34 current_version
35 );
36 let backup_path = backup_before_update(app, previous_version)?;
37 Ok(Some(backup_path))
38 } else {
39 Ok(None)
40 }
41}
42
43pub fn backup_before_update(app: &AppHandle, previous_version: &str) -> Result<PathBuf, AppError> {
47 tracing::info!("Criando backup automático antes da atualização...");
48
49 let app_data_dir = app
50 .path()
51 .app_data_dir()
52 .map_err(|e| AppError::IoError(format!("Falha ao obter app_data_dir: {}", e)))?;
53
54 let backups_dir = app_data_dir.join("backups");
55 fs::create_dir_all(&backups_dir)?;
56
57 let timestamp = chrono::Local::now().format("%Y%m%d_%H%M%S");
59 let backup_filename = format!("auto_backup_v{}_{}.json", previous_version, timestamp);
60 let backup_path = backups_dir.join(backup_filename);
61
62 let state: tauri::State<AppState> = app.state();
64 let (
65 games,
66 game_details,
67 wishlist_game,
68 game_extras,
69 system_requirements,
70 game_data_paths,
71 schema_version,
72 ) = fetch_backup_data(&state)?;
73
74 let backup = BackupData {
75 version: schema_version,
76 app_version: previous_version.to_string(),
77 date: chrono::Local::now().to_rfc3339(),
78 games,
79 game_details,
80 wishlist_game,
81 game_extras,
82 system_requirements,
83 game_data_paths,
84 };
85
86 let json = serde_json::to_string_pretty(&backup)?;
87 fs::write(&backup_path, json)?;
88
89 let cache_conn = state.cache_db.lock().map_err(|_| AppError::MutexError)?;
91 let now = Utc::now().to_rfc3339();
92 database::configs::set_config(&cache_conn, "last_auto_backup_at", &now)?;
93
94 tracing::info!("Backup automático criado: {:?}", backup_path);
95 Ok(backup_path)
96}