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

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