gitdataai/lib/service/pull_request/label.rs

101 lines
3.2 KiB
Rust

use db::sqlx;
use model::issues::LabelModel;
use serde::Deserialize;
use session::Session;
use uuid::Uuid;
use crate::{
AppService, error::AppError, issues::types::LabelResponse, session_user,
};
#[derive(Debug, Clone, Deserialize, utoipa::ToSchema)]
pub struct AddPrLabel {
pub label_id: Uuid,
}
impl AppService {
pub async fn pr_add_label(
&self,
ctx: &Session,
wk_name: &str,
repo_name: &str,
number: i64,
params: AddPrLabel,
) -> Result<Vec<LabelResponse>, AppError> {
let user_uid = session_user(ctx)?;
let wk = self.workspace_resolve(wk_name).await?;
self.workspace_require_member(wk.id, user_uid).await?;
let repo = self.repo_resolve(wk.id, repo_name).await?;
let pr = self.pr_resolve(repo.id, number).await?;
let _label = sqlx::query_as::<_, LabelModel>(
"SELECT id, wk, name, color, description, created_at, updated_at, deleted_at \
FROM label WHERE id = $1 AND wk = $2 AND deleted_at IS NULL",
)
.bind(params.label_id)
.bind(wk.id)
.fetch_optional(self.db.reader())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?
.ok_or(AppError::LabelNotFound)?;
sqlx::query(
"INSERT INTO pull_request_label (pull_request, label, created_at) VALUES ($1, $2, $3) \
ON CONFLICT (pull_request, label) DO NOTHING",
)
.bind(pr.id)
.bind(params.label_id)
.bind(chrono::Utc::now())
.execute(self.db.writer())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
self.pr_labels(pr.id).await
}
pub async fn pr_remove_label(
&self,
ctx: &Session,
wk_name: &str,
repo_name: &str,
number: i64,
label_id: Uuid,
) -> Result<Vec<LabelResponse>, AppError> {
let user_uid = session_user(ctx)?;
let wk = self.workspace_resolve(wk_name).await?;
self.workspace_require_member(wk.id, user_uid).await?;
let repo = self.repo_resolve(wk.id, repo_name).await?;
let pr = self.pr_resolve(repo.id, number).await?;
sqlx::query("DELETE FROM pull_request_label WHERE pull_request = $1 AND label = $2")
.bind(pr.id)
.bind(label_id)
.execute(self.db.writer())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
self.pr_labels(pr.id).await
}
pub async fn pr_labels(
&self,
pr_id: uuid::Uuid,
) -> Result<Vec<LabelResponse>, AppError> {
let labels = sqlx::query_as::<_, LabelModel>(
"SELECT l.id, l.wk, l.name, l.color, l.description, l.created_at, l.updated_at, l.deleted_at \
FROM pull_request_label pl INNER JOIN label l ON l.id = pl.label \
WHERE pl.pull_request = $1 AND l.deleted_at IS NULL \
ORDER BY l.name ASC",
)
.bind(pr_id)
.fetch_all(self.db.reader())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
Ok(labels
.into_iter()
.map(crate::issues::types::label_response)
.collect())
}
}