37 lines
1.9 KiB
TypeScript
37 lines
1.9 KiB
TypeScript
import type { Db } from "../connect";
|
|
|
|
export type Attempt = {
|
|
userId: string; courseId: string; lessonId: string; track: string;
|
|
code: string; result: unknown; passed: boolean; updatedAt: string;
|
|
};
|
|
|
|
export function attemptsRepo(db: Db) {
|
|
return {
|
|
async get(userId: string, courseId: string, lessonId: string, track: string): Promise<Attempt | null> {
|
|
const rows = await db.sql`SELECT * FROM exercise_attempts WHERE user_id = ${userId} AND course_id = ${courseId} AND lesson_id = ${lessonId} AND track = ${track}`;
|
|
if (rows.length === 0) return null;
|
|
const r = rows[0];
|
|
return {
|
|
userId: r.user_id, courseId: r.course_id, lessonId: r.lesson_id, track: r.track,
|
|
code: r.code, result: r.result_json === null ? null : JSON.parse(r.result_json),
|
|
passed: Number(r.passed) === 1, updatedAt: r.updated_at,
|
|
};
|
|
},
|
|
|
|
async save(a: Attempt): Promise<void> {
|
|
const resultJson = a.result === null || a.result === undefined ? null : JSON.stringify(a.result);
|
|
const passed = a.passed ? 1 : 0;
|
|
await db.sql.begin(async (tx) => {
|
|
const existing = await tx`SELECT 1 AS x FROM exercise_attempts WHERE user_id = ${a.userId} AND course_id = ${a.courseId} AND lesson_id = ${a.lessonId} AND track = ${a.track}`;
|
|
if (existing.length > 0) {
|
|
await tx`UPDATE exercise_attempts SET code = ${a.code}, result_json = ${resultJson}, passed = ${passed}, updated_at = ${a.updatedAt}
|
|
WHERE user_id = ${a.userId} AND course_id = ${a.courseId} AND lesson_id = ${a.lessonId} AND track = ${a.track}`;
|
|
} else {
|
|
await tx`INSERT INTO exercise_attempts (user_id, course_id, lesson_id, track, code, result_json, passed, updated_at)
|
|
VALUES (${a.userId}, ${a.courseId}, ${a.lessonId}, ${a.track}, ${a.code}, ${resultJson}, ${passed}, ${a.updatedAt})`;
|
|
}
|
|
});
|
|
},
|
|
};
|
|
}
|