From 2dc1f70f4fa2511d2d496638739a6020d28e4272 Mon Sep 17 00:00:00 2001 From: szumielxd <43210079+szumielxd@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:08:08 +0200 Subject: [PATCH] Removed some duplicated code and improved readability --- .../skriptdb/skript/EffExecuteStatement.java | 153 +++++++++--------- 1 file changed, 73 insertions(+), 80 deletions(-) diff --git a/src/main/java/com/btk5h/skriptdb/skript/EffExecuteStatement.java b/src/main/java/com/btk5h/skriptdb/skript/EffExecuteStatement.java index 9a935b2..70ca721 100644 --- a/src/main/java/com/btk5h/skriptdb/skript/EffExecuteStatement.java +++ b/src/main/java/com/btk5h/skriptdb/skript/EffExecuteStatement.java @@ -51,104 +51,79 @@ public class EffExecuteStatement extends Effect { static { Skript.registerEffect(EffExecuteStatement.class, - "execute %string% (in|on) %datasource% " + - "[with arg[ument][s] %-objects%] [and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]", - "quickly execute %string% (in|on) %datasource% " + + "[quickly:quickly] execute %string% (in|on) %datasource% " + "[with arg[ument][s] %-objects%] [and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]"); } private Expression query; private Expression dataSource; private Expression queryArguments; - private VariableString var; + private VariableString resultVariableName; private boolean isLocal; private boolean isList; private boolean quickly; private boolean isSync = false; - private void continueScriptExecution(Event e, Object populatedVariables) { - lastError = null; - if (populatedVariables instanceof String) { - lastError = (String) populatedVariables; - } else { - - if (getNext() != null) { - ((Map) populatedVariables).forEach((name, value) -> setVariable(e, name, value)); - } - } - TriggerItem.walk(getNext(), e); - } - @Override protected void execute(Event e) { DataSource ds = dataSource.getSingle(e); - Pair> query = parseQuery(e); - String baseVariable = var != null ? var.toString(e).toLowerCase(Locale.ENGLISH) : null; //if data source isn't set - if (ds == null) return; + if (ds == null) { + return; + } + Pair> parsedQuery = parseQuery(e); + String baseVariable = resultVariableName != null ? resultVariableName.toString(e).toLowerCase(Locale.ENGLISH) : null; + Object locals = Variables.removeLocals(e); //execute SQL statement if (Bukkit.isPrimaryThread()) { - CompletableFuture sql = CompletableFuture.supplyAsync(() -> executeStatement(ds, baseVariable, query), threadPool); - sql.whenComplete((res, err) -> { - if (err != null) { - err.printStackTrace(); - } - //handle last error syntax data - lastError = null; - if (res instanceof String) { - lastError = (String) res; - } - //if local variables are present - //bring back local variables - //populate SQL data into variables - if (!quickly) { - Bukkit.getScheduler().runTask(SkriptDB.getInstance(), () -> { - if (locals != null && getNext() != null) { - Variables.setLocalVariables(e, locals); - } - if (!(res instanceof String)) { - ((Map) res).forEach((name, value) -> setVariable(e, name, value)); - } - TriggerItem.walk(getNext(), e); - //the line below is required to prevent memory leaks - Variables.removeLocals(e); - }); - } else { - if (locals != null && getNext() != null) { - Variables.setLocalVariables(e, locals); - } - if (!(res instanceof String)) { - ((Map) res).forEach((name, value) -> setVariable(e, name, value)); - } - TriggerItem.walk(getNext(), e); - //the line below is required to prevent memory leaks - Variables.removeLocals(e); - } - }); + CompletableFuture.supplyAsync(() -> executeStatement(ds, baseVariable, parsedQuery), threadPool) + .whenComplete((resources, err) -> { + //handle last error syntax data + resetLastSQLError(); + if (err instanceof SkriptDBQueryException) { + setLastSQLError(err.getMessage()); + } + //if local variables are present + //bring back local variables + //populate SQL data into variables + if (!quickly) { + Bukkit.getScheduler().runTask(SkriptDB.getInstance(), + () -> postExecution(e, locals, resources)); + } else { + postExecution(e, locals, resources); + } + }); // sync executed SQL query, same as above, just sync } else { isSync = true; - Object resources = executeStatement(ds, baseVariable, query); - //handle last error syntax data - lastError = null; - if (resources instanceof String) { - lastError = (String) resources; - } + Map resources = null; + try { + resources = executeStatement(ds, baseVariable, parsedQuery); + resetLastSQLError(); + } catch (SkriptDBQueryException err) { + //handle last error syntax data + setLastSQLError(err.getMessage()); + } //if local variables are present //bring back local variables //populate SQL data into variables - if (locals != null && getNext() != null) { - Variables.setLocalVariables(e, locals); - } - if (!(resources instanceof String)) { - ((Map) resources).forEach((name, value) -> setVariable(e, name, value)); - } - TriggerItem.walk(getNext(), e); - Variables.removeLocals(e); + postExecution(e, locals, resources); } } + + private void postExecution(Event e, Object locals, Map resources) { + if (locals != null && getNext() != null) { + Variables.setLocalVariables(e, locals); + } + if (resources != null) { + resources.forEach((name, value) -> setVariable(e, name, value)); + } + TriggerItem.walk(getNext(), e); + //the line below is required to prevent memory leaks + Variables.removeLocals(e); + } @Override protected TriggerItem walk(Event e) { @@ -215,9 +190,9 @@ public class EffExecuteStatement extends Effect { } } - private Object executeStatement(DataSource ds, String baseVariable, Pair> query) { + private Map executeStatement(DataSource ds, String baseVariable, Pair> query) throws SkriptDBQueryException { if (ds == null) { - return "Data source is not set"; + throw new SkriptDBQueryException("Data source is not set"); } try (Connection conn = ds.getConnection()) { try (PreparedStatement stmt = createStatement(conn, query)) { @@ -229,11 +204,11 @@ public class EffExecuteStatement extends Effect { return Map.of(); } } catch (SQLException ex) { - return ex.getMessage(); + throw new SkriptDBQueryException(ex.getMessage()); } } - private Object processBaseVariable(String baseVariable, PreparedStatement stmt, boolean hasResultSet) throws SQLException { + private Map processBaseVariable(String baseVariable, PreparedStatement stmt, boolean hasResultSet) throws SQLException { Map variableList = new HashMap<>(); if (isList) { baseVariable = baseVariable.substring(0, baseVariable.length() - 1); @@ -306,7 +281,7 @@ public class EffExecuteStatement extends Effect { //fix mediumblob and similar column types, so they return a String correctly if (obj != null) { - if (obj.getClass().getName().equals("[B")) { + if (obj instanceof byte[]) { obj = new String((byte[]) obj); //in some servers instead of being byte array, it appears as SerialBlob (depends on mc version, 1.12.2 is bvte array, 1.16.5 SerialBlob) @@ -320,6 +295,14 @@ public class EffExecuteStatement extends Effect { } Variables.setVariable(name.toLowerCase(Locale.ENGLISH), obj, e, isLocal); } + + private static void resetLastSQLError() { + lastError = null; + } + + private static void setLastSQLError(String error) { + lastError = error; + } @Override public String toString(Event e, boolean debug) { @@ -328,8 +311,7 @@ public class EffExecuteStatement extends Effect { @SuppressWarnings("unchecked") @Override - public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, - SkriptParser.ParseResult parseResult) { + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { Expression statementExpr = (Expression) exprs[0]; if (statementExpr instanceof VariableString || statementExpr instanceof ExprUnsafe) { query = statementExpr; @@ -347,10 +329,10 @@ public class EffExecuteStatement extends Effect { queryArguments = (Expression) exprs[2]; } Expression resultHolder = exprs[3]; - quickly = matchedPattern == 1; + quickly = parseResult.hasTag("quickly"); if (resultHolder instanceof Variable) { Variable varExpr = (Variable) resultHolder; - var = varExpr.getName(); + resultVariableName = varExpr.getName(); isLocal = varExpr.isLocal(); isList = varExpr.isList(); } else if (resultHolder != null) { @@ -359,4 +341,15 @@ public class EffExecuteStatement extends Effect { } return true; } + + public static class SkriptDBQueryException extends RuntimeException { + + private static final long serialVersionUID = -1869895286406538884L; + + public SkriptDBQueryException(String message) { + super(message); + } + + } + } \ No newline at end of file