reformat code (thanks TPGamesNL)

This commit is contained in:
Govindas 2021-06-22 21:26:46 +03:00
parent 9b694206d3
commit 2dcd4edf58
9 changed files with 482 additions and 481 deletions

View File

@ -93,7 +93,7 @@
<dependency> <dependency>
<groupId>com.github.SkriptLang</groupId> <groupId>com.github.SkriptLang</groupId>
<artifactId>Skript</artifactId> <artifactId>Skript</artifactId>
<version>2.5.3</version> <version>2.6-alpha1</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client --> <!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->

View File

@ -5,13 +5,18 @@ import org.bukkit.event.HandlerList;
public class SQLQueryCompleteEvent extends Event { public class SQLQueryCompleteEvent extends Event {
private final static HandlerList HANDLERS = new HandlerList(); private final static HandlerList HANDLERS = new HandlerList();
private String argument; private final String argument;
public SQLQueryCompleteEvent(String argument) { public SQLQueryCompleteEvent(String argument) {
super(true); super(true);
this.argument = argument; this.argument = argument;
// this.variables = variables; // this.variables = variables;
} }
public static HandlerList getHandlerList() {
return HANDLERS;
}
@Override @Override
public String getEventName() { public String getEventName() {
return super.getEventName(); return super.getEventName();
@ -21,13 +26,10 @@ public class SQLQueryCompleteEvent extends Event {
public HandlerList getHandlers() { public HandlerList getHandlers() {
return HANDLERS; return HANDLERS;
} }
public static HandlerList getHandlerList() {
return HANDLERS;
}
public String getQuery() { public String getQuery() {
return argument; return argument;
} }
// public String getVariables() {return;} // public String getVariables() {return;}
} }

View File

@ -8,7 +8,6 @@ import ch.njol.util.Kleenean;
import ch.njol.util.Pair; import ch.njol.util.Pair;
import com.btk5h.skriptdb.SkriptDB; import com.btk5h.skriptdb.SkriptDB;
import com.btk5h.skriptdb.SkriptUtil; import com.btk5h.skriptdb.SkriptUtil;
import com.btk5h.skriptdb.events.SQLQueryCompleteEvent;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.Event; import org.bukkit.event.Event;
@ -42,288 +41,291 @@ import java.util.concurrent.Executors;
* @since 0.1.0 * @since 0.1.0
*/ */
public class EffExecuteStatement extends Effect { public class EffExecuteStatement extends Effect {
static { private static final ExecutorService threadPool =
Skript.registerEffect(EffExecuteStatement.class, Executors.newCachedThreadPool();
"execute %string% (in|on) %datasource% " + static String lastError;
"[and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]", "quickly execute %string% (in|on) %datasource% " +
"[and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]");
}
static String lastError; static {
Skript.registerEffect(EffExecuteStatement.class,
private static final ExecutorService threadPool = "execute %string% (in|on) %datasource% " +
Executors.newCachedThreadPool(); "[and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]", "quickly execute %string% (in|on) %datasource% " +
"[and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]");
private Expression<String> query;
private Expression<HikariDataSource> dataSource;
private VariableString var;
private boolean isLocal;
private boolean isList;
private boolean isSync;
private void continueScriptExecution(Event e, Object populatedVariables) {
lastError = null;
if (populatedVariables instanceof String) {
lastError = (String) populatedVariables;
} else {
if (getNext() != null) {
((Map<String, Object>) populatedVariables).forEach((name, value) -> setVariable(e, name, value));
}
}
TriggerItem.walk(getNext(), e);
}
@Override
protected void execute(Event e) {
DataSource ds = dataSource.getSingle(e);
Pair<String, List<Object>> query = parseQuery(e);
String baseVariable = var != null ? var.toString(e).toLowerCase(Locale.ENGLISH) : null;
//if data source isn't set
if (ds == null) return;
boolean sync = false;
//if current thread is not main thread, then make this query to not have delays
if (!Bukkit.isPrimaryThread()) {
sync = true;
}
Object locals = Variables.removeLocals(e);
//execute SQL statement
CompletableFuture<Object> sql =
CompletableFuture.supplyAsync(() -> executeStatement(ds, baseVariable, query), threadPool);
//when SQL statement is completed
boolean finalSync = sync;
sql.whenComplete((res, err) -> {
if (err != null) { err.printStackTrace(); }
//handle last error syntax data
lastError = null;
if (res instanceof String) {
lastError = (String) res;
}
if (getNext() != null) {
//if local variables are present
if (locals != null)
//bring back local variables
//populate SQL data into variables
if (!(res instanceof String)) {
//also set variables in the sql query complete event
//TEMPORARILY DISABLED, AS THIS WOULD WORSEN PERFORMANCE OF THE QUERIES AND NOT BE USED BY MOST PEOPLE.
//I may add config option to enable this later?
//SQLQueryCompleteEvent event = new SQLQueryCompleteEvent(this.query.getSingle(e));
//((Map<String, Object>) res).forEach((name, value) -> setVariable(event, name, value));
//SkriptDB.getPlugin(SkriptDB.class).getServer().getPluginManager().callEvent(event);
}
if (isSync || finalSync) {
Variables.setLocalVariables(e, locals);
if (!(res instanceof String)) { ((Map<String, Object>) res).forEach((name, value) -> setVariable(e, name, value)); }
TriggerItem.walk(getNext(), e);
Variables.removeLocals(e);
} else {
Bukkit.getScheduler().runTask(SkriptDB.getInstance(), () -> {
Variables.setLocalVariables(e, locals);
if (!(res instanceof String)) { ((Map<String, Object>) res).forEach((name, value) -> setVariable(e, name, value)); }
TriggerItem.walk(getNext(), e);
//the line below is required to prevent memory leaks
//no functionality difference notice with it being removed from my test, but the memory gets filled with leaks
//so it must be kept
Variables.removeLocals(e);
});
}
}
});
}
@Override
protected TriggerItem walk(Event e) {
debug(e, true);
//I think no longer needed as of 1.3.0, uncomment if something breaks
if (!isSync) {
Delay.addDelayedEvent(e);
}
execute(e);
return null;
}
private Pair<String, List<Object>> parseQuery(Event e) {
if (!(query instanceof VariableString)) {
return new Pair<>(query.getSingle(e), null);
}
VariableString q = (VariableString) query;
if (q.isSimple()) {
return new Pair<>(q.toString(e), null);
} }
StringBuilder sb = new StringBuilder(); private Expression<String> query;
List<Object> parameters = new ArrayList<>(); private Expression<HikariDataSource> dataSource;
Object[] objects = SkriptUtil.getTemplateString(q); private VariableString var;
private boolean isLocal;
private boolean isList;
private boolean isSync;
for (int i = 0; i < objects.length; i++) { private void continueScriptExecution(Event e, Object populatedVariables) {
Object o = objects[i]; lastError = null;
if (o instanceof String) { if (populatedVariables instanceof String) {
sb.append(o); lastError = (String) populatedVariables;
} else {
Expression<?> expr = SkriptUtil.getExpressionFromInfo(o);
String before = getString(objects, i - 1);
String after = getString(objects, i + 1);
boolean standaloneString = false;
if (before != null && after != null) {
if (before.endsWith("'") && after.endsWith("'")) {
standaloneString = true;
}
}
Object expressionValue = expr.getSingle(e);
if (expr instanceof ExprUnsafe) {
sb.append(expressionValue);
if (standaloneString && expressionValue instanceof String) {
String rawExpression = ((ExprUnsafe) expr).getRawExpression();
Skript.warning(
String.format("Unsafe may have been used unnecessarily. Try replacing 'unsafe %1$s' with %1$s",
rawExpression));
}
} else { } else {
parameters.add(expressionValue);
sb.append('?');
if (standaloneString) { if (getNext() != null) {
Skript.warning("Do not surround expressions with quotes!"); ((Map<String, Object>) populatedVariables).forEach((name, value) -> setVariable(e, name, value));
} }
} }
} TriggerItem.walk(getNext(), e);
} }
return new Pair<>(sb.toString(), parameters);
}
private Object executeStatement(DataSource ds, String baseVariable, Pair<String, List<Object>> query) { @Override
if (ds == null) { protected void execute(Event e) {
return "Data source is not set"; DataSource ds = dataSource.getSingle(e);
} Pair<String, List<Object>> query = parseQuery(e);
Map<String, Object> variableList = new HashMap<>(); String baseVariable = var != null ? var.toString(e).toLowerCase(Locale.ENGLISH) : null;
try (Connection conn = ds.getConnection(); //if data source isn't set
PreparedStatement stmt = createStatement(conn, query)) { if (ds == null) return;
boolean hasResultSet = stmt.execute(); boolean sync = !Bukkit.isPrimaryThread();
if (baseVariable != null) { //if current thread is not main thread, then make this query to not have delays
if (isList) {
baseVariable = baseVariable.substring(0, baseVariable.length() - 1);
}
if (hasResultSet) { Object locals = Variables.removeLocals(e);
CachedRowSet crs = SkriptDB.getRowSetFactory().createCachedRowSet();
crs.populate(stmt.getResultSet());
if (isList) { //execute SQL statement
ResultSetMetaData meta = crs.getMetaData(); CompletableFuture<Object> sql =
int columnCount = meta.getColumnCount(); CompletableFuture.supplyAsync(() -> executeStatement(ds, baseVariable, query), threadPool);
for (int i = 1; i <= columnCount; i++) { //when SQL statement is completed
String label = meta.getColumnLabel(i); boolean finalSync = sync;
variableList.put(baseVariable + label, label); sql.whenComplete((res, err) -> {
} if (err != null) {
err.printStackTrace();
}
int rowNumber = 1; //handle last error syntax data
try { lastError = null;
while (crs.next()) { if (res instanceof String) {
for (int i = 1; i <= columnCount; i++) { lastError = (String) res;
variableList.put(baseVariable + meta.getColumnLabel(i).toLowerCase(Locale.ENGLISH) }
+ Variable.SEPARATOR + rowNumber, crs.getObject(i));
} if (getNext() != null) {
rowNumber++; //if local variables are present
if (locals != null)
//bring back local variables
//populate SQL data into variables
if (!(res instanceof String)) {
//also set variables in the sql query complete event
//TEMPORARILY DISABLED, AS THIS WOULD WORSEN PERFORMANCE OF THE QUERIES AND NOT BE USED BY MOST PEOPLE.
//I may add config option to enable this later?
//SQLQueryCompleteEvent event = new SQLQueryCompleteEvent(this.query.getSingle(e));
//((Map<String, Object>) res).forEach((name, value) -> setVariable(event, name, value));
//SkriptDB.getPlugin(SkriptDB.class).getServer().getPluginManager().callEvent(event);
}
if (isSync || finalSync) {
Variables.setLocalVariables(e, locals);
if (!(res instanceof String)) {
((Map<String, Object>) res).forEach((name, value) -> setVariable(e, name, value));
}
TriggerItem.walk(getNext(), e);
Variables.removeLocals(e);
} else {
Bukkit.getScheduler().runTask(SkriptDB.getInstance(), () -> {
Variables.setLocalVariables(e, locals);
if (!(res instanceof String)) {
((Map<String, Object>) res).forEach((name, value) -> setVariable(e, name, value));
}
TriggerItem.walk(getNext(), e);
//the line below is required to prevent memory leaks
//no functionality difference notice with it being removed from my test, but the memory gets filled with leaks
//so it must be kept
Variables.removeLocals(e);
});
} }
} catch (SQLException ex) { }
return ex.getMessage(); });
} }
} else {
crs.last(); @Override
variableList.put(baseVariable, crs.getRow()); protected TriggerItem walk(Event e) {
} debug(e, true);
} else if (!isList) { //I think no longer needed as of 1.3.0, uncomment if something breaks
//if no results are returned and the specified variable isn't a list variable, put the affected rows count in the variable if (!isSync) {
variableList.put(baseVariable, stmt.getUpdateCount()); Delay.addDelayedEvent(e);
} }
} execute(e);
} catch (SQLException ex) { return null;
return ex.getMessage();
}
return variableList;
}
private PreparedStatement createStatement(Connection conn, Pair<String, List<Object>> query) throws SQLException {
PreparedStatement stmt = conn.prepareStatement(query.getFirst());
List<Object> parameters = query.getSecond();
if (parameters != null) {
for (int i = 0; i < parameters.size(); i++) {
stmt.setObject(i + 1, parameters.get(i));
}
} }
return stmt; private Pair<String, List<Object>> parseQuery(Event e) {
} if (!(query instanceof VariableString)) {
return new Pair<>(query.getSingle(e), null);
}
VariableString q = (VariableString) query;
if (q.isSimple()) {
return new Pair<>(q.toString(e), null);
}
private String getString(Object[] objects, int index) { StringBuilder sb = new StringBuilder();
if (index < 0 || index >= objects.length) { List<Object> parameters = new ArrayList<>();
return null; Object[] objects = SkriptUtil.getTemplateString(q);
for (int i = 0; i < objects.length; i++) {
Object o = objects[i];
if (o instanceof String) {
sb.append(o);
} else {
Expression<?> expr = SkriptUtil.getExpressionFromInfo(o);
String before = getString(objects, i - 1);
String after = getString(objects, i + 1);
boolean standaloneString = false;
if (before != null && after != null) {
if (before.endsWith("'") && after.endsWith("'")) {
standaloneString = true;
}
}
Object expressionValue = expr.getSingle(e);
if (expr instanceof ExprUnsafe) {
sb.append(expressionValue);
if (standaloneString && expressionValue instanceof String) {
String rawExpression = ((ExprUnsafe) expr).getRawExpression();
Skript.warning(
String.format("Unsafe may have been used unnecessarily. Try replacing 'unsafe %1$s' with %1$s",
rawExpression));
}
} else {
parameters.add(expressionValue);
sb.append('?');
if (standaloneString) {
Skript.warning("Do not surround expressions with quotes!");
}
}
}
}
return new Pair<>(sb.toString(), parameters);
} }
Object object = objects[index]; private Object executeStatement(DataSource ds, String baseVariable, Pair<String, List<Object>> query) {
if (ds == null) {
return "Data source is not set";
}
Map<String, Object> variableList = new HashMap<>();
try (Connection conn = ds.getConnection();
PreparedStatement stmt = createStatement(conn, query)) {
if (object instanceof String) { boolean hasResultSet = stmt.execute();
return (String) object;
if (baseVariable != null) {
if (isList) {
baseVariable = baseVariable.substring(0, baseVariable.length() - 1);
}
if (hasResultSet) {
CachedRowSet crs = SkriptDB.getRowSetFactory().createCachedRowSet();
crs.populate(stmt.getResultSet());
if (isList) {
ResultSetMetaData meta = crs.getMetaData();
int columnCount = meta.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String label = meta.getColumnLabel(i);
variableList.put(baseVariable + label, label);
}
int rowNumber = 1;
try {
while (crs.next()) {
for (int i = 1; i <= columnCount; i++) {
variableList.put(baseVariable + meta.getColumnLabel(i).toLowerCase(Locale.ENGLISH)
+ Variable.SEPARATOR + rowNumber, crs.getObject(i));
}
rowNumber++;
}
} catch (SQLException ex) {
return ex.getMessage();
}
} else {
crs.last();
variableList.put(baseVariable, crs.getRow());
}
} else if (!isList) {
//if no results are returned and the specified variable isn't a list variable, put the affected rows count in the variable
variableList.put(baseVariable, stmt.getUpdateCount());
}
}
} catch (SQLException ex) {
return ex.getMessage();
}
return variableList;
} }
return null; private PreparedStatement createStatement(Connection conn, Pair<String, List<Object>> query) throws SQLException {
} PreparedStatement stmt = conn.prepareStatement(query.getFirst());
List<Object> parameters = query.getSecond();
private void setVariable(Event e, String name, Object obj) { if (parameters != null) {
Variables.setVariable(name.toLowerCase(Locale.ENGLISH), obj, e, isLocal); for (int i = 0; i < parameters.size(); i++) {
} stmt.setObject(i + 1, parameters.get(i));
}
}
@Override return stmt;
public String toString(Event e, boolean debug) {
return "execute " + query.toString(e, debug) + " in " + dataSource.toString(e, debug);
}
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
SkriptParser.ParseResult parseResult) {
Expression<String> statementExpr = (Expression<String>) exprs[0];
if (statementExpr instanceof VariableString || statementExpr instanceof ExprUnsafe) {
query = statementExpr;
} else {
Skript.error("Database statements must be string literals. If you must use an expression, " +
"you may use \"%unsafe (your expression)%\", but keep in mind, you may be vulnerable " +
"to SQL injection attacks!");
return false;
} }
dataSource = (Expression<HikariDataSource>) exprs[1];
Expression<?> expr = exprs[2]; private String getString(Object[] objects, int index) {
isSync = matchedPattern == 1; if (index < 0 || index >= objects.length) {
if (expr instanceof Variable) { return null;
Variable<?> varExpr = (Variable<?>) expr; }
var = varExpr.getName();
isLocal = varExpr.isLocal(); Object object = objects[index];
isList = varExpr.isList();
} else if (expr != null) { if (object instanceof String) {
Skript.error(expr + " is not a variable"); return (String) object;
return false; }
return null;
}
private void setVariable(Event e, String name, Object obj) {
Variables.setVariable(name.toLowerCase(Locale.ENGLISH), obj, e, isLocal);
}
@Override
public String toString(Event e, boolean debug) {
return "execute " + query.toString(e, debug) + " in " + dataSource.toString(e, debug);
}
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
SkriptParser.ParseResult parseResult) {
Expression<String> statementExpr = (Expression<String>) exprs[0];
if (statementExpr instanceof VariableString || statementExpr instanceof ExprUnsafe) {
query = statementExpr;
} else {
Skript.error("Database statements must be string literals. If you must use an expression, " +
"you may use \"%unsafe (your expression)%\", but keep in mind, you may be vulnerable " +
"to SQL injection attacks!");
return false;
}
dataSource = (Expression<HikariDataSource>) exprs[1];
Expression<?> expr = exprs[2];
isSync = matchedPattern == 1;
if (expr instanceof Variable) {
Variable<?> varExpr = (Variable<?>) expr;
var = varExpr.getName();
isLocal = varExpr.isLocal();
isList = varExpr.isList();
} else if (expr != null) {
Skript.error(expr + " is not a variable");
return false;
}
return true;
} }
return true;
}
} }

