-- name: GetPreviousProgram :one SELECT p2.* FROM programs AS p1 INNER JOIN programs AS p2 ON p2.sort_order = p1.sort_order - 1 WHERE p1.id = $1; -- name: GetPreviousCourseInProgram :one SELECT c2.* FROM courses AS c1 INNER JOIN courses AS c2 ON c2.program_id = c1.program_id AND c2.sort_order = c1.sort_order - 1 WHERE c1.id = $1; -- name: GetPreviousModuleInCourse :one SELECT m2.* FROM modules AS m1 INNER JOIN modules AS m2 ON m2.course_id = m1.course_id AND m2.sort_order = m1.sort_order - 1 WHERE m1.id = $1; -- name: GetPreviousLessonInModule :one SELECT l2.* FROM lessons AS l1 INNER JOIN lessons AS l2 ON l2.module_id = l1.module_id AND l2.publish_status = 'PUBLISHED' AND l1.publish_status = 'PUBLISHED' AND ( l2.sort_order < l1.sort_order OR ( l2.sort_order = l1.sort_order AND l2.id < l1.id ) ) WHERE l1.id = $1 ORDER BY l2.sort_order DESC, l2.id DESC LIMIT 1; -- name: UserHasProgramProgress :one SELECT EXISTS ( SELECT 1 FROM lms_user_program_progress WHERE user_id = $1 AND program_id = $2) AS v; -- name: UserHasCourseProgress :one SELECT EXISTS ( SELECT 1 FROM lms_user_course_progress WHERE user_id = $1 AND course_id = $2) AS v; -- name: UserHasModuleProgress :one SELECT EXISTS ( SELECT 1 FROM lms_user_module_progress WHERE user_id = $1 AND module_id = $2) AS v; -- name: UserHasLessonProgress :one SELECT EXISTS ( SELECT 1 FROM lms_user_lesson_progress WHERE user_id = $1 AND lesson_id = $2) AS v; -- name: InsertUserLessonProgress :exec INSERT INTO lms_user_lesson_progress (user_id, lesson_id) VALUES ($1, $2) ON CONFLICT (user_id, lesson_id) DO NOTHING; -- name: InsertUserModuleProgress :exec INSERT INTO lms_user_module_progress (user_id, module_id) VALUES ($1, $2) ON CONFLICT (user_id, module_id) DO NOTHING; -- name: InsertUserCourseProgress :exec INSERT INTO lms_user_course_progress (user_id, course_id) VALUES ($1, $2) ON CONFLICT (user_id, course_id) DO NOTHING; -- name: InsertUserProgramProgress :exec INSERT INTO lms_user_program_progress (user_id, program_id) VALUES ($1, $2) ON CONFLICT (user_id, program_id) DO NOTHING; -- name: CountPublishedPracticesInLesson :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE lp.lesson_id = $1 AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountUserCompletedPublishedPracticesInLesson :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id WHERE lp.lesson_id = $1 AND upp.user_id = $2 AND upp.completed_at IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountLessonsInModule :one SELECT count(*)::int AS n FROM lessons WHERE module_id = $1 AND publish_status = 'PUBLISHED'; -- name: CountUserCompletedLessonsInModule :one SELECT count(*)::int AS n FROM lms_user_lesson_progress ulp INNER JOIN lessons l ON l.id = ulp.lesson_id WHERE l.module_id = $1 AND ulp.user_id = $2 AND l.publish_status = 'PUBLISHED'; -- name: CountModulesInCourse :one SELECT count(*)::int AS n FROM modules WHERE course_id = $1; -- name: CountUserCompletedModulesInCourse :one SELECT count(*)::int AS n FROM lms_user_module_progress ump INNER JOIN modules m ON m.id = ump.module_id WHERE m.course_id = $1 AND ump.user_id = $2; -- name: CountCoursesInProgram :one SELECT count(*)::int AS n FROM courses WHERE program_id = $1; -- name: CountUserCompletedCoursesInProgram :one SELECT count(*)::int AS n FROM lms_user_course_progress ucp INNER JOIN courses c ON c.id = ucp.course_id WHERE c.program_id = $1 AND ucp.user_id = $2; -- name: ListLMSCompletedLessonIDsByUser :many SELECT lp.lesson_id FROM lms_practices AS lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id LEFT JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id AND upp.user_id = $1 AND upp.completed_at IS NOT NULL WHERE lp.lesson_id IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED' GROUP BY lp.lesson_id HAVING count(DISTINCT lp.question_set_id) > 0 AND count(DISTINCT upp.question_set_id) >= count(DISTINCT lp.question_set_id) ORDER BY max(upp.completed_at) ASC, lp.lesson_id ASC; -- name: ListLMSCompletedModuleIDsByUser :many SELECT scoped.module_id FROM ( SELECT m.id AS module_id, lp.question_set_id FROM modules m INNER JOIN lms_practices lp ON ( lp.module_id = m.id OR lp.lesson_id IN ( SELECT id FROM lessons WHERE module_id = m.id)) INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED') scoped LEFT JOIN user_practice_progress upp ON upp.question_set_id = scoped.question_set_id AND upp.user_id = $1 AND upp.completed_at IS NOT NULL GROUP BY scoped.module_id HAVING count(DISTINCT scoped.question_set_id) > 0 AND count(DISTINCT upp.question_set_id) >= count(DISTINCT scoped.question_set_id) ORDER BY max(upp.completed_at) ASC, scoped.module_id ASC; -- name: ListLMSCompletedCourseIDsByUser :many SELECT scoped.course_id FROM ( SELECT c.id AS course_id, lp.question_set_id FROM courses c INNER JOIN lms_practices lp ON ( lp.course_id = c.id OR lp.module_id IN ( SELECT id FROM modules WHERE course_id = c.id) OR lp.lesson_id IN ( SELECT l.id FROM lessons l INNER JOIN modules m ON m.id = l.module_id WHERE m.course_id = c.id)) INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED') scoped LEFT JOIN user_practice_progress upp ON upp.question_set_id = scoped.question_set_id AND upp.user_id = $1 AND upp.completed_at IS NOT NULL GROUP BY scoped.course_id HAVING count(DISTINCT scoped.question_set_id) > 0 AND count(DISTINCT upp.question_set_id) >= count(DISTINCT scoped.question_set_id) ORDER BY max(upp.completed_at) ASC, scoped.course_id ASC; -- name: ListLMSCompletedProgramIDsByUser :many SELECT scoped.program_id FROM ( SELECT c.program_id, lp.question_set_id FROM courses c INNER JOIN lms_practices lp ON ( lp.course_id = c.id OR lp.module_id IN ( SELECT m.id FROM modules m WHERE m.course_id = c.id) OR lp.lesson_id IN ( SELECT l.id FROM lessons l INNER JOIN modules m ON m.id = l.module_id WHERE m.course_id = c.id)) INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED') scoped LEFT JOIN user_practice_progress upp ON upp.question_set_id = scoped.question_set_id AND upp.user_id = $1 AND upp.completed_at IS NOT NULL GROUP BY scoped.program_id HAVING count(DISTINCT scoped.question_set_id) > 0 AND count(DISTINCT upp.question_set_id) >= count(DISTINCT scoped.question_set_id) ORDER BY max(upp.completed_at) ASC, scoped.program_id ASC; -- Lesson-based progress within a course (all modules). -- name: CountLessonsInCourse :one SELECT count(*)::int AS n FROM lessons l INNER JOIN modules m ON m.id = l.module_id WHERE m.course_id = $1 AND l.publish_status = 'PUBLISHED'; -- name: CountUserCompletedLessonsInCourse :one SELECT count(*)::int AS n FROM lms_user_lesson_progress ulp INNER JOIN lessons l ON l.id = ulp.lesson_id INNER JOIN modules m ON m.id = l.module_id WHERE m.course_id = $1 AND ulp.user_id = $2 AND l.publish_status = 'PUBLISHED'; -- Lesson-based progress within a program (all courses). -- name: CountLessonsInProgram :one SELECT count(*)::int AS n FROM lessons l INNER JOIN modules m ON m.id = l.module_id INNER JOIN courses c ON c.id = m.course_id WHERE c.program_id = $1 AND l.publish_status = 'PUBLISHED'; -- name: CountUserCompletedLessonsInProgram :one SELECT count(*)::int AS n FROM lms_user_lesson_progress ulp INNER JOIN lessons l ON l.id = ulp.lesson_id INNER JOIN modules m ON m.id = l.module_id INNER JOIN courses c ON c.id = m.course_id WHERE c.program_id = $1 AND ulp.user_id = $2 AND l.publish_status = 'PUBLISHED'; -- Published practices in a module (direct module practices and practices on lessons in the module). -- name: CountPublishedPracticesInModule :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE ( lp.module_id = $1 OR lp.lesson_id IN ( SELECT id FROM lessons WHERE module_id = $1)) AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountUserCompletedPublishedPracticesInModule :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id WHERE ( lp.module_id = $1 OR lp.lesson_id IN ( SELECT id FROM lessons WHERE module_id = $1)) AND upp.user_id = $2 AND upp.completed_at IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountPublishedPracticesInCourse :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE ( lp.course_id = $1 OR lp.module_id IN ( SELECT id FROM modules WHERE course_id = $1) OR lp.lesson_id IN ( SELECT l.id FROM lessons l INNER JOIN modules m ON m.id = l.module_id WHERE m.course_id = $1)) AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountUserCompletedPublishedPracticesInCourse :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id WHERE ( lp.course_id = $1 OR lp.module_id IN ( SELECT id FROM modules WHERE course_id = $1) OR lp.lesson_id IN ( SELECT l.id FROM lessons l INNER JOIN modules m ON m.id = l.module_id WHERE m.course_id = $1)) AND upp.user_id = $2 AND upp.completed_at IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountPublishedPracticesInProgram :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE ( lp.course_id IN ( SELECT c.id FROM courses c WHERE c.program_id = $1) OR lp.module_id IN ( SELECT m.id FROM modules m INNER JOIN courses c ON c.id = m.course_id WHERE c.program_id = $1) OR lp.lesson_id IN ( SELECT l.id FROM lessons l INNER JOIN modules m ON m.id = l.module_id INNER JOIN courses c ON c.id = m.course_id WHERE c.program_id = $1)) AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountUserCompletedPublishedPracticesInProgram :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id WHERE ( lp.course_id IN ( SELECT c.id FROM courses c WHERE c.program_id = $1) OR lp.module_id IN ( SELECT m.id FROM modules m INNER JOIN courses c ON c.id = m.course_id WHERE c.program_id = $1) OR lp.lesson_id IN ( SELECT l.id FROM lessons l INNER JOIN modules m ON m.id = l.module_id INNER JOIN courses c ON c.id = m.course_id WHERE c.program_id = $1)) AND upp.user_id = $2 AND upp.completed_at IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- Published practices directly attached to module_id (not via lesson_id). -- name: CountPublishedDirectPracticesInModule :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE lp.module_id = $1 AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountUserCompletedPublishedDirectPracticesInModule :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id WHERE lp.module_id = $1 AND upp.user_id = $2 AND upp.completed_at IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- Published practices directly attached to course_id (not via module_id/lesson_id). -- name: CountPublishedDirectPracticesInCourse :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id WHERE lp.course_id = $1 AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: CountUserCompletedPublishedDirectPracticesInCourse :one SELECT count(*)::int AS n FROM lms_practices lp INNER JOIN question_sets qs ON qs.id = lp.question_set_id INNER JOIN user_practice_progress upp ON upp.question_set_id = lp.question_set_id WHERE lp.course_id = $1 AND upp.user_id = $2 AND upp.completed_at IS NOT NULL AND qs.set_type = 'PRACTICE' AND qs.status = 'PUBLISHED' AND lp.publish_status = 'PUBLISHED'; -- name: GetPracticeScopeByQuestionSetID :one SELECT id, course_id, module_id, lesson_id FROM lms_practices WHERE question_set_id = $1 ORDER BY id DESC LIMIT 1;