Add Copyright
Dieser Commit ist enthalten in:
Ursprung
45bc5b05d7
Commit
c94ee5c55f
@ -1,267 +0,0 @@
|
|||||||
/*
|
|
||||||
This file is a part of the SteamWar software.
|
|
||||||
|
|
||||||
Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static de.steamwar.sql.SchematicNode.TAB_CACHE;
|
|
||||||
|
|
||||||
public class EffectiveSchematicNode {
|
|
||||||
|
|
||||||
private static final Table<EffectiveSchematicNode> table = new Table<>(EffectiveSchematicNode.class, "EffectiveSchematicNode");
|
|
||||||
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
|
|
||||||
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> list_null = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode is null ORDER BY NodeName");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> list = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode = ? ORDER BY NodeName");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> byParentName = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode = ? AND NodeName = ? ORDER BY NodeName");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> byParentName_null = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode is null AND NodeName = ? ORDER BY NodeName");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> accessibleByUserTypeParent = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE RSN.ParentNode = ?");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> accessibleByUserTypeInParent_null = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE RSN.ParentNode is null");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> accessibleByUserType = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeType = ?");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
|
|
||||||
private static final SelectStatement<EffectiveSchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
|
||||||
|
|
||||||
public static List<EffectiveSchematicNode> getAll(SteamwarUser user) {
|
|
||||||
return all.listSelect(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<Integer, List<EffectiveSchematicNode>> getAllMap(SteamwarUser user) {
|
|
||||||
return map(all.listSelect(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<EffectiveSchematicNode> list(SteamwarUser user, Integer schematicId) {
|
|
||||||
if(schematicId == null || schematicId == 0) {
|
|
||||||
return list_null.listSelect(user);
|
|
||||||
} else {
|
|
||||||
return list.listSelect(user, schematicId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<EffectiveSchematicNode> byParentName(SteamwarUser user, Integer schematicId, String name) {
|
|
||||||
if(schematicId == null || schematicId == 0) {
|
|
||||||
return Optional.ofNullable(byParentName_null.select(user, name));
|
|
||||||
} else {
|
|
||||||
return Optional.ofNullable(byParentName.select(user, schematicId, name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<EffectiveSchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
|
||||||
return accessibleByUserType.listSelect(type, user, user, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Map<Integer, List<EffectiveSchematicNode>> accessibleByUserTypeMap(SteamwarUser user, SchematicType type) {
|
|
||||||
return map(accessibleByUserTypeParent.listSelect(type, user, user, user));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) {
|
|
||||||
return schematicAccessibleForUser.select(user, schematicId) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<EffectiveSchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
|
||||||
if(parentId == null || parentId == 0) {
|
|
||||||
return accessibleByUserTypeInParent_null.listSelect(type, user, user, user);
|
|
||||||
} else {
|
|
||||||
return accessibleByUserTypeInParent.listSelect(type, user, user, user, parentId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<EffectiveSchematicNode> byIdAndUser(SteamwarUser user, Integer id) {
|
|
||||||
return Optional.ofNullable(byIdAndUser.select(user, id));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<EffectiveSchematicNode> parentsOfNode(SteamwarUser user, Integer id) {
|
|
||||||
return allParentsOfNode.listSelect(id, user, user, user).stream().filter(n -> n.getNodeId() != id).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<Integer, List<EffectiveSchematicNode>> map(List<EffectiveSchematicNode> in) {
|
|
||||||
Map<Integer, List<EffectiveSchematicNode>> map = new HashMap<>();
|
|
||||||
for (EffectiveSchematicNode effectiveSchematicNode : in) {
|
|
||||||
map.computeIfAbsent(effectiveSchematicNode.getNodeParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Field
|
|
||||||
private final int nodeId;
|
|
||||||
@Getter
|
|
||||||
@Field
|
|
||||||
private final int nodeOwner;
|
|
||||||
@Getter
|
|
||||||
@Field
|
|
||||||
private final int effectiveOwner;
|
|
||||||
@Getter
|
|
||||||
@Field
|
|
||||||
private final String nodeName;
|
|
||||||
@Field(nullable = true)
|
|
||||||
private final Integer parentNode;
|
|
||||||
@Getter
|
|
||||||
@Field
|
|
||||||
private final Timestamp lastUpdate;
|
|
||||||
@Field
|
|
||||||
private final String nodeItem;
|
|
||||||
@Field(nullable = true)
|
|
||||||
private final SchematicType nodeType;
|
|
||||||
@Field
|
|
||||||
private final int nodeRank;
|
|
||||||
|
|
||||||
private String brCache = null;
|
|
||||||
|
|
||||||
public EffectiveSchematicNode(int nodeId, int nodeOwner, int effectiveOwner, String nodeName, Integer nodeParent, Timestamp lastUpdate, String nodeItem, SchematicType nodeType, int nodeRank) {
|
|
||||||
this.nodeId = nodeId;
|
|
||||||
this.nodeOwner = nodeOwner;
|
|
||||||
this.effectiveOwner = effectiveOwner;
|
|
||||||
this.nodeName = nodeName;
|
|
||||||
this.parentNode = nodeParent;
|
|
||||||
this.lastUpdate = lastUpdate;
|
|
||||||
this.nodeItem = nodeItem;
|
|
||||||
this.nodeType = nodeType;
|
|
||||||
this.nodeRank = nodeRank;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDir() {
|
|
||||||
return nodeType == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<Integer> getNodeParent() {
|
|
||||||
return Optional.ofNullable(parentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<EffectiveSchematicNode> getParentNode() {
|
|
||||||
return byIdAndUser(SteamwarUser.get(effectiveOwner), parentNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SchematicType getNodeType() {
|
|
||||||
if(isDir()) {
|
|
||||||
throw new IllegalStateException("This node is a directory");
|
|
||||||
}
|
|
||||||
return nodeType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNodeRank() {
|
|
||||||
if(isDir()) {
|
|
||||||
throw new IllegalStateException("This node is a directory");
|
|
||||||
}
|
|
||||||
return nodeRank;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SchematicNode toSchematicNode() {
|
|
||||||
return SchematicNode.getSchematicNode(nodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isWritable() {
|
|
||||||
return effectiveOwner == nodeOwner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getNodeItem() {
|
|
||||||
if (nodeItem.isEmpty()) {
|
|
||||||
return isDir() ? "CHEST" : "CAULDRON_ITEM";
|
|
||||||
}
|
|
||||||
return nodeItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> 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<String> list = new ArrayList<>();
|
|
||||||
if (s.contains("/")) {
|
|
||||||
String preTab = s.substring(0, s.lastIndexOf("/") + 1);
|
|
||||||
Optional<EffectiveSchematicNode> pa = EffectiveSchematicNode.getNodeFromPath(user, preTab);
|
|
||||||
if (!pa.isPresent()) return Collections.emptyList();
|
|
||||||
List<EffectiveSchematicNode> nodes = EffectiveSchematicNode.list(user, pa.get().getNodeId());
|
|
||||||
nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs()));
|
|
||||||
} else {
|
|
||||||
List<EffectiveSchematicNode> nodes = EffectiveSchematicNode.list(user, 0);
|
|
||||||
nodes.forEach(node -> list.add((sws ? "/" : "") + node.getNodeName() + (node.isDir() ? "/" : "")));
|
|
||||||
}
|
|
||||||
list.remove("//copy");
|
|
||||||
TAB_CACHE.computeIfAbsent(user.getId(), integer -> new HashMap<>()).putIfAbsent(cacheKey, list);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateBreadcrumbs() {
|
|
||||||
if(brCache == null) {
|
|
||||||
brCache = generateBreadcrumbs("/");
|
|
||||||
}
|
|
||||||
return brCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateBreadcrumbs(String split) {
|
|
||||||
StringBuilder builder = new StringBuilder(getNodeName());
|
|
||||||
Optional<EffectiveSchematicNode> currentNode = Optional.of(this);
|
|
||||||
if(currentNode.map(EffectiveSchematicNode::isDir).orElse(false)) {
|
|
||||||
builder.append("/");
|
|
||||||
}
|
|
||||||
while (currentNode.isPresent()) {
|
|
||||||
currentNode = currentNode.flatMap(EffectiveSchematicNode::getNodeParent).flatMap(integer -> byIdAndUser(SteamwarUser.get(effectiveOwner), integer));
|
|
||||||
currentNode.ifPresent(node -> builder.insert(0, '/').insert(0, node.getNodeName()));
|
|
||||||
}
|
|
||||||
return builder.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<EffectiveSchematicNode> getNodeFromPath(SteamwarUser user, String s) {
|
|
||||||
if (s.startsWith("/")) {
|
|
||||||
s = s.substring(1);
|
|
||||||
}
|
|
||||||
if (s.endsWith("/")) {
|
|
||||||
s = s.substring(0, s.length() - 1);
|
|
||||||
}
|
|
||||||
if (s.isEmpty()) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
if (s.contains("/")) {
|
|
||||||
String[] layers = s.split("/");
|
|
||||||
Optional<EffectiveSchematicNode> currentNode = EffectiveSchematicNode.byParentName(user, 0, layers[0]);
|
|
||||||
for (int i = 1; i < layers.length; i++) {
|
|
||||||
int finalI = i;
|
|
||||||
Optional<EffectiveSchematicNode> node = currentNode.flatMap(effectiveSchematicNode -> EffectiveSchematicNode.byParentName(user, effectiveSchematicNode.getNodeId(), layers[finalI]));
|
|
||||||
if (!node.isPresent()) {
|
|
||||||
return Optional.empty();
|
|
||||||
} else {
|
|
||||||
currentNode = node;
|
|
||||||
if (!currentNode.map(EffectiveSchematicNode::isDir).orElse(false) && i != layers.length - 1) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currentNode;
|
|
||||||
} else {
|
|
||||||
return EffectiveSchematicNode.byParentName(user, 0, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,6 +21,7 @@ package de.steamwar.sql;
|
|||||||
|
|
||||||
import de.steamwar.sql.internal.*;
|
import de.steamwar.sql.internal.*;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@ -28,7 +29,6 @@ import java.io.PrintStream;
|
|||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ public class SchematicNode {
|
|||||||
|
|
||||||
private static final String[] fields = {"NodeId", "NodeOwner", "NodeName", "ParentNode", "LastUpdate", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"};
|
private static final String[] fields = {"NodeId", "NodeOwner", "NodeName", "ParentNode", "LastUpdate", "NodeItem", "NodeType", "NodeRank", "ReplaceColor", "AllowReplay", "NodeFormat"};
|
||||||
private static String nodeSelectCreator(String itemPrefix) {
|
private static String nodeSelectCreator(String itemPrefix) {
|
||||||
return "SELECT " + Arrays.stream(fields).map(s -> itemPrefix + s).collect(Collectors.joining(", ")) + " FROM SchematicNode ";
|
return "SELECT " + Arrays.stream(fields).map(s -> itemPrefix + s).collect(Collectors.joining(", ")) + ", NodeOwner AS EffectiveOwner FROM SchematicNode ";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
private static final Table<SchematicNode> table = new Table<>(SchematicNode.class);
|
||||||
@ -60,11 +60,19 @@ public class SchematicNode {
|
|||||||
private static final SelectStatement<SchematicNode> byParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> byParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL ORDER BY NodeName");
|
||||||
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> dirsByParent = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode = ? AND NodeType is NULL ORDER BY NodeName");
|
||||||
private static final SelectStatement<SchematicNode> dirsByParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> dirsByParent_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE ParentNode is NULL AND NodeType is NULL ORDER BY NodeName");
|
||||||
private static final SelectStatement<SchematicNode> byParentName = table.selectFields("NodeName", "ParentNode");
|
|
||||||
private static final SelectStatement<SchematicNode> byParentName_null = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeName = ? AND ParentNode is NULL");
|
|
||||||
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> byOwnerType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeOwner = ? AND NodeType = ? ORDER BY NodeName");
|
||||||
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeType = ? ORDER BY NodeName");
|
private static final SelectStatement<SchematicNode> byType = new SelectStatement<>(table, nodeSelectCreator("") + "WHERE NodeType = ? 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> all = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> list_null = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode is null ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> list = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> byParentName = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode = ? AND NodeName = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> byParentName_null = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND ParentNode is null AND NodeName = ? ORDER BY NodeName");
|
||||||
|
private static final SelectStatement<SchematicNode> schematicAccessibleForUser = new SelectStatement<>(table, "SELECT COUNT(DISTINCT NodeId) FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
|
||||||
|
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE RSN.ParentNode = ?");
|
||||||
|
private static final SelectStatement<SchematicNode> accessibleByUserTypeInParent_null = new SelectStatement<>(table, "WITH RECURSIVE RSN AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeType = ? AND EffectiveOwner = ? UNION SELECT SN.NodeId, SN.ParentNode FROM RSN, EffectiveSchematicNode SN WHERE SN.NodeId = RSN.ParentNode AND EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, RSN.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM RSN INNER JOIN SchematicNode SN ON RSN.NodeId = SN.NodeId WHERE RSN.ParentNode is null");
|
||||||
|
private static final SelectStatement<SchematicNode> accessibleByUserType = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeType = ?");
|
||||||
|
private static final SelectStatement<SchematicNode> byIdAndUser = new SelectStatement<>(table, "SELECT * FROM EffectiveSchematicNode WHERE EffectiveOwner = ? AND NodeId = ?");
|
||||||
|
private static final SelectStatement<SchematicNode> allParentsOfNode = new SelectStatement<>(table, "WITH RECURSIVE R AS (SELECT NodeId, ParentNode FROM EffectiveSchematicNode WHERE NodeId = ? AND EffectiveOwner = ? UNION SELECT E.NodeId, E.ParentNode FROM R, EffectiveSchematicNode E WHERE R.ParentNode = E.NodeId AND E.EffectiveOwner = ?) SELECT SN.NodeId, SN.NodeOwner, ? AS EffectiveOwner, SN.NodeName, R.ParentNode, SN.LastUpdate, SN.NodeItem, SN.NodeType, SN.NodeRank FROM R INNER JOIN SchematicNode SN ON SN.NodeId = R.NodeId");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
NodeMember.init();
|
NodeMember.init();
|
||||||
@ -74,6 +82,9 @@ public class SchematicNode {
|
|||||||
private final int nodeId;
|
private final int nodeId;
|
||||||
@Field(keys = {"OwnerNameParent"})
|
@Field(keys = {"OwnerNameParent"})
|
||||||
private final int nodeOwner;
|
private final int nodeOwner;
|
||||||
|
@Field
|
||||||
|
@Getter
|
||||||
|
private final int effectiveOwner;
|
||||||
@Field(keys = {"OwnerNameParent"})
|
@Field(keys = {"OwnerNameParent"})
|
||||||
private String nodeName;
|
private String nodeName;
|
||||||
@Field(keys = {"OwnerNameParent"}, nullable = true)
|
@Field(keys = {"OwnerNameParent"}, nullable = true)
|
||||||
@ -94,9 +105,12 @@ public class SchematicNode {
|
|||||||
@Field(def = "1")
|
@Field(def = "1")
|
||||||
private boolean nodeFormat;
|
private boolean nodeFormat;
|
||||||
|
|
||||||
|
private String brCache;
|
||||||
|
|
||||||
public SchematicNode(
|
public SchematicNode(
|
||||||
int nodeId,
|
int nodeId,
|
||||||
int nodeOwner,
|
int nodeOwner,
|
||||||
|
int effectiveOwner,
|
||||||
String nodeName,
|
String nodeName,
|
||||||
Integer parentNode,
|
Integer parentNode,
|
||||||
Timestamp lastUpdate,
|
Timestamp lastUpdate,
|
||||||
@ -109,6 +123,7 @@ public class SchematicNode {
|
|||||||
) {
|
) {
|
||||||
this.nodeId = nodeId;
|
this.nodeId = nodeId;
|
||||||
this.nodeOwner = nodeOwner;
|
this.nodeOwner = nodeOwner;
|
||||||
|
this.effectiveOwner = effectiveOwner;
|
||||||
this.nodeName = nodeName;
|
this.nodeName = nodeName;
|
||||||
this.parentNode = parentNode;
|
this.parentNode = parentNode;
|
||||||
this.nodeItem = nodeItem;
|
this.nodeItem = nodeItem;
|
||||||
@ -120,6 +135,66 @@ public class SchematicNode {
|
|||||||
this.nodeFormat = nodeFormat;
|
this.nodeFormat = nodeFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> getAll(SteamwarUser user) {
|
||||||
|
return all.listSelect(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Integer, List<SchematicNode>> getAllMap(SteamwarUser user) {
|
||||||
|
return map(getAll(user));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> list(SteamwarUser user, Integer schematicId) {
|
||||||
|
if(schematicId == null || schematicId == 0) {
|
||||||
|
return list_null.listSelect(user);
|
||||||
|
} else {
|
||||||
|
return list.listSelect(user, schematicId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SchematicNode byParentName(SteamwarUser user, Integer schematicId, String name) {
|
||||||
|
if(schematicId == null || schematicId == 0) {
|
||||||
|
return byParentName_null.select(user, name);
|
||||||
|
} else {
|
||||||
|
return byParentName.select(user, schematicId, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> accessibleByUserType(SteamwarUser user, SchematicType type) {
|
||||||
|
return accessibleByUserType.listSelect(type, user, user, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<Integer, List<SchematicNode>> accessibleByUserTypeMap(SteamwarUser user, SchematicType type) {
|
||||||
|
return map(accessibleByUserType(user, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean schematicAccessibleForUser(SteamwarUser user, Integer schematicId) {
|
||||||
|
return schematicAccessibleForUser.select(user, schematicId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> accessibleByUserTypeParent(SteamwarUser user, SchematicType type, Integer parentId) {
|
||||||
|
if(parentId == null || parentId == 0) {
|
||||||
|
return accessibleByUserTypeInParent_null.listSelect(type, user, user, user);
|
||||||
|
} else {
|
||||||
|
return accessibleByUserTypeInParent.listSelect(type, user, user, user, parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SchematicNode byIdAndUser(SteamwarUser user, Integer id) {
|
||||||
|
return byIdAndUser.select(user, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<SchematicNode> parentsOfNode(SteamwarUser user, Integer id) {
|
||||||
|
return allParentsOfNode.listSelect(id, user, user, user).stream().filter(n -> n.getId() != id).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, List<SchematicNode>> map(List<SchematicNode> in) {
|
||||||
|
Map<Integer, List<SchematicNode>> map = new HashMap<>();
|
||||||
|
for (SchematicNode effectiveSchematicNode : in) {
|
||||||
|
map.computeIfAbsent(effectiveSchematicNode.getOptionalParent().orElse(0), k -> new ArrayList<>()).add(effectiveSchematicNode);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
public static SchematicNode createSchematic(int owner, String name, Integer parent) {
|
public static SchematicNode createSchematic(int owner, String name, Integer parent) {
|
||||||
return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), "");
|
return createSchematicNode(owner, name, parent, SchematicType.Normal.toDB(), "");
|
||||||
}
|
}
|
||||||
@ -188,14 +263,12 @@ public class SchematicNode {
|
|||||||
return byId.select(id);
|
return byId.select(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
|
public static List<SchematicNode> getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) {
|
||||||
return EffectiveSchematicNode.accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent).stream().map(EffectiveSchematicNode::toSchematicNode).collect(Collectors.toList());
|
return accessibleByUserTypeParent(SteamwarUser.get(owner), SchematicType.fromDB(schemType), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static List<SchematicNode> getAllAccessibleSchematicsOfType(int user, String schemType) {
|
public static List<SchematicNode> getAllAccessibleSchematicsOfType(int user, String schemType) {
|
||||||
return EffectiveSchematicNode.accessibleByUserType(SteamwarUser.get(user), SchematicType.fromDB(schemType)).stream().map(EffectiveSchematicNode::toSchematicNode).collect(Collectors.toList());
|
return accessibleByUserType(SteamwarUser.get(user), SchematicType.fromDB(schemType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<SchematicNode> getAllSchematicsOfType(int owner, String schemType) {
|
public static List<SchematicNode> getAllSchematicsOfType(int owner, String schemType) {
|
||||||
@ -227,12 +300,12 @@ public class SchematicNode {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static List<SchematicNode> getSchematicsAccessibleByUser(int user, Integer parent) {
|
public static List<SchematicNode> getSchematicsAccessibleByUser(int user, Integer parent) {
|
||||||
return EffectiveSchematicNode.list(SteamwarUser.get(user), parent).stream().map(EffectiveSchematicNode::toSchematicNode).collect(Collectors.toList());
|
return list(SteamwarUser.get(user), parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static List<SchematicNode> getAllSchematicsAccessibleByUser(int user) {
|
public static List<SchematicNode> getAllSchematicsAccessibleByUser(int user) {
|
||||||
return EffectiveSchematicNode.getAll(SteamwarUser.get(user)).stream().map(EffectiveSchematicNode::toSchematicNode).collect(Collectors.toList());
|
return getAll(SteamwarUser.get(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<SchematicNode> getAllParentsOfNode(SchematicNode node) {
|
public static List<SchematicNode> getAllParentsOfNode(SchematicNode node) {
|
||||||
@ -243,9 +316,35 @@ public class SchematicNode {
|
|||||||
return allParentsOfNode.listSelect(node);
|
return allParentsOfNode.listSelect(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static SchematicNode getNodeFromPath(SteamwarUser user, String s) {
|
public static SchematicNode getNodeFromPath(SteamwarUser user, String s) {
|
||||||
return EffectiveSchematicNode.getNodeFromPath(user, s).map(EffectiveSchematicNode::toSchematicNode).orElse(null);
|
if (s.startsWith("/")) {
|
||||||
|
s = s.substring(1);
|
||||||
|
}
|
||||||
|
if (s.endsWith("/")) {
|
||||||
|
s = s.substring(0, s.length() - 1);
|
||||||
|
}
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (s.contains("/")) {
|
||||||
|
String[] layers = s.split("/");
|
||||||
|
Optional<SchematicNode> currentNode = Optional.ofNullable(SchematicNode.byParentName(user, 0, layers[0]));
|
||||||
|
for (int i = 1; i < layers.length; i++) {
|
||||||
|
int finalI = i;
|
||||||
|
Optional<SchematicNode> node = currentNode.map(effectiveSchematicNode -> SchematicNode.byParentName(user, effectiveSchematicNode.getId(), layers[finalI]));
|
||||||
|
if (!node.isPresent()) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
currentNode = node;
|
||||||
|
if (!currentNode.map(SchematicNode::isDir).orElse(false) && i != layers.length - 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentNode.orElse(null);
|
||||||
|
} else {
|
||||||
|
return SchematicNode.byParentName(user, 0, s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<SchematicNode> filterSchems(int user, Predicate<SchematicNode> filter) {
|
public static List<SchematicNode> filterSchems(int user, Predicate<SchematicNode> filter) {
|
||||||
@ -262,11 +361,6 @@ public class SchematicNode {
|
|||||||
return finalList;
|
return finalList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public static Integer countNodes() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return nodeId;
|
return nodeId;
|
||||||
}
|
}
|
||||||
@ -288,6 +382,10 @@ public class SchematicNode {
|
|||||||
return parentNode;
|
return parentNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Integer> getOptionalParent() {
|
||||||
|
return Optional.ofNullable(parentNode);
|
||||||
|
}
|
||||||
|
|
||||||
public void setParent(Integer parent) {
|
public void setParent(Integer parent) {
|
||||||
this.parentNode = parent;
|
this.parentNode = parent;
|
||||||
updateDB();
|
updateDB();
|
||||||
@ -424,12 +522,34 @@ public class SchematicNode {
|
|||||||
return ((SchematicNode) obj).getId() == nodeId;
|
return ((SchematicNode) obj).getId() == nodeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public String generateBreadcrumbs(SteamwarUser user) {
|
public String generateBreadcrumbs(SteamwarUser user) {
|
||||||
return EffectiveSchematicNode.byIdAndUser(user, nodeId).map(EffectiveSchematicNode::generateBreadcrumbs).orElse("/");
|
return generateBreadcrumbs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public String generateBreadcrumbs(String split, SteamwarUser user) {
|
public String generateBreadcrumbs(String split, SteamwarUser user) {
|
||||||
return EffectiveSchematicNode.byIdAndUser(user, nodeId).map(node -> node.generateBreadcrumbs(split)).orElse("/");
|
return generateBreadcrumbs(split);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateBreadcrumbs() {
|
||||||
|
if(brCache == null) {
|
||||||
|
brCache = generateBreadcrumbs("/");
|
||||||
|
}
|
||||||
|
return brCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateBreadcrumbs(String split) {
|
||||||
|
StringBuilder builder = new StringBuilder(getName());
|
||||||
|
Optional<SchematicNode> currentNode = Optional.of(this);
|
||||||
|
if(currentNode.map(SchematicNode::isDir).orElse(false)) {
|
||||||
|
builder.append(split);
|
||||||
|
}
|
||||||
|
while (currentNode.isPresent()) {
|
||||||
|
currentNode = currentNode.flatMap(SchematicNode::getOptionalParent).map(integer -> byIdAndUser(SteamwarUser.get(effectiveOwner), integer));
|
||||||
|
currentNode.ifPresent(node -> builder.insert(0, split).insert(0, node.getName()));
|
||||||
|
}
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
private static final List<String> FORBIDDEN_NAMES = Collections.unmodifiableList(Arrays.asList("public"));
|
||||||
@ -458,7 +578,29 @@ public class SchematicNode {
|
|||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static List<String> getNodeTabcomplete(SteamwarUser user, String s) {
|
public static List<String> getNodeTabcomplete(SteamwarUser user, String s) {
|
||||||
return EffectiveSchematicNode.getNodeTabcomplete(user, 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<String> 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<SchematicNode> nodes = SchematicNode.list(user, pa.getId());
|
||||||
|
nodes.forEach(node -> list.add((sws ? "/" : "") + node.generateBreadcrumbs()));
|
||||||
|
} else {
|
||||||
|
List<SchematicNode> nodes = SchematicNode.list(user, 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() {
|
private static void rootWarning() {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren