use eyre::Result; use foxchat::FoxError; use sqlx::PgExecutor; use ulid::Ulid; pub struct Guild { pub id: String, pub owner_id: String, pub name: String, } pub async fn create_guild( executor: impl PgExecutor<'_>, owner_id: &str, name: &str, ) -> Result { let guild = sqlx::query_as!( Guild, "insert into guilds (id, owner_id, name) values ($1, $2, $3) returning *", Ulid::new().to_string(), owner_id, name ) .fetch_one(executor) .await?; Ok(guild) } pub async fn join_guild( executor: impl PgExecutor<'_>, guild_id: &str, user_id: &str, ) -> Result<()> { sqlx::query!( "insert into guilds_users (guild_id, user_id) values ($1, $2) on conflict (guild_id, user_id) do nothing", guild_id, user_id ) .execute(executor) .await?; Ok(()) } pub async fn get_guild( executor: impl PgExecutor<'_>, guild_id: &str, user_id: &str, ) -> Result { println!("guild id: {}, user id: {}", guild_id, user_id); let guild = sqlx::query_as!( Guild, "select g.* from guilds_users u join guilds g on u.guild_id = g.id where u.guild_id = $1 and u.user_id = $2", guild_id, user_id ) .fetch_one(executor) .await .map_err(|e| match e { sqlx::Error::RowNotFound => FoxError::NotInGuild, _ => { tracing::error!("database error: {}", e); return FoxError::DatabaseError; } })?; Ok(guild) }