diff --git a/build.gradle b/build.gradle index a333b98..c30bdbd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,53 +1,37 @@ -plugins { - id 'java' - id 'maven-publish' -} +subprojects { + apply plugin: 'java' + apply plugin: 'maven-publish' + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 -group "${project.maven_group}" -version "${project.maven_version}" - -repositories { - maven { - name 'altarik-snapshots' - url 'https://repo.altarik.fr/snapshots/' - } - maven { - name 'altarik-releases' - url 'https://repo.altarik.fr/releases/' - } - - mavenCentral() -} - -dependencies { - testImplementation "org.junit.jupiter:junit-jupiter-api:${project.junit_version}" - testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${project.junit_version}" -} - -java { - withSourcesJar() - withJavadocJar() -} - - -test { - useJUnitPlatform() -} - -publishing { - publications { - mavenJava(MavenPublication) { - from components.java + publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } } - } - repositories { - maven { - name 'altarik' - url 'https://repo.altarik.fr/'.concat(version.endsWith('SNAPSHOT') ? 'snapshots/' : 'releases/') - credentials { - username = project.repo_username - password = project.repo_password + repositories { + maven { + name 'altarik' + url 'https://repo.altarik.fr/'.concat(version.endsWith('SNAPSHOT') ? 'snapshots/' : 'releases/') + credentials { + username = project.repo_username + password = project.repo_password + } } } } + + repositories { + maven { + name 'altarik-snapshots' + url 'https://repo.altarik.fr/snapshots/' + } + maven { + name 'altarik-releases' + url 'https://repo.altarik.fr/releases/' + } + + mavenCentral() + } } diff --git a/database/build.gradle b/database/build.gradle new file mode 100644 index 0000000..ee22d47 --- /dev/null +++ b/database/build.gradle @@ -0,0 +1,24 @@ +plugins { + id 'java' + id 'maven-publish' +} + +group "${project.maven_group}" +version "${project.maven_version}" + +dependencies { + implementation 'org.postgresql:postgresql:42.5.0' + testImplementation 'com.google.code.gson:gson:2.10' + testImplementation "org.junit.jupiter:junit-jupiter-api:5.9.0" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.9.0" +} + +java { + withSourcesJar() + withJavadocJar() +} + +test { + useJUnitPlatform() +} + diff --git a/database/src/main/java/fr/altarik/toolbox/database/AbstractSqlConnection.java b/database/src/main/java/fr/altarik/toolbox/database/AbstractSqlConnection.java new file mode 100644 index 0000000..7fefcce --- /dev/null +++ b/database/src/main/java/fr/altarik/toolbox/database/AbstractSqlConnection.java @@ -0,0 +1,40 @@ +package fr.altarik.toolbox.database; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +public abstract class AbstractSqlConnection implements SqlConnection { + + protected final ConnectionConfig config; + protected Connection connection; + + protected AbstractSqlConnection(ConnectionConfig config) throws SQLException { + this.config = config; + DriverManager.setLoginTimeout(3); + connect(); + } + + public void checkConnection() throws SQLException { + if(connection == null || connection.isClosed() || !connection.isValid(1)) + connect(); + } + + @Override + public Connection getConnection() { + return connection; + } + + public void closeConnection() { + try { + if(!connection.isClosed()) { + connection.close(); + connection = null; + } + } catch(SQLException ignored) { + // no op + } + } + + +} diff --git a/database/src/main/java/fr/altarik/toolbox/database/ConnectionConfig.java b/database/src/main/java/fr/altarik/toolbox/database/ConnectionConfig.java new file mode 100644 index 0000000..31d1a35 --- /dev/null +++ b/database/src/main/java/fr/altarik/toolbox/database/ConnectionConfig.java @@ -0,0 +1,5 @@ +package fr.altarik.toolbox.database; + +public record ConnectionConfig(String host, int port, String database, String username, String password) { + +} diff --git a/database/src/main/java/fr/altarik/toolbox/database/Connections.java b/database/src/main/java/fr/altarik/toolbox/database/Connections.java new file mode 100644 index 0000000..7d8f5a7 --- /dev/null +++ b/database/src/main/java/fr/altarik/toolbox/database/Connections.java @@ -0,0 +1,14 @@ +package fr.altarik.toolbox.database; + +import java.sql.SQLException; + +public class Connections { + + /** + * Create a new Connection object for a postgresql database server + * @return + */ + public static SqlConnection newPostgresConnection(ConnectionConfig config) throws SQLException { + return new PostgresConnection(config); + } +} diff --git a/database/src/main/java/fr/altarik/toolbox/database/PostgresConnection.java b/database/src/main/java/fr/altarik/toolbox/database/PostgresConnection.java new file mode 100644 index 0000000..beac2bb --- /dev/null +++ b/database/src/main/java/fr/altarik/toolbox/database/PostgresConnection.java @@ -0,0 +1,21 @@ +package fr.altarik.toolbox.database; + +import java.sql.DriverManager; +import java.sql.SQLException; + +public class PostgresConnection extends AbstractSqlConnection { + + PostgresConnection(ConnectionConfig config) throws SQLException { + super(config); + } + + @Override + public void connect() throws SQLException { + String host = config.host(); + int port = config.port(); + String username = config.username(); + String password = config.password(); + String database = config.database(); + this.connection = DriverManager.getConnection("jdbc:postgresql://"+ host + ":" + port + "/" + database + "?autoReconnect=true", username, password); + } +} diff --git a/database/src/main/java/fr/altarik/toolbox/database/SqlConnection.java b/database/src/main/java/fr/altarik/toolbox/database/SqlConnection.java new file mode 100644 index 0000000..0b04fe4 --- /dev/null +++ b/database/src/main/java/fr/altarik/toolbox/database/SqlConnection.java @@ -0,0 +1,16 @@ +package fr.altarik.toolbox.database; + +import java.sql.Connection; +import java.sql.SQLException; + +public interface SqlConnection { + + void connect() throws SQLException; + + Connection getConnection(); + + void checkConnection() throws SQLException; + + void closeConnection(); + +} diff --git a/database/src/test/java/fr/altarik/toolbox/database/ConnectionTest.java b/database/src/test/java/fr/altarik/toolbox/database/ConnectionTest.java new file mode 100644 index 0000000..955151d --- /dev/null +++ b/database/src/test/java/fr/altarik/toolbox/database/ConnectionTest.java @@ -0,0 +1,52 @@ +package fr.altarik.toolbox.database; + +import com.google.gson.Gson; +import org.junit.jupiter.api.Test; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.net.URLConnection; +import java.sql.PreparedStatement; +import java.util.Objects; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + + +class ConnectionTest { + + @Test + void databaseTest() { + assertDoesNotThrow(() -> { + InputStream configInput = getResource("config.yml"); + String configStr = new BufferedReader(new InputStreamReader(Objects.requireNonNull(configInput))) + .lines().collect(Collectors.joining("\n")); + Gson gson = new Gson(); + ConnectionConfig config = gson.fromJson(configStr, ConnectionConfig.class); + SqlConnection connection = Connections.newPostgresConnection(config); + try(PreparedStatement statement = connection.getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS toolbox(id SERIAL, PRIMARY KEY (id));")) { + statement.executeUpdate(); + } + }); + } + + private InputStream getResource(String resourcePath) { + try { + URL url = this.getClass().getClassLoader().getResource(resourcePath); + if(url == null) + return null; + + URLConnection connection = url.openConnection(); + connection.setUseCaches(false); + return connection.getInputStream(); + } catch (IOException e){ + return null; + } + } + + + +} diff --git a/database/src/test/resources/config.yml b/database/src/test/resources/config.yml new file mode 100644 index 0000000..9e2feb9 --- /dev/null +++ b/database/src/test/resources/config.yml @@ -0,0 +1,7 @@ +{ + "host": "127.0.0.1", + "port": 5432, + "database": "postgres", + "username": "postgres", + "password": "root" +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index a93ba4e..773c15c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = 'Toolbox' - +include(':tasks', ':database') diff --git a/tasks/build.gradle b/tasks/build.gradle new file mode 100644 index 0000000..e8595b4 --- /dev/null +++ b/tasks/build.gradle @@ -0,0 +1,21 @@ +plugins { + id 'java' + id 'maven-publish' +} + +group "${project.maven_group}" +version "${project.maven_version}" + +dependencies { + testImplementation "org.junit.jupiter:junit-jupiter-api:${project.junit_version}" + testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${project.junit_version}" +} + +java { + withSourcesJar() + withJavadocJar() +} + +test { + useJUnitPlatform() +} diff --git a/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java b/tasks/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java similarity index 100% rename from src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java rename to tasks/src/main/java/fr/altarik/toolbox/asynctasks/AsyncTasks.java diff --git a/src/test/java/fr/altarik/toolbox/AsyncTaskTest.java b/tasks/src/test/java/fr/altarik/toolbox/AsyncTaskTest.java similarity index 100% rename from src/test/java/fr/altarik/toolbox/AsyncTaskTest.java rename to tasks/src/test/java/fr/altarik/toolbox/AsyncTaskTest.java