headless_lms_models/
offered_answers_to_peer_review_temporary.rs1use rand::Rng;
2
3use crate::{exercise_slide_submissions::ExerciseSlideSubmission, prelude::*};
4
5pub async fn try_to_restore_previously_given_exercise_slide_submission(
8 conn: &mut PgConnection,
9 exercise_id: Uuid,
10 user_id: Uuid,
11 course_instance_id: Uuid,
12) -> ModelResult<Option<ExerciseSlideSubmission>> {
13 if rand::rng().random_range(0..10) == 0 {
15 delete_expired_records(&mut *conn).await?;
16 }
17
18 let res = sqlx::query!(
19 "
20SELECT exercise_slide_submission_id
21FROM offered_answers_to_peer_review_temporary
22WHERE exercise_id = $1
23 AND user_id = $2
24 AND course_instance_id = $3
25 AND created_at > now() - '1 hour'::interval
26 ",
27 exercise_id,
28 user_id,
29 course_instance_id,
30 )
31 .fetch_optional(&mut *conn)
32 .await?;
33
34 if let Some(res) = res {
35 match crate::peer_review_queue_entries::get_by_receiving_peer_reviews_exercise_slide_submission_id(&mut *conn, res.exercise_slide_submission_id).await.optional()? { Some(peer_review_queue_entry) => {
37 if peer_review_queue_entry.received_enough_peer_reviews || peer_review_queue_entry.removed_from_queue_for_unusual_reason || peer_review_queue_entry.deleted_at.is_some() {
38 return Ok(None);
39 }
40 } _ => {
41 return Ok(None)
42 }}
43
44 let ess = crate::exercise_slide_submissions::get_by_id(
45 &mut *conn,
46 res.exercise_slide_submission_id,
47 )
48 .await?;
49
50 if ess.deleted_at.is_some() {
51 return Ok(None);
52 }
53 return Ok(Some(ess));
54 }
55 Ok(None)
56}
57
58pub async fn save_given_exercise_slide_submission(
60 conn: &mut PgConnection,
61 exercise_slide_submission_id: Uuid,
62 exercise_id: Uuid,
63 user_id: Uuid,
64 course_instance_id: Uuid,
65) -> ModelResult<()> {
66 let _res = sqlx::query!(
67 "
68INSERT INTO offered_answers_to_peer_review_temporary (
69 exercise_slide_submission_id,
70 user_id,
71 course_instance_id,
72 exercise_id
73 )
74VALUES ($1, $2, $3, $4) ON CONFLICT ON CONSTRAINT offered_answers_to_peer_review_temporary_pkey DO
75UPDATE
76SET exercise_slide_submission_id = $1,
77 user_id = $2,
78 course_instance_id = $3,
79 exercise_id = $4,
80 created_at = now()
81",
82 exercise_slide_submission_id,
83 user_id,
84 course_instance_id,
85 exercise_id,
86 )
87 .execute(&mut *conn)
88 .await?;
89
90 Ok(())
91}
92
93pub async fn delete_saved_submissions_for_user(
95 conn: &mut PgConnection,
96 exercise_id: Uuid,
97 user_id: Uuid,
98) -> ModelResult<()> {
99 info!("Deleting expired records from offered_answers_to_peer_review_temporary");
100 let _res = sqlx::query!(
101 "
102DELETE FROM offered_answers_to_peer_review_temporary
103WHERE exercise_id = $1
104 AND user_id = $2
105",
106 exercise_id,
107 user_id
108 )
109 .execute(&mut *conn)
110 .await?;
111 Ok(())
112}
113
114async fn delete_expired_records(conn: &mut PgConnection) -> ModelResult<()> {
116 info!("Deleting expired records from offered_answers_to_peer_review_temporary");
117 let _res = sqlx::query!(
118 "
119DELETE FROM offered_answers_to_peer_review_temporary
120WHERE created_at < now() - '1 hour'::interval
121"
122 )
123 .execute(&mut *conn)
124 .await?;
125 Ok(())
126}