1use super::*;
2
3#[derive(Debug)]
4pub enum ContributorSelector {
5 GitHubUserId { github_user_id: i32 },
6 GitHubLogin { github_login: String },
7}
8
9impl Database {
10 /// Retrieves the GitHub logins of all users who have signed the CLA.
11 pub async fn get_contributors(&self) -> Result<Vec<String>> {
12 self.transaction(|tx| async move {
13 #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
14 enum QueryGithubLogin {
15 GithubLogin,
16 }
17
18 Ok(contributor::Entity::find()
19 .inner_join(user::Entity)
20 .order_by_asc(contributor::Column::SignedAt)
21 .select_only()
22 .column(user::Column::GithubLogin)
23 .into_values::<_, QueryGithubLogin>()
24 .all(&*tx)
25 .await?)
26 })
27 .await
28 }
29
30 /// Records that a given user has signed the CLA.
31 pub async fn get_contributor_sign_timestamp(
32 &self,
33 selector: &ContributorSelector,
34 ) -> Result<Option<DateTime>> {
35 self.transaction(|tx| async move {
36 let condition = match selector {
37 ContributorSelector::GitHubUserId { github_user_id } => {
38 user::Column::GithubUserId.eq(*github_user_id)
39 }
40 ContributorSelector::GitHubLogin { github_login } => {
41 user::Column::GithubLogin.eq(github_login)
42 }
43 };
44
45 let Some(user) = user::Entity::find().filter(condition).one(&*tx).await? else {
46 return Ok(None);
47 };
48 let Some(contributor) = contributor::Entity::find_by_id(user.id).one(&*tx).await?
49 else {
50 return Ok(None);
51 };
52 Ok(Some(contributor.signed_at))
53 })
54 .await
55 }
56
57 /// Records that a given user has signed the CLA.
58 pub async fn add_contributor(
59 &self,
60 github_login: &str,
61 github_user_id: Option<i32>,
62 github_email: Option<&str>,
63 ) -> Result<()> {
64 self.transaction(|tx| async move {
65 let user = self
66 .get_or_create_user_by_github_account_tx(
67 github_login,
68 github_user_id,
69 github_email,
70 &*tx,
71 )
72 .await?;
73
74 contributor::Entity::insert(contributor::ActiveModel {
75 user_id: ActiveValue::Set(user.id),
76 signed_at: ActiveValue::NotSet,
77 })
78 .on_conflict(
79 OnConflict::column(contributor::Column::UserId)
80 .do_nothing()
81 .to_owned(),
82 )
83 .exec_without_returning(&*tx)
84 .await?;
85 Ok(())
86 })
87 .await
88 }
89}