use async_trait::async_trait; use sqlx::Executor; use sqlx::postgres::PgRow; use crate::{CoveDB, CoveDBImpl}; use crate::part::{BindQuery, BindQueryBuilder, SqlPart}; use crate::part::delete::SqlDelete; use crate::part::insert::SqlInsert; use crate::part::select::SqlSelect; use crate::part::sql_where::SqlWhere; pub mod attachment; pub mod channel; pub mod guild; pub mod guild_member; pub mod message; pub mod nonce; pub mod user; pub trait TableRow { type Error; type PartialRow: PartialTableRow; fn get_table_name() -> &'static str; } #[async_trait] pub trait PartialTableRow { type Error; type FullTableRow: TableRow; fn get_table_name() -> &'static str { Self::FullTableRow::get_table_name() } async fn get_full(&self, db: &CoveDB) -> Result where Self: SelectableRow + WhereRow, ::Error: From, Self::FullTableRow: TryFrom, <::FullTableRow as TryFrom>::Error: Into { let mut query_builder = BindQueryBuilder::new(); self.select(vec!["*"]).encode(&mut query_builder)?; let sql_where = self.where_all(); sql_where.encode(&mut query_builder)?; let query = self.bind(sql_where, query_builder.to_query())?; let out_full_row: Self::FullTableRow = db.get_pool() .fetch_one(query.sql_query).await.map_err(|e|e.into())? .try_into().map_err(|e: >::Error | e.into())?; Ok(out_full_row) } } pub trait InsertableRow: TableRow { fn insert(&'_ self) -> SqlInsert; fn bind<'a>(&'a self, query: BindQuery<'a>) -> Result, Self::Error>; } pub trait SelectableRow: PartialTableRow { fn select(&'_ self, selected_columns: Vec>) -> SqlSelect { let mut select = SqlSelect::with_table(Self::get_table_name()); for column in selected_columns { select.add_column(column); } select } } pub trait DeletableRow: PartialTableRow { fn delete(&'_ self) -> SqlDelete { SqlDelete::with_table(Self::get_table_name()) } } pub trait WhereRow: PartialTableRow { fn wheres(&'_ self, where_fn: impl Fn(SqlWhere) -> Result + Send + Sync) -> Result { let wheres = SqlWhere::new(); let wheres = where_fn(wheres)?; Ok(wheres) } fn where_all(&'_ self) -> SqlWhere; fn bind<'a>(&'a self, wheres: SqlWhere, query: BindQuery<'a>) -> Result, Self::Error>; }