module sample_data; import ddbc; import db; import data_utils; import slf4d; import std.random; import std.algorithm; import std.array; import std.datetime; private const STUDENT_NAMES = [ "Andrew", "Richard", "Klaus", "John", "Wilson", "Grace", "Sarah", "Rebecca", "Lily", "Thomas", "Michael", "Jennifer", "Robert", "Christopher", "Margaret", "Mordecai", "Rigby", "Walter", "Roy", "Cindy" ]; void insertSampleData() { Connection conn = getDb(); conn.setAutoCommit(false); scope(exit) { conn.commit(); conn.close(); } deleteAllData(conn); addUser(conn, "sample-user-A", "test", false, false); addUser(conn, "sample-user-B", "test", true, false); addUser(conn, "sample-user-C", "test", false, false); addUser(conn, "sample-user-D", "test", false, false); ulong adminUserId = addUser(conn, "test", "test", false, true); ulong normalUserId = addUser(conn, "test2", "test", false, false); Random rand = Random(0); addClassroomComplianceSampleData(rand, adminUserId, conn); addClassroomComplianceSampleData(rand, normalUserId, conn); info("Inserted sample data."); } void addClassroomComplianceSampleData(ref Random rand, ulong adminUserId, Connection conn) { const SysTime now = Clock.currTime(); const Date today = Date(now.year, now.month, now.day); for (ushort i = 1; i <= 6; i++) { ulong classId = addClass(conn, "2024-2025", i, adminUserId); bool classHasAssignedDesks = uniform01(rand) < 0.5; size_t count = uniform(10, STUDENT_NAMES.length, rand); auto studentsToAdd = randomSample(STUDENT_NAMES, count, rand); ushort deskNumber = 1; foreach (name; studentsToAdd) { bool removed = uniform01(rand) < 0.1; ushort assignedDeskNumber = 0; if (classHasAssignedDesks) { assignedDeskNumber = deskNumber++; } ulong studentId = addStudent(conn, name, classId, assignedDeskNumber, removed); // Add entries for the last N days for (int n = 0; n < 30; n++) { Date entryDate = today - days(n); bool missingEntry = uniform01(rand) < 0.05; if (missingEntry) continue; addEntry(conn, classId, studentId, entryDate, rand); } } } } ulong addUser(Connection conn, string username, string password, bool locked, bool admin) { import std.digest.sha; string passwordHash = cast(string) sha256Of(password).toHexString().idup; return insertOne( conn, "INSERT INTO auth_user (username, password_hash, is_locked, is_admin) VALUES (?, ?, ?, ?) RETURNING id", username, passwordHash, locked, admin ); } ulong addClass(Connection conn, string schoolYear, ushort number, ulong userId) { return insertOne( conn, "INSERT INTO classroom_compliance_class (number, school_year, user_id) VALUES (?, ?, ?) RETURNING id", number, schoolYear, userId ); } ulong addStudent(Connection conn, string name, ulong classId, ushort deskNumber, bool removed) { return insertOne( conn, "INSERT INTO classroom_compliance_student (name, class_id, desk_number, removed) VALUES (?, ?, ?, ?) RETURNING id", name, classId, deskNumber, removed ); } void addEntry( Connection conn, ulong classId, ulong studentId, Date date, ref Random rand ) { bool absent = uniform01(rand) < 0.05; bool hasComment = uniform01(rand) < 0.25; string comment = hasComment ? "This is a sample comment." : ""; const entryQuery = " INSERT INTO classroom_compliance_entry (class_id, student_id, date, absent, comment) VALUES (?, ?, ?, ?, ?)"; PreparedStatement ps = conn.prepareStatement(entryQuery); scope(exit) ps.close(); ps.setUlong(1, classId); ps.setUlong(2, studentId); ps.setDate(3, date); ps.setBoolean(4, absent); ps.setString(5, comment); ps.executeUpdate(); bool hasChecklistItems = uniform01(rand) < 0.75; if (!hasChecklistItems) return; const checklistItemQuery = " INSERT INTO classroom_compliance_entry_checklist_item (class_id, student_id, date, item, checked, category) VALUES (?, ?, ?, ?, ?, ?)"; PreparedStatement ckPs = conn.prepareStatement(checklistItemQuery); scope(exit) ckPs.close(); const categories = ["Classroom Readiness", "Behavior"]; foreach (category; categories) { for (int i = 0; i < 6; i++) { import std.conv : to; string item = "Checklist item " ~ (i+1).to!string; bool checked = uniform01(rand) < 0.25; ckPs.setUlong(1, classId); ckPs.setUlong(2, studentId); ckPs.setDate(3, date); ckPs.setString(4, item); ckPs.setBoolean(5, checked); ckPs.setString(6, category); ckPs.executeUpdate(); } } } void deleteAllData(Connection conn) { Statement stmt = conn.createStatement(); scope(exit) stmt.close(); const tables = [ "announcement", "classroom_compliance_class_note", "classroom_compliance_entry_checklist_item", "classroom_compliance_entry", "classroom_compliance_student", "classroom_compliance_class", "auth_user" ]; foreach (tableName; tables) { int rows = stmt.executeUpdate("DELETE FROM " ~ tableName); infoF!"Deleted %d rows from %s."(rows, tableName); } }