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