Skip to main content

shared/models/
system_backup_policy_database_agent_host.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 SystemBackupPolicyDatabaseAgentHost {
13    pub system_backup_policy: Fetchable<super::system_backup_policy::SystemBackupPolicy>,
14    pub database_agent_host: Fetchable<super::database_agent_host::DatabaseAgentHost>,
15
16    pub created: chrono::NaiveDateTime,
17
18    extension_data: super::ModelExtensionData,
19}
20
21impl BaseModel for SystemBackupPolicyDatabaseAgentHost {
22    const NAME: &'static str = "system_backup_policy_database_agent_host";
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_database_agent_hosts.system_backup_policy_uuid",
42                compact_str::format_compact!("{prefix}system_backup_policy_uuid"),
43            ),
44            (
45                "system_backup_policy_database_agent_hosts.database_agent_host_uuid",
46                compact_str::format_compact!("{prefix}database_agent_host_uuid"),
47            ),
48            (
49                "system_backup_policy_database_agent_hosts.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            database_agent_host: super::database_agent_host::DatabaseAgentHost::get_fetchable(
66                row.try_get(
67                    compact_str::format_compact!("{prefix}database_agent_host_uuid").as_str(),
68                )?,
69            ),
70            created: row.try_get(compact_str::format_compact!("{prefix}created").as_str())?,
71            extension_data: Self::map_extensions(prefix, row)?,
72        })
73    }
74}
75
76impl SystemBackupPolicyDatabaseAgentHost {
77    pub async fn by_system_backup_policy_uuid_database_agent_host_uuid(
78        database: &crate::database::Database,
79        system_backup_policy_uuid: uuid::Uuid,
80        database_agent_host_uuid: uuid::Uuid,
81    ) -> Result<Option<Self>, crate::database::DatabaseError> {
82        let row = sqlx::query(sqlx::AssertSqlSafe(format!(
83            r#"
84            SELECT {}
85            FROM system_backup_policy_database_agent_hosts
86            WHERE
87                system_backup_policy_database_agent_hosts.system_backup_policy_uuid = $1
88                AND system_backup_policy_database_agent_hosts.database_agent_host_uuid = $2
89            "#,
90            Self::columns_sql(None)
91        )))
92        .bind(system_backup_policy_uuid)
93        .bind(database_agent_host_uuid)
94        .fetch_optional(database.read())
95        .await?;
96
97        row.try_map(|row| Self::map(None, &row))
98    }
99
100    pub async fn by_system_backup_policy_uuid_with_pagination(
101        database: &crate::database::Database,
102        system_backup_policy_uuid: uuid::Uuid,
103        page: i64,
104        per_page: i64,
105        search: Option<&str>,
106    ) -> Result<super::Pagination<Self>, crate::database::DatabaseError> {
107        let offset = (page - 1) * per_page;
108
109        let rows = sqlx::query(sqlx::AssertSqlSafe(format!(
110            r#"
111            SELECT {}, COUNT(*) OVER() AS total_count
112            FROM system_backup_policy_database_agent_hosts
113            JOIN database_agent_hosts ON database_agent_hosts.uuid = system_backup_policy_database_agent_hosts.database_agent_host_uuid
114            WHERE
115                system_backup_policy_database_agent_hosts.system_backup_policy_uuid = $1
116                AND {search}
117            ORDER BY system_backup_policy_database_agent_hosts.created
118            LIMIT $3 OFFSET $4
119            "#,
120            Self::columns_sql(None),
121            search = super::search_sql(2, &["database_agent_hosts.name"], &["database_agent_hosts.uuid"])
122        )))
123        .bind(system_backup_policy_uuid)
124        .bind(search)
125        .bind(per_page)
126        .bind(offset)
127        .fetch_all(database.read())
128        .await?;
129
130        Ok(super::Pagination {
131            total: rows
132                .first()
133                .map_or(Ok(0), |row| row.try_get("total_count"))?,
134            per_page,
135            page,
136            data: rows
137                .into_iter()
138                .map(|row| Self::map(None, &row))
139                .try_collect_vec()?,
140        })
141    }
142}
143
144#[async_trait::async_trait]
145impl IntoAdminApiObject for SystemBackupPolicyDatabaseAgentHost {
146    type AdminApiObject = AdminApiSystemBackupPolicyDatabaseAgentHost;
147    type ExtraArgs<'a> = ();
148
149    async fn into_admin_api_object<'a>(
150        self,
151        state: &crate::State,
152        _args: Self::ExtraArgs<'a>,
153    ) -> Result<Self::AdminApiObject, crate::database::DatabaseError> {
154        let api_object =
155            AdminApiSystemBackupPolicyDatabaseAgentHost::init_hooks(&self, state).await?;
156
157        let api_object = finish_extendible!(
158            AdminApiSystemBackupPolicyDatabaseAgentHost {
159                database_agent_host: self
160                    .database_agent_host
161                    .fetch_cached(&state.database)
162                    .await?
163                    .into_admin_api_object(state, ())
164                    .await?,
165                created: self.created.and_utc(),
166            },
167            api_object,
168            state
169        )?;
170
171        Ok(api_object)
172    }
173}
174
175#[derive(ToSchema, Deserialize, Validate)]
176pub struct CreateSystemBackupPolicyDatabaseAgentHostOptions {
177    #[garde(skip)]
178    pub system_backup_policy_uuid: uuid::Uuid,
179    #[garde(skip)]
180    pub database_agent_host_uuid: uuid::Uuid,
181}
182
183#[async_trait::async_trait]
184impl CreatableModel for SystemBackupPolicyDatabaseAgentHost {
185    type CreateOptions<'a> = CreateSystemBackupPolicyDatabaseAgentHostOptions;
186    type CreateResult = Self;
187
188    fn get_create_handlers() -> &'static LazyLock<CreateListenerList<Self>> {
189        static CREATE_LISTENERS: LazyLock<CreateListenerList<SystemBackupPolicyDatabaseAgentHost>> =
190            LazyLock::new(|| Arc::new(ModelHandlerList::default()));
191
192        &CREATE_LISTENERS
193    }
194
195    async fn create_with_transaction(
196        state: &crate::State,
197        mut options: Self::CreateOptions<'_>,
198        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
199    ) -> Result<Self, crate::database::DatabaseError> {
200        options.validate()?;
201
202        super::database_agent_host::DatabaseAgentHost::by_uuid_optional_cached(
203            &state.database,
204            options.database_agent_host_uuid,
205        )
206        .await?
207        .ok_or(crate::database::InvalidRelationError("database_agent_host"))?;
208
209        let mut query_builder =
210            InsertQueryBuilder::new("system_backup_policy_database_agent_hosts");
211
212        Self::run_create_handlers(&mut options, &mut query_builder, state, transaction).await?;
213
214        query_builder
215            .set(
216                "system_backup_policy_uuid",
217                options.system_backup_policy_uuid,
218            )
219            .set("database_agent_host_uuid", options.database_agent_host_uuid);
220
221        let row = query_builder
222            .returning(&Self::columns_sql(None))
223            .fetch_one(&mut **transaction)
224            .await?;
225        let mut policy_database_agent_host = Self::map(None, &row)?;
226
227        Self::run_after_create_handlers(
228            &mut policy_database_agent_host,
229            &options,
230            state,
231            transaction,
232        )
233        .await?;
234
235        Ok(policy_database_agent_host)
236    }
237}
238
239#[async_trait::async_trait]
240impl DeletableModel for SystemBackupPolicyDatabaseAgentHost {
241    type DeleteOptions = ();
242
243    fn get_delete_handlers() -> &'static LazyLock<DeleteHandlerList<Self>> {
244        static DELETE_LISTENERS: LazyLock<DeleteHandlerList<SystemBackupPolicyDatabaseAgentHost>> =
245            LazyLock::new(|| Arc::new(ModelHandlerList::default()));
246
247        &DELETE_LISTENERS
248    }
249
250    async fn delete_with_transaction(
251        &self,
252        state: &crate::State,
253        options: Self::DeleteOptions,
254        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
255    ) -> Result<(), anyhow::Error> {
256        self.run_delete_handlers(&options, state, transaction)
257            .await?;
258
259        sqlx::query(
260            r#"
261            DELETE FROM system_backup_policy_database_agent_hosts
262            WHERE
263                system_backup_policy_database_agent_hosts.system_backup_policy_uuid = $1
264                AND system_backup_policy_database_agent_hosts.database_agent_host_uuid = $2
265            "#,
266        )
267        .bind(self.system_backup_policy.uuid)
268        .bind(self.database_agent_host.uuid)
269        .execute(&mut **transaction)
270        .await?;
271
272        self.run_after_delete_handlers(&options, state, transaction)
273            .await?;
274
275        Ok(())
276    }
277}
278
279#[schema_extension_derive::extendible]
280#[init_args(SystemBackupPolicyDatabaseAgentHost, crate::State)]
281#[hook_args(crate::State)]
282#[derive(ToSchema, Serialize)]
283#[schema(title = "SystemBackupPolicyDatabaseAgentHost")]
284pub struct AdminApiSystemBackupPolicyDatabaseAgentHost {
285    pub database_agent_host: super::database_agent_host::AdminApiDatabaseAgentHost,
286
287    pub created: chrono::DateTime<chrono::Utc>,
288}