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}