Added builder, DataTracker and KeyValue #16

Manually merged
quentinlegot merged 40 commits from dev into master 2023-06-13 22:15:40 +02:00
8 changed files with 132 additions and 11 deletions
Showing only changes of commit ee67f7e075 - Show all commits

5
.gitignore vendored
View File

@ -4,8 +4,9 @@ build/
!**/src/main/**/build/
!**/src/test/**/build/
*/run
*/logs
run/*
**/run
**/logs
### IntelliJ IDEA ###
.idea

View File

@ -1,9 +1,9 @@
dependencies {
implementation 'org.postgresql:postgresql:42.5.0'
implementation 'org.postgresql:postgresql:42.6.0'
testImplementation 'com.google.code.gson:gson:2.10'
implementation project(':Core')
}
test {
exclude 'fr/altarik/toolbox/database/**'
exclude 'fr/altarik/toolbox/database/**' // exclude for runner
}

View File

@ -1,14 +1,28 @@
package fr.altarik.toolbox.database;
import fr.altarik.toolbox.database.keyValue.KeyValueBuilder;
import fr.altarik.toolbox.database.keyValue.KeyValueTable;
import java.sql.SQLException;
public class Connections {
/**
* Create a new Connection object for a postgresql database server
* @return
* @return postgresql connection
*/
public static SqlConnection newPostgresConnection(ConnectionConfig config) throws SQLException {
return new PostgresConnection(config);
}
/**
* Create a new (key, value) table if not exist and use it through {@link KeyValueTable} interface
* @param connection Postgresql connection
* @param tableName name of the table to use
* @return interface to control the table
* @throws SQLException if connection is lost
*/
public static KeyValueTable newKeyValueTable(SqlConnection connection, String tableName) throws SQLException {
return KeyValueBuilder.builder().setConnection(connection).setTableName(tableName).build();
}
}

View File

@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
import java.sql.SQLException;
public class KeyValueBuilder implements IBuilder<KeyValueConnection> {
public class KeyValueBuilder implements IBuilder<KeyValuePostgresql> {
private final RequiredParamBuilder<String> tableName;
private final RequiredParamBuilder<SqlConnection> connection;
@ -32,8 +32,8 @@ public class KeyValueBuilder implements IBuilder<KeyValueConnection> {
return this;
}
public KeyValueConnection build() throws SQLException {
return new KeyValueConnection(connection.get(), tableName.get());
public KeyValuePostgresql build() throws SQLException {
return new KeyValuePostgresql(connection.get(), tableName.get());
}
}

View File

@ -9,16 +9,19 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class KeyValueConnection implements KeyValueTable {
public class KeyValuePostgresql implements KeyValueTable {
private final SqlConnection connection;
private final String tableName;
public KeyValueConnection(@NotNull SqlConnection connection, @NotNull String tableName) throws SQLException {
public KeyValuePostgresql(@NotNull SqlConnection connection, @NotNull String tableName) throws SQLException {
this.connection = connection;
this.tableName = tableName;
connection.checkConnection();
createTable(tableName);
}
private void createTable(String tableName) throws SQLException {
try(Statement statement = connection.getConnection().createStatement()) {
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + "(key VARCHAR(50) NOT NULL, value TEXT NOT NULL, PRIMARY KEY(key));");
}
@ -55,4 +58,21 @@ public class KeyValueConnection implements KeyValueTable {
preparedStatement.executeUpdate();
}
}
@Override
public void deleteRow(String key) throws SQLException {
connection.checkConnection();
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("DELETE FROM " + tableName + " WHERE key=?")) {
preparedStatement.setString(1, key);
preparedStatement.executeUpdate();
}
}
@Override
public void truncateTable() throws SQLException {
connection.checkConnection();
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("TRUNCATE TABLE " + tableName)) {
preparedStatement.executeUpdate();
}
}
}

View File

@ -4,6 +4,10 @@ import org.jetbrains.annotations.Nullable;
import java.sql.SQLException;
/**
* <p>Implement of a key value table, abstract the actual representation of the table and its manipulation between this interface</p>
* @see KeyValuePostgresql
*/
public interface KeyValueTable {
/**
@ -33,4 +37,18 @@ public interface KeyValueTable {
*/
void updateValue(String key, String value) throws SQLException;
/**
* <p>Delete row with having {@code key} as unique key</p>
* <p>If key doesn't exist in database, will delete no row without warning</p>
* @param key the key of the row to delete
* @throws SQLException if connection is lost
*/
void deleteRow(String key) throws SQLException;
/**
* Will delete every data inside the table
* @throws SQLException if connection is lost
*/
void truncateTable() throws SQLException;
}

View File

@ -0,0 +1,68 @@
package fr.altarik.toolbox.database.keyValue;
import com.google.gson.Gson;
import fr.altarik.toolbox.database.ConnectionConfig;
import fr.altarik.toolbox.database.Connections;
import fr.altarik.toolbox.database.SqlConnection;
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.util.Objects;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
public class KeyValueTest {
@Test
void tableTest() {
System.out.println("Hello");
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);
try(SqlConnection connection = Connections.newPostgresConnection(config)) {
KeyValueTable keyValueTable = Connections.newKeyValueTable(connection, "toolbox_keyvalue");
keyValueTable.truncateTable();
keyValueTable.insertValue("location", "here");
keyValueTable.insertValue("experience", "5");
assertEquals("here", keyValueTable.getValue("location"));
assertEquals("5", keyValueTable.getValue("experience"));
keyValueTable.updateValue("location", "Elsewhere");
assertEquals("Elsewhere", keyValueTable.getValue("location"));
assertEquals("5", keyValueTable.getValue("experience"));
keyValueTable.updateValue("experience", "10");
assertEquals("Elsewhere", keyValueTable.getValue("location"));
assertEquals("10", keyValueTable.getValue("experience"));
keyValueTable.deleteRow("experience");
assertEquals("Elsewhere", keyValueTable.getValue("location"));
assertNull(keyValueTable.getValue("experience"));
keyValueTable.truncateTable();
assertNull(keyValueTable.getValue("location"));
assertNull(keyValueTable.getValue("experience"));
}
});
}
// TODO: 08/06/2023 Move to Core module in a toolkit class
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;
}
}
}

View File

@ -3,5 +3,5 @@
"port": 5432,
"database": "postgres",
"username": "postgres",
"password": "root"
"password": "Vaubadon1"
}