Current state
Dieser Commit ist enthalten in:
Ursprung
92bea6255f
Commit
bd626bb4e6
@ -24,7 +24,6 @@ import de.steamwar.sql.internal.SelectStatement;
|
|||||||
import de.steamwar.sql.internal.Statement;
|
import de.steamwar.sql.internal.Statement;
|
||||||
import de.steamwar.sql.internal.Table;
|
import de.steamwar.sql.internal.Table;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -32,6 +31,10 @@ import java.util.Set;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class NodeMember {
|
public class NodeMember {
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
// enforce class initialization
|
||||||
|
}
|
||||||
|
|
||||||
private static final Table<NodeMember> table = new Table<>(NodeMember.class);
|
private static final Table<NodeMember> table = new Table<>(NodeMember.class);
|
||||||
private static final SelectStatement<NodeMember> getNodeMember = table.select(Table.PRIMARY);
|
private static final SelectStatement<NodeMember> getNodeMember = table.select(Table.PRIMARY);
|
||||||
private static final SelectStatement<NodeMember> getNodeMembers = table.selectFields("Node");
|
private static final SelectStatement<NodeMember> getNodeMembers = table.selectFields("Node");
|
||||||
@ -39,15 +42,21 @@ public class NodeMember {
|
|||||||
private static final Statement create = table.insertAll();
|
private static final Statement create = table.insertAll();
|
||||||
private static final Statement delete = table.delete(Table.PRIMARY);
|
private static final Statement delete = table.delete(Table.PRIMARY);
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Field(keys = {Table.PRIMARY})
|
@Field(keys = {Table.PRIMARY})
|
||||||
private final int node;
|
private final int nodeId;
|
||||||
@Getter
|
|
||||||
@Field(keys = {Table.PRIMARY})
|
@Field(keys = {Table.PRIMARY})
|
||||||
private final int member;
|
private final int userId;
|
||||||
|
|
||||||
|
public int getNodeId() {
|
||||||
|
return nodeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
delete.update(node, member);
|
delete.update(nodeId, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NodeMember createNodeMember(int node, int member) {
|
public static NodeMember createNodeMember(int node, int member) {
|
||||||
|
@ -28,6 +28,7 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -36,9 +37,9 @@ public class Replay {
|
|||||||
static {
|
static {
|
||||||
new SqlTypeMapper<>(File.class, "BLOB", (rs, identifier) -> {
|
new SqlTypeMapper<>(File.class, "BLOB", (rs, identifier) -> {
|
||||||
try {
|
try {
|
||||||
File file = File.createTempFile("replay", "replay");
|
File file = File.createTempFile("replay", ".replay");
|
||||||
file.deleteOnExit();
|
file.deleteOnExit();
|
||||||
Files.copy(rs.getBinaryStream(identifier), file.toPath());
|
Files.copy(rs.getBinaryStream(identifier), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||||
return file;
|
return file;
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SQLException(e);
|
throw new SQLException(e);
|
||||||
|
@ -40,7 +40,7 @@ public class SWException {
|
|||||||
private static final Table<SWException> table = new Table<>(SWException.class, "Exception");
|
private static final Table<SWException> table = new Table<>(SWException.class, "Exception");
|
||||||
private static final Statement insert = table.insertFields("server", "message", "stacktrace");
|
private static final Statement insert = table.insertFields("server", "message", "stacktrace");
|
||||||
|
|
||||||
@Field(keys = {Table.PRIMARY})
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
private final int id;
|
private final int id;
|
||||||
@Field(def = "CURRENT_TIMESTAMP")
|
@Field(def = "CURRENT_TIMESTAMP")
|
||||||
private final Timestamp time;
|
private final Timestamp time;
|
||||||
|
@ -72,6 +72,10 @@ public class SchematicNode {
|
|||||||
private static final SelectStatement<SchematicNode> allAccessibleByUser = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> allAccessibleByUser = new SelectStatement<>(table, "WITH RECURSIVE RSN as (" + nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId UNION " + nodeSelectCreator("SN.") + "AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
||||||
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT * FROM RSN ORDER BY NodeName");
|
||||||
|
|
||||||
|
static {
|
||||||
|
NodeMember.init();
|
||||||
|
}
|
||||||
|
|
||||||
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
@Field(keys = {Table.PRIMARY}, autoincrement = true)
|
||||||
private final int nodeId;
|
private final int nodeId;
|
||||||
@Field(keys = {"OwnerNameParent"})
|
@Field(keys = {"OwnerNameParent"})
|
||||||
@ -476,7 +480,7 @@ public class SchematicNode {
|
|||||||
final Set<NodeMember> nodeMembers = NodeMember.getSchematics(user.getId());
|
final Set<NodeMember> nodeMembers = NodeMember.getSchematics(user.getId());
|
||||||
AtomicInteger i = new AtomicInteger();
|
AtomicInteger i = new AtomicInteger();
|
||||||
i.set(currentNode.getId());
|
i.set(currentNode.getId());
|
||||||
while (currentNode.getParentNode() != null && nodeMembers.stream().noneMatch(nodeMember -> nodeMember.getNode() == i.get())) {
|
while (currentNode.getParentNode() != null && nodeMembers.stream().noneMatch(nodeMember -> nodeMember.getNodeId() == i.get())) {
|
||||||
currentNode = currentNode.getParentNode();
|
currentNode = currentNode.getParentNode();
|
||||||
i.set(currentNode.getId());
|
i.set(currentNode.getId());
|
||||||
builder.insert(0, split)
|
builder.insert(0, split)
|
||||||
|
@ -101,7 +101,7 @@ public class SteamwarUser {
|
|||||||
this.leader = leader;
|
this.leader = leader;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.manualLocale = manualLocale;
|
this.manualLocale = manualLocale;
|
||||||
this.discordId = discordId != 0 ? discordId : null;
|
this.discordId = discordId != null && discordId != 0 ? discordId : null;
|
||||||
|
|
||||||
usersById.put(id, this);
|
usersById.put(id, this);
|
||||||
usersByName.put(userName.toLowerCase(), this);
|
usersByName.put(userName.toLowerCase(), this);
|
||||||
@ -118,7 +118,16 @@ public class SteamwarUser {
|
|||||||
public Locale getLocale() {
|
public Locale getLocale() {
|
||||||
if(locale != null)
|
if(locale != null)
|
||||||
return locale;
|
return locale;
|
||||||
return Locale.getDefault(); //TODO test correct locale on join (z.B. FightSystem Hotbarkit)
|
return Locale.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocale(Locale locale, boolean manualLocale) {
|
||||||
|
if (locale == null || (this.manualLocale && !manualLocale))
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.locale = locale;
|
||||||
|
this.manualLocale = manualLocale;
|
||||||
|
updateLocale.update(locale.toLanguageTag(), manualLocale, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SteamwarUser get(String userName){
|
public static SteamwarUser get(String userName){
|
||||||
|
@ -31,7 +31,7 @@ public class SelectStatement<T> extends Statement {
|
|||||||
private final Table<T> table;
|
private final Table<T> table;
|
||||||
|
|
||||||
SelectStatement(Table<T> table, String... kfields) {
|
SelectStatement(Table<T> table, String... kfields) {
|
||||||
this(table, "SELECT " + Arrays.stream(table.fields).map(f -> f.identifier).collect(Collectors.joining(", ")) + " FROM " + table.name + " WHERE " + Arrays.stream(kfields).map(f -> f + " = ?").collect(Collectors.joining(", ")));
|
this(table, "SELECT " + Arrays.stream(table.fields).map(f -> f.identifier).collect(Collectors.joining(", ")) + " FROM " + table.name + " WHERE " + Arrays.stream(kfields).map(f -> f + " = ?").collect(Collectors.joining(" AND ")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SelectStatement(Table<T> table, String sql) {
|
public SelectStatement(Table<T> table, String sql) {
|
||||||
|
@ -47,7 +47,7 @@ public final class SqlTypeMapper<T> {
|
|||||||
public static <T extends Enum<T>> void nameEnumMapper(Class<T> type) {
|
public static <T extends Enum<T>> void nameEnumMapper(Class<T> type) {
|
||||||
new SqlTypeMapper<>(
|
new SqlTypeMapper<>(
|
||||||
type,
|
type,
|
||||||
"VARCHAR(" + Arrays.stream(type.getEnumConstants()).map(e -> e.name().length()).max(Integer::compareTo).get() + ")",
|
"VARCHAR(" + Arrays.stream(type.getEnumConstants()).map(e -> e.name().length()).max(Integer::compareTo).orElse(0) + ")",
|
||||||
(rs, identifier) -> Enum.valueOf(type, rs.getString(identifier)),
|
(rs, identifier) -> Enum.valueOf(type, rs.getString(identifier)),
|
||||||
(st, index, value) -> st.setString(index, value.name())
|
(st, index, value) -> st.setString(index, value.name())
|
||||||
);
|
);
|
||||||
@ -57,7 +57,7 @@ public final class SqlTypeMapper<T> {
|
|||||||
primitiveMapper(boolean.class, Boolean.class, "BOOLEAN", ResultSet::getBoolean, PreparedStatement::setBoolean);
|
primitiveMapper(boolean.class, Boolean.class, "BOOLEAN", ResultSet::getBoolean, PreparedStatement::setBoolean);
|
||||||
primitiveMapper(byte.class, Byte.class, "INTEGER(1)", ResultSet::getByte, PreparedStatement::setByte);
|
primitiveMapper(byte.class, Byte.class, "INTEGER(1)", ResultSet::getByte, PreparedStatement::setByte);
|
||||||
primitiveMapper(short.class, Short.class, "INTEGER(2)", ResultSet::getShort, PreparedStatement::setShort);
|
primitiveMapper(short.class, Short.class, "INTEGER(2)", ResultSet::getShort, PreparedStatement::setShort);
|
||||||
primitiveMapper(int.class, Integer.class, "INTEGER(4)", ResultSet::getInt, PreparedStatement::setInt);
|
primitiveMapper(int.class, Integer.class, "INTEGER", ResultSet::getInt, PreparedStatement::setInt);
|
||||||
primitiveMapper(long.class, Long.class, "INTEGER(8)", ResultSet::getLong, PreparedStatement::setLong);
|
primitiveMapper(long.class, Long.class, "INTEGER(8)", ResultSet::getLong, PreparedStatement::setLong);
|
||||||
primitiveMapper(float.class, Float.class, "REAL", ResultSet::getFloat, PreparedStatement::setFloat);
|
primitiveMapper(float.class, Float.class, "REAL", ResultSet::getFloat, PreparedStatement::setFloat);
|
||||||
primitiveMapper(double.class, Double.class, "REAL", ResultSet::getDouble, PreparedStatement::setDouble);
|
primitiveMapper(double.class, Double.class, "REAL", ResultSet::getDouble, PreparedStatement::setDouble);
|
||||||
|
@ -26,6 +26,7 @@ import java.sql.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -38,15 +39,17 @@ public class Statement implements AutoCloseable {
|
|||||||
private static final int MAX_CONNECTIONS;
|
private static final int MAX_CONNECTIONS;
|
||||||
private static final Supplier<Connection> conProvider;
|
private static final Supplier<Connection> conProvider;
|
||||||
static final Consumer<Table<?>> schemaCreator;
|
static final Consumer<Table<?>> schemaCreator;
|
||||||
|
static final String ON_DUPLICATE_KEY;
|
||||||
|
static final UnaryOperator<String> upsertWrapper;
|
||||||
|
|
||||||
private static final boolean mysqlMode;
|
private static final boolean MYSQL_MODE;
|
||||||
private static final boolean productionDatabase;
|
private static final boolean PRODUCTION_DATABASE;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
File file = new File(System.getProperty("user.home"), "mysql.properties");
|
File file = new File(System.getProperty("user.home"), "mysql.properties");
|
||||||
mysqlMode = file.exists();
|
MYSQL_MODE = file.exists();
|
||||||
|
|
||||||
if(mysqlMode) {
|
if(MYSQL_MODE) {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
try {
|
try {
|
||||||
properties.load(new FileReader(file));
|
properties.load(new FileReader(file));
|
||||||
@ -58,7 +61,7 @@ public class Statement implements AutoCloseable {
|
|||||||
String user = properties.getProperty("user");
|
String user = properties.getProperty("user");
|
||||||
String password = properties.getProperty("password");
|
String password = properties.getProperty("password");
|
||||||
|
|
||||||
productionDatabase = "core".equals(properties.getProperty("database"));
|
PRODUCTION_DATABASE = "core".equals(properties.getProperty("database"));
|
||||||
MAX_CONNECTIONS = SQLConfig.impl.maxConnections();
|
MAX_CONNECTIONS = SQLConfig.impl.maxConnections();
|
||||||
conProvider = () -> {
|
conProvider = () -> {
|
||||||
try {
|
try {
|
||||||
@ -68,6 +71,8 @@ public class Statement implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
schemaCreator = table -> {};
|
schemaCreator = table -> {};
|
||||||
|
ON_DUPLICATE_KEY = " ON DUPLICATE KEY UPDATE ";
|
||||||
|
upsertWrapper = f -> f + " = VALUES(" + f + ")";
|
||||||
} else {
|
} else {
|
||||||
Connection connection;
|
Connection connection;
|
||||||
|
|
||||||
@ -78,10 +83,12 @@ public class Statement implements AutoCloseable {
|
|||||||
throw new SecurityException("Could not create sqlite connection", e);
|
throw new SecurityException("Could not create sqlite connection", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
productionDatabase = false;
|
PRODUCTION_DATABASE = false;
|
||||||
MAX_CONNECTIONS = 1;
|
MAX_CONNECTIONS = 1;
|
||||||
conProvider = () -> connection;
|
conProvider = () -> connection;
|
||||||
schemaCreator = Table::ensureExistanceInSqlite;
|
schemaCreator = Table::ensureExistanceInSqlite;
|
||||||
|
ON_DUPLICATE_KEY = " ON CONFLICT DO UPDATE SET ";
|
||||||
|
upsertWrapper = f -> f + " = " + f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,11 +106,11 @@ public class Statement implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean mysqlMode() {
|
public static boolean mysqlMode() {
|
||||||
return mysqlMode;
|
return MYSQL_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean productionDatabase() {
|
public static boolean productionDatabase() {
|
||||||
return productionDatabase;
|
return PRODUCTION_DATABASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean returnGeneratedKeys;
|
private final boolean returnGeneratedKeys;
|
||||||
|
@ -53,7 +53,7 @@ public class Table<T> {
|
|||||||
keys = Arrays.stream(fields).flatMap(field -> Arrays.stream(field.field.keys())).distinct().collect(Collectors.toMap(Function.identity(), key -> Arrays.stream(fields).filter(field -> Arrays.asList(field.field.keys()).contains(key)).toArray(TableField[]::new)));
|
keys = Arrays.stream(fields).flatMap(field -> Arrays.stream(field.field.keys())).distinct().collect(Collectors.toMap(Function.identity(), key -> Arrays.stream(fields).filter(field -> Arrays.asList(field.field.keys()).contains(key)).toArray(TableField[]::new)));
|
||||||
|
|
||||||
for (TableField<?> field : fields) {
|
for (TableField<?> field : fields) {
|
||||||
fieldsByIdentifier.put(field.identifier, field);
|
fieldsByIdentifier.put(field.identifier.toLowerCase(), field);
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement.schemaCreator.accept(this);
|
Statement.schemaCreator.accept(this);
|
||||||
@ -91,8 +91,8 @@ public class Table<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Statement insertFields(boolean returnGeneratedKeys, String... fields) {
|
public Statement insertFields(boolean returnGeneratedKeys, String... fields) {
|
||||||
List<String> nonKeyFields = Arrays.stream(fields).filter(f -> fieldsByIdentifier.get(f).field.keys().length == 0).collect(Collectors.toList());
|
List<String> nonKeyFields = Arrays.stream(fields).filter(f -> fieldsByIdentifier.get(f.toLowerCase()).field.keys().length == 0).collect(Collectors.toList());
|
||||||
return new Statement("INSERT INTO " + name + " (" + String.join(", ", fields) + ") VALUES (" + Arrays.stream(fields).map(f -> "?").collect(Collectors.joining(", ")) + ")" + (nonKeyFields.isEmpty() ? "" : " ON DUPLICATE KEY UPDATE " + nonKeyFields.stream().map(f -> f + " = VALUES(" + f + ")").collect(Collectors.joining(", "))), returnGeneratedKeys);
|
return new Statement("INSERT INTO " + name + " (" + String.join(", ", fields) + ") VALUES (" + Arrays.stream(fields).map(f -> "?").collect(Collectors.joining(", ")) + ")" + (nonKeyFields.isEmpty() ? "" : Statement.ON_DUPLICATE_KEY + nonKeyFields.stream().map(Statement.upsertWrapper).collect(Collectors.joining(", "))), returnGeneratedKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Statement delete(String name) {
|
public Statement delete(String name) {
|
||||||
@ -104,12 +104,11 @@ public class Table<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ensureExistanceInSqlite() {
|
void ensureExistanceInSqlite() {
|
||||||
List<TableField<?>> primaryKey = keys.containsKey(PRIMARY) ? Arrays.asList(keys.get(PRIMARY)) : Collections.emptyList();
|
|
||||||
try (Statement statement = new Statement(
|
try (Statement statement = new Statement(
|
||||||
"CREATE TABLE IF NOT EXISTS " + name + "(" +
|
"CREATE TABLE IF NOT EXISTS " + name + "(" +
|
||||||
Arrays.stream(fields).map(field -> field.identifier + " " + field.mapper.sqlType() + (field.field.nullable() ? " DEFAULT NULL" : " NOT NULL") + (field.field.nullable() || field.field.def().equals("") ? "" : " DEFAULT " + field.field.def()) + (primaryKey.contains(field) ? " PRIMARY KEY" : "")).collect(Collectors.joining(", ")) +
|
Arrays.stream(fields).map(field -> field.identifier + " " + field.mapper.sqlType() + (field.field.nullable() ? " DEFAULT NULL" : " NOT NULL") + (field.field.nullable() || field.field.def().equals("") ? "" : " DEFAULT " + field.field.def())).collect(Collectors.joining(", ")) +
|
||||||
keys.entrySet().stream().filter(entry -> !entry.getKey().equals(PRIMARY)).map(key -> ", UNIQUE (" + Arrays.stream(key.getValue()).map(field -> field.identifier).collect(Collectors.joining(", ")) + ")").collect(Collectors.joining(" ")) +
|
keys.entrySet().stream().map(key -> (key.getKey().equals(PRIMARY) ? ", PRIMARY KEY(" : ", UNIQUE (") + Arrays.stream(key.getValue()).map(field -> field.identifier).collect(Collectors.joining(", ")) + ")").collect(Collectors.joining(" ")) +
|
||||||
") WITHOUT ROWID")) {
|
")")) {
|
||||||
statement.update();
|
statement.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren