use db::sqlx; use session::Session; use crate::{AppService, error::AppError, session_user}; impl AppService { pub async fn git_repo_star( &self, ctx: &Session, wk_name: &str, repo_name: &str, ) -> Result { let user_uid = session_user(ctx)?; let repo = self.git_require_member(ctx, wk_name, repo_name).await?; sqlx::query( "INSERT INTO repo_star (repo, \"user\", created_at) VALUES ($1, $2, $3) \ ON CONFLICT (repo, \"user\") DO NOTHING", ) .bind(repo.id) .bind(user_uid) .bind(chrono::Utc::now()) .execute(self.db.writer()) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; let count: (i64,) = sqlx::query_as( "SELECT COUNT(*) FROM repo_star WHERE repo = $1", ) .bind(repo.id) .fetch_one(self.db.reader()) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; Ok(serde_json::json!({ "starred": true, "count": count.0 })) } pub async fn git_repo_unstar( &self, ctx: &Session, wk_name: &str, repo_name: &str, ) -> Result { let user_uid = session_user(ctx)?; let repo = self.git_require_member(ctx, wk_name, repo_name).await?; sqlx::query( "DELETE FROM repo_star WHERE repo = $1 AND \"user\" = $2", ) .bind(repo.id) .bind(user_uid) .execute(self.db.writer()) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; let count: (i64,) = sqlx::query_as( "SELECT COUNT(*) FROM repo_star WHERE repo = $1", ) .bind(repo.id) .fetch_one(self.db.reader()) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; Ok(serde_json::json!({ "starred": false, "count": count.0 })) } pub async fn git_repo_star_status( &self, ctx: &Session, wk_name: &str, repo_name: &str, ) -> Result { let user_uid = session_user(ctx)?; let repo = self.git_require_member(ctx, wk_name, repo_name).await?; let exists: (bool,) = sqlx::query_as( "SELECT EXISTS(SELECT 1 FROM repo_star WHERE repo = $1 AND \"user\" = $2)", ) .bind(repo.id) .bind(user_uid) .fetch_one(self.db.reader()) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; let count: (i64,) = sqlx::query_as( "SELECT COUNT(*) FROM repo_star WHERE repo = $1", ) .bind(repo.id) .fetch_one(self.db.reader()) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; Ok(serde_json::json!({ "starred": exists.0, "count": count.0, })) } }