View File

@ -12,15 +12,16 @@ public class EvtSQLQueryComplete extends SkriptEvent {
static { static {
Skript.registerEvent("complete of sql query", EvtSQLQueryComplete.class, SQLQueryCompleteEvent.class, "complete of [(sql|database)] query"); Skript.registerEvent("complete of sql query", EvtSQLQueryComplete.class, SQLQueryCompleteEvent.class, "complete of [(sql|database)] query");
} }
@Override
public boolean init(final Literal<?>[] literals, final int i, final SkriptParser.ParseResult parseResult) {
return true;
}
@Override @Override
public boolean check(Event event) { public boolean init(final Literal<?>[] literals, final int i, final SkriptParser.ParseResult parseResult) {
return (event instanceof SQLQueryCompleteEvent); return true;
} }
@Override
public boolean check(Event event) {
return (event instanceof SQLQueryCompleteEvent);
}
@Override @Override
public String toString(@Nullable Event event, boolean debug) { public String toString(@Nullable Event event, boolean debug) {

View File

@ -1,13 +1,12 @@
package com.btk5h.skriptdb.skript; package com.btk5h.skriptdb.skript;
import org.bukkit.event.Event;
import ch.njol.skript.Skript; import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser; import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean; import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
/** /**
* Stores the error from the last executed statement, if there was one. * Stores the error from the last executed statement, if there was one.
@ -18,33 +17,33 @@ import ch.njol.util.Kleenean;
* @since 0.1.0 * @since 0.1.0
*/ */
public class ExprDBError extends SimpleExpression<String> { public class ExprDBError extends SimpleExpression<String> {
static { static {
Skript.registerExpression(ExprDBError.class, String.class, Skript.registerExpression(ExprDBError.class, String.class,
ExpressionType.SIMPLE, "[the] [last] (sql|db|data(base|[ ]source)) error"); ExpressionType.SIMPLE, "[the] [last] (sql|db|data(base|[ ]source)) error");
} }
@Override @Override
protected String[] get(Event e) { protected String[] get(Event e) {
return new String[]{EffExecuteStatement.lastError}; return new String[]{EffExecuteStatement.lastError};
} }
@Override @Override
public boolean isSingle() { public boolean isSingle() {
return true; return true;
} }
@Override @Override
public Class<? extends String> getReturnType() { public Class<? extends String> getReturnType() {
return String.class; return String.class;
} }
@Override @Override
public String toString(Event e, boolean debug) { public String toString(Event e, boolean debug) {
return "last database error"; return "last database error";
} }
@Override @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) {
return true; return true;
} }
} }

View File

@ -1,13 +1,5 @@
package com.btk5h.skriptdb.skript; package com.btk5h.skriptdb.skript;
import com.btk5h.skriptdb.SkriptDB;
import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.event.Event;
import java.util.HashMap;
import java.util.Map;
import ch.njol.skript.Skript; import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.ExpressionType;
@ -15,11 +7,17 @@ import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.util.Timespan; import ch.njol.skript.util.Timespan;
import ch.njol.util.Kleenean; import ch.njol.util.Kleenean;
import com.btk5h.skriptdb.SkriptDB;
import com.zaxxer.hikari.HikariDataSource;
import org.bukkit.event.Event;
import java.util.HashMap;
import java.util.Map;
/** /**
* Stores the connection information for a data source. This should be saved to a variable in a * Stores the connection information for a data source. This should be saved to a variable in a
* `script load` event or manually through an effect command. * `script load` event or manually through an effect command.
* * <p>
* The url format for your database may vary! The example provided uses a MySQL database. * The url format for your database may vary! The example provided uses a MySQL database.
* *
* @name Data Source * @name Data Source
@ -30,74 +28,74 @@ import ch.njol.util.Kleenean;
* @since 0.1.0 * @since 0.1.0
*/ */
public class ExprDataSource extends SimpleExpression<HikariDataSource> { public class ExprDataSource extends SimpleExpression<HikariDataSource> {
static { private static final Map<String, HikariDataSource> connectionCache = new HashMap<>();
Skript.registerExpression(ExprDataSource.class, HikariDataSource.class,
ExpressionType.COMBINED, "[the] data(base|[ ]source) [(of|at)] %string% " +
"[with [a] [max[imum]] [connection] life[ ]time of %-timespan%]");
}
private static Map<String, HikariDataSource> connectionCache = new HashMap<>(); static {
Skript.registerExpression(ExprDataSource.class, HikariDataSource.class,
private Expression<String> url; ExpressionType.COMBINED, "[the] data(base|[ ]source) [(of|at)] %string% " +
private Expression<Timespan> maxLifetime; "[with [a] [max[imum]] [connection] life[ ]time of %-timespan%]");
@Override
protected HikariDataSource[] get(Event e) {
String jdbcUrl = url.getSingle(e);
if (jdbcUrl == null) {
return null;
} }
if (!jdbcUrl.startsWith("jdbc:")) { private Expression<String> url;
jdbcUrl = "jdbc:" + jdbcUrl; private Expression<Timespan> maxLifetime;
@Override
protected HikariDataSource[] get(Event e) {
String jdbcUrl = url.getSingle(e);
if (jdbcUrl == null) {
return null;
}
if (!jdbcUrl.startsWith("jdbc:")) {
jdbcUrl = "jdbc:" + jdbcUrl;
}
if (connectionCache.containsKey(jdbcUrl)) {
return new HikariDataSource[]{connectionCache.get(jdbcUrl)};
}
HikariDataSource ds = new HikariDataSource();
//allow specifying of own sql driver class name
if (!SkriptDB.getInstance().getConfig().getString("sql-driver-class-name", "default").equals("default")) {
ds.setDriverClassName(SkriptDB.getInstance().getConfig().getString("sql-driver-class-name"));
}
ds.setJdbcUrl(jdbcUrl);
if (maxLifetime != null) {
Timespan l = maxLifetime.getSingle(e);
if (l != null) {
ds.setMaxLifetime(l.getMilliSeconds());
}
}
connectionCache.put(jdbcUrl, ds);
return new HikariDataSource[]{ds};
} }
if (connectionCache.containsKey(jdbcUrl)) { @Override
return new HikariDataSource[]{connectionCache.get(jdbcUrl)}; public boolean isSingle() {
return true;
} }
HikariDataSource ds = new HikariDataSource(); @Override
public Class<? extends HikariDataSource> getReturnType() {
//allow specifying of own sql driver class name return HikariDataSource.class;
if (!SkriptDB.getInstance().getConfig().getString("sql-driver-class-name", "default").equals("default")) {
ds.setDriverClassName(SkriptDB.getInstance().getConfig().getString("sql-driver-class-name"));
}
ds.setJdbcUrl(jdbcUrl);
if (maxLifetime != null) {
Timespan l = maxLifetime.getSingle(e);
if (l != null) {
ds.setMaxLifetime(l.getMilliSeconds());
}
} }
connectionCache.put(jdbcUrl, ds); @Override
public String toString(Event e, boolean debug) {
return "datasource " + url.toString(e, debug);
}
return new HikariDataSource[]{ds}; @SuppressWarnings("unchecked")
} @Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
@Override SkriptParser.ParseResult parseResult) {
public boolean isSingle() { url = (Expression<String>) exprs[0];
return true; maxLifetime = (Expression<Timespan>) exprs[1];
} return true;
}
@Override
public Class<? extends HikariDataSource> getReturnType() {
return HikariDataSource.class;
}
@Override
public String toString(Event e, boolean debug) {
return "datasource " + url.toString(e, debug);
}
@SuppressWarnings("unchecked")
@Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
SkriptParser.ParseResult parseResult) {
url = (Expression<String>) exprs[0];
maxLifetime = (Expression<Timespan>) exprs[1];
return true;
}
} }

