omni_orchestrator/schemas/v1/db/queries/
backup.rs

1use rocket::{serde::json::Json, State};
2use sqlx::MySql;
3use crate::models::backup::Backup;
4
5/// Paginated backups list
6pub async fn list_backups_paginated(
7    pool: &State<sqlx::Pool<MySql>>,
8    page: i64,
9    page_size: i64,
10) -> Result<Vec<Backup>, sqlx::Error> {
11    tracing::info!(
12        page = page,
13        page_size = page_size,
14        "Fetching paginated backups"
15    );
16    
17    // Add simple plain text logs
18    tracing::info!("About to execute SQL query");
19    
20    // Use match to explicitly handle success vs error
21    match sqlx::query_as::<_, Backup>(
22        "SELECT * FROM backups LIMIT ? OFFSET ?"
23    )
24    .bind(page_size)
25    .bind((page - 1) * page_size)
26    .fetch_all(&**pool)
27    .await {
28        Ok(backups) => {
29            // Simple log without structured fields
30            tracing::info!("Query successful, returned {} backups", backups.len());
31            
32            // Try to log each backup ID to see if any data is returned
33            for backup in &backups {
34                tracing::info!("Found backup ID: {}", backup.id);
35            }
36            
37            tracing::info!("Returning {} backups for page {}", backups.len(), page);
38            Ok(backups)
39        },
40        Err(err) => {
41            // Log the error explicitly
42            tracing::error!("Database query failed: {:?}", err);
43            Err(err)
44        }
45    }
46}
47
48/// Paginated backups list by app_id
49pub async fn list_backups_by_app_id(
50    pool: &State<sqlx::Pool<MySql>>,
51    app_id: i64,
52    page: i64,
53    page_size: i64,
54) -> Result<Vec<Backup>, sqlx::Error> {
55    let backups = sqlx::query_as::<_, Backup>(
56        "SELECT * FROM backups WHERE app_id = ? LIMIT ? OFFSET ?",
57    )
58    .bind(app_id)
59    .bind(page_size)
60    .bind((page - 1) * page_size)
61    .fetch_all(&**pool)
62    .await?;
63    println!("Found {} backups", backups.len());
64    println!("Returning {} backups", backups.len());
65
66    Ok(backups)
67}
68
69/// Get a backup by ID
70pub async fn get_backup_by_id(
71    pool: &State<sqlx::Pool<MySql>>,
72    backup_id: i64,
73) -> Result<Option<Backup>, sqlx::Error> {
74    let backup = sqlx::query_as::<_, Backup>(
75        "SELECT * FROM backups WHERE id = ?",
76    )
77    .bind(backup_id)
78    .fetch_optional(&**pool)
79    .await?;
80    println!("Found backup: {:?}", backup);
81
82    Ok(backup)
83}
84
85/// Create a new backup
86/// This function creates a new app backup in the database
87pub async fn create_backup(
88    pool: &State<sqlx::Pool<MySql>>,
89    backup: &Backup,
90) -> Result<Backup, sqlx::Error> {
91    sqlx::query(
92        "INSERT INTO backups (
93            name, description, created_at, created_by, backup_type, status, format_version,
94            source_environment, encryption_method, encryption_key_id, size_bytes, has_system_core,
95            has_directors, has_orchestrators, has_network_config, has_app_definitions, has_volume_data,
96            included_apps, included_services, last_validated_at, last_restored_at, restore_target_environment,
97            restore_status, storage_location, manifest_path, metadata
98        ) VALUES (
99            ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
100        )",
101    )
102    .bind(backup.name.clone())
103    .bind(backup.description.clone())
104    .bind(backup.created_at)
105    .bind(backup.created_by.clone())
106    .bind(backup.backup_type.clone())
107    .bind(backup.status.clone())
108    .bind(backup.format_version.clone())
109    .bind(backup.source_environment.clone())
110    .bind(backup.encryption_method.clone())
111    .bind(backup.encryption_key_id)
112    .bind(backup.size_bytes)
113    .bind(backup.has_system_core)
114    .bind(backup.has_directors)
115    .bind(backup.has_orchestrators)
116    .bind(backup.has_network_config)
117    .bind(backup.has_app_definitions)
118    .bind(backup.has_volume_data)
119    .bind(backup.included_apps.clone())
120    .bind(backup.included_services.clone())
121    .bind(backup.last_validated_at)
122    .bind(backup.last_restored_at)
123    .bind(backup.restore_target_environment.clone())
124    .bind(backup.restore_status.clone())
125    .bind(backup.storage_location.clone())
126    .bind(backup.manifest_path.clone())
127    .bind(backup.metadata.clone())
128    .execute(&**pool)
129    .await?;
130
131    let last_insert_id: i64 = sqlx::query_scalar("SELECT LAST_INSERT_ID()")
132        .fetch_one(&**pool)
133        .await?;
134
135    let created_backup = sqlx::query_as::<_, Backup>(
136        "SELECT * FROM backups WHERE id = ?",
137    )
138    .bind(last_insert_id)
139    .fetch_one(&**pool)
140    .await?;
141    Ok(created_backup)
142}