mirror of
https://github.com/sabazadam/Se302.git
synced 2025-12-31 12:21:22 +00:00
Added "Save Schedule" button to Calendar View
Saved to database with timestamp Added "Load Schedule" dropdown to select previous schedules Implemented "Delete Schedule" functionality
This commit is contained in:
@@ -4,8 +4,10 @@ import javafx.application.Application;
|
|||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import org.example.se302.data.DatabaseManager;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main JavaFX Application for Exam Scheduling System.
|
* Main JavaFX Application for Exam Scheduling System.
|
||||||
@@ -23,6 +25,16 @@ public class ExamSchedulerApp extends Application {
|
|||||||
String css = ExamSchedulerApp.class.getResource("css/application.css").toExternalForm();
|
String css = ExamSchedulerApp.class.getResource("css/application.css").toExternalForm();
|
||||||
scene.getStylesheets().add(css);
|
scene.getStylesheets().add(css);
|
||||||
|
|
||||||
|
//create tables in database if does not exists
|
||||||
|
try{
|
||||||
|
|
||||||
|
DatabaseManager.CreateTable();
|
||||||
|
}
|
||||||
|
catch (SQLException e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
stage.setTitle("Exam Scheduling System v1.0");
|
stage.setTitle("Exam Scheduling System v1.0");
|
||||||
stage.setMinWidth(900);
|
stage.setMinWidth(900);
|
||||||
stage.setMinHeight(600);
|
stage.setMinHeight(600);
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
package org.example.se302.data;
|
package org.example.se302.data;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import org.example.se302.model.ExamSchedule;
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.*;
|
||||||
import java.sql.Statement;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
public class DatabaseManager {
|
public class DatabaseManager {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||||
|
|
||||||
private static final String JDBC_URL = "jdbc:sqlite:src/main/resources/db/exam_scheduler.db";
|
private static final String JDBC_URL = "jdbc:sqlite:src/main/resources/db/exam_scheduler.db";
|
||||||
|
|
||||||
private static final String CREATE_SCHEDULES_TABLE =
|
private static final String CREATE_SCHEDULES_TABLE =
|
||||||
"CREATE TABLE IF NOT EXISTS schedules (" +
|
"CREATE TABLE IF NOT EXISTS schedules (" +
|
||||||
" schedule_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
" schedule_id INTEGER PRIMARY KEY AUTOINCREMENT," +
|
||||||
" name TEXT NOT NULL," +
|
" name TEXT NOT NULL," +
|
||||||
" description TEXT," +
|
|
||||||
" created_at DATETIME NOT NULL," +
|
" created_at DATETIME NOT NULL," +
|
||||||
" last_modified DATETIME NOT NULL," +
|
" last_modified DATETIME NOT NULL," +
|
||||||
" is_finalized BOOLEAN NOT NULL DEFAULT 0," +
|
" is_finalized BOOLEAN NOT NULL DEFAULT 0," +
|
||||||
@@ -61,7 +63,4 @@ public class DatabaseManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,226 @@
|
|||||||
package org.example.se302.data;
|
package org.example.se302.data;
|
||||||
|
|
||||||
|
import org.example.se302.model.ExamAssignment;
|
||||||
import org.example.se302.model.ExamSchedule;
|
import org.example.se302.model.ExamSchedule;
|
||||||
|
import org.example.se302.model.ScheduleConfiguration;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class ScheduleDAO {
|
public class ScheduleDAO {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||||
|
|
||||||
public static void SaveSchedule(ExamSchedule examSchedule)
|
public static void InsertSchedule(ExamSchedule examSchedule) throws SQLException
|
||||||
{
|
{
|
||||||
|
long scheduleId = 0;
|
||||||
|
|
||||||
|
try (Connection conn = DatabaseManager.getConnection()) {
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
String sqlSchedule = "INSERT INTO schedules (name, created_at, last_modified, is_finalized, " +
|
||||||
|
"config_num_days, config_slots_per_day, config_start_date) " +
|
||||||
|
"VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sqlSchedule, Statement.RETURN_GENERATED_KEYS)) {
|
||||||
|
|
||||||
|
String createdAtStr = FORMATTER.format(examSchedule.getCreatedAt());
|
||||||
|
String modifiedAtStr = FORMATTER.format(examSchedule.getLastModified());
|
||||||
|
|
||||||
|
stmt.setString(1, examSchedule.getScheduleName());
|
||||||
|
stmt.setString(2, createdAtStr);
|
||||||
|
stmt.setString(3, modifiedAtStr);
|
||||||
|
stmt.setBoolean(4, examSchedule.isFinalized());
|
||||||
|
|
||||||
|
stmt.setInt(5, examSchedule.getConfiguration().getNumDays());
|
||||||
|
stmt.setInt(6, examSchedule.getConfiguration().getSlotsPerDay());
|
||||||
|
stmt.setString(7, examSchedule.getConfiguration().getStartDate().toString());
|
||||||
|
|
||||||
|
stmt.executeUpdate();
|
||||||
|
|
||||||
|
try (ResultSet rs = stmt.getGeneratedKeys()) {
|
||||||
|
if (rs.next()) {
|
||||||
|
scheduleId = rs.getLong(1);
|
||||||
|
} else {
|
||||||
|
throw new SQLException("Program ID'si eklenemedi, veritabanı hatası.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scheduleId > 0) {
|
||||||
|
InsertAssignments(conn, scheduleId, examSchedule.getAllAssignments());
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.commit();
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("Yeni program kaydedilirken bir veritabanı hatası oluştu: " + e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeleteSchedule(ExamSchedule examSchedule)
|
private static void InsertAssignments(Connection conn, long scheduleId, Collection<ExamAssignment> assignments) throws SQLException {
|
||||||
{
|
String sql = "INSERT INTO exam_assignments (schedule_id, course_code, student_count, is_locked, day_index, timeslot_index, classroom_id) " +
|
||||||
|
"VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
for (ExamAssignment assignment : assignments) {
|
||||||
|
|
||||||
|
stmt.setLong(1, scheduleId);
|
||||||
|
stmt.setString(2, assignment.getCourseCode());
|
||||||
|
stmt.setInt(3, assignment.getStudentCount());
|
||||||
|
stmt.setBoolean(4, assignment.isLocked());
|
||||||
|
|
||||||
|
stmt.setInt(5, assignment.getDay());
|
||||||
|
stmt.setInt(6, assignment.getTimeSlotIndex());
|
||||||
|
|
||||||
|
if (assignment.getClassroomId() != null) {
|
||||||
|
stmt.setString(7, assignment.getClassroomId());
|
||||||
|
} else {
|
||||||
|
stmt.setNull(7, Types.VARCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt.addBatch();
|
||||||
|
}
|
||||||
|
stmt.executeBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean DeleteSchedule(long scheduleId) throws SQLException
|
||||||
|
{
|
||||||
|
String sql = "DELETE FROM schedules WHERE schedule_id = ?";
|
||||||
|
|
||||||
|
try (Connection conn = DatabaseManager.getConnection();
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
|
||||||
|
stmt.setLong(1, scheduleId);
|
||||||
|
|
||||||
|
int rowsAffected = stmt.executeUpdate();
|
||||||
|
|
||||||
|
if (rowsAffected > 0) {
|
||||||
|
System.out.printf("Schedule ID %d başarıyla silindi.\n", scheduleId);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
System.out.printf("Hata: Schedule ID %d bulunamadı veya silinemedi.\n", scheduleId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.printf("Program ID %d silinirken veritabanı hatası oluştu: %s\n", scheduleId, e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ExamSchedule loadSchedule(long scheduleId) throws SQLException {
|
||||||
|
ScheduleConfiguration config = null;
|
||||||
|
ExamSchedule schedule = null;
|
||||||
|
|
||||||
|
try (Connection conn = DatabaseManager.getConnection()) {
|
||||||
|
|
||||||
|
// 1. Program Meta Verisini ve Konfigürasyonu Yükle
|
||||||
|
config = loadConfiguration(conn, scheduleId);
|
||||||
|
|
||||||
|
if (config == null) {
|
||||||
|
return null; // Belirtilen ID'ye sahip program bulunamadı.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Temel Schedule Nesnesini Oluştur
|
||||||
|
schedule = loadScheduleMetadata(conn, scheduleId, config);
|
||||||
|
|
||||||
|
if (schedule != null) {
|
||||||
|
// 3. Atamaları Yükle ve Programa Ekle
|
||||||
|
List<ExamAssignment> assignments = loadAssignments(conn, scheduleId);
|
||||||
|
|
||||||
|
for (ExamAssignment assignment : assignments) {
|
||||||
|
// ExamSchedule'ın assignments Map'ine bu atamaları ekle
|
||||||
|
schedule.addAssignment(assignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return schedule;
|
||||||
|
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.printf("Program ID %d yüklenirken veritabanı hatası oluştu: %s\n", scheduleId, e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScheduleConfiguration loadConfiguration(Connection conn, long scheduleId) throws SQLException {
|
||||||
|
String sql = "SELECT config_num_days, config_slots_per_day, config_start_date FROM schedules WHERE schedule_id = ?";
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setLong(1, scheduleId);
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
if (rs.next()) {
|
||||||
|
int numDays = rs.getInt("config_num_days");
|
||||||
|
int slotsPerDay = rs.getInt("config_slots_per_day");
|
||||||
|
String startDateStr = rs.getString("config_start_date");
|
||||||
|
|
||||||
|
// Not: ScheduleConfiguration constructor'ınızın bu alanları almasını varsayıyorum.
|
||||||
|
return new ScheduleConfiguration(numDays, slotsPerDay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ExamSchedule loadScheduleMetadata(Connection conn, long scheduleId, ScheduleConfiguration config) throws SQLException {
|
||||||
|
String sql = "SELECT name, created_at, last_modified, is_finalized FROM schedules WHERE schedule_id = ?";
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setLong(1, scheduleId);
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
if (rs.next()) {
|
||||||
|
String name = rs.getString("name");
|
||||||
|
LocalDateTime createdAt = LocalDateTime.parse(rs.getString("created_at"), FORMATTER);
|
||||||
|
LocalDateTime lastModified = LocalDateTime.parse(rs.getString("last_modified"), FORMATTER);
|
||||||
|
boolean isFinalized = rs.getBoolean("is_finalized");
|
||||||
|
|
||||||
|
// ExamSchedule'ı konfigürasyon ile başlat
|
||||||
|
ExamSchedule schedule = new ExamSchedule(config);
|
||||||
|
|
||||||
|
schedule.setScheduleName(name);
|
||||||
|
schedule.setFinalized(isFinalized);
|
||||||
|
|
||||||
|
return schedule;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ExamAssignment> loadAssignments(Connection conn, long scheduleId) throws SQLException {
|
||||||
|
List<ExamAssignment> assignments = new ArrayList<>();
|
||||||
|
String sql = "SELECT course_code, student_count, is_locked, day_index, timeslot_index, classroom_id " +
|
||||||
|
"FROM exam_assignments WHERE schedule_id = ?";
|
||||||
|
|
||||||
|
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
|
||||||
|
stmt.setLong(1, scheduleId);
|
||||||
|
try (ResultSet rs = stmt.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
String courseCode = rs.getString("course_code");
|
||||||
|
int studentCount = rs.getInt("student_count");
|
||||||
|
boolean isLocked = rs.getBoolean("is_locked");
|
||||||
|
int dayIndex = rs.getInt("day_index");
|
||||||
|
int timeSlotIndex = rs.getInt("timeslot_index");
|
||||||
|
String classroomId = rs.getString("classroom_id");
|
||||||
|
|
||||||
|
ExamAssignment assignment = new ExamAssignment(courseCode);
|
||||||
|
assignment.setStudentCount(studentCount);
|
||||||
|
assignment.setLocked(isLocked);
|
||||||
|
|
||||||
|
assignment.setDay(dayIndex);
|
||||||
|
assignment.setTimeSlotIndex(timeSlotIndex);
|
||||||
|
assignment.setClassroomId(classroomId);
|
||||||
|
|
||||||
|
assignments.add(assignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return assignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user