View File

@ -20,41 +20,41 @@ import org.bukkit.event.Event;
* @since 0.1.0 * @since 0.1.0
*/ */
public class ExprSQLQuery extends SimpleExpression<String> { public class ExprSQLQuery extends SimpleExpression<String> {
static { static {
Skript.registerExpression(ExprSQLQuery.class, String.class, Skript.registerExpression(ExprSQLQuery.class, String.class,
ExpressionType.SIMPLE, "sql query"); ExpressionType.SIMPLE, "sql query");
}
@Override
protected String[] get(Event e) {
if (e instanceof SQLQueryCompleteEvent){
return new String[]{((SQLQueryCompleteEvent) e).getQuery()};
} }
return null;
}
@Override
public boolean isSingle() {
return true;
}
@Override @Override
public Class<? extends String> getReturnType() { protected String[] get(Event e) {
return String.class; if (e instanceof SQLQueryCompleteEvent) {
} return new String[]{((SQLQueryCompleteEvent) e).getQuery()};
}
@Override return null;
public String toString(Event e, boolean debug) { }
return "sql query";
} @Override
public boolean isSingle() {
@Override return true;
public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) { }
if (!ScriptLoader.isCurrentEvent(SQLQueryCompleteEvent.class)) {
Skript.error("Cannot use 'sql query' outside of a complete of sql query event", ErrorQuality.SEMANTIC_ERROR); @Override
return false; public Class<? extends String> getReturnType() {
return String.class;
}
@Override
public String toString(Event e, boolean debug) {
return "sql query";
}
@Override
public boolean init(final Expression<?>[] expressions, final int matchedPattern, final Kleenean isDelayed, final SkriptParser.ParseResult parseResult) {
if (!ScriptLoader.isCurrentEvent(SQLQueryCompleteEvent.class)) {
Skript.error("Cannot use 'sql query' outside of a complete of sql query event", ErrorQuality.SEMANTIC_ERROR);
return false;
}
return true;
} }
return true;
}
} }

