headless_lms_models/
repository_exercises.rs1use crate::prelude::*;
2use utoipa::ToSchema;
3
4#[derive(Debug, Serialize, ToSchema)]
5
6pub struct RepositoryExercise {
7 pub id: Uuid,
8 pub repository_id: Uuid,
9 pub part: String,
10 pub name: String,
11 pub repository_url: String,
12 pub checksum: Vec<u8>,
13 pub download_url: String,
14}
15
16pub async fn new(
17 conn: &mut PgConnection,
18 id: Uuid,
19 repository_id: Uuid,
20 part: &str,
21 name: &str,
22 checksum: &[u8],
23 download_url: &str,
24) -> ModelResult<()> {
25 sqlx::query!(
26 "
27INSERT INTO repository_exercises (
28 id,
29 repository_id,
30 part,
31 name,
32 checksum,
33 download_url
34)
35VALUES ($1, $2, $3, $4, $5, $6)
36",
37 id,
38 repository_id,
39 part,
40 name,
41 checksum,
42 download_url,
43 )
44 .execute(conn)
45 .await?;
46 Ok(())
47}
48
49pub async fn update_checksum(
50 conn: &mut PgConnection,
51 exercise: Uuid,
52 checksum: &[u8],
53) -> ModelResult<()> {
54 sqlx::query!(
55 "
56UPDATE repository_exercises
57SET checksum = $1
58WHERE id = $2
59",
60 checksum,
61 exercise
62 )
63 .execute(conn)
64 .await?;
65 Ok(())
66}
67
68pub async fn update_part_and_name(
69 conn: &mut PgConnection,
70 exercise: Uuid,
71 part: &str,
72 name: &str,
73) -> ModelResult<()> {
74 sqlx::query!(
75 "
76UPDATE repository_exercises
77SET part = $1,
78 name = $2
79WHERE id = $3
80",
81 part,
82 name,
83 exercise
84 )
85 .execute(conn)
86 .await?;
87 Ok(())
88}
89
90pub async fn delete_for_repository(
91 conn: &mut PgConnection,
92 repository: Uuid,
93) -> ModelResult<Vec<Uuid>> {
94 let res = sqlx::query!(
95 "
96UPDATE repository_exercises
97SET deleted_at = now()
98WHERE repository_id = $1
99AND deleted_at IS NULL
100RETURNING id
101",
102 repository
103 )
104 .fetch_all(conn)
105 .await?
106 .into_iter()
107 .map(|r| r.id)
108 .collect();
109 Ok(res)
110}
111
112pub async fn get_for_repository(
113 conn: &mut PgConnection,
114 repository: Uuid,
115) -> ModelResult<Vec<RepositoryExercise>> {
116 let exercises = sqlx::query_as!(
117 RepositoryExercise,
118 "
119SELECT re.id,
120 er.id AS repository_id,
121 re.part,
122 re.name,
123 er.url AS repository_url,
124 re.checksum,
125 re.download_url
126FROM repository_exercises AS re
127JOIN exercise_repositories AS er ON er.id = re.repository_id
128WHERE repository_id = $1
129AND re.deleted_at IS NULL
130",
131 repository
132 )
133 .fetch_all(conn)
134 .await?;
135 Ok(exercises)
136}
137
138pub async fn get_for_course(
139 conn: &mut PgConnection,
140 course: Uuid,
141) -> ModelResult<Vec<RepositoryExercise>> {
142 let exercises = sqlx::query_as!(
143 RepositoryExercise,
144 "
145SELECT re.id,
146er.id AS repository_id,
147 re.part,
148 re.name,
149 er.url AS repository_url,
150 re.checksum,
151 re.download_url
152FROM repository_exercises AS re
153JOIN exercise_repositories AS er ON er.id = re.repository_id
154WHERE er.course_id = $1
155AND re.deleted_at IS NULL
156and er.deleted_at IS NULL
157",
158 course
159 )
160 .fetch_all(conn)
161 .await?;
162 Ok(exercises)
163}
164
165pub async fn delete_from_repository(
166 conn: &mut PgConnection,
167 repository_id: Uuid,
168) -> ModelResult<()> {
169 sqlx::query!(
170 "
171UPDATE repository_exercises
172SET deleted_at = now()
173WHERE repository_id = $1
174AND deleted_at IS NULL
175",
176 repository_id
177 )
178 .execute(conn)
179 .await?;
180 Ok(())
181}