Skip to content

Commit

Permalink
Suppression de la configuration de Thread Virtuel, c'est vraiment une…
Browse files Browse the repository at this point in the history
… mauvaise idée de l'utiliser

JavaDoc pour la db
  • Loading branch information
Euphillya committed Dec 23, 2024
1 parent a4cdf88 commit 03e632e
Show file tree
Hide file tree
Showing 20 changed files with 264 additions and 85 deletions.
13 changes: 12 additions & 1 deletion database/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
plugins {
id("java")
id("maven-publish")
}
group = "fr.euphyllia.skyllia";
version = "1.3";
version = "2.0";

java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
withJavadocJar()
withSourcesJar()
}

tasks {
compileJava {
options.encoding = "UTF-8"
}
}

publishing {
publications {
create<MavenPublication>("gpr") {
from(components["java"])
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,81 @@
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
* The {@code DatabaseLoader} class provides methods to load and close a MariaDB connection pool,
* execute SQL queries, and handle prepared statements with various parameter types.
*/
public class DatabaseLoader {

private final MariaDB mariaDB;

/**
* Constructs a new {@code DatabaseLoader} with the specified {@link MariaDB} instance.
*
* @param mariaDB the {@link MariaDB} instance used to manage connections.
*/
public DatabaseLoader(MariaDB mariaDB) {
this.mariaDB = mariaDB;
}

/**
* Loads the database connection if not already connected.
*
* @return {@code true} if the database was successfully connected; {@code false} otherwise.
* @throws DatabaseException if an error occurs while initializing the connection pool.
*/
public boolean loadDatabase() throws DatabaseException {
if (mariaDB != null && !mariaDB.isConnected()) {
return mariaDB.onLoad();
}
return false;
}

/**
* Closes the database connection if it is currently open.
*/
public void closeDatabase() {
if (mariaDB != null) {
mariaDB.onClose();
}
}

/**
* Retrieves a {@link Connection} from the {@link MariaDB} instance.
*
* @return a valid {@link Connection}, or {@code null} if {@code mariaDB} is {@code null}.
* @throws DatabaseException if an error occurs while retrieving the connection.
*/
@Nullable
public Connection getMariaDBConnection() throws DatabaseException {
return mariaDB != null ? mariaDB.getConnection() : null;
}

/**
* Executes an SQL statement that modifies data (e.g., INSERT, UPDATE, DELETE)
* and returns the number of affected rows.
*
* @param connection the active SQL {@link Connection}.
* @param query the SQL query string to be executed.
* @param param a list of parameters (in the correct order) to be bound to the query.
* @return the number of rows affected by the query.
* @throws SQLException if an error occurs during the SQL execution.
*/
public int executeInt(Connection connection, String query, List<?> param) throws SQLException {
return this.getStatementFinal(connection, query, param).join().executeUpdate();
}


private CompletableFuture<PreparedStatement> getStatementFinal(Connection connection, String query, List<?> param) throws SQLException {
/**
* Creates and prepares a {@link PreparedStatement} asynchronously using the provided query and parameters.
*
* @param connection the active SQL {@link Connection}.
* @param query the SQL query string to prepare.
* @param param a list of parameters to set on the {@link PreparedStatement}.
* @return a {@link CompletableFuture} containing the prepared statement.
* @throws SQLException if an error occurs while preparing the statement.
*/
private CompletableFuture<PreparedStatement> getStatementFinal(Connection connection, String query, List<?> param)
throws SQLException {
CompletableFuture<PreparedStatement> completableFuture = new CompletableFuture<>();
PreparedStatement statement = connection.prepareStatement(query);
try {
Expand All @@ -53,11 +96,21 @@ private CompletableFuture<PreparedStatement> getStatementFinal(Connection connec
}
}
} finally {
// Ensure the statement is always completed in the future
completableFuture.complete(statement);
}
return completableFuture;
}

/**
* Inserts a value into the {@link PreparedStatement} at the specified parameter index,
* supporting multiple data types.
*
* @param i the parameter index.
* @param statement the {@link PreparedStatement} where the value will be inserted.
* @param value the value to set in the statement parameter.
* @throws SQLException if an error occurs while setting the parameter value.
*/
private void insertStatement(int i, PreparedStatement statement, Object value) throws SQLException {
switch (value) {
case byte[] valueBytes -> statement.setBytes(i, valueBytes);
Expand All @@ -83,6 +136,15 @@ private void insertStatement(int i, PreparedStatement statement, Object value) t
}
}

/**
* Executes an SQL query that may return a result set.
*
* @param connection the active SQL {@link Connection}.
* @param query the SQL query string to be executed.
* @param param a list of parameters (in the correct order) to be bound to the query.
* @return a {@link ResultSet} if the query returns a result, or {@code null} otherwise.
* @throws SQLException if an error occurs during the SQL execution.
*/
public @Nullable ResultSet execute(Connection connection, String query, List<?> param) throws SQLException {
PreparedStatement statement = this.getStatementFinal(connection, query, param).join();
boolean hasResult = statement.execute();
Expand Down
62 changes: 51 additions & 11 deletions database/src/main/java/fr/euphyllia/skyllia/sgbd/MariaDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,74 +12,114 @@
import java.sql.Connection;
import java.sql.SQLException;

/**
* The {@code MariaDB} class is responsible for managing a MariaDB connection using
* a HikariCP connection pool. It implements both {@link DBConnect} and {@link DBInterface},
* providing methods to load and close the pool, check the connection status, and retrieve
* a valid SQL connection.
*/
public class MariaDB implements DBConnect, DBInterface {

private final Logger logger = LogManager.getLogger(MariaDB.class);
private final MariaDBConfig mariaDBConfig;
private HikariDataSource pool;
private boolean connected;

/**
* Constructs a new {@code MariaDB} instance with the specified configuration.
*
* @param configMariaDB the configuration object for connecting to the MariaDB database.
*/
public MariaDB(final MariaDBConfig configMariaDB) {
this.mariaDBConfig = configMariaDB;
this.connected = false;
}


/**
* Initializes the HikariCP connection pool for MariaDB using the provided configuration.
*
* @return {@code true} if the connection pool was successfully initialized, {@code false} otherwise.
* @throws DatabaseException if any error occurs during the pool initialization.
*/
@Override
public boolean onLoad() throws DatabaseException {
if (pool != null && !pool.isClosed()) {
logger.warn("Le pool de connexions est déjà initialisé.");
logger.warn("The connection pool is already initialized.");
return connected;
}

this.pool = new HikariDataSource();
this.pool.setPoolName("skyllia-hikari");
this.pool.setDriverClassName("org.mariadb.jdbc.Driver");
this.pool.setJdbcUrl("jdbc:mariadb://%s:%s/".formatted(mariaDBConfig.hostname(), mariaDBConfig.port()));
this.pool.setUsername(mariaDBConfig.user());
this.pool.setPassword(mariaDBConfig.pass());
this.pool.setConnectionTimeout(mariaDBConfig.timeOut());

// Configure the connection pool
this.pool.setMaximumPoolSize(mariaDBConfig.maxPool());
this.pool.setMinimumIdle(mariaDBConfig.maxPool());
this.pool.setMinimumIdle(mariaDBConfig.minPool());
this.pool.setMaxLifetime(mariaDBConfig.maxLifeTime());
this.pool.setKeepaliveTime(mariaDBConfig.keepAliveTime());
this.pool.setConnectionTimeout(mariaDBConfig.timeOut());

try (Connection connection = pool.getConnection()) {
if (connection.isValid(2)) {
this.connected = true;
this.logger.info("Pool MariaDB initialisé avec succès. Taille maximale du pool : {}", mariaDBConfig.maxPool());
this.logger.info(
"MariaDB pool initialized successfully. Minimum pool size: {}, Maximum pool size: {}",
mariaDBConfig.minPool(),
mariaDBConfig.maxPool()
);
return true;
}
} catch (SQLException e) {
this.logger.fatal("Échec de l'initialisation du pool MariaDB : {}", e.getMessage(), e);
throw new DatabaseException("Échec de l'initialisation du pool MariaDB", e);
throw new DatabaseException("Failed to initialize the MariaDB pool", e);
}
return false;
}

/**
* Closes the HikariCP connection pool if it is currently open and connected.
*/
@Override
public void onClose() {
if (isConnected() && this.pool != null && !this.pool.isClosed()) {
this.pool.close();
connected = false;
logger.info("Pool MariaDB fermé.");
logger.info("MariaDB pool has been closed.");
}
}

/**
* Indicates whether a valid connection to the database is currently active.
*
* @return {@code true} if the connection is active, otherwise {@code false}.
*/
@Override
public boolean isConnected() {
return connected && this.pool != null && !this.pool.isClosed();
}

/**
* Retrieves a {@link Connection} from the HikariCP connection pool.
*
* @return a valid {@link Connection} to the MariaDB database.
* @throws DatabaseException if the pool is not initialized or if retrieving the connection fails.
*/
@Override
public @Nullable Connection getConnection() throws DatabaseException {
if (this.pool == null) {
throw new DatabaseException("Unable to get a connection from the pool (pool is null).");
}

if (!isConnected()) {
throw new DatabaseException("Non connecté à la base de données.");
throw new DatabaseException("Not connected to the database.");
}

try {
return this.pool.getConnection();
} catch (SQLException e) {
this.logger.fatal("Erreur lors de l'obtention de la connexion : {}", e.getMessage(), e);
throw new DatabaseException("Erreur lors de l'obtention de la connexion.", e);
throw new DatabaseException("Unable to get a connection from the pool (getConnection returned null).", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

public record MariaDBConfig(String hostname, String port, String user, String pass,
Boolean useSSL,
Integer maxPool, Integer timeOut, String database, int dbVersion) {
Integer maxPool, Integer minPool, Integer timeOut, Long maxLifeTime, Long keepAliveTime, String database, int dbVersion) {
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
package fr.euphyllia.skyllia.sgbd.model;

import java.sql.ResultSet;

/**
* The {@code DBCallback} interface defines a single method to process
* the {@link ResultSet} returned by a SQL query.
* <p>
* Implementations of this interface allow for custom handling of
* the results obtained from executing a SQL query.
*/
public interface DBCallback {
void run(java.sql.ResultSet resultSet);

/**
* Processes the provided {@link ResultSet}.
*
* @param resultSet the {@link ResultSet} obtained from a SQL query
*/
void run(ResultSet resultSet);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
package fr.euphyllia.skyllia.sgbd.model;

/**
* The {@code DBCallbackInt} interface defines a single method
* to process an integer result, typically the number of affected rows
* from a DML operation (INSERT, UPDATE, DELETE).
*/
public interface DBCallbackInt {

/**
* Processes the provided integer result.
*
* @param var1 the integer result to be processed, often the number of rows affected
* by an INSERT, UPDATE, or DELETE operation
*/
void run(int var1);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,31 @@

import fr.euphyllia.skyllia.sgbd.exceptions.DatabaseException;

/**
* The {@code DBConnect} interface provides methods to manage the life cycle
* of a database connection, including initialization, shutdown, and checking
* connection status.
*/
public interface DBConnect {

/**
* Initializes and loads the database connection.
*
* @return {@code true} if the connection is successfully established,
* {@code false} otherwise
* @throws DatabaseException if any error occurs during initialization
*/
boolean onLoad() throws DatabaseException;

/**
* Closes the database connection if it is currently open.
*/
void onClose();

/**
* Checks whether the database connection is active and valid.
*
* @return {@code true} if the database is connected, {@code false} otherwise
*/
boolean isConnected();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
package fr.euphyllia.skyllia.sgbd.model;

import fr.euphyllia.skyllia.sgbd.exceptions.DatabaseException;
import org.jetbrains.annotations.Nullable;

import java.sql.Connection;

/**
* The {@code DBInterface} interface defines a method for retrieving
* a {@link Connection} to the database. Implementations should handle
* connection details, such as pooling or direct connections.
*/
public interface DBInterface {
@org.jetbrains.annotations.Nullable
java.sql.Connection getConnection() throws DatabaseException;
}

/**
* Retrieves a valid {@link Connection} to the database.
*
* @return a {@link Connection}, or {@code null} if no connection could be established
* @throws DatabaseException if an error occurs while obtaining the connection
*/
@Nullable
Connection getConnection() throws DatabaseException;
}
Loading

0 comments on commit 03e632e

Please sign in to comment.