1use ag_session::ReviewRequest;
4use async_trait::async_trait;
5use sqlx::SqlitePool;
6
7use crate::DbError;
8
9#[derive(Clone, Debug, Eq, PartialEq)]
11pub struct SessionReviewRequestRow {
12 pub display_id: String,
14 pub forge_kind: String,
16 pub last_refreshed_at: i64,
18 pub source_branch: String,
20 pub state: String,
22 pub status_summary: Option<String>,
24 pub target_branch: String,
26 pub title: String,
28 pub web_url: String,
30}
31
32#[cfg_attr(test, mockall::automock)]
34#[async_trait]
35pub trait ReviewRepository: Send + Sync {
36 async fn load_session_review_request(
38 &self,
39 id: &str,
40 ) -> Result<Option<SessionReviewRequestRow>, DbError>;
41
42 async fn update_session_review_request(
44 &self,
45 id: &str,
46 review_request: Option<ReviewRequest>,
47 ) -> Result<(), DbError>;
48}
49
50#[derive(Clone)]
52pub(crate) struct SqliteReviewRepository(SqlitePool);
53
54impl SqliteReviewRepository {
55 pub(crate) fn new(pool: SqlitePool) -> Self {
57 Self(pool)
58 }
59}
60
61#[async_trait]
62impl ReviewRepository for SqliteReviewRepository {
63 async fn load_session_review_request(
64 &self,
65 id: &str,
66 ) -> Result<Option<SessionReviewRequestRow>, DbError> {
67 let review_request = sqlx::query_as!(
68 SessionReviewRequestRow,
69 r"
70SELECT display_id,
71 forge_kind,
72 last_refreshed_at,
73 source_branch,
74 state,
75 status_summary,
76 target_branch,
77 title,
78 web_url
79FROM session_review_request
80WHERE session_id = ?
81",
82 id
83 )
84 .fetch_optional(&self.0)
85 .await?;
86
87 Ok(review_request)
88 }
89
90 async fn update_session_review_request(
91 &self,
92 id: &str,
93 review_request: Option<ReviewRequest>,
94 ) -> Result<(), DbError> {
95 if let Some(review_request) = review_request.as_ref() {
96 sqlx::query!(
97 r"
98INSERT INTO session_review_request (
99 session_id,
100 display_id,
101 forge_kind,
102 last_refreshed_at,
103 source_branch,
104 state,
105 status_summary,
106 target_branch,
107 title,
108 web_url
109)
110VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
111ON CONFLICT(session_id) DO UPDATE
112SET display_id = excluded.display_id,
113 forge_kind = excluded.forge_kind,
114 last_refreshed_at = excluded.last_refreshed_at,
115 source_branch = excluded.source_branch,
116 state = excluded.state,
117 status_summary = excluded.status_summary,
118 target_branch = excluded.target_branch,
119 title = excluded.title,
120 web_url = excluded.web_url
121",
122 id,
123 review_request.summary.display_id.as_str(),
124 review_request.summary.forge_kind.as_str(),
125 review_request.last_refreshed_at,
126 review_request.summary.source_branch.as_str(),
127 review_request.summary.state.as_str(),
128 review_request.summary.status_summary.as_deref(),
129 review_request.summary.target_branch.as_str(),
130 review_request.summary.title.as_str(),
131 review_request.summary.web_url.as_str()
132 )
133 .execute(&self.0)
134 .await?;
135 } else {
136 sqlx::query!(
137 r"
138DELETE FROM session_review_request
139WHERE session_id = ?
140",
141 id
142 )
143 .execute(&self.0)
144 .await?;
145 }
146
147 Ok(())
148 }
149}