Don't create backing tables on startup
This commit is contained in:
parent
5331e2bec9
commit
1c66c10293
@ -1,5 +1,6 @@
|
||||
package mineplex.core.database;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
@ -20,22 +21,31 @@ import java.util.concurrent.CompletableFuture;
|
||||
* <p>
|
||||
* {@code new PlayerKeyValueRepository("tableName", PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")}
|
||||
* <p>
|
||||
* NOTE: EACH CONSTRUCTOR IS BLOCKING, and initializes a backing table
|
||||
* if one does not yet exist
|
||||
* Compatible backing table schemas can be written as follows (replace $VARS as appropriate):
|
||||
* <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
|
||||
*/
|
||||
public class PlayerKeyValueRepository<V>
|
||||
{
|
||||
private static final ImmutableMap<Class<?>, ValueMapper<?>> PRIM_MAPPERS = ImmutableMap.<Class<?>, ValueMapper<?>>builder()
|
||||
.put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)"))
|
||||
.put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean, "BOOL"))
|
||||
.put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte, "TINYINT"))
|
||||
.put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort, "SMALLINT"))
|
||||
.put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt, "INTEGER"))
|
||||
.put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong, "BIGINT"))
|
||||
.put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat, "REAL"))
|
||||
.put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble, "DOUBLE"))
|
||||
.put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString))
|
||||
.put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean))
|
||||
.put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte))
|
||||
.put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort))
|
||||
.put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt))
|
||||
.put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong))
|
||||
.put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat))
|
||||
.put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble))
|
||||
.build();
|
||||
private final String _tableName;
|
||||
private final ValueMapper<V> _mapper;
|
||||
@ -51,7 +61,11 @@ public class PlayerKeyValueRepository<V>
|
||||
@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
|
||||
{
|
||||
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 deserializer the deserializing function used to retrieve
|
||||
* 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)
|
||||
{
|
||||
this(tableName, new ValueMapper<V>(serializer, deserializer, columnDef));
|
||||
}
|
||||
|
||||
private PlayerKeyValueRepository(String tableName, ValueMapper<V> mapper)
|
||||
public PlayerKeyValueRepository(String tableName, Serializer<V> serializer, Deserializer<V> deserializer)
|
||||
{
|
||||
this._tableName = tableName;
|
||||
this._mapper = mapper;
|
||||
|
||||
// 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();
|
||||
}
|
||||
this._mapper = new ValueMapper<V>(serializer, deserializer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -279,13 +269,11 @@ public class PlayerKeyValueRepository<V>
|
||||
{
|
||||
private final Serializer<V> _serializer;
|
||||
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;
|
||||
_deserializer = deserializer;
|
||||
_columnDef = columnDef;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user