Don't create backing tables on startup
This commit is contained in:
parent
5331e2bec9
commit
1c66c10293
@ -1,5 +1,6 @@
|
|||||||
package mineplex.core.database;
|
package mineplex.core.database;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import mineplex.serverdata.database.DBPool;
|
import mineplex.serverdata.database.DBPool;
|
||||||
|
|
||||||
@ -20,22 +21,31 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
* <p>
|
* <p>
|
||||||
* {@code new PlayerKeyValueRepository("tableName", PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")}
|
* {@code new PlayerKeyValueRepository("tableName", PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")}
|
||||||
* <p>
|
* <p>
|
||||||
* NOTE: EACH CONSTRUCTOR IS BLOCKING, and initializes a backing table
|
* Compatible backing table schemas can be written as follows (replace $VARS as appropriate):
|
||||||
* if one does not yet exist
|
* <p><blockquote><pre>
|
||||||
|
* CREATE TABLE IF NOT EXISTS $TABLE_NAME (
|
||||||
|
* accountId INT NOT NULL,
|
||||||
|
* kvKey VARCHAR(255) NOT NULL,
|
||||||
|
* kvValue $VALUE_COLUMN_TYPE
|
||||||
|
* PRIMARY KEY (accountId,kvKey),
|
||||||
|
* INDEX acc_ind (accountId),
|
||||||
|
* FOREIGN KEY (accountId) REFERENCES accounts(id)
|
||||||
|
* )}
|
||||||
|
* </pre></blockquote></p>
|
||||||
*
|
*
|
||||||
* @param <V> The value type to use for this repository
|
* @param <V> The value type to use for this repository
|
||||||
*/
|
*/
|
||||||
public class PlayerKeyValueRepository<V>
|
public class PlayerKeyValueRepository<V>
|
||||||
{
|
{
|
||||||
private static final ImmutableMap<Class<?>, ValueMapper<?>> PRIM_MAPPERS = ImmutableMap.<Class<?>, ValueMapper<?>>builder()
|
private static final ImmutableMap<Class<?>, ValueMapper<?>> PRIM_MAPPERS = ImmutableMap.<Class<?>, ValueMapper<?>>builder()
|
||||||
.put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)"))
|
.put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString))
|
||||||
.put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean, "BOOL"))
|
.put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean))
|
||||||
.put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte, "TINYINT"))
|
.put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte))
|
||||||
.put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort, "SMALLINT"))
|
.put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort))
|
||||||
.put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt, "INTEGER"))
|
.put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt))
|
||||||
.put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong, "BIGINT"))
|
.put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong))
|
||||||
.put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat, "REAL"))
|
.put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat))
|
||||||
.put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble, "DOUBLE"))
|
.put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble))
|
||||||
.build();
|
.build();
|
||||||
private final String _tableName;
|
private final String _tableName;
|
||||||
private final ValueMapper<V> _mapper;
|
private final ValueMapper<V> _mapper;
|
||||||
@ -51,7 +61,11 @@ public class PlayerKeyValueRepository<V>
|
|||||||
@SuppressWarnings("unchecked") // java's generics are garbage.
|
@SuppressWarnings("unchecked") // java's generics are garbage.
|
||||||
public PlayerKeyValueRepository(String tableName, Class<V> clazz) // we could infer the type parameter at runtime, but it's super ugly
|
public PlayerKeyValueRepository(String tableName, Class<V> clazz) // we could infer the type parameter at runtime, but it's super ugly
|
||||||
{
|
{
|
||||||
this(tableName, (ValueMapper<V>) PRIM_MAPPERS.get(clazz));
|
ValueMapper<V> mapper = (ValueMapper<V>) PRIM_MAPPERS.get(clazz);
|
||||||
|
Preconditions.checkNotNull(mapper, "Unsupported value type: " + clazz.getName() + ". (use the other constructor)");
|
||||||
|
|
||||||
|
this._tableName = tableName;
|
||||||
|
this._mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,35 +77,11 @@ public class PlayerKeyValueRepository<V>
|
|||||||
* @param serializer the serializing function used to insert values
|
* @param serializer the serializing function used to insert values
|
||||||
* @param deserializer the deserializing function used to retrieve
|
* @param deserializer the deserializing function used to retrieve
|
||||||
* values
|
* values
|
||||||
* @param columnDef the value type's SQL datatype declaration, e.g., {@code "VARCHAR(255)"} for Strings.
|
|
||||||
*/
|
*/
|
||||||
public PlayerKeyValueRepository(String tableName, Serializer<V> serializer, Deserializer<V> deserializer, String columnDef)
|
public PlayerKeyValueRepository(String tableName, Serializer<V> serializer, Deserializer<V> deserializer)
|
||||||
{
|
|
||||||
this(tableName, new ValueMapper<V>(serializer, deserializer, columnDef));
|
|
||||||
}
|
|
||||||
|
|
||||||
private PlayerKeyValueRepository(String tableName, ValueMapper<V> mapper)
|
|
||||||
{
|
{
|
||||||
this._tableName = tableName;
|
this._tableName = tableName;
|
||||||
this._mapper = mapper;
|
this._mapper = new ValueMapper<V>(serializer, deserializer);
|
||||||
|
|
||||||
// Create a table to back this repository
|
|
||||||
try (Connection conn = DBPool.getAccount().getConnection())
|
|
||||||
{
|
|
||||||
Statement stmt = conn.createStatement();
|
|
||||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + _tableName + "("
|
|
||||||
+ "accountId INT NOT NULL,"
|
|
||||||
+ "kvKey VARCHAR(255) NOT NULL,"
|
|
||||||
+ "kvValue " + _mapper._columnDef + ","
|
|
||||||
+ "PRIMARY KEY (accountId,kvKey),"
|
|
||||||
+ "INDEX acc_ind (accountId),"
|
|
||||||
+ "FOREIGN KEY (accountId) REFERENCES accounts(id) ON DELETE NO ACTION ON UPDATE NO ACTION"
|
|
||||||
+ ")");
|
|
||||||
}
|
|
||||||
catch (SQLException e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -279,13 +269,11 @@ public class PlayerKeyValueRepository<V>
|
|||||||
{
|
{
|
||||||
private final Serializer<V> _serializer;
|
private final Serializer<V> _serializer;
|
||||||
private final Deserializer<V> _deserializer;
|
private final Deserializer<V> _deserializer;
|
||||||
private final String _columnDef;
|
|
||||||
|
|
||||||
private ValueMapper(Serializer<V> serializer, Deserializer<V> deserializer, String columnDef)
|
private ValueMapper(Serializer<V> serializer, Deserializer<V> deserializer)
|
||||||
{
|
{
|
||||||
_serializer = serializer;
|
_serializer = serializer;
|
||||||
_deserializer = deserializer;
|
_deserializer = deserializer;
|
||||||
_columnDef = columnDef;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user