gitdataai/lib/service/git/star.rs

94 lines
2.9 KiB
Rust

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<serde_json::Value, AppError> {
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<serde_json::Value, AppError> {
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<serde_json::Value, AppError> {
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,
}))
}
}