View File

@ -1,13 +1,12 @@
package com.btk5h.skriptdb.skript; package com.btk5h.skriptdb.skript;
import org.bukkit.event.Event;
import ch.njol.skript.Skript; import ch.njol.skript.Skript;
import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.SkriptParser; import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.util.Kleenean; import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
/** /**
* Opts out of automatic SQL injection protection for a specific expression in a statement. * Opts out of automatic SQL injection protection for a specific expression in a statement.
@ -20,44 +19,44 @@ import ch.njol.util.Kleenean;
* @since 0.1.0 * @since 0.1.0
*/ */
public class ExprUnsafe extends SimpleExpression<String> { public class ExprUnsafe extends SimpleExpression<String> {
static { static {
Skript.registerExpression(ExprUnsafe.class, String.class, ExpressionType.COMBINED, Skript.registerExpression(ExprUnsafe.class, String.class, ExpressionType.COMBINED,
"unsafe %string%"); "unsafe %string%");
} }
private Expression<String> stringExpression; private Expression<String> stringExpression;
private String rawExpression; private String rawExpression;
public String getRawExpression() { public String getRawExpression() {
return rawExpression; return rawExpression;
} }
@Override @Override
protected String[] get(Event e) { protected String[] get(Event e) {
return stringExpression.getArray(e); return stringExpression.getArray(e);
} }
@Override @Override
public boolean isSingle() { public boolean isSingle() {
return true; return true;
} }
@Override @Override
public Class<? extends String> getReturnType() { public Class<? extends String> getReturnType() {
return String.class; return String.class;
} }
@Override @Override
public String toString(Event e, boolean debug) { public String toString(Event e, boolean debug) {
return "unsafe " + stringExpression.toString(e, debug); return "unsafe " + stringExpression.toString(e, debug);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed,
SkriptParser.ParseResult parseResult) { SkriptParser.ParseResult parseResult) {
stringExpression = (Expression<String>) exprs[0]; stringExpression = (Expression<String>) exprs[0];
rawExpression = parseResult.expr.substring("unsafe".length()).trim(); rawExpression = parseResult.expr.substring("unsafe".length()).trim();
return true; return true;
} }
} }

