ddnet_account_sql/
query.rs

1use async_trait::async_trait;
2
3use crate::any::{AnyConnection, AnyQuery, AnyRow, AnyStatement};
4
5/// An interface for queries to allow converting them to various database implementations
6#[async_trait]
7pub trait Query<A> {
8    /// MySQL version of [`Query::prepare`].
9    #[cfg(feature = "mysql")]
10    async fn prepare_mysql(
11        connection: &mut sqlx::mysql::MySqlConnection,
12    ) -> anyhow::Result<sqlx::mysql::MySqlStatement<'static>>;
13
14    /// Sqlite version of [`Query::prepare`].
15    #[cfg(feature = "sqlite")]
16    async fn prepare_sqlite(
17        connection: &mut sqlx::sqlite::SqliteConnection,
18    ) -> anyhow::Result<sqlx::sqlite::SqliteStatement<'static>>;
19
20    /// Prepare a statement to be later used by [`Query::query`].
21    async fn prepare(connection: &mut AnyConnection) -> anyhow::Result<AnyStatement<'static>> {
22        Ok(match connection {
23            #[cfg(feature = "mysql")]
24            AnyConnection::MySql(connection) => {
25                AnyStatement::MySql(Self::prepare_mysql(connection).await?)
26            }
27            #[cfg(feature = "sqlite")]
28            AnyConnection::Sqlite(connection) => {
29                AnyStatement::Sqlite(Self::prepare_sqlite(connection).await?)
30            }
31        })
32    }
33
34    /// MySQL version of [`Query::query`].
35    #[cfg(feature = "mysql")]
36    fn query_mysql<'a>(
37        &'a self,
38        statement: &'a sqlx::mysql::MySqlStatement<'static>,
39    ) -> sqlx::query::Query<'a, sqlx::MySql, sqlx::mysql::MySqlArguments>;
40
41    /// Sqlite version of [`Query::query`].
42    #[cfg(feature = "sqlite")]
43    fn query_sqlite<'a>(
44        &'a self,
45        statement: &'a sqlx::sqlite::SqliteStatement<'static>,
46    ) -> sqlx::query::Query<'a, sqlx::Sqlite, sqlx::sqlite::SqliteArguments<'a>>;
47
48    /// Get a query with all arguments bound already, ready to be fetched.
49    fn query<'a>(&'a self, statement: &'a AnyStatement<'static>) -> AnyQuery<'a> {
50        match statement {
51            #[cfg(feature = "mysql")]
52            AnyStatement::MySql(statement) => AnyQuery::MySql(self.query_mysql(statement)),
53            #[cfg(feature = "sqlite")]
54            AnyStatement::Sqlite(statement) => AnyQuery::Sqlite(self.query_sqlite(statement)),
55        }
56    }
57
58    /// MySQL version of [`Query::row_data`].
59    #[cfg(feature = "mysql")]
60    fn row_data_mysql(row: &sqlx::mysql::MySqlRow) -> anyhow::Result<A>;
61
62    /// Sqlite version of [`Query::row_data`].
63    #[cfg(feature = "sqlite")]
64    fn row_data_sqlite(row: &sqlx::sqlite::SqliteRow) -> anyhow::Result<A>;
65
66    /// Gets the row data for a result row of this query
67    fn row_data(row: &AnyRow) -> anyhow::Result<A> {
68        match row {
69            #[cfg(feature = "mysql")]
70            AnyRow::MySql(row) => Self::row_data_mysql(row),
71            #[cfg(feature = "sqlite")]
72            AnyRow::Sqlite(row) => Self::row_data_sqlite(row),
73        }
74    }
75}