KeyValue has been simplified
All checks were successful
/ build (17, ubuntu-latest) (push) Successful in 4m34s
All checks were successful
/ build (17, ubuntu-latest) (push) Successful in 4m34s
This commit is contained in:
parent
c66067da8c
commit
17cf359e83
@ -1,29 +1,21 @@
|
|||||||
package fr.altarik.toolbox.database.keyvalue;
|
package fr.altarik.toolbox.database.keyvalue;
|
||||||
|
|
||||||
import fr.altarik.toolbox.core.builder.IBuilder;
|
import fr.altarik.toolbox.core.builder.IBuilder;
|
||||||
import fr.altarik.toolbox.core.builder.RequiredCollectionParameterBuilder;
|
|
||||||
import fr.altarik.toolbox.core.builder.RequiredParamBuilder;
|
import fr.altarik.toolbox.core.builder.RequiredParamBuilder;
|
||||||
import fr.altarik.toolbox.database.SqlConnection;
|
import fr.altarik.toolbox.database.SqlConnection;
|
||||||
import net.minecraft.util.Pair;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.sql.JDBCType;
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class KeyValueBuilder implements IBuilder<KeyValueConnection> {
|
public class KeyValueBuilder implements IBuilder<KeyValueConnection> {
|
||||||
|
|
||||||
private final RequiredParamBuilder<String> tableName;
|
private final RequiredParamBuilder<String> tableName;
|
||||||
private final RequiredCollectionParameterBuilder<AdditionalColumn, List<AdditionalColumn>> additionalColumns;
|
|
||||||
private final RequiredParamBuilder<SqlConnection> connection;
|
private final RequiredParamBuilder<SqlConnection> connection;
|
||||||
|
|
||||||
private KeyValueBuilder() {
|
private KeyValueBuilder() {
|
||||||
this.tableName = new RequiredParamBuilder<>();
|
this.tableName = new RequiredParamBuilder<>();
|
||||||
this.connection = new RequiredParamBuilder<>();
|
this.connection = new RequiredParamBuilder<>();
|
||||||
this.additionalColumns = new RequiredCollectionParameterBuilder<>(new ArrayList<>(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static KeyValueBuilder builder() {
|
public static KeyValueBuilder builder() {
|
||||||
@ -40,33 +32,8 @@ public class KeyValueBuilder implements IBuilder<KeyValueConnection> {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyValueBuilder addColumn(AdditionalColumn additionalColumn) {
|
|
||||||
this.additionalColumns.add(additionalColumn);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public KeyValueConnection build() throws SQLException {
|
public KeyValueConnection build() throws SQLException {
|
||||||
return new KeyValueConnection(connection.get(), tableName.get(), additionalColumns.get());
|
return new KeyValueConnection(connection.get(), tableName.get());
|
||||||
}
|
|
||||||
|
|
||||||
public record AdditionalColumn(@NotNull String columnName, @NotNull JDBCType type, boolean notNull, @Nullable AdditionalColumnReference reference) {
|
|
||||||
public AdditionalColumn {
|
|
||||||
Objects.requireNonNull(columnName);
|
|
||||||
Objects.requireNonNull(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pair<AdditionalColumn, Object> toPair(Object value) {
|
|
||||||
return new Pair<>(this, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public record AdditionalColumnReference(@NotNull String referenceTable, @NotNull String... referenceColumns) {
|
|
||||||
public AdditionalColumnReference {
|
|
||||||
Objects.requireNonNull(referenceTable);
|
|
||||||
if(Objects.requireNonNull(referenceColumns).length == 0)
|
|
||||||
throw new IllegalArgumentException("Reference Columns should not be empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package fr.altarik.toolbox.database.keyvalue;
|
package fr.altarik.toolbox.database.keyvalue;
|
||||||
|
|
||||||
import fr.altarik.toolbox.database.SqlConnection;
|
import fr.altarik.toolbox.database.SqlConnection;
|
||||||
import net.minecraft.util.Pair;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -9,151 +8,51 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class KeyValueConnection implements KeyValueTable {
|
public class KeyValueConnection implements KeyValueTable {
|
||||||
|
|
||||||
private final SqlConnection connection;
|
private final SqlConnection connection;
|
||||||
private final String tableName;
|
private final String tableName;
|
||||||
private final List<KeyValueBuilder.AdditionalColumn> additionColumns;
|
|
||||||
|
|
||||||
public KeyValueConnection(@NotNull SqlConnection connection, @NotNull String tableName, @NotNull List<KeyValueBuilder.AdditionalColumn> additionalColumns) throws SQLException {
|
public KeyValueConnection(@NotNull SqlConnection connection, @NotNull String tableName) throws SQLException {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.tableName = tableName;
|
this.tableName = tableName;
|
||||||
this.additionColumns = additionalColumns;
|
|
||||||
connection.checkConnection();
|
connection.checkConnection();
|
||||||
|
|
||||||
try(Statement statement = connection.getConnection().createStatement()) {
|
try(Statement statement = connection.getConnection().createStatement()) {
|
||||||
StringBuilder sql = new StringBuilder("CREATE TABLE IF NOT EXISTS ").append(tableName).append("(id SERIAL,");
|
statement.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + "(key VARCHAR(50) NOT NULL, value TEXT NOT NULL, PRIMARY KEY(key));");
|
||||||
for(KeyValueBuilder.AdditionalColumn additionalColumn : additionalColumns) {
|
|
||||||
sql.append(additionalColumn.columnName()).append(" ").append(additionalColumn.type().getName());
|
|
||||||
if(additionalColumn.notNull()) {
|
|
||||||
sql.append(" NOT NULL ");
|
|
||||||
}
|
|
||||||
if(additionalColumn.reference() != null) {
|
|
||||||
sql.append("REFERENCES ").append(additionalColumn.reference().referenceTable()).append("(");
|
|
||||||
for(int i = 0; i < additionalColumn.reference().referenceColumns().length; ++i) {
|
|
||||||
sql.append(additionalColumn.reference().referenceColumns()[i]);
|
|
||||||
if(i != additionalColumn.reference().referenceColumns().length - 1) {
|
|
||||||
sql.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sql.append(")");
|
|
||||||
}
|
|
||||||
sql.append(",");
|
|
||||||
sql.append("key VARCHAR(50) NOT NULL,").append("value TEXT NOT NULL,").append("PRIMARY KEY(id)");
|
|
||||||
}
|
|
||||||
statement.executeUpdate(sql.toString());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable String getValueById(int id) throws SQLException {
|
public @Nullable String getValue(String key) throws SQLException {
|
||||||
connection.checkConnection();
|
connection.checkConnection();
|
||||||
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("SELECT value FROM " + tableName + " WHERE id=?")) {
|
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("SELECT value FROM " + tableName + " WHERE key=?;")) {
|
||||||
preparedStatement.setInt(1, id);
|
|
||||||
ResultSet resultSet = preparedStatement.executeQuery();
|
|
||||||
if(resultSet.next()) {
|
|
||||||
return resultSet.getString(1);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable Result getValueByAdditionalColumnAndKey(String key, List<Pair<KeyValueBuilder.AdditionalColumn, Object>> additionalColumns) throws SQLException {
|
|
||||||
connection.checkConnection();
|
|
||||||
StringBuilder sql = new StringBuilder("SELECT id, value FROM ").append(tableName).append(" WHERE key=? AND ");
|
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
sql.append(additionalColumns.get(i).getLeft().columnName()).append("=?");
|
|
||||||
if(i != additionalColumns.size() - 1) {
|
|
||||||
sql.append(" AND ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sql.append(";");
|
|
||||||
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement(sql.toString())) {
|
|
||||||
preparedStatement.setString(1, key);
|
preparedStatement.setString(1, key);
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
preparedStatement.setObject(i + 1, additionalColumns.get(i).getRight());
|
|
||||||
}
|
|
||||||
ResultSet resultSet = preparedStatement.executeQuery();
|
ResultSet resultSet = preparedStatement.executeQuery();
|
||||||
if(resultSet.next())
|
if(resultSet.next())
|
||||||
return new Result(resultSet.getString(1), resultSet.getString(2));
|
return resultSet.getString(1);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long insertValue(String key, String value, List<Pair<KeyValueBuilder.AdditionalColumn, Object>> additionalColumns) throws SQLException {
|
public void insertValue(String key, String value) throws SQLException {
|
||||||
connection.checkConnection();
|
connection.checkConnection();
|
||||||
StringBuilder sql = new StringBuilder("INSERT INTO " + tableName + "(key, value");
|
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("INSERT INTO " + tableName + "(key, value) VALUES (?, ?);")){
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
if(i != additionalColumns.size() - 1) {
|
|
||||||
sql.append(", ");
|
|
||||||
}
|
|
||||||
sql.append(additionalColumns.get(i).getLeft().columnName());
|
|
||||||
|
|
||||||
}
|
|
||||||
sql.append(") VALUES (?, ?");
|
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
if(i != additionalColumns.size() - 1) {
|
|
||||||
sql.append(", ");
|
|
||||||
}
|
|
||||||
sql.append("?");
|
|
||||||
}
|
|
||||||
sql.append(");");
|
|
||||||
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS)){
|
|
||||||
preparedStatement.setString(1, key);
|
preparedStatement.setString(1, key);
|
||||||
preparedStatement.setString(2, value);
|
preparedStatement.setString(2, value);
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
preparedStatement.setObject(i + 3, additionalColumns.get(i).getRight());
|
|
||||||
}
|
|
||||||
preparedStatement.executeUpdate();
|
preparedStatement.executeUpdate();
|
||||||
try(ResultSet resultSet = preparedStatement.getGeneratedKeys()) {
|
|
||||||
if(resultSet.next()) {
|
|
||||||
return resultSet.getLong(1);
|
|
||||||
}
|
|
||||||
return -1L;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateValueById(String key, String value) throws SQLException {
|
public void updateValue(String key, String value) throws SQLException {
|
||||||
connection.checkConnection();
|
connection.checkConnection();
|
||||||
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("UPDATE " + tableName + " SET value=? WHERE key=?")) {
|
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement("UPDATE " + tableName + " SET value=? WHERE key=?;")) {
|
||||||
preparedStatement.setString(1, value);
|
preparedStatement.setString(1, value);
|
||||||
preparedStatement.setString(2, key);
|
preparedStatement.setString(2, key);
|
||||||
preparedStatement.executeUpdate();
|
preparedStatement.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updateValue(String key, String value, List<Pair<KeyValueBuilder.AdditionalColumn, Object>> additionalColumns) throws SQLException {
|
|
||||||
connection.checkConnection();
|
|
||||||
StringBuilder sql = new StringBuilder("UPDATE " + tableName + " SET value=? WHERE key=?");
|
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
if(i != additionalColumns.size() - 1) {
|
|
||||||
sql.append(" AND ");
|
|
||||||
}
|
|
||||||
sql.append(additionalColumns.get(i).getLeft().columnName()).append("=?");
|
|
||||||
}
|
|
||||||
sql.append(";");
|
|
||||||
try(PreparedStatement preparedStatement = connection.getConnection().prepareStatement(sql.toString())) {
|
|
||||||
preparedStatement.setString(1, value);
|
|
||||||
preparedStatement.setString(2, key);
|
|
||||||
for(int i = 0; i < additionalColumns.size(); ++i) {
|
|
||||||
preparedStatement.setObject(3 + i, additionalColumns.get(i).getRight());
|
|
||||||
}
|
|
||||||
preparedStatement.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<KeyValueBuilder.AdditionalColumn> getAdditionColumns() {
|
|
||||||
return additionColumns;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,72 +1,36 @@
|
|||||||
package fr.altarik.toolbox.database.keyvalue;
|
package fr.altarik.toolbox.database.keyvalue;
|
||||||
|
|
||||||
import net.minecraft.util.Pair;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface KeyValueTable {
|
public interface KeyValueTable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value which correspond to the given id
|
* <p>Return the first value associated with the unique key.</p>
|
||||||
* @param id primary key, unique id of the key value table
|
|
||||||
* @return the correspond value
|
|
||||||
* @throws SQLException when connection is lost
|
|
||||||
*/
|
|
||||||
@Nullable String getValueById(int id) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Return the first value associated with the key and all the additional columns values given.</p>
|
|
||||||
* <p>In a perfect context, key and additional columns combinaison return a pseudo unique result.</p>
|
|
||||||
*
|
*
|
||||||
* @param key String key of associated to the value, doesn't require to be unique
|
* @param key String key of associated to the value
|
||||||
* @param additionalColumns Object keys of associated to the value, doesn't require to be unique
|
* @return value associated with the key
|
||||||
* @return first (id, value) pair associated with the key and additonal columns combinaison
|
* @throws SQLException if connection is lost
|
||||||
* @throws SQLException if connection is lost, or if additional columns name or value format is incorrect
|
|
||||||
*/
|
*/
|
||||||
@Nullable Result getValueByAdditionalColumnAndKey(String key, List<Pair<KeyValueBuilder.AdditionalColumn, Object>> additionalColumns) throws SQLException;
|
@Nullable String getValue(String key) throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Insert a new value in the table, associate key and additional columns with the value</p>
|
* <p>Insert a new value in the table, associated with key</p>
|
||||||
* <p>Key and additional columns doesn't need to be unique, the combinaison of them have the goal to be unique or it isn't a hard requirement</p>
|
*
|
||||||
* @param key String key which will be associated with the value, doesn't require to be unique
|
* @param key String key which will be associated with the value, is unique
|
||||||
* @param value String value which will be stored in the database
|
* @param value String value which will be stored in the database
|
||||||
* @param additionalColumns Additional columns which will be associated with the value, doesn't require to be unique
|
* @throws SQLException if connection is lost or if {@code key} is not unique (already exist in database)
|
||||||
* @return the id (unique id) of the newly inserted value
|
|
||||||
* @throws SQLException if connection is lost, or if additional columns name or value format is incorrect
|
|
||||||
*/
|
*/
|
||||||
long insertValue(String key, String value, List<Pair<KeyValueBuilder.AdditionalColumn, Object>> additionalColumns) throws SQLException;
|
void insertValue(String key, String value) throws SQLException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update a row associated with the unique key {@code id} with the new value given in parameter
|
* <p>Update value column of the row associated with the key by {@code value}</p>
|
||||||
* @param key unique key associated with the value
|
* <p>If {@code key} doesn't exist in table, will update no row without warning</p>
|
||||||
|
* @param key String key which will is associated with the value, is unique
|
||||||
* @param value new value
|
* @param value new value
|
||||||
* @throws SQLException if connection is lost
|
* @throws SQLException if connection is lost
|
||||||
*/
|
*/
|
||||||
void updateValueById(String key, String value) throws SQLException;
|
void updateValue(String key, String value) throws SQLException;
|
||||||
|
|
||||||
/**
|
|
||||||
* Update all rows associated with the key and additional columns combinaisons with the new value given in parameter
|
|
||||||
* @param key String key which will is associated with the value, doesn't require to be unique
|
|
||||||
* @param value new value
|
|
||||||
* @param additionalColumns Additional columns which are associated with the value, doesn't require to be unique
|
|
||||||
* @throws SQLException if connection is lost, or if additional columns name or value format is incorrect
|
|
||||||
*/
|
|
||||||
void updateValue(String key, String value, List<Pair<KeyValueBuilder.AdditionalColumn, Object>> additionalColumns) throws SQLException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Give the declared additional columns given during initialisation of the class
|
|
||||||
* @return list of declared additional columns
|
|
||||||
*/
|
|
||||||
List<KeyValueBuilder.AdditionalColumn> getAdditionColumns();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Result unique id and value pair stored in the table when using {@link KeyValueTable#getValueByAdditionalColumnAndKey(String, List)}
|
|
||||||
* @param id unique id the row
|
|
||||||
* @param value value store in the same row as {@code id}
|
|
||||||
*/
|
|
||||||
record Result(String id, String value) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user