module api_modules.classroom_compliance.api_class; import handy_httpd; import ddbc; import api_modules.classroom_compliance.model; import api_modules.classroom_compliance.util; import api_modules.auth : User, getUserOrThrow; import db; import data_utils; void createClass(ref HttpRequestContext ctx) { Connection conn = getDb(); scope(exit) conn.close(); User user = getUserOrThrow(ctx, conn); struct ClassPayload { ushort number; string schoolYear; } auto payload = readJsonPayload!(ClassPayload)(ctx); const bool classNumberExists = recordExists( conn, "SELECT id FROM classroom_compliance_class WHERE number = ? AND school_year = ? AND user_id = ?", payload.number, payload.schoolYear, user.id ); if (classNumberExists) { ctx.response.status = HttpStatus.BAD_REQUEST; ctx.response.writeBodyString("There is already a class with this number, for the same school year."); return; } ulong classId = insertOne( conn, "INSERT INTO classroom_compliance_class (number, school_year, user_id) VALUES (?, ?, ?) RETURNING id", payload.number, payload.schoolYear, user.id ); auto newClass = findOne( conn, "SELECT * FROM classroom_compliance_class WHERE id = ? AND user_id = ?", &ClassroomComplianceClass.parse, classId, user.id ).orElseThrow(); writeJsonBody(ctx, newClass); } void getClasses(ref HttpRequestContext ctx) { Connection conn = getDb(); scope(exit) conn.close(); User user = getUserOrThrow(ctx, conn); const query = " SELECT c.id, c.number, c.school_year, COUNT(DISTINCT s.id) AS student_count, COUNT(DISTINCT e.id) AS entry_count, MAX(e.date) AS last_entry_date FROM classroom_compliance_class c LEFT JOIN classroom_compliance_student s ON c.id = s.class_id LEFT JOIN classroom_compliance_entry e ON c.id = e.class_id WHERE c.user_id = ? GROUP BY c.id ORDER BY school_year DESC, number ASC "; struct ClassResponse { ulong id; ushort number; string schoolYear; uint studentCount; uint entryCount; string lastEntryDate; } ClassResponse[] classes = findAll( conn, query, r => ClassResponse( r.getUlong(1), r.getUshort(2), r.getString(3), r.getUint(4), r.getUint(5), r.getDate(6).toISOExtString() ), user.id ); writeJsonBody(ctx, classes); } void getClass(ref HttpRequestContext ctx) { Connection conn = getDb(); scope(exit) conn.close(); User user = getUserOrThrow(ctx, conn); auto cls = getClassOrThrow(ctx, conn, user); writeJsonBody(ctx, cls); } void deleteClass(ref HttpRequestContext ctx) { Connection conn = getDb(); scope(exit) conn.close(); User user = getUserOrThrow(ctx, conn); auto cls = getClassOrThrow(ctx, conn, user); const query = "DELETE FROM classroom_compliance_class WHERE id = ? AND user_id = ?"; PreparedStatement ps = conn.prepareStatement(query); scope(exit) ps.close(); ps.setUlong(1, cls.id); ps.setUlong(2, user.id); ps.executeUpdate(); }