diff --git a/src/de/steamwar/sql/CheckedSchematic.java b/src/de/steamwar/sql/CheckedSchematic.java
new file mode 100644
index 0000000..71fe24a
--- /dev/null
+++ b/src/de/steamwar/sql/CheckedSchematic.java
@@ -0,0 +1,71 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.SelectStatement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.sql.Timestamp;
+import java.util.List;
+
+@AllArgsConstructor
+public class CheckedSchematic {
+
+ private static final Table table = new Table<>(CheckedSchematic.class);
+ private static final SelectStatement statusOfNode = new SelectStatement<>(table, "SELECT * FROM CheckedSchematic WHERE NodeId = ? AND DeclineReason != 'Prüfvorgang abgebrochen' ORDER BY EndTime DESC");
+
+ public static List getLastDeclinedOfNode(int node){
+ return statusOfNode.listSelect(node);
+ }
+
+ @Field(nullable = true)
+ private final Integer nodeId;
+ @Field
+ private final int nodeOwner;
+ @Field
+ private final String nodeName;
+ @Getter
+ @Field
+ private final int validator;
+ @Getter
+ @Field
+ private final Timestamp startTime;
+ @Getter
+ @Field
+ private final Timestamp endTime;
+ @Getter
+ @Field
+ private final String declineReason;
+
+ public int getNode() {
+ return nodeId;
+ }
+
+ public String getSchemName() {
+ return nodeName;
+ }
+
+ public int getSchemOwner() {
+ return nodeOwner;
+ }
+}
diff --git a/src/de/steamwar/sql/NodeDownload.java b/src/de/steamwar/sql/NodeDownload.java
new file mode 100644
index 0000000..0984096
--- /dev/null
+++ b/src/de/steamwar/sql/NodeDownload.java
@@ -0,0 +1,69 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.Statement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Timestamp;
+import java.time.Instant;
+
+@AllArgsConstructor
+public class NodeDownload {
+
+ private static final char[] HEX = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+ private static final String LINK_BASE = "https://steamwar.de/download.php?schem=";
+
+ private static final Table table = new Table<>(NodeDownload.class);
+ private static final Statement insert = table.insertFields("NodeId", "Link");
+
+ @Field(keys = {Table.PRIMARY})
+ private final int nodeId;
+ @Field
+ private final String link;
+ @Field(def = "CURRENT_TIMESTAMP")
+ private final Timestamp timestamp;
+
+ public static String getLink(SchematicNode schem){
+ if(schem.isDir())
+ throw new SecurityException("Can not Download Directorys");
+ MessageDigest digest;
+ try {
+ digest = MessageDigest.getInstance("SHA-1");
+ } catch (NoSuchAlgorithmException e) {
+ throw new SecurityException(e);
+ }
+ digest.reset();
+ digest.update((Instant.now().toString() + schem.getOwner() + schem.getId()).getBytes());
+ String hash = base16encode(digest.digest());
+ insert.update(schem.getId(), hash);
+ return LINK_BASE + hash;
+ }
+ public static String base16encode(byte[] byteArray) {
+ StringBuilder hexBuffer = new StringBuilder(byteArray.length * 2);
+ for (byte b : byteArray)
+ hexBuffer.append(HEX[b >> 4]).append(HEX[b & 0xF]);
+ return hexBuffer.toString();
+ }
+}
diff --git a/src/de/steamwar/sql/Punishment.java b/src/de/steamwar/sql/Punishment.java
new file mode 100644
index 0000000..22f54ce
--- /dev/null
+++ b/src/de/steamwar/sql/Punishment.java
@@ -0,0 +1,119 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2022 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.SelectStatement;
+import de.steamwar.sql.internal.SqlTypeMapper;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.sql.Timestamp;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+
+@AllArgsConstructor
+public class Punishment {
+
+ static {
+ SqlTypeMapper.nameEnumMapper(PunishmentType.class);
+ }
+
+ private static final Table table = new Table<>(Punishment.class, "Punishments");
+ private static final SelectStatement getPunishments = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE PunishmentId IN (SELECT MAX(PunishmentId) FROM Punishments WHERE UserId = ? GROUP BY Type)");
+ private static final SelectStatement getPunishment = new SelectStatement<>(table, "SELECT * FROM Punishments WHERE UserId = ? AND Type = ? ORDER BY PunishmentId DESC LIMIT 1");
+
+ @Field(keys = {Table.PRIMARY}, autoincrement = true)
+ private final int punishmentId;
+ @Field
+ @Getter
+ private final int user;
+ @Field
+ @Getter
+ private final int punisher;
+ @Field
+ @Getter
+ private final PunishmentType type;
+ @Field
+ @Getter
+ private final Timestamp startTime;
+ @Field
+ @Getter
+ private final Timestamp endTime;
+ @Field
+ @Getter
+ private final boolean perma;
+ @Field
+ @Getter
+ private final String reason;
+
+ public static Punishment getPunishmentOfPlayer(int user, PunishmentType type) {
+ return getPunishment.select(user, type);
+ }
+
+ public static Map getPunishmentsOfPlayer(int user) {
+ return getPunishments.listSelect(user).stream().collect(Collectors.toMap(Punishment::getType, punishment -> punishment));
+ }
+
+ public static boolean isPunished(SteamwarUser user, Punishment.PunishmentType type, Consumer callback) {
+ Punishment punishment = Punishment.getPunishmentOfPlayer(user.getId(), type);
+ if(punishment == null || !punishment.isCurrent()) {
+ return false;
+ } else {
+ callback.accept(punishment);
+ return true;
+ }
+ }
+
+ @Deprecated // Not multiling, misleading title
+ public String getBantime(Timestamp endTime, boolean perma) {
+ if (perma) {
+ return "permanent";
+ } else {
+ return endTime.toLocalDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"));
+ }
+ }
+
+ public boolean isCurrent() {
+ return isPerma() || getEndTime().after(new Date());
+ }
+
+ @AllArgsConstructor
+ @Getter
+ public enum PunishmentType {
+ Ban(false, "BAN_TEAM", "BAN_PERMA", "BAN_UNTIL", "UNBAN_ERROR", "UNBAN"),
+ Mute( false, "MUTE_TEAM", "MUTE_PERMA", "MUTE_UNTIL", "UNMUTE_ERROR", "UNMUTE"),
+ NoSchemReceiving(false, "NOSCHEMRECEIVING_TEAM", "NOSCHEMRECEIVING_PERMA", "NOSCHEMRECEIVING_UNTIL", "UNNOSCHEMRECEIVING_ERROR", "UNNOSCHEMRECEIVING"),
+ NoSchemSharing(false, "NOSCHEMSHARING_TEAM", "NOSCHEMSHARING_PERMA", "NOSCHEMSHARING_UNTIL", "UNNOSCHEMSHARING_ERROR", "UNNOSCHEMSHARING"),
+ NoSchemSubmitting(true, "NOSCHEMSUBMITTING_TEAM", "NOSCHEMSUBMITTING_PERMA", "NOSCHEMSUBMITTING_UNTIL", "UNNOSCHEMSUBMITTING_ERROR", "UNNOSCHEMSUBMITTING"),
+ NoDevServer(true, "NODEVSERVER_TEAM", "NODEVSERVER_PERMA", "NODEVSERVER_UNTIL", "UNNODEVSERVER_ERROR", "UNNODEVSERVER");
+
+ private final boolean needsAdmin;
+ private final String teamMessage;
+ private final String playerMessagePerma;
+ private final String playerMessageUntil;
+ private final String usageNotPunished;
+ private final String unpunishmentMessage;
+ }
+}
diff --git a/src/de/steamwar/sql/SQLWrapper.java b/src/de/steamwar/sql/SQLWrapper.java
index 81abe61..cff7dec 100644
--- a/src/de/steamwar/sql/SQLWrapper.java
+++ b/src/de/steamwar/sql/SQLWrapper.java
@@ -28,4 +28,6 @@ public interface SQLWrapper {
SQLWrapper impl = ImplementationProvider.getImpl("de.steamwar.sql.SQLWrapperImpl");
void loadSchemTypes(List tmpTypes, Map tmpFromDB);
+
+ void additionalExceptionMetadata(StringBuilder builder);
}
diff --git a/src/de/steamwar/sql/SWException.java b/src/de/steamwar/sql/SWException.java
new file mode 100644
index 0000000..af1f9c1
--- /dev/null
+++ b/src/de/steamwar/sql/SWException.java
@@ -0,0 +1,52 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2022 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.Statement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+
+import java.io.File;
+
+@AllArgsConstructor
+public class SWException {
+
+ private static final String CWD = System.getProperty("user.dir");
+ private static final String SERVER_NAME = new File(CWD).getName();
+
+ private static final Table table = new Table<>(SWException.class, "Exception");
+ private static final Statement insert = table.insertAll();
+
+ @Field
+ private final String server;
+ @Field
+ private final String message;
+ @Field
+ private final String stacktrace;
+
+ public static void log(String message, String stacktrace){
+ StringBuilder msgBuilder = new StringBuilder(message);
+ SQLWrapper.impl.additionalExceptionMetadata(msgBuilder);
+ msgBuilder.append("\nCWD: ").append(CWD);
+
+ insert.update(SERVER_NAME, msgBuilder.toString(), stacktrace);
+ }
+}
diff --git a/src/de/steamwar/sql/SchemElo.java b/src/de/steamwar/sql/SchemElo.java
new file mode 100644
index 0000000..3aedaba
--- /dev/null
+++ b/src/de/steamwar/sql/SchemElo.java
@@ -0,0 +1,43 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2022 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.SelectStatement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+
+@AllArgsConstructor
+public class SchemElo {
+
+ private static final Table table = new Table<>(SchemElo.class);
+ private static final SelectStatement select = table.select(Table.PRIMARY);
+
+ @Field(keys = {Table.PRIMARY})
+ private final int schemId;
+ @Field
+ private final int elo;
+ @Field(keys = {Table.PRIMARY})
+ private final int season;
+
+ public static int getElo(SchematicNode node, int season) {
+ return select.select(node, season).elo;
+ }
+}
diff --git a/src/de/steamwar/sql/SchematicNode.java b/src/de/steamwar/sql/SchematicNode.java
new file mode 100644
index 0000000..cc62acc
--- /dev/null
+++ b/src/de/steamwar/sql/SchematicNode.java
@@ -0,0 +1,543 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.*;
+import lombok.AccessLevel;
+import lombok.Setter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+public class SchematicNode {
+
+ static {
+ new SqlTypeMapper<>(SchematicNode.class, null, (rs, identifier) -> { throw new SecurityException("SchematicNode cannot be used as type (recursive select)"); }, (st, index, value) -> st.setInt(index, value.nodeId));
+ }
+
+ private static final Map>> TAB_CACHE = new HashMap<>();
+ public static void clear() {
+ TAB_CACHE.clear();
+ }
+
+ private static final String[] fields = {"NodeId", "NodeOwner", "NodeName", "ParentNode", "LastUpdate", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"};
+ private static String nodeSelectCreator(String itemPrefix) {
+ return "SELECT " + Arrays.stream(fields).map(s -> itemPrefix + s).collect(Collectors.joining(", ")) + " FROM SchematicNode ";
+ }
+
+ private static final Table table = new Table<>(SchematicNode.class);
+ private static final Statement create = table.insertFields(true, "NodeOwner", "NodeName", "ParentNode", "NodeItem", "NodeType");
+ private static final Statement update = table.insertAll();
+ private static final Statement delete = table.delete(Table.PRIMARY);
+
+ private static final SelectStatement byId = table.select(Table.PRIMARY);
+ private static final SelectStatement byOwnerNameParent = table.select("OwnerNameParent");
+ private static final SelectStatement byOwnerNameParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeName = ? AND ParentNode is NULL");
+ private static final SelectStatement byParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? ORDER BY NodeName");
+ private static final SelectStatement byParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL ORDER BY NodeName");
+ private static final SelectStatement dirsByParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
+ private static final SelectStatement dirsByParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName");
+ private static final SelectStatement byParentName = table.selectFields("NodeName", "ParentNode");
+ private static final SelectStatement byParentName_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeName = ? AND ParentNode is NULL");
+ private static final SelectStatement accessibleByUserTypeParent = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (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 WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ? ORDER BY NodeName");
+ private static final SelectStatement accessibleByUserTypeParent_Null = new SelectStatement<>(table, "WITH RECURSIVE RSNB AS (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 WHERE NodeType = ? UNION " + nodeSelectCreator("SN.") + "AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null ORDER BY NodeName");
+ private static final SelectStatement accessibleByUserType = 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 WHERE NodeType = ? ORDER BY NodeName");
+ private static final SelectStatement byOwnerType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
+ private static final SelectStatement byType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeType = ? ORDER BY NodeName");
+ private static final SelectStatement accessibleByUser = new SelectStatement<>(table, nodeSelectCreator("s.") + "s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND ((s.NodeOwner = ? AND s.ParentNode IS NULL) OR NOT s.NodeOwner = ?) GROUP BY s.NodeId ORDER BY s.NodeName");
+ private static final Statement schematicAccessibleForUser = new Statement("WITH RECURSIVE RSN AS (" + nodeSelectCreator("") + "WHERE NodeId = ? UNION " + nodeSelectCreator("SN.") + "SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN LEFT Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1");
+ private static final SelectStatement 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 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");
+
+ @Field(keys = {Table.PRIMARY}, autoincrement = true)
+ private final int nodeId;
+ @Field(keys = {"OwnerNameParent"})
+ private final int nodeOwner;
+ @Field(keys = {"OwnerNameParent"})
+ private String nodeName;
+ @Field(keys = {"OwnerNameParent"}, nullable = true)
+ private Integer parentNode;
+ @Field(def = "CURRENT_TIMESTAMP")
+ private Timestamp lastUpdate;
+ @Field(def = "''")
+ private String nodeItem;
+ @Field(def = "'normal'", nullable = true)
+ private SchematicType nodeType;
+ @Field(def = "0")
+ private int nodeRank;
+ @Field(def = "1")
+ private boolean replaceColor;
+ @Field(def = "1")
+ private boolean allowReplay;
+ @Setter(AccessLevel.PACKAGE)
+ @Field(def = "1")
+ private boolean nodeFormat;
+
+ private final Map brCache = new HashMap<>();
+
+ public SchematicNode(
+ int nodeId,
+ int nodeOwner,
+ String nodeName,
+ Integer parentNode,
+ Timestamp lastUpdate,
+ String nodeItem,
+ SchematicType nodeType,
+ int nodeRank,
+ boolean replaceColor,
+ boolean allowReplay,
+ boolean nodeFormat
+ ) {
+ this.nodeId = nodeId;
+ this.nodeOwner = nodeOwner;
+ this.nodeName = nodeName;
+ this.parentNode = parentNode;
+ this.nodeItem = nodeItem;
+ this.nodeType = nodeType;
+ this.lastUpdate = lastUpdate;
+ this.nodeRank = nodeRank;
+ this.replaceColor = replaceColor;
+ this.allowReplay = allowReplay;
+ this.nodeFormat = nodeFormat;
+ }
+
+ public static SchematicNode createSchematic(int owner, String name, Integer parent) {
+ return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), "");
+ }
+
+ public static SchematicNode createSchematicDirectory(int owner, String name, Integer parent) {
+ return createSchematicNode(owner, name, parent, null, "");
+ }
+
+ public static SchematicNode createSchematicNode(int owner, String name, Integer parent, String type, String item) {
+ if (parent != null && parent == 0)
+ parent = null;
+ int nodeId = create.insertGetKey(owner, name, parent, type, item);
+ return getSchematicNode(nodeId);
+ }
+
+ public static SchematicNode getSchematicNode(int owner, String name, SchematicNode parent) {
+ return getSchematicNode(owner, name, parent.getId());
+ }
+
+ public static SchematicNode getSchematicNode(int owner, String name, Integer parent) {
+ if (parent == null || parent == 0)
+ return byOwnerNameParent_null.select(owner, name);
+ return byOwnerNameParent.select(owner, name, parent);
+ }
+
+ public static List getSchematicNodeInNode(SchematicNode parent) {
+ return getSchematicNodeInNode(parent.getId());
+ }
+
+ public static List getSchematicNodeInNode(Integer parent) {
+ if(parent == null || parent == 0) {
+ rootWarning();
+ return byParent_null.listSelect();
+ }
+
+ return byParent.listSelect(parent);
+ }
+
+ public static List getSchematicDirectoryInNode(Integer parent) {
+ if(parent == null || parent == 0) {
+ rootWarning();
+ return dirsByParent_null.listSelect();
+ }
+ return dirsByParent.listSelect(parent);
+ }
+
+ @Deprecated
+ public static SchematicNode getSchematicDirectory(String name, SchematicNode parent) {
+ return getSchematicNode(name, parent.getId());
+ }
+
+ @Deprecated
+ public static SchematicNode getSchematicDirectory(String name, Integer parent) {
+ return getSchematicNode(name, parent);
+ }
+
+ public static SchematicNode getSchematicNode(String name, Integer parent) {
+ if(parent == null || parent == 0) {
+ rootWarning();
+ return byParentName_null.select(name);
+ }
+ return byParentName.select(name, parent);
+ }
+
+ public static SchematicNode getSchematicNode(int id) {
+ return byId.select(id);
+ }
+
+ public static List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
+ if(parent == null || parent == 0)
+ return accessibleByUserTypeParent_Null.listSelect(owner, owner, schemType);
+ return accessibleByUserTypeParent.listSelect(owner, owner, schemType, parent);
+ }
+
+ public static List getAllAccessibleSchematicsOfType(int user, String schemType) {
+ return accessibleByUserType.listSelect(user, user, schemType);
+ }
+
+ public static List getAllSchematicsOfType(int owner, String schemType) {
+ return byOwnerType.listSelect(owner, schemType);
+ }
+
+ @Deprecated
+ public static List getAllSchematicsOfType(String schemType) {
+ return byType.listSelect(schemType);
+ }
+
+ public static List getAllSchematicsOfType(SchematicType schemType) {
+ return byType.listSelect(schemType);
+ }
+
+ public static List deepGet(Integer parent, Predicate filter) {
+ List finalList = new ArrayList<>();
+ List nodes = SchematicNode.getSchematicNodeInNode(parent);
+ nodes.forEach(node -> {
+ if (node.isDir()) {
+ finalList.addAll(deepGet(node.getId(), filter));
+ } else {
+ if (filter.test(node))
+ finalList.add(node);
+ }
+ });
+ return finalList;
+ }
+
+ public static List getSchematicsAccessibleByUser(int user, Integer parent) {
+ if (parent == null || parent == 0)
+ return accessibleByUser.listSelect(user, user, user, user);
+
+ if(schematicAccessibleForUser.select(rs -> {
+ rs.next();
+ return rs.getInt("Accessible") > 0;
+ }, parent, user, user))
+ return getSchematicNodeInNode(parent);
+
+ return Collections.emptyList();
+ }
+
+ public static List getAllSchematicsAccessibleByUser(int user) {
+ return allAccessibleByUser.listSelect(user, user);
+ }
+
+ public static List getAllParentsOfNode(SchematicNode node) {
+ return getAllParentsOfNode(node.getId());
+ }
+
+ public static List getAllParentsOfNode(int node) {
+ return allParentsOfNode.listSelect(node);
+ }
+
+ public static SchematicNode getNodeFromPath(SteamwarUser user, String s) {
+ if (s.startsWith("/")) {
+ s = s.substring(1);
+ }
+ if (s.isEmpty()) {
+ return null;
+ }
+ if (s.contains("/")) {
+ String[] layers = s.split("/");
+ SchematicNode currentNode = null;
+ for (int i = 0; i < layers.length; i++) {
+ int finalI = i;
+ Optional node;
+ if (currentNode == null) {
+ node = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(layers[finalI])).findAny();
+ } else {
+ node = Optional.ofNullable(SchematicNode.getSchematicNode(layers[i], currentNode.getId()));
+ }
+ if (!node.isPresent()) {
+ return null;
+ } else {
+ currentNode = node.get();
+ if (!currentNode.isDir() && i != layers.length - 1) {
+ return null;
+ }
+ }
+ }
+ return currentNode;
+ } else {
+ String finalS = s;
+ return SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0).stream().filter(node1 -> node1.getName().equals(finalS)).findAny().orElse(null);
+ }
+ }
+
+ public static List filterSchems(int user, Predicate filter) {
+ List finalList = new ArrayList<>();
+ List nodes = getSchematicsAccessibleByUser(user, null);
+ nodes.forEach(node -> {
+ if (node.isDir()) {
+ finalList.addAll(deepGet(node.getId(), filter));
+ } else {
+ if (filter.test(node))
+ finalList.add(node);
+ }
+ });
+ return finalList;
+ }
+
+ @Deprecated
+ public static Integer countNodes() {
+ return -1;
+ }
+
+ public int getId() {
+ return nodeId;
+ }
+
+ public int getOwner() {
+ return nodeOwner;
+ }
+
+ public String getName() {
+ return nodeName;
+ }
+
+ public void setName(String name) {
+ this.nodeName = name;
+ updateDB();
+ }
+
+ public Integer getParent() {
+ return parentNode;
+ }
+
+ public void setParent(Integer parent) {
+ this.parentNode = parent;
+ updateDB();
+ }
+
+ public String getItem() {
+ if (nodeItem.isEmpty()) {
+ return isDir() ? "CHEST" : "CAULDRON_ITEM";
+ }
+ return nodeItem;
+ }
+
+ public void setItem(String item) {
+ this.nodeItem = item;
+ updateDB();
+ }
+
+ @Deprecated
+ public String getType() {
+ return nodeType.name();
+ }
+
+ @Deprecated
+ public void setType(String type) {
+ if(isDir())
+ throw new SecurityException("Node is Directory");
+ this.nodeType = SchematicType.fromDB(type);
+ updateDB();
+ }
+
+ public boolean isDir() {
+ return nodeType == null;
+ }
+
+ public boolean getSchemFormat() {
+ if(isDir())
+ throw new SecurityException("Node is Directory");
+ return nodeFormat;
+ }
+
+ public int getRank() {
+ if(isDir())
+ throw new SecurityException("Node is Directory");
+ return nodeRank;
+ }
+
+ @Deprecated
+ public int getRankUnsafe() {
+ return nodeRank;
+ }
+
+ public void setRank(int rank) {
+ if(isDir())
+ throw new SecurityException("Node is Directory");
+ this.nodeRank = rank;
+ }
+
+ public SchematicType getSchemtype() {
+ if(isDir())
+ throw new SecurityException("Is Directory");
+ return nodeType;
+ }
+
+ public void setSchemtype(SchematicType type) {
+ if(isDir())
+ throw new SecurityException("Is Directory");
+ this.nodeType = type;
+ updateDB();
+ }
+
+ public boolean replaceColor() {
+ return replaceColor;
+ }
+
+ public void setReplaceColor(boolean replaceColor) {
+ if(isDir())
+ throw new SecurityException("Is Directory");
+ this.replaceColor = replaceColor;
+ updateDB();
+ }
+
+ public boolean allowReplay() {
+ return allowReplay;
+ }
+
+ public void setAllowReplay(boolean allowReplay) {
+ if(isDir())
+ throw new SecurityException("Is Directory");
+ this.allowReplay = allowReplay;
+ updateDB();
+ }
+
+ public SchematicNode getParentNode() {
+ if(parentNode == null) return null;
+ return SchematicNode.getSchematicNode(parentNode);
+ }
+
+ public int getElo(int season) {
+ return SchemElo.getElo(this, season);
+ }
+
+ public boolean accessibleByUser(int user) {
+ return NodeMember.getNodeMember(nodeId, user) != null;
+ }
+
+ public Set getMembers() {
+ return NodeMember.getNodeMembers(nodeId);
+ }
+
+ public Timestamp getLastUpdate() {
+ return lastUpdate;
+ }
+
+ private void updateDB() {
+ this.lastUpdate = Timestamp.from(Instant.now());
+ update.update(nodeId, nodeOwner, nodeName, parentNode, nodeItem, nodeType, lastUpdate, nodeRank, replaceColor, allowReplay, nodeFormat);
+ this.brCache.clear();
+ TAB_CACHE.clear();
+ }
+
+ public void delete() {
+ delete.update(nodeId);
+ }
+
+ @Override
+ public int hashCode() {
+ return nodeId;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof SchematicNode))
+ return false;
+
+ return ((SchematicNode) obj).getId() == nodeId;
+ }
+
+ public String generateBreadcrumbs(SteamwarUser user) {
+ return brCache.computeIfAbsent(user.getId(), integer -> generateBreadcrumbs("/", user));
+ }
+
+ public String generateBreadcrumbs(String split, SteamwarUser user) {
+ StringBuilder builder = new StringBuilder(getName());
+ SchematicNode currentNode = this;
+ if (currentNode.isDir()) builder.append("/");
+ final Set nodeMembers = NodeMember.getSchematics(user.getId());
+ AtomicInteger i = new AtomicInteger();
+ i.set(currentNode.getId());
+ while (currentNode.getParentNode() != null && nodeMembers.stream().noneMatch(nodeMember -> nodeMember.getNode() == i.get())) {
+ currentNode = currentNode.getParentNode();
+ i.set(currentNode.getId());
+ builder.insert(0, split)
+ .insert(0, currentNode.getName());
+ }
+ return builder.toString();
+ }
+
+ private static final List FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
+ public static boolean invalidSchemName(String[] layers) {
+ for (String layer : layers) {
+ if (layer.isEmpty()) {
+ return true;
+ }
+ if (layer.contains("/") ||
+ layer.contains("\\") ||
+ layer.contains("<") ||
+ layer.contains(">") ||
+ layer.contains("^") ||
+ layer.contains("°") ||
+ layer.contains("'") ||
+ layer.contains("\"") ||
+ layer.contains(" ")) {
+ return true;
+ }
+ if(FORBIDDEN_NAMES.contains(layer.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static List getNodeTabcomplete(SteamwarUser user, String s) {
+ boolean sws = s.startsWith("/");
+ if (sws) {
+ s = s.substring(1);
+ }
+ int index = s.lastIndexOf("/");
+ String cacheKey = index == -1 ? "" : s.substring(0, index);
+ if(TAB_CACHE.containsKey(user.getId()) && TAB_CACHE.get(user.getId()).containsKey(cacheKey)) {
+ return new ArrayList<>(TAB_CACHE.get(user.getId()).get(cacheKey));
+ }
+ List list = new ArrayList<>();
+ if (s.contains("/")) {
+ String preTab = s.substring(0, s.lastIndexOf("/") + 1);
+ SchematicNode pa = SchematicNode.getNodeFromPath(user, preTab);
+ if (pa == null) return Collections.emptyList();
+ List nodes = SchematicNode.getSchematicNodeInNode(pa);
+ nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs(user)));
+ } else {
+ List nodes = SchematicNode.getSchematicsAccessibleByUser(user.getId(), 0);
+ nodes.forEach(node -> list.add((sws ? "/" : "") + node.getName() + (node.isDir() ? "/" : "")));
+ }
+ list.remove("//copy");
+ TAB_CACHE.computeIfAbsent(user.getId(), integer -> new HashMap<>()).putIfAbsent(cacheKey, list);
+ return list;
+ }
+
+ private static void rootWarning() {
+ ByteArrayOutputStream stacktraceOutput = new ByteArrayOutputStream();
+ new Throwable().printStackTrace(new PrintStream(stacktraceOutput));
+ SWException.log("PERFORMANCE!!! Getting all/weird subset of schematic nodes with parent NULL", stacktraceOutput.toString());
+ }
+}
diff --git a/src/de/steamwar/sql/SchematicType.java b/src/de/steamwar/sql/SchematicType.java
index 56c46ad..d87065c 100644
--- a/src/de/steamwar/sql/SchematicType.java
+++ b/src/de/steamwar/sql/SchematicType.java
@@ -101,7 +101,7 @@ public class SchematicType {
}
public static SchematicType fromDB(String input){
- return fromDB.getOrDefault(input.toLowerCase(), null);
+ return fromDB.get(input.toLowerCase());
}
public static List values(){
diff --git a/src/de/steamwar/sql/Season.java b/src/de/steamwar/sql/Season.java
new file mode 100644
index 0000000..8768ad8
--- /dev/null
+++ b/src/de/steamwar/sql/Season.java
@@ -0,0 +1,54 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import java.util.Calendar;
+
+public class Season {
+ private Season() {}
+
+ public static int getSeason() {
+ Calendar calendar = Calendar.getInstance();
+ int yearIndex = calendar.get(Calendar.MONTH) / 4;
+ return (calendar.get(Calendar.YEAR) * 3 + yearIndex);
+ }
+
+ public static String getSeasonStart() {
+ Calendar calendar = Calendar.getInstance();
+ return calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH) / 4 * 3 + 1) + "-1";
+ }
+
+ public static String convertSeasonToString(int season){
+ if (season == -1) return "";
+ int yearSeason = season % 3;
+ int year = (season - yearSeason) / 3;
+ return String.format("%d-%d", year, yearSeason);
+ }
+
+ public static int convertSeasonToNumber(String season){
+ if (season.isEmpty()) return -1;
+ String[] split = season.split("-");
+ try {
+ return Integer.parseInt(split[0]) * 3 + Integer.parseInt(split[1]);
+ } catch (NumberFormatException e) {
+ return -1;
+ }
+ }
+}
diff --git a/src/de/steamwar/sql/SteamwarUser.java b/src/de/steamwar/sql/SteamwarUser.java
index 7245db7..c5ccbd5 100644
--- a/src/de/steamwar/sql/SteamwarUser.java
+++ b/src/de/steamwar/sql/SteamwarUser.java
@@ -42,6 +42,7 @@ public class SteamwarUser {
private static final SelectStatement byUUID = table.selectFields("UUID");
private static final SelectStatement byName = table.selectFields("UserName");
private static final SelectStatement byDiscord = table.selectFields("DiscordId");
+ private static final SelectStatement byTeam = table.selectFields("Team");
private static final SelectStatement getServerTeam = new SelectStatement<>(table, "SELECT * FROM UserData WHERE UserGroup != 'Member' AND UserGroup != 'YouTuber'");
private static final Statement updateName = table.update(Table.PRIMARY, "UserName");
private static final Statement updateLocale = table.update(Table.PRIMARY, "Locale", "ManualLocale");
@@ -147,7 +148,15 @@ public class SteamwarUser {
return byDiscord.select(discordId);
}
+ public static void createOrUpdateUsername(UUID uuid, String userName) {
+ insert.update(uuid, userName);
+ }
+
public static List getServerTeam() {
return getServerTeam.listSelect();
}
+
+ public static List getTeam(int teamId) {
+ return byTeam.listSelect(teamId);
+ }
}
diff --git a/src/de/steamwar/sql/Team.java b/src/de/steamwar/sql/Team.java
new file mode 100644
index 0000000..10e6892
--- /dev/null
+++ b/src/de/steamwar/sql/Team.java
@@ -0,0 +1,61 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.SelectStatement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@AllArgsConstructor
+public class Team {
+
+ private static final Table table = new Table<>(Team.class);
+ private static final SelectStatement select = table.select(Table.PRIMARY);
+
+ @Field(keys = {Table.PRIMARY})
+ @Getter
+ private final int teamId;
+ @Field
+ @Getter
+ private final String teamKuerzel;
+ @Field
+ @Getter
+ private final String teamName;
+ @Field(def = "'8'")
+ @Getter
+ private final String teamColor;
+
+ private static final Team pub = new Team(0, "PUB", "Öffentlich", "8");
+
+ public static Team get(int id) {
+ if(id == 0)
+ return pub;
+ return select.select(id);
+ }
+
+ public List getMembers(){
+ return SteamwarUser.getTeam(teamId).stream().map(SteamwarUser::getId).collect(Collectors.toList());
+ }
+}
diff --git a/src/de/steamwar/sql/TeamTeilnahme.java b/src/de/steamwar/sql/TeamTeilnahme.java
new file mode 100644
index 0000000..533b830
--- /dev/null
+++ b/src/de/steamwar/sql/TeamTeilnahme.java
@@ -0,0 +1,54 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.SelectStatement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@AllArgsConstructor
+public class TeamTeilnahme {
+
+ private static final Table table = new Table<>(TeamTeilnahme.class);
+ private static final SelectStatement select = table.select(Table.PRIMARY);
+ private static final SelectStatement selectTeams = table.selectFields("EventID");
+ private static final SelectStatement selectEvents = table.selectFields("TeamID");
+
+ @Field(keys = {Table.PRIMARY})
+ private final int teamId;
+ @Field(keys = {Table.PRIMARY})
+ private final int eventId;
+
+ public static boolean nimmtTeil(int teamID, int eventID){
+ return select.select(teamID, eventID) != null;
+ }
+
+ public static Set getTeams(int eventID){
+ return selectTeams.listSelect(eventID).stream().map(tt -> Team.get(tt.teamId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries)
+ }
+
+ public static Set getEvents(int teamID){
+ return selectEvents.listSelect(teamID).stream().map(tt -> Event.get(tt.eventId)).collect(Collectors.toSet()); // suboptimal performance (O(n) database queries)
+ }
+}
diff --git a/src/de/steamwar/sql/UserConfig.java b/src/de/steamwar/sql/UserConfig.java
new file mode 100644
index 0000000..0b45f1f
--- /dev/null
+++ b/src/de/steamwar/sql/UserConfig.java
@@ -0,0 +1,72 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.sql;
+
+import de.steamwar.sql.internal.Field;
+import de.steamwar.sql.internal.SelectStatement;
+import de.steamwar.sql.internal.Statement;
+import de.steamwar.sql.internal.Table;
+import lombok.AllArgsConstructor;
+
+import java.util.UUID;
+
+@AllArgsConstructor
+public class UserConfig {
+
+ private static final Table table = new Table<>(UserConfig.class);
+ private static final SelectStatement select = table.select(Table.PRIMARY);
+ private static final Statement insert = table.insertAll();
+ private static final Statement delete = table.delete(Table.PRIMARY);
+
+ @Field(keys = {Table.PRIMARY})
+ private final int user;
+ @Field(keys = {Table.PRIMARY})
+ private final String config;
+ @Field
+ private final String value;
+
+ public static String getConfig(UUID player, String config) {
+ return getConfig(SteamwarUser.get(player).getId(), config);
+ }
+
+ public static String getConfig(int player, String config) {
+ return select.select(player, config).value;
+ }
+
+ public static void updatePlayerConfig(UUID uuid, String config, String value) {
+ updatePlayerConfig(SteamwarUser.get(uuid).getId(), config, value);
+ }
+
+ public static void updatePlayerConfig(int id, String config, String value) {
+ if (value == null) {
+ removePlayerConfig(id, config);
+ return;
+ }
+ insert.update(id, config, value);
+ }
+
+ public static void removePlayerConfig(UUID uuid, String config) {
+ removePlayerConfig(SteamwarUser.get(uuid).getId(), config);
+ }
+
+ public static void removePlayerConfig(int id, String config) {
+ delete.update(id, config);
+ }
+}
diff --git a/src/de/steamwar/sql/internal/Statement.java b/src/de/steamwar/sql/internal/Statement.java
index 2e9edb8..c436fc2 100644
--- a/src/de/steamwar/sql/internal/Statement.java
+++ b/src/de/steamwar/sql/internal/Statement.java
@@ -39,10 +39,14 @@ public class Statement implements AutoCloseable {
private static final Supplier conProvider;
static final Consumer> schemaCreator;
+ private static final boolean mysqlMode;
+ private static final boolean productionDatabase;
+
static {
File file = new File(System.getProperty("user.home"), "mysql.properties");
+ mysqlMode = file.exists();
- if(file.exists()) {
+ if(mysqlMode) {
Properties properties = new Properties();
try {
properties.load(new FileReader(file));
@@ -54,6 +58,7 @@ public class Statement implements AutoCloseable {
String user = properties.getProperty("user");
String password = properties.getProperty("password");
+ productionDatabase = "core".equals(properties.getProperty("database"));
MAX_CONNECTIONS = SQLConfig.impl.maxConnections();
conProvider = () -> {
try {
@@ -64,7 +69,6 @@ public class Statement implements AutoCloseable {
};
schemaCreator = table -> {};
} else {
- MAX_CONNECTIONS = 1;
Connection connection;
try {
@@ -74,6 +78,8 @@ public class Statement implements AutoCloseable {
throw new SecurityException("Could not create sqlite connection", e);
}
+ productionDatabase = false;
+ MAX_CONNECTIONS = 1;
conProvider = () -> connection;
schemaCreator = Table::ensureExistanceInSqlite;
}
@@ -92,6 +98,14 @@ public class Statement implements AutoCloseable {
}
}
+ public static boolean mysqlMode() {
+ return mysqlMode;
+ }
+
+ public static boolean productionDatabase() {
+ return productionDatabase;
+ }
+
private final boolean returnGeneratedKeys;
private final String sql;
private final Map cachedStatements = new HashMap<>();
diff --git a/src/de/steamwar/sql/internal/Table.java b/src/de/steamwar/sql/internal/Table.java
index ffef01c..937f54d 100644
--- a/src/de/steamwar/sql/internal/Table.java
+++ b/src/de/steamwar/sql/internal/Table.java
@@ -59,7 +59,6 @@ public class Table {
Statement.schemaCreator.accept(this);
}
-
public SelectStatement select(String name) {
return selectFields(keyFields(name));
}
@@ -108,7 +107,7 @@ public class Table {
List> primaryKey = keys.containsKey(PRIMARY) ? Arrays.asList(keys.get(PRIMARY)) : Collections.emptyList();
try (Statement statement = new Statement(
"CREATE TABLE IF NOT EXISTS " + name + "(" +
- Arrays.stream(fields).map(field -> field.identifier + " " + field.mapper.sqlType() + (field.field.nullable() ? "" : " NOT NULL DEFAULT NULL") + (!field.field.nullable() && field.field.def().equals("") ? "" : " DEFAULT " + field.field.def()) + (primaryKey.contains(field) ? " PRIMARY KEY" : "") + (field.field.autoincrement() ? " AUTOINCREMENT" : "")).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()) + (primaryKey.contains(field) ? " PRIMARY KEY" : "") + (field.field.autoincrement() ? " AUTOINCREMENT" : "")).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(" ")) +
") STRICT, WITHOUT ROWID")) {
statement.update();