shared/models/
server_variable.rs1use crate::prelude::*;
2use serde::{Deserialize, Serialize};
3use sqlx::{Row, postgres::PgRow};
4use std::collections::BTreeMap;
5use utoipa::ToSchema;
6
7#[derive(Serialize, Deserialize)]
8pub struct ServerVariable {
9 pub variable: super::nest_egg_variable::NestEggVariable,
10
11 pub value: String,
12
13 pub created: chrono::NaiveDateTime,
14}
15
16impl BaseModel for ServerVariable {
17 const NAME: &'static str = "server_variable";
18
19 #[inline]
20 fn columns(prefix: Option<&str>) -> BTreeMap<&'static str, compact_str::CompactString> {
21 let prefix = prefix.unwrap_or_default();
22
23 let mut columns = BTreeMap::from([
24 (
25 "server_variables.value",
26 compact_str::format_compact!("{prefix}value"),
27 ),
28 (
29 "server_variables.created",
30 compact_str::format_compact!("{prefix}created"),
31 ),
32 ]);
33
34 columns.extend(super::nest_egg_variable::NestEggVariable::columns(Some(
35 "variable_",
36 )));
37
38 columns
39 }
40
41 #[inline]
42 fn map(prefix: Option<&str>, row: &PgRow) -> Result<Self, crate::database::DatabaseError> {
43 let prefix = prefix.unwrap_or_default();
44
45 let variable = super::nest_egg_variable::NestEggVariable::map(Some("variable_"), row)?;
46 let value = row
47 .try_get(compact_str::format_compact!("{prefix}value").as_str())
48 .unwrap_or_else(|_| {
49 variable
50 .default_value
51 .clone()
52 .unwrap_or_else(|| "".to_string())
53 });
54
55 Ok(Self {
56 variable,
57 value,
58 created: row
59 .try_get(compact_str::format_compact!("{prefix}created").as_str())
60 .unwrap_or_else(|_| chrono::Utc::now().naive_utc()),
61 })
62 }
63}
64
65impl ServerVariable {
66 pub async fn create(
67 database: &crate::database::Database,
68 server_uuid: uuid::Uuid,
69 variable_uuid: uuid::Uuid,
70 value: &str,
71 ) -> Result<(), crate::database::DatabaseError> {
72 sqlx::query(
73 r#"
74 INSERT INTO server_variables (server_uuid, variable_uuid, value)
75 VALUES ($1, $2, $3)
76 ON CONFLICT (server_uuid, variable_uuid) DO UPDATE SET value = EXCLUDED.value
77 "#,
78 )
79 .bind(server_uuid)
80 .bind(variable_uuid)
81 .bind(value)
82 .execute(database.write())
83 .await?;
84
85 Ok(())
86 }
87
88 pub async fn all_by_server_uuid_egg_uuid(
89 database: &crate::database::Database,
90 server_uuid: uuid::Uuid,
91 egg_uuid: uuid::Uuid,
92 ) -> Result<Vec<Self>, crate::database::DatabaseError> {
93 let rows = sqlx::query(&format!(
94 r#"
95 SELECT {}
96 FROM nest_egg_variables
97 LEFT JOIN server_variables ON server_variables.variable_uuid = nest_egg_variables.uuid AND server_variables.server_uuid = $1
98 WHERE nest_egg_variables.egg_uuid = $2
99 ORDER BY nest_egg_variables.order_, nest_egg_variables.created
100 "#,
101 Self::columns_sql(None)
102 ))
103 .bind(server_uuid)
104 .bind(egg_uuid)
105 .fetch_all(database.read())
106 .await?;
107
108 rows.into_iter()
109 .map(|row| Self::map(None, &row))
110 .try_collect_vec()
111 }
112
113 #[inline]
114 pub fn into_api_object(self) -> ApiServerVariable {
115 ApiServerVariable {
116 name: self.variable.name,
117 description: self.variable.description,
118 env_variable: self.variable.env_variable,
119 default_value: self.variable.default_value,
120 value: self.value,
121 is_editable: self.variable.user_editable,
122 is_secret: self.variable.secret,
123 rules: self.variable.rules,
124 created: self.created.and_utc(),
125 }
126 }
127}
128
129#[derive(ToSchema, Serialize)]
130#[schema(title = "ServerVariable")]
131pub struct ApiServerVariable {
132 pub name: compact_str::CompactString,
133 pub description: Option<compact_str::CompactString>,
134
135 pub env_variable: compact_str::CompactString,
136 pub default_value: Option<String>,
137 pub value: String,
138 pub is_editable: bool,
139 pub is_secret: bool,
140 pub rules: Vec<compact_str::CompactString>,
141
142 pub created: chrono::DateTime<chrono::Utc>,
143}