headless_lms_models/
repository_exercises.rs

1use 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}