use anyhow::Result; use diesel::{ dsl::{auto_type, insert_into, AsSelect, Eq}, pg::Pg, prelude::*, }; use uuid::Uuid; use crate::{ channels::Channel, schema::{channel_selections, channels, projects}, teams::Team, }; pub const DEFAULT_PROJECT_NAME: &'static str = "default"; #[derive(Associations, Clone, Debug, Identifiable, Insertable, Queryable, Selectable)] #[diesel(table_name = projects)] #[diesel(belongs_to(Team))] pub struct Project { pub id: Uuid, pub team_id: Uuid, pub name: String, } impl Project { pub fn insert_new<'a>( db_conn: &mut diesel::PgConnection, team_id: &'a Uuid, name: &'a str, ) -> Result { let default_channels = Channel::all() .filter(Channel::with_team(team_id)) .filter(Channel::where_enabled_by_default()) .load(db_conn)?; let id: Uuid = Uuid::now_v7(); let project: Self = insert_into(projects::table) .values(( projects::id.eq(id), projects::team_id.eq(team_id), projects::name.eq(name), )) .get_result(db_conn)?; for channel in default_channels { insert_into(channel_selections::table) .values(( channel_selections::project_id.eq(&project.id), channel_selections::channel_id.eq(&channel.id), )) .execute(db_conn)?; } Ok(project) } #[auto_type(no_type_alias)] pub fn all() -> _ { let select: AsSelect = Project::as_select(); projects::table.select(select) } #[auto_type(no_type_alias)] pub fn with_id(project_id: Uuid) -> _ { projects::id.eq(project_id) } #[auto_type(no_type_alias)] pub fn with_team(team_id: Uuid) -> _ { projects::team_id.eq(team_id) } #[auto_type(no_type_alias)] pub fn with_name(name: String) -> _ { projects::name.eq(name) } #[auto_type(no_type_alias)] pub fn selected_channels(&self) -> _ { let select: AsSelect = Channel::as_select(); let project_filter: Eq = channel_selections::project_id.eq(self.id); channels::table .inner_join(channel_selections::table) .filter(project_filter) .select(select) } }