Plan API version 5 - Query API
This page is about API that is available in version 4.9.0 and above.
API can be called on all platforms.
This API requires QUERY_API
capability.
See APIv5 for dependency information
💭 What is this API for?
Query API is for accessing the Plan database from within your plugin. This can be used to store data in the database, or to write custom queries against the database.
Table of contents
- Obtaining QueryService
- Checking that database is what you expect
- Performing Queries
- Available pre-made queries
- Executing Statements
- Recap of Thread blocking
Obtaining QueryService
QueryService
can be obtained like so:
try {
QueryService queryService = QueryService.getInstance();
} catch (IllegalStateException planIsNotEnabled) {
// Plan is not enabled, handle exception
}
Checking that database is what you expect
Database schema might change due to optimizations or additions so it might be necessary to check if the schema matches what you need.
You can check if a table exists like this:
boolean hasTable = queryService.getCommonQueries().doesDBHaveTable(tableName);
You can check if a table has a column like this:
boolean hasColumn = queryService.getCommonQueries().doesDBHaveTableColumn(tableName, columName);
Any method called in CommonQueries
blocks the thread.
In order to perform queries in the correct SQL dialect, you might need the following code.
String dbType = queryService.getDBType(); // SQLITE, MYSQL
Performing queries
Queries can be done with QueryService#query
method. Queries block the thread.
Here is an example of a completed query
String result = queryService.query(
"SELECT * FROM plan_users WHERE uuid=?",
(PreparedStatement) statement -> {
statement.setString(1, playerUUID.toString());
try (ResultSet results = statement.executeQuery()) {
return results.next ? results.getString("name") : null;
}
}
);
Available pre-made queries
Some queries can be performed without the query method above, they are available with QueryService#getCommonQueries
Any method called in CommonQueries
blocks the thread.
Executing statements
Statements can be executed with QueryService#execute
method.
Here is an example of a executed statement
Future<?> done = queryService.execute(
"INSERT INTO custom_table (uuid, value) VALUES (?, ?)",
(PreparedStatement) statement -> {
statement.setString(1, playerUUID.toString());
statement.setString(2, value);
statement.execute();
}
);
done.get(); // (Optional) Block thread until transaction was executed
Note: Transactions
execute
does not block the thread, because the SQL is executed on another thread concurrently.
If you would like to wait for the statement to execute you can call Future#get()
to block the thread.
Do not call Future#get()
inside execute
- This might deadlock the whole database due to blocked transaction thread!
Example of update - insert if not exist procedure
public void storeProtocolVersion(UUID uuid, int version) throws ExecutionException {
String update = "UPDATE plan_version_protocol SET protocol_version=? WHERE uuid=?";
String insert = "INSERT INTO plan_version_protocol (protocol_version, uuid) VALUES (?, ?)";
AtomicBoolean updated = new AtomicBoolean(false);
try {
queryService.execute(update, statement -> {
statement.setInt(1, version);
statement.setString(2, uuid.toString());
updated.set(statement.executeUpdate() > 0);
}).get(); // Wait
if (!updated.get()) {
queryService.execute(insert, statement -> {
statement.setInt(1, version);
statement.setString(2, uuid.toString());
statement.execute();
});
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
Recap on thread blocking
Blocking the server-thread usually leads to a crash. If something blocks a thread it is best to be executed inside an asynchronous task or on a separate thread.
QueryService#execute
does not block the thread.- The
Future
returned byQueryService#execute
can be used to block the thread until SQL executes withFuture#get
. QueryService#query
blocks the thread.- All methods in
CommonQueries
block the thread.
Documentation
Tutorials
Configuration
- Game server Set-up
- Network Set-up
- Game server Configuration
- Network Configuration
- Login / HTTPS Set-Up
- Commands & Permissions
- Database management
- PlaceholderAPI