From c49daba060deefba6c472a0c86874d069c364889 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Sat, 13 Nov 2021 15:09:53 +0100 Subject: [PATCH] Some Crazy-Ass SQL-Statements and Performance! Signed-off-by: Chaoscaot --- .../src/de/steamwar/sql/Schematic.java | 2 +- .../src/de/steamwar/sql/SchematicNode.java | 63 ++++++++++--------- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/SpigotCore_Main/src/de/steamwar/sql/Schematic.java b/SpigotCore_Main/src/de/steamwar/sql/Schematic.java index f781f09..efe4b66 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/Schematic.java +++ b/SpigotCore_Main/src/de/steamwar/sql/Schematic.java @@ -93,7 +93,7 @@ public class Schematic { public static List getSchemsOfType(int schemOwner, SchematicType schemType){ List schematics = new ArrayList<>(); - SchematicNode.getSchematicsOfType(schemOwner, schemType.toDB(), null) + SchematicNode.getAllAccessibleSchematicsOfType(schemOwner, schemType.toDB()) .forEach(node1 -> { if (!node1.isDir()) schematics.add(new Schematic(node1)); }); diff --git a/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java b/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java index 3b6ee03..878b4b7 100644 --- a/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java +++ b/SpigotCore_Main/src/de/steamwar/sql/SchematicNode.java @@ -35,6 +35,7 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.time.Instant; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; import java.util.zip.GZIPInputStream; @@ -53,6 +54,11 @@ public class SchematicNode { private static final SQL.Statement getAllSchemsOfTypeOwner = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeOwner = ? AND NodeType = ?"); private static final SQL.Statement getAllSchemsOfType = new SQL.Statement("SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeType = ?"); private static final SQL.Statement getAccessibleByUser = new SQL.Statement("SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) AND s.ParentNode is NULL GROUP BY s.NodeId ORDER BY s.NodeName"); + private static final SQL.Statement getAccessibleByUserByTypeInNode = new SQL.Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode = ?"); + private static final SQL.Statement getAccessibleByUserByTypeInNode_Null = new SQL.Statement("WITH RECURSIVE RSNB AS (WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSNB WHERE SN.NodeId = RSNB.ParentNode)SELECT * FROM RSNB WHERE ParentNode is null"); + private static final SQL.Statement getAccessibleByUserByType = new SQL.Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType = ?"); + private static final SQL.Statement getAllSchematicsAccessibleByUser = new SQL.Statement("WITH RECURSIVE RSN as (SELECT s.NodeId, s.NodeName, s.NodeOwner, s.NodeItem, s.NodeType, s.ParentNode, s.NodeRank, s.NodeFormat, s.LastUpdate FROM SchematicNode s LEFT JOIN NodeMember n ON s.NodeId = n.NodeId WHERE (s.NodeOwner = ? OR n.UserId = ?) GROUP BY s.NodeId union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.NodeItem, SN.NodeType, SN.ParentNode, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode AS SN, RSN WHERE SN.ParentNode = RSN.NodeId) SELECT * FROM RSN WHERE NodeType is not null"); + private static final SQL.Statement isSchematicAccessibleForUser = new SQL.Statement("WITH RECURSIVE RSN AS (SELECT NodeId, NodeName, NodeOwner, ParentNode, NodeType, NodeItem, NodeRank, NodeFormat, LastUpdate FROM SchematicNode WHERE NodeId = ? union select SN.NodeId, SN.NodeName, SN.NodeOwner, SN.ParentNode, SN.NodeType, SN.NodeItem, SN.NodeRank, SN.NodeFormat, SN.LastUpdate FROM SchematicNode SN, RSN WHERE RSN.ParentNode = SN.NodeId) SELECT COUNT(RSN.NodeId) AS `Accessible` FROM RSN Join NodeMember NM On NM.NodeId = RSN.NodeId WHERE NodeOwner = ? OR UserId = ? LIMIT 1"); private static final SQL.Statement countNodes = new SQL.Statement("SELECT COUNT(NodeId) AS 'count' FROM SchematicNode"); private static final SQL.Statement updateDB = new SQL.Statement("UPDATE SchematicNode SET NodeName = ?, NodeOwner = ?, ParentNode = ?, NodeItem = ?, NodeType = ?, NodeRank = ? WHERE NodeId = ?"); private static final SQL.Statement updateDatabase = new SQL.Statement("UPDATE SchematicNode SET NodeData = ?, NodeFormat = ? WHERE NodeId = ?"); @@ -182,18 +188,29 @@ public class SchematicNode { }); } - public static List getSchematicsOfType(int owner, String schemType, Integer parent) { - List schems = getAllSchematicsAccessibleByUser(owner); - schems.removeIf(node -> node.isDir() || !node.getType().equals(schemType)); - Map nodesInParent = new LinkedHashMap<>(); - for (SchematicNode schematicNode : schems) { - SchematicNode currentNode = schematicNode; - while (currentNode.getParent() != parent) { - currentNode = currentNode.getParentNode(); + public static List getAccessibleSchematicsOfTypeInParent(int owner, String schemType, Integer parent) { + SQL.Statement.ResultSetUser> user = rs -> { + List nodes = new ArrayList<>(); + while (rs.next()) { + nodes.add(new SchematicNode(rs)); } - nodesInParent.putIfAbsent(currentNode.getId(), currentNode); + return nodes; + }; + if(parent == null || parent == 0) { + return getAccessibleByUserByTypeInNode_Null.select(user, owner, owner, schemType); + } else { + return getAccessibleByUserByTypeInNode.select(user, owner, owner, parent, schemType); } - return new ArrayList<>(nodesInParent.values()); + } + + public static List getAllAccessibleSchematicsOfType(int user, String schemType) { + return getAccessibleByUserByType.select(rs -> { + List nodes = new ArrayList<>(); + while (rs.next()) { + nodes.add(new SchematicNode(rs)); + } + return nodes; + }, user, user, schemType); } public static List getAllSchematicsOfType(int owner, String schemType) { @@ -205,7 +222,6 @@ public class SchematicNode { }, owner, schemType); } - public static List getAllSchematicsOfType(String schemType) { return getAllSchemsOfType.select(rs -> { List nodes = new ArrayList<>(); @@ -231,18 +247,10 @@ public class SchematicNode { public static List getSchematicsAccessibleByUser(int user, Integer parent) { if (parent != null && parent != 0) { - SchematicNode node = SchematicNode.getSchematicNode(parent); - boolean isAdded = false; - while (node.getId() != 0) { - for (NodeMember member:node.getMembers()) { - if (member.getMember() == user) { - isAdded = true; - break; - } - } - node = SchematicNode.getSchematicNode(node.getParent()); - } - if(isAdded) + if(isSchematicAccessibleForUser.select(rs -> { + rs.next(); + return rs.getInt("Accessible") > 0; + }, parent, user, user)) return getSchematicNodeInNode(parent); } else { return getAccessibleByUser.select(rs -> { @@ -256,15 +264,10 @@ public class SchematicNode { } public static List getAllSchematicsAccessibleByUser(int user) { - return getAccessibleByUser.select(rs -> { + return getAllSchematicsAccessibleByUser.select(rs -> { List nodes = new ArrayList<>(); while(rs.next()) { - SchematicNode node = new SchematicNode(rs); - if(node.isDir()) { - nodes.addAll(deepGet(node.getId(), node1 -> true)); - } else { - nodes.add(node); - } + nodes.add(new SchematicNode(rs)); } return nodes; }, user, user);