headless_lms_models/
user_course_exercise_service_variables.rs1use std::collections::HashMap;
2
3use utoipa::ToSchema;
4
5use crate::{exercise_tasks::ExerciseTask, prelude::*, user_exercise_states::UserExerciseState};
6
7#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, ToSchema)]
8
9pub struct UserCourseExerciseServiceVariable {
10 pub id: Uuid,
11 pub created_at: DateTime<Utc>,
12 pub updated_at: DateTime<Utc>,
13 pub deleted_at: Option<DateTime<Utc>>,
14 pub exercise_service_slug: String,
15 pub user_id: Uuid,
16 pub course_id: Option<Uuid>,
17 pub exam_id: Option<Uuid>,
18 pub variable_key: String,
19 pub variable_value: serde_json::Value,
20}
21
22pub(crate) async fn get_all_variables_for_user_and_course_or_exam(
23 conn: &mut PgConnection,
24 user_id: Uuid,
25 instance_or_exam_id: CourseOrExamId,
26) -> ModelResult<Vec<UserCourseExerciseServiceVariable>> {
27 let (course_id, exam_id) = instance_or_exam_id.to_course_and_exam_ids();
28 let res = sqlx::query_as!(
29 UserCourseExerciseServiceVariable,
30 r#"
31SELECT *
32FROM user_course_exercise_service_variables
33WHERE deleted_at IS NULL
34 AND user_id = $1
35 AND (course_id = $2 OR course_id IS NULL)
36 AND (exam_id = $3 OR exam_id IS NULL);
37 "#,
38 user_id,
39 course_id,
40 exam_id
41 )
42 .fetch_all(conn)
43 .await?;
44 Ok(res)
45}
46
47pub async fn get_all_user_variables_for_user_and_course_and_exercise_type(
48 conn: &mut PgConnection,
49 user_id: Uuid,
50 course_id: Uuid,
51 exercise_type: &str,
52) -> ModelResult<Vec<UserCourseExerciseServiceVariable>> {
53 let res = sqlx::query_as!(
54 UserCourseExerciseServiceVariable,
55 r#"
56SELECT *
57FROM user_course_exercise_service_variables
58WHERE deleted_at IS NULL
59 AND user_id = $1
60 AND course_id = $2
61 AND exercise_service_slug = $3;
62 "#,
63 user_id,
64 course_id,
65 exercise_type
66 )
67 .fetch_all(conn)
68 .await?;
69 Ok(res)
70}
71
72pub(crate) async fn insert_after_exercise_task_graded(
73 conn: &mut PgConnection,
74 set_user_variables: &Option<HashMap<String, serde_json::Value>>,
75 exercise_task: &ExerciseTask,
76 user_exercise_state: &UserExerciseState,
77) -> ModelResult<()> {
78 if let Some(set_user_variables) = set_user_variables {
79 for (k, v) in set_user_variables {
80 sqlx::query!(
81 r#"
82INSERT INTO user_course_exercise_service_variables (
83 exercise_service_slug,
84 user_id,
85 course_id,
86 exam_id,
87 variable_key,
88 variable_value
89 )
90VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (
91 variable_key,
92 user_id,
93 course_id,
94 exercise_service_slug,
95 exam_id,
96 deleted_at
97 ) DO
98UPDATE
99SET variable_value = $6;
100 "#,
101 exercise_task.exercise_type,
102 user_exercise_state.user_id,
103 user_exercise_state.course_id,
104 user_exercise_state.exam_id,
105 k,
106 v
107 )
108 .execute(&mut *conn)
109 .await?;
110 }
111 Ok(())
112 } else {
113 Ok(())
114 }
115}