Skip to content

Commit

Permalink
Merge pull request #47 from Learn-Quickly/dev
Browse files Browse the repository at this point in the history
fix lesson_progress state. added get_number_of_lesson_completed_exerc…
  • Loading branch information
advanced-user authored Jun 14, 2024
2 parents 09276c8 + 511693e commit 1360a32
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 6 deletions.
8 changes: 4 additions & 4 deletions crates/libs/lib-db/src/command_repository/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,16 +266,16 @@ impl IExerciseCommandRepository for ExerciseCommandRepository {
async fn get_number_of_lesson_completed_exercises(&self, _: &Ctx, lesson_id: i64, user_id: i64) -> ExerciseResult<i64> {
let mut subquery = Query::select();
subquery.from(Self::table_ref())
.expr(Expr::col((ExerciseIden::Exercise, CommonIden::Id)))
.distinct_on([CommonIden::Id])
.column(CommonIden::Id)
.inner_join(
get_exercise_completion_table_ref(),
Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::ExerciseCompletionId))
Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::ExerciseId))
.equals((ExerciseIden::Exercise, CommonIden::Id))
)
.and_where(Expr::col((ExerciseIden::Exercise, ExerciseIden::LessonId)).eq(lesson_id))
.and_where(Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::UserId)).eq(user_id))
.and_where(Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::State)).eq("Succeeded"))
.distinct();
.and_where(Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::State)).eq("Succeeded"));

let mut query = Query::select();
query.expr(Expr::col(Alias::new("subquery")).count())
Expand Down
32 changes: 30 additions & 2 deletions crates/libs/lib-db/src/query_repository/exercise.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use lib_core::ctx::Ctx;
use modql::field::{Fields, HasFields};
use sea_query::{Expr, PostgresQueryBuilder, Query};
use sea_query::{Alias, Expr, PostgresQueryBuilder, Query};
use sea_query_binder::SqlxBinder;
use serde_json::Value;
use sqlx::FromRow;

use crate::{base::{self, idens::ExerciseIden, DbRepository}, store::{db_manager::DbManager, error::{DbError, DbResult}}};
use crate::{base::{self, idens::{CommonIden, ExerciseCompletionIden, ExerciseIden}, table_ref::get_exercise_completion_table_ref, DbRepository}, store::{db_manager::DbManager, error::{DbError, DbResult}}};

#[derive(Clone, Fields, FromRow, Debug)]
pub struct ExerciseQuery {
Expand Down Expand Up @@ -72,4 +72,32 @@ impl ExerciseQueryRepository {
.await
.map_err(Into::<DbError>::into)
}

pub async fn get_number_of_lesson_completed_exercises(&self, _: &Ctx, lesson_id: i64, user_id: i64) -> DbResult<i64> {
let mut subquery = Query::select();
subquery.from(Self::table_ref())
.distinct_on([CommonIden::Id])
.column(CommonIden::Id)
.inner_join(
get_exercise_completion_table_ref(),
Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::ExerciseId))
.equals((ExerciseIden::Exercise, CommonIden::Id))
)
.and_where(Expr::col((ExerciseIden::Exercise, ExerciseIden::LessonId)).eq(lesson_id))
.and_where(Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::UserId)).eq(user_id))
.and_where(Expr::col((ExerciseCompletionIden::ExerciseCompletion, ExerciseCompletionIden::State)).eq("Succeeded"));

let mut query = Query::select();
query.expr(Expr::col(Alias::new("subquery")).count())
.from_subquery(subquery, Alias::new("subquery"));

let (sql, values) = query.build_sqlx(PostgresQueryBuilder);

let sqlx_query = sqlx::query_scalar_with::<_, i64, _>(&sql, values);
let entities = self.dbm.dbx().fetch_one_scalar(sqlx_query).await
.map_err(Into::<DbError>::into)?;

Ok(entities)
}

}
1 change: 1 addition & 0 deletions crates/services/web-server/src/api_doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ use crate::routes::creator::{course as creator_course, lesson as creator_lesson,
user_exercise::api_get_exercise_handler,
user_exercise::api_get_exercise_completions_handler,
user_exercise::api_get_exercises_completions_handler,
user_exercise::api_get_number_of_lesson_completed_exercises_handler,
),
components(
schemas(
Expand Down
34 changes: 34 additions & 0 deletions crates/services/web-server/src/routes/user/exercise.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub fn routes(app_state: AppState) -> Router {
.route("/get_exercise/:i64", get(api_get_exercise_handler))
.route("/get_exercise_completions/:i64", get(api_get_exercise_completions_handler))
.route("/get_exercises_completions/:i64", get(api_get_exercises_completions_handler))
.route("/get_number_of_lesson_completed_exercises/:i64", get(api_get_number_of_lesson_completed_exercises_handler))
.with_state(app_state)
}

Expand Down Expand Up @@ -138,4 +139,37 @@ async fn api_get_exercises_completions_handler(
.map(|exercise| exercise.clone().into()).collect();

Ok(Json(exercises_completions))
}

#[utoipa::path(
get,
path = "/api/course/lesson/exercise/get_number_of_lesson_completed_exercises/{lesson_id}",
params(
("lesson_id", description = "ID of the lesson")
),
responses(
(status = 200, body=i64),
),
security(
("bearerAuth" = [])
)
)]
async fn api_get_number_of_lesson_completed_exercises_handler(
ctx: CtxW,
State(app_state): State<AppState>,
Path(lesson_id): Path<i64>,
) -> AppResult<Json<i64>> {
let ctx = ctx.0;
let user_id = ctx.user_id();

let exercise_query_repository = app_state
.query_repository_manager
.get_exercise_repository();

let exercises = exercise_query_repository
.get_number_of_lesson_completed_exercises(&ctx, lesson_id, user_id)
.await?;


Ok(Json(exercises))
}

0 comments on commit 1360a32

Please sign in to comment.