57 lines
1.7 KiB
Rust
57 lines
1.7 KiB
Rust
use db::sqlx;
|
|
use serde::{Deserialize, Serialize};
|
|
use session::Session;
|
|
use utoipa::ToSchema;
|
|
|
|
use crate::{AppService, Pagination, error::AppError};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
|
pub struct ContributorDto {
|
|
pub name: String,
|
|
pub email: String,
|
|
#[schema(value_type = Option<String>)]
|
|
pub user_id: Option<uuid::Uuid>,
|
|
pub commit_count: i64,
|
|
}
|
|
|
|
impl AppService {
|
|
pub async fn git_repo_contributors(
|
|
&self,
|
|
ctx: &Session,
|
|
wk_name: &str,
|
|
repo_name: &str,
|
|
pagination: Pagination,
|
|
) -> Result<Vec<ContributorDto>, AppError> {
|
|
let repo = self.git_require_member(ctx, wk_name, repo_name).await?;
|
|
|
|
let offset = pagination.offset() as i64;
|
|
let limit = pagination.limit() as i64;
|
|
|
|
let rows = sqlx::query_as::<_, (String, String, Option<uuid::Uuid>, Option<i64>)>(
|
|
"SELECT rc.name, rc.email, rc.user, COUNT(rco.id)::bigint AS commit_count \
|
|
FROM repo_committer rc \
|
|
LEFT JOIN repo_commit rco ON rc.id = rco.author \
|
|
WHERE rc.repo = $1 \
|
|
GROUP BY rc.id, rc.name, rc.email, rc.user \
|
|
ORDER BY commit_count DESC \
|
|
OFFSET $2 LIMIT $3",
|
|
)
|
|
.bind(repo.id)
|
|
.bind(offset)
|
|
.bind(limit)
|
|
.fetch_all(self.db.reader())
|
|
.await
|
|
.map_err(|e| AppError::DatabaseError(e.to_string()))?;
|
|
|
|
Ok(rows
|
|
.into_iter()
|
|
.map(|(name, email, user_id, commit_count)| ContributorDto {
|
|
name,
|
|
email,
|
|
user_id,
|
|
commit_count: commit_count.unwrap_or(0),
|
|
})
|
|
.collect())
|
|
}
|
|
}
|