Skip to main content

shared/models/
mod.rs

1use crate::database::DatabaseError;
2use compact_str::CompactStringExt;
3use futures_util::{StreamExt, TryStreamExt};
4use garde::Validate;
5use serde::{Deserialize, Serialize, de::DeserializeOwned};
6use sqlx::{
7    Arguments, Postgres, QueryBuilder, Row,
8    encode::IsNull,
9    error::BoxDynError,
10    postgres::{PgArgumentBuffer, PgArguments, PgRow, PgTypeInfo},
11};
12use std::{
13    collections::{BTreeMap, HashSet},
14    marker::PhantomData,
15    pin::Pin,
16    sync::{Arc, LazyLock},
17};
18use tokio::sync::RwLock;
19use utoipa::ToSchema;
20
21pub mod admin_activity;
22pub mod announcement;
23pub mod backup_configuration;
24pub mod database_host;
25pub mod egg_configuration;
26pub mod egg_repository;
27pub mod egg_repository_egg;
28pub mod location;
29pub mod location_database_host;
30pub mod mount;
31pub mod nest;
32pub mod nest_egg;
33pub mod nest_egg_mount;
34pub mod nest_egg_variable;
35pub mod node;
36pub mod node_allocation;
37pub mod node_mount;
38pub mod oauth_provider;
39pub mod oauth_provider_mapping;
40pub mod role;
41pub mod server;
42pub mod server_activity;
43pub mod server_allocation;
44pub mod server_backup;
45pub mod server_database;
46pub mod server_mount;
47pub mod server_schedule;
48pub mod server_schedule_step;
49pub mod server_subuser;
50pub mod server_variable;
51pub mod user;
52pub mod user_activity;
53pub mod user_api_key;
54pub mod user_command_snippet;
55pub mod user_oauth_link;
56pub mod user_password_reset;
57pub mod user_recovery_code;
58pub mod user_security_key;
59pub mod user_server_group;
60pub mod user_session;
61pub mod user_ssh_key;
62
63#[derive(ToSchema, Validate, Deserialize, Serialize)]
64pub struct PaginationParams {
65    #[garde(range(min = 1))]
66    #[schema(minimum = 1)]
67    #[serde(default = "Pagination::default_page")]
68    pub page: i64,
69    #[garde(range(min = 1, max = 100))]
70    #[schema(minimum = 1, maximum = 100)]
71    #[serde(default = "Pagination::default_per_page")]
72    pub per_page: i64,
73}
74
75#[derive(ToSchema, Validate, Deserialize, Serialize)]
76pub struct PaginationParamsWithSearch {
77    #[garde(range(min = 1))]
78    #[schema(minimum = 1)]
79    #[serde(default = "Pagination::default_page")]
80    pub page: i64,
81    #[garde(range(min = 1, max = 100))]
82    #[schema(minimum = 1, maximum = 100)]
83    #[serde(default = "Pagination::default_per_page")]
84    pub per_page: i64,
85    #[garde(length(chars, min = 1, max = 128))]
86    #[schema(min_length = 1, max_length = 128)]
87    #[serde(
88        default,
89        deserialize_with = "crate::deserialize::deserialize_string_option"
90    )]
91    pub search: Option<compact_str::CompactString>,
92}
93
94#[derive(ToSchema, Deserialize, Serialize)]
95pub struct Pagination<T: Serialize = serde_json::Value> {
96    pub total: i64,
97    pub per_page: i64,
98    pub page: i64,
99
100    pub data: Vec<T>,
101}
102
103impl Pagination {
104    #[inline]
105    pub const fn default_page() -> i64 {
106        1
107    }
108
109    #[inline]
110    pub const fn default_per_page() -> i64 {
111        25
112    }
113}
114
115impl<T: Serialize> Pagination<T> {
116    pub async fn async_map<R: serde::Serialize, Fut: Future<Output = R>>(
117        self,
118        mapper: impl Fn(T) -> Fut,
119    ) -> Pagination<R> {
120        let mut results = Vec::new();
121        results.reserve_exact(self.data.len());
122        let mut result_stream =
123            futures_util::stream::iter(self.data.into_iter().map(mapper)).buffered(25);
124
125        while let Some(result) = result_stream.next().await {
126            results.push(result);
127        }
128
129        Pagination {
130            total: self.total,
131            per_page: self.per_page,
132            page: self.page,
133            data: results,
134        }
135    }
136
137    pub async fn try_async_map<R: serde::Serialize, E, Fut: Future<Output = Result<R, E>>>(
138        self,
139        mapper: impl Fn(T) -> Fut,
140    ) -> Result<Pagination<R>, E> {
141        let mut results = Vec::new();
142        results.reserve_exact(self.data.len());
143        let mut result_stream =
144            futures_util::stream::iter(self.data.into_iter().map(mapper)).buffered(25);
145
146        while let Some(result) = result_stream.try_next().await? {
147            results.push(result);
148        }
149
150        Ok(Pagination {
151            total: self.total,
152            per_page: self.per_page,
153            page: self.page,
154            data: results,
155        })
156    }
157}
158
159pub type ModelExtensionList = parking_lot::RwLock<Vec<Box<dyn ModelExtension + Send + Sync>>>;
160pub type ModelExtensionData = Vec<(compact_str::CompactString, Vec<u8>)>;
161pub type ModelExtensionMapType = Box<dyn erased_serde::Serialize>;
162
163pub trait ModelExtension {
164    fn extension_name(&self) -> &'static str;
165
166    fn extended_columns(&self, prefix: &str) -> BTreeMap<&'static str, compact_str::CompactString>;
167
168    fn map_extended(
169        &self,
170        prefix: &str,
171        row: &PgRow,
172    ) -> Result<ModelExtensionMapType, crate::database::DatabaseError>;
173}
174
175pub trait SafeModelExtension: ModelExtension {
176    type Value: Serialize + DeserializeOwned;
177
178    fn name() -> &'static str;
179}
180
181pub trait BaseModel: Serialize + DeserializeOwned {
182    const NAME: &'static str;
183
184    fn get_extension_list() -> &'static ModelExtensionList;
185    fn get_extension_data(&self) -> &ModelExtensionData;
186
187    /// Registers a model extension. If an extension with the same name is already registered, this function will do nothing.
188    fn register_model_extension(extension: impl ModelExtension + Send + Sync + 'static) {
189        let mut extensions = Self::get_extension_list().write();
190
191        if extensions
192            .iter()
193            .any(|e| e.extension_name() == extension.extension_name())
194        {
195            return;
196        }
197
198        extensions.push(Box::new(extension));
199    }
200
201    /// Parses a model extension from the model's extension data. If the extension is not found, or if the data cannot be deserialized, an error is returned.
202    ///
203    /// This can be costly depending on what is stored, so use sparingly.
204    fn parse_model_extension<Extension: SafeModelExtension>(
205        &self,
206    ) -> Result<Extension::Value, crate::database::DatabaseError>
207    where
208        Extension::Value: Serialize + DeserializeOwned,
209    {
210        let data = self.get_extension_data();
211
212        for (name, value) in data.iter() {
213            if name.as_str() == Extension::name() {
214                let deserialized =
215                    rmp_serde::from_slice::<Extension::Value>(value).map_err(anyhow::Error::new)?;
216
217                return Ok(deserialized);
218            }
219        }
220
221        Err(crate::database::DatabaseError::Any(anyhow::anyhow!(
222            "model extension not found"
223        )))
224    }
225
226    fn base_columns(prefix: Option<&str>) -> BTreeMap<&'static str, compact_str::CompactString>;
227    fn columns(prefix: Option<&str>) -> BTreeMap<&'static str, compact_str::CompactString> {
228        let extensions = Self::get_extension_list().read();
229
230        let mut columns = Self::base_columns(prefix);
231
232        for extension in extensions.iter() {
233            columns.extend(extension.extended_columns(prefix.unwrap_or_default()));
234        }
235
236        columns
237    }
238
239    #[inline]
240    fn columns_sql(prefix: Option<&str>) -> compact_str::CompactString {
241        Self::columns(prefix)
242            .iter()
243            .map(|(key, value)| compact_str::format_compact!("{key} as {value}"))
244            .join_compact(", ")
245    }
246
247    fn map_extensions(
248        prefix: &str,
249        row: &PgRow,
250    ) -> Result<ModelExtensionData, crate::database::DatabaseError> {
251        let mut data = Vec::new();
252
253        let extensions = Self::get_extension_list().read();
254        for extension in extensions.iter() {
255            let value = extension.map_extended(prefix, row)?;
256            let serialized = rmp_serde::to_vec(&value).map_err(anyhow::Error::new)?;
257
258            data.push((
259                compact_str::CompactString::const_new(extension.extension_name()),
260                serialized,
261            ));
262        }
263
264        Ok(data)
265    }
266
267    fn map(prefix: Option<&str>, row: &PgRow) -> Result<Self, crate::database::DatabaseError>;
268}
269
270#[async_trait::async_trait]
271pub trait EventEmittingModel: BaseModel {
272    type Event: Send + Sync + 'static;
273
274    fn get_event_emitter() -> &'static crate::events::EventEmitter<Self::Event>;
275
276    async fn register_event_handler<
277        F: Fn(crate::State, Arc<Self::Event>) -> Fut + Send + Sync + 'static,
278        Fut: Future<Output = Result<(), anyhow::Error>> + Send + 'static,
279    >(
280        listener: F,
281    ) -> crate::events::EventHandlerHandle {
282        Self::get_event_emitter()
283            .register_event_handler(listener)
284            .await
285    }
286
287    /// # Warning
288    /// This method will block the current thread if the lock is not available
289    fn blocking_register_event_handler<
290        F: Fn(crate::State, Arc<Self::Event>) -> Fut + Send + Sync + 'static,
291        Fut: Future<Output = Result<(), anyhow::Error>> + Send + 'static,
292    >(
293        listener: F,
294    ) -> crate::events::EventHandlerHandle {
295        Self::get_event_emitter().blocking_register_event_handler(listener)
296    }
297}
298
299type CreateHandlerResult<'a> =
300    Pin<Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>>;
301type CreateHandler<M> = dyn for<'a> Fn(
302        &'a mut <M as CreatableModel>::CreateOptions<'_>,
303        &'a mut InsertQueryBuilder,
304        &'a crate::State,
305        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
306    ) -> CreateHandlerResult<'a>
307    + Send
308    + Sync;
309type CreateAfterHandler<M> = dyn for<'a> Fn(
310        &'a mut <M as CreatableModel>::CreateResult,
311        &'a <M as CreatableModel>::CreateOptions<'_>,
312        &'a crate::State,
313        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
314    ) -> CreateHandlerResult<'a>
315    + Send
316    + Sync;
317pub type CreateListenerList<M> =
318    Arc<ModelHandlerList<Box<CreateHandler<M>>, Box<CreateAfterHandler<M>>>>;
319
320#[async_trait::async_trait]
321pub trait CreatableModel: BaseModel + Send + Sync + 'static {
322    type CreateOptions<'a>: Send + Sync + Validate;
323    type CreateResult: Send;
324
325    fn get_create_handlers() -> &'static LazyLock<CreateListenerList<Self>>;
326
327    async fn register_create_handler<
328        F: for<'a> Fn(
329                &'a mut Self::CreateOptions<'_>,
330                &'a mut InsertQueryBuilder,
331                &'a crate::State,
332                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
333            ) -> Pin<
334                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
335            > + Send
336            + Sync
337            + 'static,
338    >(
339        priority: ListenerPriority,
340        callback: F,
341    ) {
342        let erased = Box::new(callback) as Box<CreateHandler<Self>>;
343
344        Self::get_create_handlers()
345            .register_handler(priority, erased)
346            .await;
347    }
348
349    async fn register_after_create_handler<
350        F: for<'a> Fn(
351                &'a mut Self::CreateResult,
352                &'a Self::CreateOptions<'_>,
353                &'a crate::State,
354                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
355            ) -> Pin<
356                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
357            > + Send
358            + Sync
359            + 'static,
360    >(
361        priority: ListenerPriority,
362        callback: F,
363    ) {
364        let erased = Box::new(callback) as Box<CreateAfterHandler<Self>>;
365
366        Self::get_create_handlers()
367            .register_after_handler(priority, erased)
368            .await;
369    }
370
371    /// # Warning
372    /// This method will block the current thread if the lock is not available
373    fn blocking_register_create_handler<
374        F: for<'a> Fn(
375                &'a mut Self::CreateOptions<'_>,
376                &'a mut InsertQueryBuilder,
377                &'a crate::State,
378                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
379            ) -> Pin<
380                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
381            > + Send
382            + Sync
383            + 'static,
384    >(
385        priority: ListenerPriority,
386        callback: F,
387    ) {
388        let erased = Box::new(callback) as Box<CreateHandler<Self>>;
389
390        Self::get_create_handlers().blocking_register_handler(priority, erased);
391    }
392
393    /// # Warning
394    /// This method will block the current thread if the lock is not available
395    fn blocking_register_after_create_handler<
396        F: for<'a> Fn(
397                &'a mut Self::CreateResult,
398                &'a Self::CreateOptions<'_>,
399                &'a crate::State,
400                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
401            ) -> Pin<
402                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
403            > + Send
404            + Sync
405            + 'static,
406    >(
407        priority: ListenerPriority,
408        callback: F,
409    ) {
410        let erased = Box::new(callback) as Box<CreateAfterHandler<Self>>;
411
412        Self::get_create_handlers().blocking_register_after_handler(priority, erased);
413    }
414
415    async fn run_create_handlers(
416        options: &mut Self::CreateOptions<'_>,
417        query_builder: &mut InsertQueryBuilder,
418        state: &crate::State,
419        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
420    ) -> Result<(), crate::database::DatabaseError> {
421        let listeners = Self::get_create_handlers().before_handlers.read().await;
422
423        for listener in listeners.iter() {
424            (*listener.callback)(options, query_builder, state, transaction).await?;
425        }
426
427        Ok(())
428    }
429
430    async fn run_after_create_handlers(
431        result: &mut Self::CreateResult,
432        options: &Self::CreateOptions<'_>,
433        state: &crate::State,
434        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
435    ) -> Result<(), crate::database::DatabaseError> {
436        let listeners = Self::get_create_handlers().after_handlers.read().await;
437
438        for listener in listeners.iter() {
439            (*listener.callback)(result, options, state, transaction).await?;
440        }
441
442        Ok(())
443    }
444
445    async fn create_with_transaction(
446        state: &crate::State,
447        options: Self::CreateOptions<'_>,
448        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
449    ) -> Result<Self::CreateResult, crate::database::DatabaseError>;
450
451    async fn create(
452        state: &crate::State,
453        options: Self::CreateOptions<'_>,
454    ) -> Result<Self::CreateResult, crate::database::DatabaseError> {
455        let mut transaction = state.database.write().begin().await?;
456
457        let result = match Self::create_with_transaction(state, options, &mut transaction).await {
458            Ok(result) => result,
459            Err(err) => {
460                transaction.rollback().await?;
461                return Err(err);
462            }
463        };
464
465        transaction.commit().await?;
466
467        Ok(result)
468    }
469}
470
471type UpdateHandlerResult<'a> =
472    Pin<Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>>;
473type UpdateHandler<M> = dyn for<'a> Fn(
474        &'a mut M,
475        &'a mut <M as UpdatableModel>::UpdateOptions,
476        &'a mut UpdateQueryBuilder,
477        &'a crate::State,
478        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
479    ) -> UpdateHandlerResult<'a>
480    + Send
481    + Sync;
482type UpdateAfterHandler<M> = dyn for<'a> Fn(
483        &'a mut M,
484        &'a crate::State,
485        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
486    ) -> UpdateHandlerResult<'a>
487    + Send
488    + Sync;
489pub type UpdateHandlerList<M> =
490    Arc<ModelHandlerList<Box<UpdateHandler<M>>, Box<UpdateAfterHandler<M>>>>;
491
492#[async_trait::async_trait]
493pub trait UpdatableModel: BaseModel + Send + Sync + 'static {
494    type UpdateOptions: Send + Sync + Default + ToSchema + DeserializeOwned + Serialize + Validate;
495
496    fn get_update_handlers() -> &'static LazyLock<UpdateHandlerList<Self>>;
497
498    async fn register_update_handler<
499        F: for<'a> Fn(
500                &'a mut Self,
501                &'a mut Self::UpdateOptions,
502                &'a mut UpdateQueryBuilder,
503                &'a crate::State,
504                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
505            ) -> Pin<
506                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
507            > + Send
508            + Sync
509            + 'static,
510    >(
511        priority: ListenerPriority,
512        callback: F,
513    ) {
514        let erased = Box::new(callback) as Box<UpdateHandler<Self>>;
515
516        Self::get_update_handlers()
517            .register_handler(priority, erased)
518            .await;
519    }
520
521    async fn register_after_update_handler<
522        F: for<'a> Fn(
523                &'a mut Self,
524                &'a crate::State,
525                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
526            ) -> Pin<
527                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
528            > + Send
529            + Sync
530            + 'static,
531    >(
532        priority: ListenerPriority,
533        callback: F,
534    ) {
535        let erased = Box::new(callback) as Box<UpdateAfterHandler<Self>>;
536
537        Self::get_update_handlers()
538            .register_after_handler(priority, erased)
539            .await;
540    }
541
542    /// # Warning
543    /// This method will block the current thread if the lock is not available
544    fn blocking_register_update_handler<
545        F: for<'a> Fn(
546                &'a mut Self,
547                &'a mut Self::UpdateOptions,
548                &'a mut UpdateQueryBuilder,
549                &'a crate::State,
550                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
551            ) -> Pin<
552                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
553            > + Send
554            + Sync
555            + 'static,
556    >(
557        priority: ListenerPriority,
558        callback: F,
559    ) {
560        let erased = Box::new(callback) as Box<UpdateHandler<Self>>;
561
562        Self::get_update_handlers().blocking_register_handler(priority, erased);
563    }
564
565    /// # Warning
566    /// This method will block the current thread if the lock is not available
567    fn blocking_register_after_update_handler<
568        F: for<'a> Fn(
569                &'a mut Self,
570                &'a crate::State,
571                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
572            ) -> Pin<
573                Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>,
574            > + Send
575            + Sync
576            + 'static,
577    >(
578        priority: ListenerPriority,
579        callback: F,
580    ) {
581        let erased = Box::new(callback) as Box<UpdateAfterHandler<Self>>;
582
583        Self::get_update_handlers().blocking_register_after_handler(priority, erased);
584    }
585
586    async fn run_update_handlers(
587        &mut self,
588        options: &mut Self::UpdateOptions,
589        query_builder: &mut UpdateQueryBuilder,
590        state: &crate::State,
591        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
592    ) -> Result<(), crate::database::DatabaseError> {
593        let listeners = Self::get_update_handlers().before_handlers.read().await;
594
595        for listener in listeners.iter() {
596            (*listener.callback)(self, options, query_builder, state, transaction).await?;
597        }
598
599        Ok(())
600    }
601
602    async fn run_after_update_handlers(
603        &mut self,
604        state: &crate::State,
605        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
606    ) -> Result<(), crate::database::DatabaseError> {
607        let listeners = Self::get_update_handlers().after_handlers.read().await;
608
609        for listener in listeners.iter() {
610            (*listener.callback)(self, state, transaction).await?;
611        }
612
613        Ok(())
614    }
615
616    async fn update_with_transaction(
617        &mut self,
618        state: &crate::State,
619        options: Self::UpdateOptions,
620        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
621    ) -> Result<(), crate::database::DatabaseError>;
622
623    async fn update(
624        &mut self,
625        state: &crate::State,
626        options: Self::UpdateOptions,
627    ) -> Result<(), crate::database::DatabaseError> {
628        let mut transaction = state.database.write().begin().await?;
629
630        if let Err(err) = self
631            .update_with_transaction(state, options, &mut transaction)
632            .await
633        {
634            transaction.rollback().await?;
635            return Err(err);
636        }
637
638        transaction.commit().await?;
639
640        Ok(())
641    }
642}
643
644type DeleteHandlerResult<'a> = Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + Send + 'a>>;
645type DeleteHandler<M> = dyn for<'a> Fn(
646        &'a M,
647        &'a <M as DeletableModel>::DeleteOptions,
648        &'a crate::State,
649        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
650    ) -> DeleteHandlerResult<'a>
651    + Send
652    + Sync;
653type DeleteAfterHandler<M> = dyn for<'a> Fn(
654        &'a M,
655        &'a <M as DeletableModel>::DeleteOptions,
656        &'a crate::State,
657        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
658    ) -> DeleteHandlerResult<'a>
659    + Send
660    + Sync;
661pub type DeleteHandlerList<M> =
662    Arc<ModelHandlerList<Box<DeleteHandler<M>>, Box<DeleteAfterHandler<M>>>>;
663
664#[async_trait::async_trait]
665pub trait DeletableModel: BaseModel + Send + Sync + 'static {
666    type DeleteOptions: Send + Sync + Default + Clone;
667
668    fn get_delete_handlers() -> &'static LazyLock<DeleteHandlerList<Self>>;
669
670    async fn register_delete_handler<
671        F: for<'a> Fn(
672                &'a Self,
673                &'a Self::DeleteOptions,
674                &'a crate::State,
675                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
676            )
677                -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + Send + 'a>>
678            + Send
679            + Sync
680            + 'static,
681    >(
682        priority: ListenerPriority,
683        callback: F,
684    ) {
685        let erased = Box::new(callback) as Box<DeleteHandler<Self>>;
686
687        Self::get_delete_handlers()
688            .register_handler(priority, erased)
689            .await;
690    }
691
692    async fn register_after_delete_handler<
693        F: for<'a> Fn(
694                &'a Self,
695                &'a Self::DeleteOptions,
696                &'a crate::State,
697                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
698            )
699                -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + Send + 'a>>
700            + Send
701            + Sync
702            + 'static,
703    >(
704        priority: ListenerPriority,
705        callback: F,
706    ) {
707        let erased = Box::new(callback) as Box<DeleteAfterHandler<Self>>;
708
709        Self::get_delete_handlers()
710            .register_after_handler(priority, erased)
711            .await;
712    }
713
714    /// # Warning
715    /// This method will block the current thread if the lock is not available
716    fn blocking_register_delete_handler<
717        F: for<'a> Fn(
718                &'a Self,
719                &'a Self::DeleteOptions,
720                &'a crate::State,
721                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
722            )
723                -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + Send + 'a>>
724            + Send
725            + Sync
726            + 'static,
727    >(
728        priority: ListenerPriority,
729        callback: F,
730    ) {
731        let erased = Box::new(callback) as Box<DeleteHandler<Self>>;
732
733        Self::get_delete_handlers().blocking_register_handler(priority, erased);
734    }
735
736    /// # Warning
737    /// This method will block the current thread if the lock is not available
738    fn blocking_register_after_delete_handler<
739        F: for<'a> Fn(
740                &'a Self,
741                &'a Self::DeleteOptions,
742                &'a crate::State,
743                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
744            )
745                -> Pin<Box<dyn Future<Output = Result<(), anyhow::Error>> + Send + 'a>>
746            + Send
747            + Sync
748            + 'static,
749    >(
750        priority: ListenerPriority,
751        callback: F,
752    ) {
753        let erased = Box::new(callback) as Box<DeleteAfterHandler<Self>>;
754
755        Self::get_delete_handlers().blocking_register_after_handler(priority, erased);
756    }
757
758    async fn run_delete_handlers(
759        &self,
760        options: &Self::DeleteOptions,
761        state: &crate::State,
762        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
763    ) -> Result<(), anyhow::Error> {
764        let listeners = Self::get_delete_handlers().before_handlers.read().await;
765
766        for listener in listeners.iter() {
767            (*listener.callback)(self, options, state, transaction).await?;
768        }
769
770        Ok(())
771    }
772
773    async fn run_after_delete_handlers(
774        &self,
775        options: &Self::DeleteOptions,
776        state: &crate::State,
777        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
778    ) -> Result<(), anyhow::Error> {
779        let listeners = Self::get_delete_handlers().after_handlers.read().await;
780
781        for listener in listeners.iter() {
782            (*listener.callback)(self, options, state, transaction).await?;
783        }
784
785        Ok(())
786    }
787
788    async fn delete_with_transaction(
789        &self,
790        state: &crate::State,
791        options: Self::DeleteOptions,
792        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
793    ) -> Result<(), anyhow::Error>;
794
795    async fn delete(
796        &self,
797        state: &crate::State,
798        options: Self::DeleteOptions,
799    ) -> Result<(), anyhow::Error> {
800        let mut transaction = state.database.write().begin().await?;
801
802        if let Err(err) = self
803            .delete_with_transaction(state, options, &mut transaction)
804            .await
805        {
806            transaction.rollback().await?;
807            return Err(err);
808        }
809
810        transaction.commit().await?;
811
812        Ok(())
813    }
814}
815
816type DuplicateHandlerResult<'a> =
817    Pin<Box<dyn Future<Output = Result<(), crate::database::DatabaseError>> + Send + 'a>>;
818type DuplicateHandler<M> = dyn for<'a> Fn(
819        &'a M,
820        &'a <M as DuplicableModel>::DuplicateOptions<'_>,
821        &'a crate::State,
822        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
823    ) -> DuplicateHandlerResult<'a>
824    + Send
825    + Sync;
826type DuplicateAfterHandler<M> = dyn for<'a> Fn(
827        &'a M,
828        &'a mut M,
829        &'a <M as DuplicableModel>::DuplicateOptions<'_>,
830        &'a crate::State,
831        &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
832    ) -> DuplicateHandlerResult<'a>
833    + Send
834    + Sync;
835pub type DuplicateHandlerList<M> =
836    Arc<ModelHandlerList<Box<DuplicateHandler<M>>, Box<DuplicateAfterHandler<M>>>>;
837
838#[async_trait::async_trait]
839pub trait DuplicableModel: BaseModel + Send + Sync + 'static {
840    type DuplicateOptions<'a>: Send + Sync + Validate;
841
842    fn get_duplicate_handlers() -> &'static LazyLock<DuplicateHandlerList<Self>>;
843
844    async fn register_duplicate_handler<
845        F: for<'a> Fn(
846                &'a Self,
847                &'a Self::DuplicateOptions<'_>,
848                &'a crate::State,
849                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
850            ) -> DuplicateHandlerResult<'a>
851            + Send
852            + Sync
853            + 'static,
854    >(
855        priority: ListenerPriority,
856        callback: F,
857    ) {
858        let erased = Box::new(callback) as Box<DuplicateHandler<Self>>;
859
860        Self::get_duplicate_handlers()
861            .register_handler(priority, erased)
862            .await;
863    }
864
865    async fn register_after_duplicate_handler<
866        F: for<'a> Fn(
867                &'a Self,
868                &'a mut Self,
869                &'a Self::DuplicateOptions<'_>,
870                &'a crate::State,
871                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
872            ) -> DuplicateHandlerResult<'a>
873            + Send
874            + Sync
875            + 'static,
876    >(
877        priority: ListenerPriority,
878        callback: F,
879    ) {
880        let erased = Box::new(callback) as Box<DuplicateAfterHandler<Self>>;
881
882        Self::get_duplicate_handlers()
883            .register_after_handler(priority, erased)
884            .await;
885    }
886
887    /// # Warning
888    /// This method will block the current thread if the lock is not available
889    fn blocking_register_duplicate_handler<
890        F: for<'a> Fn(
891                &'a Self,
892                &'a Self::DuplicateOptions<'_>,
893                &'a crate::State,
894                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
895            ) -> DuplicateHandlerResult<'a>
896            + Send
897            + Sync
898            + 'static,
899    >(
900        priority: ListenerPriority,
901        callback: F,
902    ) {
903        let erased = Box::new(callback) as Box<DuplicateHandler<Self>>;
904
905        Self::get_duplicate_handlers().blocking_register_handler(priority, erased);
906    }
907
908    /// # Warning
909    /// This method will block the current thread if the lock is not available
910    fn blocking_register_after_duplicate_handler<
911        F: for<'a> Fn(
912                &'a Self,
913                &'a mut Self,
914                &'a Self::DuplicateOptions<'_>,
915                &'a crate::State,
916                &'a mut sqlx::Transaction<'_, sqlx::Postgres>,
917            ) -> DuplicateHandlerResult<'a>
918            + Send
919            + Sync
920            + 'static,
921    >(
922        priority: ListenerPriority,
923        callback: F,
924    ) {
925        let erased = Box::new(callback) as Box<DuplicateAfterHandler<Self>>;
926
927        Self::get_duplicate_handlers().blocking_register_after_handler(priority, erased);
928    }
929
930    async fn run_duplicate_handlers(
931        &self,
932        options: &Self::DuplicateOptions<'_>,
933        state: &crate::State,
934        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
935    ) -> Result<(), crate::database::DatabaseError> {
936        let listeners = Self::get_duplicate_handlers().before_handlers.read().await;
937
938        for listener in listeners.iter() {
939            (*listener.callback)(self, options, state, transaction).await?;
940        }
941
942        Ok(())
943    }
944
945    async fn run_after_duplicate_handlers(
946        &self,
947        duplicated: &mut Self,
948        options: &Self::DuplicateOptions<'_>,
949        state: &crate::State,
950        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
951    ) -> Result<(), crate::database::DatabaseError> {
952        let listeners = Self::get_duplicate_handlers().after_handlers.read().await;
953
954        for listener in listeners.iter() {
955            (*listener.callback)(self, duplicated, options, state, transaction).await?;
956        }
957
958        Ok(())
959    }
960
961    async fn duplicate_with_transaction(
962        &self,
963        state: &crate::State,
964        options: Self::DuplicateOptions<'_>,
965        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
966    ) -> Result<Self, crate::database::DatabaseError>;
967
968    async fn duplicate(
969        &self,
970        state: &crate::State,
971        options: Self::DuplicateOptions<'_>,
972    ) -> Result<Self, crate::database::DatabaseError> {
973        let mut transaction = state.database.write().begin().await?;
974
975        let duplicated = match self
976            .duplicate_with_transaction(state, options, &mut transaction)
977            .await
978        {
979            Ok(duplicated) => duplicated,
980            Err(err) => {
981                transaction.rollback().await?;
982                return Err(err);
983            }
984        };
985
986        transaction.commit().await?;
987
988        Ok(duplicated)
989    }
990}
991
992#[async_trait::async_trait]
993pub trait ByUuid: BaseModel {
994    async fn by_uuid(
995        database: &crate::database::Database,
996        uuid: uuid::Uuid,
997    ) -> Result<Self, DatabaseError>;
998
999    async fn by_uuid_with_transaction(
1000        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
1001        uuid: uuid::Uuid,
1002    ) -> Result<Self, DatabaseError>;
1003
1004    async fn by_uuid_cached(
1005        database: &crate::database::Database,
1006        uuid: uuid::Uuid,
1007    ) -> Result<Self, anyhow::Error> {
1008        database
1009            .cache
1010            .cached(&format!("{}::{uuid}", Self::NAME), 10, || {
1011                Self::by_uuid(database, uuid)
1012            })
1013            .await
1014    }
1015
1016    async fn by_uuid_optional(
1017        database: &crate::database::Database,
1018        uuid: uuid::Uuid,
1019    ) -> Result<Option<Self>, DatabaseError> {
1020        match Self::by_uuid(database, uuid).await {
1021            Ok(res) => Ok(Some(res)),
1022            Err(DatabaseError::Sqlx(sqlx::Error::RowNotFound)) => Ok(None),
1023            Err(err) => Err(err),
1024        }
1025    }
1026
1027    async fn by_uuid_optional_with_transaction(
1028        transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
1029        uuid: uuid::Uuid,
1030    ) -> Result<Option<Self>, DatabaseError> {
1031        match Self::by_uuid_with_transaction(transaction, uuid).await {
1032            Ok(res) => Ok(Some(res)),
1033            Err(DatabaseError::Sqlx(sqlx::Error::RowNotFound)) => Ok(None),
1034            Err(err) => Err(err),
1035        }
1036    }
1037
1038    async fn by_uuid_optional_cached(
1039        database: &crate::database::Database,
1040        uuid: uuid::Uuid,
1041    ) -> Result<Option<Self>, anyhow::Error> {
1042        match Self::by_uuid_cached(database, uuid).await {
1043            Ok(res) => Ok(Some(res)),
1044            Err(err) => {
1045                if let Some(DatabaseError::Sqlx(sqlx::Error::RowNotFound)) =
1046                    err.downcast_ref::<DatabaseError>()
1047                {
1048                    Ok(None)
1049                } else {
1050                    Err(err)
1051                }
1052            }
1053        }
1054    }
1055
1056    #[inline]
1057    fn get_fetchable(uuid: uuid::Uuid) -> Fetchable<Self> {
1058        Fetchable {
1059            uuid,
1060            _model: PhantomData,
1061        }
1062    }
1063
1064    #[inline]
1065    fn get_fetchable_from_row(row: &PgRow, column: impl AsRef<str>) -> Option<Fetchable<Self>> {
1066        match row.try_get(column.as_ref()) {
1067            Ok(uuid) => Some(Fetchable {
1068                uuid,
1069                _model: PhantomData,
1070            }),
1071            Err(_) => None,
1072        }
1073    }
1074}
1075
1076#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
1077pub enum ListenerPriority {
1078    Highest,
1079    High,
1080    #[default]
1081    Normal,
1082    Low,
1083    Lowest,
1084}
1085
1086impl ListenerPriority {
1087    #[inline]
1088    fn rank(self) -> u8 {
1089        match self {
1090            Self::Highest => 5,
1091            Self::High => 4,
1092            Self::Normal => 3,
1093            Self::Low => 2,
1094            Self::Lowest => 1,
1095        }
1096    }
1097}
1098
1099impl PartialOrd for ListenerPriority {
1100    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
1101        Some(self.cmp(other))
1102    }
1103}
1104
1105impl Ord for ListenerPriority {
1106    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
1107        let self_rank = self.rank();
1108        let other_rank = other.rank();
1109
1110        other_rank.cmp(&self_rank)
1111    }
1112}
1113
1114#[async_trait::async_trait]
1115impl<F: Send + Sync, AfterF: Send + Sync> crate::events::DisconnectEventHandler
1116    for ModelHandlerList<F, AfterF>
1117{
1118    #[inline]
1119    async fn disconnect(&self, id: uuid::Uuid) {
1120        self.before_handlers.write().await.retain(|l| l.uuid != id);
1121        self.after_handlers.write().await.retain(|l| l.uuid != id);
1122    }
1123
1124    #[inline]
1125    fn blocking_disconnect(&self, id: uuid::Uuid) {
1126        self.before_handlers
1127            .blocking_write()
1128            .retain(|l| l.uuid != id);
1129        self.after_handlers
1130            .blocking_write()
1131            .retain(|l| l.uuid != id);
1132    }
1133}
1134
1135pub struct ModelHandlerList<F: Send + Sync + 'static, AfterF: Send + Sync + 'static> {
1136    before_handlers: RwLock<Vec<ModelHandler<F>>>,
1137    after_handlers: RwLock<Vec<ModelHandler<AfterF>>>,
1138}
1139
1140impl<F: Send + Sync + 'static, AfterF: Send + Sync + 'static> Default
1141    for ModelHandlerList<F, AfterF>
1142{
1143    fn default() -> Self {
1144        Self {
1145            before_handlers: RwLock::new(Vec::new()),
1146            after_handlers: RwLock::new(Vec::new()),
1147        }
1148    }
1149}
1150
1151impl<F: Send + Sync + 'static, AfterF: Send + Sync + 'static> ModelHandlerList<F, AfterF> {
1152    pub async fn register_handler(
1153        self: &Arc<Self>,
1154        priority: ListenerPriority,
1155        callback: F,
1156    ) -> ModelHandlerHandle {
1157        let (listener, aborter) = ModelHandler::new(callback, priority, self.clone());
1158
1159        let mut self_listeners = self.before_handlers.write().await;
1160        self_listeners.push(listener);
1161        self_listeners.sort_by_key(|a| a.priority);
1162
1163        aborter
1164    }
1165
1166    pub async fn register_after_handler(
1167        self: &Arc<Self>,
1168        priority: ListenerPriority,
1169        callback: AfterF,
1170    ) -> ModelHandlerHandle {
1171        let (listener, aborter) = ModelHandler::new(callback, priority, self.clone());
1172
1173        let mut self_listeners = self.after_handlers.write().await;
1174        self_listeners.push(listener);
1175        self_listeners.sort_by_key(|a| a.priority);
1176
1177        aborter
1178    }
1179
1180    /// # Warning
1181    /// This method will block the current thread if the lock is not available
1182    pub fn blocking_register_handler(
1183        self: &Arc<Self>,
1184        priority: ListenerPriority,
1185        callback: F,
1186    ) -> ModelHandlerHandle {
1187        let (listener, aborter) = ModelHandler::new(callback, priority, self.clone());
1188
1189        let mut self_listeners = self.before_handlers.blocking_write();
1190        self_listeners.push(listener);
1191        self_listeners.sort_by_key(|a| a.priority);
1192
1193        aborter
1194    }
1195
1196    /// # Warning
1197    /// This method will block the current thread if the lock is not available
1198    pub fn blocking_register_after_handler(
1199        self: &Arc<Self>,
1200        priority: ListenerPriority,
1201        callback: AfterF,
1202    ) -> ModelHandlerHandle {
1203        let (listener, aborter) = ModelHandler::new(callback, priority, self.clone());
1204
1205        let mut self_listeners = self.after_handlers.blocking_write();
1206        self_listeners.push(listener);
1207        self_listeners.sort_by_key(|a| a.priority);
1208
1209        aborter
1210    }
1211}
1212
1213pub struct ModelHandler<F: Send + Sync + 'static> {
1214    uuid: uuid::Uuid,
1215    priority: ListenerPriority,
1216
1217    pub callback: F,
1218}
1219
1220impl<F: Send + Sync + 'static> ModelHandler<F> {
1221    pub(crate) fn new(
1222        callback: F,
1223        priority: ListenerPriority,
1224        list: Arc<dyn crate::events::DisconnectEventHandler + Send + Sync>,
1225    ) -> (Self, ModelHandlerHandle) {
1226        let handler = Self {
1227            uuid: uuid::Uuid::new_v4(),
1228            priority,
1229            callback,
1230        };
1231        let handle = ModelHandlerHandle {
1232            list_ref: list,
1233            id: handler.uuid,
1234        };
1235        (handler, handle)
1236    }
1237}
1238
1239pub struct ModelHandlerHandle {
1240    list_ref: Arc<dyn crate::events::DisconnectEventHandler + Send + Sync>,
1241    id: uuid::Uuid,
1242}
1243
1244impl ModelHandlerHandle {
1245    pub async fn disconnect(&self) {
1246        self.list_ref.disconnect(self.id).await;
1247    }
1248
1249    /// # Warning
1250    /// This method will block the current thread if the lists' lock is not available
1251    pub fn blocking_disconnect(&self) {
1252        self.list_ref.blocking_disconnect(self.id);
1253    }
1254}
1255
1256#[derive(Serialize, Deserialize, Clone, Copy)]
1257pub struct Fetchable<M: ByUuid> {
1258    pub uuid: uuid::Uuid,
1259    #[serde(skip)]
1260    _model: PhantomData<M>,
1261}
1262
1263impl<M: ByUuid + Send> Fetchable<M> {
1264    #[inline]
1265    pub async fn fetch(&self, database: &crate::database::Database) -> Result<M, DatabaseError> {
1266        M::by_uuid(database, self.uuid).await
1267    }
1268
1269    #[inline]
1270    pub async fn fetch_cached(
1271        &self,
1272        database: &crate::database::Database,
1273    ) -> Result<M, anyhow::Error> {
1274        M::by_uuid_cached(database, self.uuid).await
1275    }
1276
1277    #[inline]
1278    pub async fn fetch_optional(
1279        &self,
1280        database: &crate::database::Database,
1281    ) -> Result<Option<M>, DatabaseError> {
1282        M::by_uuid_optional(database, self.uuid).await
1283    }
1284
1285    #[inline]
1286    pub async fn fetch_optional_cached(
1287        &self,
1288        database: &crate::database::Database,
1289    ) -> Result<Option<M>, anyhow::Error> {
1290        M::by_uuid_optional_cached(database, self.uuid).await
1291    }
1292}
1293
1294pub struct InsertQueryBuilder<'a> {
1295    table: &'a str,
1296    columns: Vec<&'a str>,
1297    expressions: Vec<String>,
1298    arguments: PgArguments,
1299    returning_clause: Option<&'a str>,
1300}
1301
1302impl<'a> InsertQueryBuilder<'a> {
1303    pub fn new(table: &'a str) -> Self {
1304        Self {
1305            table,
1306            columns: Vec::new(),
1307            expressions: Vec::new(),
1308            arguments: PgArguments::default(),
1309            returning_clause: None,
1310        }
1311    }
1312
1313    pub fn set<T: 'a + sqlx::Encode<'a, Postgres> + sqlx::Type<Postgres> + Send>(
1314        &mut self,
1315        column: &'a str,
1316        value: T,
1317    ) -> &mut Self {
1318        if self.columns.contains(&column) {
1319            return self;
1320        }
1321
1322        if self.arguments.add(value).is_ok() {
1323            self.columns.push(column);
1324            let idx = self.arguments.len();
1325            self.expressions.push(format!("${}", idx));
1326        }
1327
1328        self
1329    }
1330
1331    pub fn set_expr<T: 'a + sqlx::Encode<'a, Postgres> + sqlx::Type<Postgres> + Send>(
1332        &mut self,
1333        column: &'a str,
1334        expression: &str,
1335        values: Vec<T>,
1336    ) -> &mut Self {
1337        if self.columns.contains(&column) {
1338            return self;
1339        }
1340
1341        let start_len = self.arguments.len();
1342
1343        for value in values {
1344            if self.arguments.add(value).is_err() {
1345                return self;
1346            }
1347        }
1348
1349        let mut expr = expression.to_string();
1350        let added_count = self.arguments.len() - start_len;
1351
1352        for i in (1..=added_count).rev() {
1353            let global_idx = start_len + i;
1354            expr = expr.replace(&format!("${}", i), &format!("${}", global_idx));
1355        }
1356
1357        self.columns.push(column);
1358        self.expressions.push(expr);
1359
1360        self
1361    }
1362
1363    pub fn returning(mut self, clause: &'a str) -> Self {
1364        self.returning_clause = Some(clause);
1365        self
1366    }
1367
1368    fn build_sql(&self) -> String {
1369        let columns_sql = self.columns.join(", ");
1370        let values_sql = self.expressions.join(", ");
1371
1372        let mut sql = format!(
1373            "INSERT INTO {} ({}) VALUES ({})",
1374            self.table, columns_sql, values_sql
1375        );
1376
1377        if let Some(clause) = self.returning_clause {
1378            sql.push_str(" RETURNING ");
1379            sql.push_str(clause);
1380        }
1381
1382        sql
1383    }
1384
1385    pub async fn execute(
1386        self,
1387        executor: impl sqlx::Executor<'a, Database = Postgres>,
1388    ) -> Result<sqlx::postgres::PgQueryResult, sqlx::Error> {
1389        let sql = self.build_sql();
1390        sqlx::query_with(sqlx::AssertSqlSafe(sql), self.arguments)
1391            .execute(executor)
1392            .await
1393    }
1394
1395    pub async fn fetch_one(
1396        self,
1397        executor: impl sqlx::Executor<'a, Database = Postgres>,
1398    ) -> Result<sqlx::postgres::PgRow, sqlx::Error> {
1399        let sql = self.build_sql();
1400        sqlx::query_with(sqlx::AssertSqlSafe(sql), self.arguments)
1401            .fetch_one(executor)
1402            .await
1403    }
1404}
1405
1406pub struct UpdateQueryBuilder<'a> {
1407    builder: QueryBuilder<Postgres>,
1408    updated_fields: HashSet<&'a str>,
1409    has_set_fields: bool,
1410    has_where: bool,
1411}
1412
1413impl<'a> UpdateQueryBuilder<'a> {
1414    pub fn new(table: &'a str) -> Self {
1415        let mut builder = QueryBuilder::new("UPDATE ");
1416        builder.push(table);
1417        builder.push(" SET ");
1418
1419        Self {
1420            builder,
1421            updated_fields: HashSet::new(),
1422            has_set_fields: false,
1423            has_where: false,
1424        }
1425    }
1426
1427    /// Adds a field to be updated, if `None`, will not add the field
1428    /// To set a field to null (`None`), you need a `Some(None)`
1429    pub fn set<T: 'a + sqlx::Encode<'a, Postgres> + sqlx::Type<Postgres> + Send>(
1430        &mut self,
1431        column: &'a str,
1432        value: Option<T>,
1433    ) -> &mut Self {
1434        let Some(value) = value else {
1435            return self;
1436        };
1437
1438        if !self.updated_fields.insert(column) {
1439            return self;
1440        }
1441
1442        if self.has_set_fields {
1443            self.builder.push(", ");
1444        }
1445
1446        self.builder.push(column);
1447        self.builder.push(" = ");
1448        self.builder.push_bind(value);
1449
1450        self.has_set_fields = true;
1451        self
1452    }
1453
1454    pub fn where_eq<T: 'a + sqlx::Encode<'a, Postgres> + sqlx::Type<Postgres> + Send>(
1455        &mut self,
1456        column: &'a str,
1457        value: T,
1458    ) -> &mut Self {
1459        if self.has_where {
1460            self.builder.push(" AND ");
1461        } else {
1462            self.builder.push(" WHERE ");
1463            self.has_where = true;
1464        }
1465
1466        self.builder.push(column);
1467        self.builder.push(" = ");
1468        self.builder.push_bind(value);
1469        self
1470    }
1471
1472    pub async fn execute(
1473        mut self,
1474        executor: impl sqlx::Executor<'a, Database = Postgres>,
1475    ) -> Result<sqlx::any::AnyQueryResult, sqlx::Error> {
1476        if !self.has_set_fields {
1477            return Ok(sqlx::any::AnyQueryResult::default());
1478        }
1479
1480        let query = self.builder.build();
1481        query.execute(executor).await.map(|r| r.into())
1482    }
1483}
1484
1485/// SQLx helper type to preserve order of keys when encoding JSON. By default, SQLx encodes JSON using `serde_json::Value`, which does not preserve order of keys. This type allows you to encode any serializable type as JSON while preserving the order of keys.
1486pub struct OrderedJson<T>(pub T);
1487
1488impl<T: Serialize> sqlx::Encode<'_, sqlx::Postgres> for OrderedJson<T> {
1489    fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
1490        serde_json::to_writer(&mut **buf, &self.0)?;
1491        Ok(IsNull::No)
1492    }
1493}
1494
1495impl<T> sqlx::Type<sqlx::Postgres> for OrderedJson<T> {
1496    fn type_info() -> PgTypeInfo {
1497        // JSON, not JSONB, to preserve order of keys
1498        PgTypeInfo::with_oid(sqlx::postgres::types::Oid(114))
1499    }
1500}
1501
1502#[async_trait::async_trait]
1503pub trait IntoApiObject {
1504    type ApiObject: Send;
1505    type ExtraArgs<'a>: Send;
1506
1507    async fn into_api_object<'a>(
1508        self,
1509        state: &crate::State,
1510        args: Self::ExtraArgs<'a>,
1511    ) -> Result<Self::ApiObject, DatabaseError>;
1512}
1513
1514#[async_trait::async_trait]
1515pub trait IntoAdminApiObject {
1516    type AdminApiObject: Send;
1517    type ExtraArgs<'a>: Send;
1518
1519    async fn into_admin_api_object<'a>(
1520        self,
1521        state: &crate::State,
1522        args: Self::ExtraArgs<'a>,
1523    ) -> Result<Self::AdminApiObject, DatabaseError>;
1524}