Skip to main content

shared/models/
system_backup_policy_server.rs

1use crate::{models::InsertQueryBuilder, prelude::*};
2use garde::Validate;
3use serde::{Deserialize, Serialize};
4use sqlx::{Row, postgres::PgRow};
5use std::{
6    collections::BTreeMap,
7    sync::{Arc, LazyLock},
8};
9use utoipa::ToSchema;
10
11#[derive(Serialize, Deserialize)]
12pub struct SystemBackupPolicyServer {
13    pub system_backup_policy: Fetchable<super::system_backup_policy::SystemBackupPolicy>,
14    pub server: Fetchable<super::server::Server>,
15
16    pub created: chrono::NaiveDateTime,
17
18    extension_data: super::ModelExtensionData,
19}
20
21impl BaseModel for SystemBackupPolicyServer {
22    const NAME: &'static str = "system_backup_policy_server";
23
24    fn get_extension_list() -> &'static super::ModelExtensionList {
25        static EXTENSIONS: LazyLock<super::ModelExtensionList> =
26            LazyLock::new(|| parking_lot::RwLock::new(Vec::new()));
27
28        &EXTENSIONS
29    }
30
31    fn get_extension_data(&self) -> &super::ModelExtensionData {
32        &self.extension_data
33    }
34
35    #[inline]
36    fn base_columns(prefix: Option<&str>) -> BTreeMap<&'static str, compact_str::CompactString> {
37        let prefix = prefix.unwrap_or_default();
38
39        BTreeMap::from([
40            (
41                "system_backup_policy_servers.system_backup_policy_uuid",
42                compact_str::format_compact!("{prefix}system_backup_policy_uuid"),
43            ),
44            (
45                "system_backup_policy_servers.server_uuid",
46                compact_str::format_compact!("{prefix}server_uuid"),
47            ),
48            (
49                "system_backup_policy_servers.created",
50                compact_str::format_compact!("{prefix}created"),
51            ),
52        ])
53    }
54
55    #[inline]
56    fn map(prefix: Option<&str>, row: &PgRow) -> Result<Self, crate::database::DatabaseError> {
57        let prefix = prefix.unwrap_or_default();
58
59        Ok(Self {
60            system_backup_policy: super::system_backup_policy::SystemBackupPolicy::get_fetchable(
61                row.try_get(
62                    compact_str::format_compact!("{prefix}system_backup_policy_uuid").as_str(),
63                )?,
64            ),
65            server: super::server::Server::get_fetchable(
66                row.try_get(compact_str::format_compact!("{prefix}server_uuid").as_str())?,
67            ),
68            created: row.try_get(compact_str::format_compact!("{prefix}created").as_str())?,
69            extension_data: Self::map_extensions(prefix, row)?,
70        })
71    }
72}
73
74impl SystemBackupPolicyServer {
75    pub async fn by_system_backup_policy_uuid_server_uuid(
76        database: &crate::database::Database,
77        system_backup_policy_uuid: uuid::Uuid,
78        server_uuid: uuid::Uuid,
79    ) -> Result<Option<Self>, crate::database::DatabaseError> {
80        let row = sqlx::query(sqlx::AssertSqlSafe(format!(
81            r#"
82            SELECT {}
83            FROM system_backup_policy_servers
84            WHERE
85                system_backup_policy_servers.system_backup_policy_uuid = $1
86                AND system_backup_policy_servers.server_uuid = $2
87            "#,
88            Self::columns_sql(None)
89        )))
90        .bind(system_backup_policy_uuid)
91        .bind(server_uuid)
92        .fetch_optional(database.read())
93        .await?;
94
95        row.try_map(|row| Self::map(None, &row))
96    }
97
98    pub async fn by_system_backup_policy_uuid_with_pagination(
99        database: &crate::database::Database,
100        system_backup_policy_uuid: uuid::Uuid,
101        page: i64,
102        per_page: i64,
103        search: Option<&str>,
104    ) -> Result<super::Pagination<Self>, crate::database::DatabaseError> {
105        super::PaginatedQueryBuilder::new(
106            Self::columns_sql(None),
107            format!(
108                r#"
109                FROM system_backup_policy_servers
110                JOIN servers ON servers.uuid = system_backup_policy_servers.server_uuid
111                WHERE
112                    system_backup_policy_servers.system_backup_policy_uuid = $1
113                    AND {search}
114                "#,
115                search = super::search_sql(2, &["servers.name"], &["servers.uuid"]),
116            ),
117            "system_backup_policy_servers.created, system_backup_policy_servers.system_backup_policy_uuid, system_backup_policy_servers.server_uuid",
118        )
119        .bind(system_backup_policy_uuid)
120        .bind(search)
121        .fetch(database, page, per_page)
122        .await
123    }
124}
125
126#[async_trait::async_trait]
127impl IntoAdminApiObject for SystemBackupPolicyServer {
128    type AdminApiObject = AdminApiSystemBackupPolicyServer;
129    type ExtraArgs<'a> = &'a crate::storage::StorageUrlRetriever<'a>;
130
131    async fn into_admin_api_object<'a>(
132        self,
133        state: &crate::State,
134        storage_url_retriever: Self::ExtraArgs<'a>,
135    ) -> Result<Self::AdminApiObject, crate::database::DatabaseError> {
136        let api_object = AdminApiSystemBackupPolicyServer::init_hooks(&self, state).await?;
137
138        let api_object = finish_extendible!(
139            AdminApiSystemBackupPolicyServer {
140                server: self
141                    .server
142                    .fetch_cached(&state.database)
143                    .await?
144                    .into_admin_api_object(state, storage_url_retriever)
145                    .await?,
146                created: self.created.and_utc(),
147            },
148            api_object,
149            state
150        )?;
151
152        Ok(api_object)
153    }
154}
155
156#[derive(ToSchema, Deserialize, Validate)]
157pub struct CreateSystemBackupPolicyServerOptions {
158    #[garde(skip)]
159    pub system_backup_policy_uuid: uuid::Uuid,
160    #[garde(skip)]
161    pub server_uuid: uuid::Uuid,
162}
163
164#[async_trait::async_trait]
165impl CreatableModel for SystemBackupPolicyServer {
166    type CreateOptions<'a> = CreateSystemBackupPolicyServerOptions;
167    type CreateResult = Self;
168
169    fn get_create_handlers() -> &'static LazyLock<CreateListenerList<Self>> {
170        static CREATE_LISTENERS: LazyLock<CreateListenerList<SystemBackupPolicyServer>> =
171            LazyLock::new(|| Arc::new(ModelHandlerList::default()));
172
173        &CREATE_LISTENERS
174    }
175
176    async fn create_with_transaction(
177        state: &crate::State,
178        mut options: Self::CreateOptions<'_>,
179        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
180    ) -> Result<Self, crate::database::DatabaseError> {
181        options.validate()?;
182
183        super::server::Server::by_uuid_optional_cached(&state.database, options.server_uuid)
184            .await?
185            .ok_or(crate::database::InvalidRelationError("server"))?;
186
187        let mut query_builder = InsertQueryBuilder::new("system_backup_policy_servers");
188
189        Self::run_create_handlers(&mut options, &mut query_builder, state, transaction).await?;
190
191        query_builder
192            .set(
193                "system_backup_policy_uuid",
194                options.system_backup_policy_uuid,
195            )
196            .set("server_uuid", options.server_uuid);
197
198        let row = query_builder
199            .returning(&Self::columns_sql(None))
200            .fetch_one(&mut **transaction)
201            .await?;
202        let mut policy_server = Self::map(None, &row)?;
203
204        Self::run_after_create_handlers(&mut policy_server, &options, state, transaction).await?;
205
206        Ok(policy_server)
207    }
208}
209
210#[async_trait::async_trait]
211impl DeletableModel for SystemBackupPolicyServer {
212    type DeleteOptions = ();
213
214    fn get_delete_handlers() -> &'static LazyLock<DeleteHandlerList<Self>> {
215        static DELETE_LISTENERS: LazyLock<DeleteHandlerList<SystemBackupPolicyServer>> =
216            LazyLock::new(|| Arc::new(ModelHandlerList::default()));
217
218        &DELETE_LISTENERS
219    }
220
221    async fn delete_with_transaction(
222        &self,
223        state: &crate::State,
224        options: Self::DeleteOptions,
225        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
226    ) -> Result<(), anyhow::Error> {
227        self.run_delete_handlers(&options, state, transaction)
228            .await?;
229
230        sqlx::query(
231            r#"
232            DELETE FROM system_backup_policy_servers
233            WHERE
234                system_backup_policy_servers.system_backup_policy_uuid = $1
235                AND system_backup_policy_servers.server_uuid = $2
236            "#,
237        )
238        .bind(self.system_backup_policy.uuid)
239        .bind(self.server.uuid)
240        .execute(&mut **transaction)
241        .await?;
242
243        self.run_after_delete_handlers(&options, state, transaction)
244            .await?;
245
246        Ok(())
247    }
248}
249
250#[schema_extension_derive::extendible]
251#[init_args(SystemBackupPolicyServer, crate::State)]
252#[hook_args(crate::State)]
253#[derive(ToSchema, Serialize)]
254#[schema(title = "SystemBackupPolicyServer")]
255pub struct AdminApiSystemBackupPolicyServer {
256    pub server: super::server::AdminApiServer,
257
258    pub created: chrono::DateTime<chrono::Utc>,
259}