package fr.monkhanny.dorfromantik.utils; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.sql.ResultSet; import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.List; import java.util.Date; import javax.swing.ImageIcon; import fr.monkhanny.dorfromantik.gui.Reward; public class Database { // Chargement des variables d'environnement private static final String URL = "jdbc:mariadb://dwarves.iut-fbleau.fr/stiti"; private static final String LOGIN = "stiti"; private static final String PASSWORD = "stiti1234"; // Variable de passerelle entre le programme et la base de données private Connection database; /** * Ouvre la connexion avec la base de données */ public Database() throws SQLException { try { // Chargement du driver MariaDB Class.forName("org.mariadb.jdbc.Driver"); try { // Connexion à la base de données this.database = DriverManager.getConnection(URL, LOGIN, PASSWORD); }catch (SQLException e) { // Gestion de l'erreur de connexion throw new SQLException("Échec de la connexion à la base de données: " + e.getMessage(), e); } } catch (ClassNotFoundException e) { // Si le driver n'est pas trouvé throw new SQLException("Driver MariaDB introuvable dans le classpath", e); } } public Connection getDatabase() { return this.database; } /** * Récupère le seed correspondant au mode de jeu (series_id) * @param seriesId L'ID de la série (mode de jeu) * @return Le seed associé à ce mode de jeu * @throws SQLException Si une erreur se produit lors de la récupération du seed */ public long getSeedBySeriesId(long seriesId) throws SQLException { String query = "SELECT series_id FROM Series WHERE series_id = " + seriesId; long seed = -1; // Valeur par défaut si le seed n'est pas trouvé try (Statement stmt = this.database.createStatement(); ResultSet rs = stmt.executeQuery(query)) { if (rs.next()) { seed = rs.getLong("series_id"); } } return seed; } public List getAllScores(long seriesId) throws SQLException { List allScores = new ArrayList<>(); // Requête pour récupérer les scores et le nom de la série String query = "SELECT s.score, se.name " + "FROM Scores s " + "JOIN Series se ON s.series_id = se.series_id " + "WHERE s.series_id = ? " + "ORDER BY s.score DESC"; try (PreparedStatement stmt = this.database.prepareStatement(query)) { stmt.setLong(1, seriesId); // Paramètre pour filtrer par series_id try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { int score = rs.getInt("score"); String seriesName = rs.getString("name"); // Nom de la série // Créer un texte à afficher incluant le score et le nom de la série String displayText = "Score: " + score + " | Série: " + seriesName; // Ajouter l'objet PlayerScore à la liste avec un nom générique et le score allScores.add(new PlayerScore(seriesName, score)); // Ajout du nom de la série } } } return allScores; } public List getAllSeries() { List series = new ArrayList<>(); try { String query = "SELECT name FROM series ORDER BY date_created DESC"; // Trier par date Statement statement = this.database.createStatement(); ResultSet resultSet = statement.executeQuery(query); while (resultSet.next()) { series.add(resultSet.getString("name")); } } catch (SQLException e) { e.printStackTrace(); } return series; } // New method to get series filtered by date range public List getSeriesByDateRange(Date startDate, Date endDate) { List series = new ArrayList<>(); try { String query = "SELECT name FROM Series WHERE creation_date BETWEEN ? AND ? ORDER BY creation_date DESC"; PreparedStatement statement = this.database.prepareStatement(query); statement.setDate(1, new java.sql.Date(startDate.getTime())); statement.setDate(2, new java.sql.Date(endDate.getTime())); ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { series.add(resultSet.getString("name")); } } catch (SQLException e) { e.printStackTrace(); } return series; } // New method to count series within a date range public int countSeriesByDateRange(Date startDate, Date endDate) { int count = 0; try { String query = "SELECT COUNT(*) as series_count FROM Series WHERE creation_date BETWEEN ? AND ?"; PreparedStatement statement = this.database.prepareStatement(query); statement.setDate(1, new java.sql.Date(startDate.getTime())); statement.setDate(2, new java.sql.Date(endDate.getTime())); ResultSet resultSet = statement.executeQuery(); if (resultSet.next()) { count = resultSet.getInt("series_count"); } } catch (SQLException e) { e.printStackTrace(); } return count; } // New method to get paginated series within a date range public List getSeriesByDateRangePaginated(Date startDate, Date endDate, int page, int itemsPerPage) { List series = new ArrayList<>(); try { String query = "SELECT name FROM Series " + "WHERE creation_date BETWEEN ? AND ? " + "ORDER BY creation_date DESC " + "LIMIT ? OFFSET ?"; PreparedStatement statement = this.database.prepareStatement(query); statement.setDate(1, new java.sql.Date(startDate.getTime())); statement.setDate(2, new java.sql.Date(endDate.getTime())); statement.setInt(3, itemsPerPage); statement.setInt(4, (page - 1) * itemsPerPage); ResultSet resultSet = statement.executeQuery(); while (resultSet.next()) { series.add(resultSet.getString("name")); } } catch (SQLException e) { e.printStackTrace(); } return series; } // Optional: Method to get series within a specific number of days public List getRecentSeries(int days) { Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, -days); Date pastDate = calendar.getTime(); return getSeriesByDateRange(pastDate, new Date()); } public long getSeedByName(String name) throws SQLException { String query = "SELECT series_id FROM Series WHERE name = " + "\'" + name + "\'" +";"; long seed = -1; // Valeur par défaut si le seed n'est pas trouvé try (Statement stmt = this.database.createStatement(); ResultSet rs = stmt.executeQuery(query)) { if (rs.next()) { seed = rs.getLong("series_id"); } } return seed; } public void addScore(long seriesId, int score) throws SQLException { String insertQuery = "INSERT INTO Scores (series_id, score) VALUES (?, ?)"; try (PreparedStatement stmt = this.database.prepareStatement(insertQuery)) { stmt.setLong(1, seriesId); stmt.setInt(2, score); stmt.executeUpdate(); } catch (SQLException e) { System.err.println("Erreur lors de l'ajout du score: " + e.getMessage()); throw e; } } public void addCustomSeed(long customSeed) throws SQLException { // Vérifier si la seed existe déjà String checkQuery = "SELECT COUNT(*) FROM Series WHERE series_id = ?"; try (PreparedStatement checkStmt = this.database.prepareStatement(checkQuery)) { checkStmt.setLong(1, customSeed); ResultSet rs = checkStmt.executeQuery(); if (rs.next() && rs.getInt(1) > 0) { // La seed existe déjà return; // Ne pas insérer si la seed existe déjà } } // Trouver le plus grand numéro existant dans les noms de série String lastSeriesQuery = "SELECT name FROM Series"; int nextId = 1; // Valeur par défaut si aucune série n'existe try (PreparedStatement lastSeriesStmt = this.database.prepareStatement(lastSeriesQuery)) { ResultSet rs = lastSeriesStmt.executeQuery(); while (rs.next()) { String seriesName = rs.getString("name"); // Extraire le numéro à la fin du nom de la série String[] parts = seriesName.split(" "); try { int number = Integer.parseInt(parts[parts.length - 1]); if (number >= nextId) { nextId = number + 1; // Incrémenter pour la nouvelle série } } catch (NumberFormatException e) { // Ignorer les séries dont le nom ne suit pas le format attendu continue; } } } // Générer le nom dynamique "Série Custom X" String seriesName = "Série custom " + nextId; // Insérer la nouvelle série dans la base de données String insertQuery = "INSERT INTO Series (name, series_id, creation_date) VALUES (?, ?, CURRENT_TIMESTAMP)"; try (PreparedStatement stmt = this.database.prepareStatement(insertQuery)) { stmt.setString(1, seriesName); stmt.setLong(2, customSeed); // Utiliser customSeed comme series_id stmt.executeUpdate(); } catch (SQLException e) { System.err.println("Erreur lors de l'ajout de la seed custom: " + e.getMessage()); throw e; } } /** * Récupère les meilleurs scores des joueurs (limite de 10 scores) * @return une liste de résultats sous forme de tableau contenant le score et la date formatée */ public List getTopPlayers() throws SQLException { List topPlayers = new ArrayList<>(); // Requête pour récupérer les scores et le nom de la série, triée par score décroissant String query = "SELECT s.score, se.name FROM Scores s " + "JOIN Series se ON s.series_id = se.series_id " + "ORDER BY s.score DESC LIMIT 10"; try (Statement stmt = this.database.createStatement(); ResultSet rs = stmt.executeQuery(query)) { while (rs.next()) { int score = rs.getInt("score"); String seriesName = rs.getString("name"); // Nom de la série // Créer un texte à afficher incluant le score et le nom de la série String displayText = "Score: " + score + " | Série: " + seriesName; // Ajouter l'objet PlayerScore à la liste topPlayers.add(new PlayerScore(seriesName, score)); // Assurez-vous que PlayerScore accepte un nom de série } } return topPlayers; } /** * Récupère les scores d'une série spécifique, triés en ordre décroissant (du plus élevé au plus bas) * @param seriesId L'ID de la série * @return Liste des scores pour la série donnée * @throws SQLException En cas d'erreur lors de la récupération des scores */ public List getScoresBySeriesId(long seriesId) throws SQLException { List scores = new ArrayList<>(); String query = "SELECT score FROM Scores WHERE series_id = ? ORDER BY score DESC"; try (PreparedStatement stmt = this.database.prepareStatement(query)) { stmt.setLong(1, seriesId); try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { scores.add(rs.getInt("score")); } } } // If you want the scores to be in descending order (from highest to lowest) Collections.sort(scores, Collections.reverseOrder()); return scores; } public void close() { try { if (this.database != null && !this.database.isClosed()) { this.database.close(); } } catch (SQLException e) { System.err.println("Erreur lors de la fermeture de la base de données : " + e.getMessage()); } } }