103 lines
3.4 KiB
Rust
103 lines
3.4 KiB
Rust
use db::sqlx;
|
|
use session::Session;
|
|
|
|
use crate::{AppService, error::AppError, session_user};
|
|
|
|
impl AppService {
|
|
pub async fn git_repo_watch(
|
|
&self,
|
|
ctx: &Session,
|
|
wk_name: &str,
|
|
repo_name: &str,
|
|
level: Option<String>,
|
|
) -> Result<serde_json::Value, AppError> {
|
|
let user_uid = session_user(ctx)?;
|
|
let repo = self.git_require_member(ctx, wk_name, repo_name).await?;
|
|
let level = level.unwrap_or_else(|| "participating".to_string());
|
|
|
|
sqlx::query(
|
|
"INSERT INTO repo_watch (repo, \"user\", \"level\", created_at, updated_at) \
|
|
VALUES ($1, $2, $3, $4, $5) \
|
|
ON CONFLICT (repo, \"user\") DO UPDATE SET level = $3, updated_at = $5",
|
|
)
|
|
.bind(repo.id)
|
|
.bind(user_uid)
|
|
.bind(&level)
|
|
.bind(chrono::Utc::now())
|
|
.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_watch WHERE repo = $1")
|
|
.bind(repo.id)
|
|
.fetch_one(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
Ok(
|
|
serde_json::json!({ "watching": true, "count": count.0, "level": level }),
|
|
)
|
|
}
|
|
|
|
pub async fn git_repo_unwatch(
|
|
&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_watch 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_watch WHERE repo = $1")
|
|
.bind(repo.id)
|
|
.fetch_one(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
Ok(serde_json::json!({ "watching": false, "count": count.0 }))
|
|
}
|
|
|
|
pub async fn git_repo_watch_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 watch: Option<(bool, String)> = sqlx::query_as(
|
|
"SELECT EXISTS(SELECT 1 FROM repo_watch WHERE repo = $1 AND \"user\" = $2), \
|
|
COALESCE((SELECT level FROM repo_watch WHERE repo = $1 AND \"user\" = $2), '')",
|
|
)
|
|
.bind(repo.id)
|
|
.bind(user_uid)
|
|
.fetch_optional(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
let count: (i64,) =
|
|
sqlx::query_as("SELECT COUNT(*) FROM repo_watch WHERE repo = $1")
|
|
.bind(repo.id)
|
|
.fetch_one(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
Ok(serde_json::json!({
|
|
"watching": watch.as_ref().map(|(w, _)| *w).unwrap_or(false),
|
|
"count": count.0,
|
|
"level": watch.map(|(_, l)| l).unwrap_or_default(),
|
|
}))
|
|
}
|
|
}
|