1
use std::collections::BTreeMap;
2

            
3
use serde::{Deserialize, Serialize};
4
use serde_json::json;
5
use thiserror::Error;
6

            
7
use crate::core::{
8
    protocol::request_validation::ValidationError,
9
    types::{DbOrUser, MySQLDatabase},
10
};
11

            
12
pub type CreateDatabasesRequest = Vec<MySQLDatabase>;
13

            
14
pub type CreateDatabasesResponse = BTreeMap<MySQLDatabase, Result<(), CreateDatabaseError>>;
15

            
16
#[derive(Error, Debug, Clone, PartialEq, Serialize, Deserialize)]
17
pub enum CreateDatabaseError {
18
    #[error("Validation error: {0}")]
19
    ValidationError(#[from] ValidationError),
20

            
21
    #[error("Database already exists")]
22
    DatabaseAlreadyExists,
23

            
24
    #[error("MySQL error: {0}")]
25
    MySqlError(String),
26
}
27

            
28
pub fn print_create_databases_output_status(output: &CreateDatabasesResponse) {
29
    for (database_name, result) in output {
30
        match result {
31
            Ok(()) => {
32
                println!("Database '{database_name}' created successfully.");
33
            }
34
            Err(err) => {
35
                eprintln!("{}", err.to_error_message(database_name));
36
                eprintln!("Skipping...");
37
            }
38
        }
39
        println!();
40
    }
41
}
42

            
43
pub fn print_create_databases_output_status_json(output: &CreateDatabasesResponse) {
44
    let value = output
45
        .iter()
46
        .map(|(name, result)| match result {
47
            Ok(()) => (name.to_string(), json!({ "status": "success" })),
48
            Err(err) => (
49
                name.to_string(),
50
                json!({
51
                  "status": "error",
52
                  "type": err.error_type(),
53
                  "error": err.to_error_message(name),
54
                }),
55
            ),
56
        })
57
        .collect::<serde_json::Map<_, _>>();
58
    println!(
59
        "{}",
60
        serde_json::to_string_pretty(&value)
61
            .unwrap_or("Failed to serialize result to JSON".to_string())
62
    );
63
}
64

            
65
impl CreateDatabaseError {
66
    #[must_use]
67
    pub fn to_error_message(&self, database_name: &MySQLDatabase) -> String {
68
        match self {
69
            CreateDatabaseError::ValidationError(err) => {
70
                err.to_error_message(&DbOrUser::Database(database_name.clone()))
71
            }
72
            CreateDatabaseError::DatabaseAlreadyExists => {
73
                format!("Database {database_name} already exists.")
74
            }
75
            CreateDatabaseError::MySqlError(err) => {
76
                format!("MySQL error: {err}")
77
            }
78
        }
79
    }
80

            
81
    #[must_use]
82
    pub fn error_type(&self) -> String {
83
        match self {
84
            CreateDatabaseError::ValidationError(err) => err.error_type(),
85
            CreateDatabaseError::DatabaseAlreadyExists => "database-already-exists".to_string(),
86
            CreateDatabaseError::MySqlError(_) => "mysql-error".to_string(),
87
        }
88
    }
89
}