View File

@ -11,58 +11,58 @@ import com.zaxxer.hikari.HikariDataSource;
import java.io.StreamCorruptedException; import java.io.StreamCorruptedException;
public class Types { public class Types {
static { static {
Classes.registerClass(new ClassInfo<>(HikariDataSource.class, "datasource") Classes.registerClass(new ClassInfo<>(HikariDataSource.class, "datasource")
.user("datasources?") .user("datasources?")
.parser(new Parser<HikariDataSource>() { .parser(new Parser<HikariDataSource>() {
@Override @Override
public HikariDataSource parse(String s, ParseContext context) { public HikariDataSource parse(String s, ParseContext context) {
return null; return null;
} }
@Override @Override
public String toString(HikariDataSource o, int flags) { public String toString(HikariDataSource o, int flags) {
return o.getJdbcUrl(); return o.getJdbcUrl();
} }
@Override @Override
public String toVariableNameString(HikariDataSource o) { public String toVariableNameString(HikariDataSource o) {
return o.getJdbcUrl(); return o.getJdbcUrl();
} }
@Override @Override
public String getVariableNamePattern() { public String getVariableNamePattern() {
return "jdbc:.+"; return "jdbc:.+";
} }
}) })
.serializer(new Serializer<HikariDataSource>() { .serializer(new Serializer<HikariDataSource>() {
@Override @Override
public Fields serialize(HikariDataSource o) { public Fields serialize(HikariDataSource o) {
Fields fields = new Fields(); Fields fields = new Fields();
fields.putObject("jdbcurl", o.getJdbcUrl()); fields.putObject("jdbcurl", o.getJdbcUrl());
return fields; return fields;
} }
@Override @Override
public void deserialize(HikariDataSource o, Fields f) { public void deserialize(HikariDataSource o, Fields f) {
} }
@Override @Override
protected HikariDataSource deserialize(Fields fields) throws StreamCorruptedException { protected HikariDataSource deserialize(Fields fields) throws StreamCorruptedException {
HikariDataSource ds = new HikariDataSource(); HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl((String) fields.getObject("jdbcurl")); ds.setJdbcUrl((String) fields.getObject("jdbcurl"));
return ds; return ds;
} }
@Override @Override
public boolean mustSyncDeserialization() { public boolean mustSyncDeserialization() {
return false; return false;
} }
@Override @Override
protected boolean canBeInstantiated() { protected boolean canBeInstantiated() {
return false; return false;
} }
})); }));
} }
} }