Add synchronous execution flag

This commit is contained in:
Bryan Terce 2019-06-22 12:09:17 -07:00
parent 74d4918f44
commit 1f6091eb95
No known key found for this signature in database
GPG Key ID: DF2E2829CA6E5BF4

View File

@ -41,17 +41,20 @@ import ch.njol.util.Kleenean;
* If a list variable, such as `{test::*}`, is passed, the query result will be mapped to the list * If a list variable, such as `{test::*}`, is passed, the query result will be mapped to the list
* variable in the form `{test::<column name>::<row number>}` * variable in the form `{test::<column name>::<row number>}`
* *
* Specifying `synchronously` will make skript-db execute the query on the event thread, which is useful for async
* events. Note that skript-db will ignore this flag if you attempt to run this on the main thread.
*
* @name Execute Statement * @name Execute Statement
* @pattern execute %string% (in|on) %datasource% [and store [[the] (output|result)[s]] (to|in) * @pattern [synchronously] execute %string% (in|on) %datasource% [and store [[the] (output|result)[s]] (to|in)
* [the] [var[iable]] %-objects%] * [the] [var[iable]] %-objects%]
* @example execute "select * from table" in {sql} and store the result in {output::*} * @example execute "select * from table" in {sql} and store the result in {output::*}
* @example execute "select * from %{table variable}%" in {sql} and store the result in {output::*} * @example execute "select * where player=%{player}%" in {sql} and store the result in {output::*}
* @since 0.1.0 * @since 0.1.0
*/ */
public class EffExecuteStatement extends Delay { public class EffExecuteStatement extends Delay {
static { static {
Skript.registerEffect(EffExecuteStatement.class, Skript.registerEffect(EffExecuteStatement.class,
"execute %string% (in|on) %datasource% " + "[(1¦synchronously)] execute %string% (in|on) %datasource% " +
"[and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]"); "[and store [[the] (output|result)[s]] (to|in) [the] [var[iable]] %-objects%]");
} }
@ -65,25 +68,43 @@ public class EffExecuteStatement extends Delay {
private VariableString var; private VariableString var;
private boolean isLocal; private boolean isLocal;
private boolean isList; private boolean isList;
private boolean isSync;
private void continueScriptExecution(Event e, String res) {
lastError = res;
if (getNext() != null) {
TriggerItem.walk(getNext(), e);
}
}
@Override @Override
protected void execute(Event e) { protected void execute(Event e) {
CompletableFuture<String> sql = boolean isMainThread = Bukkit.isPrimaryThread();
CompletableFuture.supplyAsync(() -> executeStatement(e), threadPool);
sql.whenComplete((res, err) -> { if (isSync && !isMainThread) {
if (err != null) { String result = executeStatement(e);
err.printStackTrace(); continueScriptExecution(e, result);
} else {
if (isMainThread) {
Skript.warning("A SQL query was attempted on the main thread!");
} }
Bukkit.getScheduler().runTask(SkriptDB.getInstance(), () -> { CompletableFuture<String> sql =
lastError = res; CompletableFuture.supplyAsync(() -> executeStatement(e), threadPool);
if (getNext() != null) { sql.whenComplete((res, err) -> {
TriggerItem.walk(getNext(), e); if (err != null) {
err.printStackTrace();
}
if (isSync) {
continueScriptExecution(e, res);
} else {
Bukkit.getScheduler().runTask(SkriptDB.getInstance(), () -> continueScriptExecution(e, res));
} }
}); });
}); }
} }
@Override @Override
@ -251,6 +272,7 @@ public class EffExecuteStatement extends Delay {
} }
dataSource = (Expression<HikariDataSource>) exprs[1]; dataSource = (Expression<HikariDataSource>) exprs[1];
Expression<?> expr = exprs[2]; Expression<?> expr = exprs[2];
isSync = parseResult.mark == 1;
if (expr instanceof Variable) { if (expr instanceof Variable) {
Variable<?> varExpr = (Variable<?>) expr; Variable<?> varExpr = (Variable<?>) expr;
var = SkriptUtil.getVariableName(varExpr); var = SkriptUtil.getVariableName(varExpr);