api 0.0.6: Query API

Affects issues:
- #1117
This commit is contained in:
Rsl1122 2019-07-28 10:24:01 +03:00
parent cba0a055d2
commit 43a43b604c
4 changed files with 233 additions and 2 deletions

View File

@ -2,7 +2,7 @@ plugins {
id "com.jfrog.bintray" version "1.8.4"
}
ext.apiVersion = '0.0.5'
ext.apiVersion = '0.0.6'
bintray {
user = System.getenv('BINTRAY_USER')

View File

@ -50,7 +50,11 @@ enum Capability {
* <p>
* When the parameter is set to {@code true} the value from this Provider is shown on a table alongside players.
*/
DATA_EXTENSION_SHOW_IN_PLAYER_TABLE;
DATA_EXTENSION_SHOW_IN_PLAYER_TABLE,
/**
*
*/
QUERY_API;
static Optional<Capability> getByName(String name) {
if (name == null) {

View File

@ -0,0 +1,64 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.query;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
/**
* Class that allows performing most commonly wanted queries.
* <p>
* This exists so that SQL does not necessarily need to be written.
* Obtain an instance from {@link QueryService}.
*
* @author Rsl1122
*/
public interface CommonQueries {
/**
* Fetch playtime of a player on a server.
* <p>
* Returns 0 for any non existing players or servers.
*
* @param playerUUID UUID of the player.
* @param serverUUID UUID of the Plan server.
* @param after Data after this Epoch ms should be fetched
* @param before Data before this Epoch ms should be fetched
* @return Milliseconds the player has played with the defined parameters.
*/
long fetchPlaytime(UUID playerUUID, UUID serverUUID, long after, long before);
/**
* Fetch last seen Epoch ms for a player on a server.
*
* @param playerUUID UUID of the player.
* @param serverUUID UUID of the Plan server.
* @return Epoch ms the player was last seen, 0 if player has not played on server.
*/
long fetchLastSeen(UUID playerUUID, UUID serverUUID);
Set<UUID> fetchServerUUIDs();
Optional<UUID> fetchUUIDOf(String playerName);
Optional<String> fetchNameOf(UUID playerUUID);
boolean doesDBHaveTable(String table);
boolean doesDBHaveTableColumn(String table, String column);
}

View File

@ -0,0 +1,163 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.query;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.function.Consumer;
/**
* Service for Query API.
* <p>
* Requires Capability QUERY_API
*
* @author Rsl1122
*/
public interface QueryService {
/**
* Obtain instance of QueryService.
*
* @return QueryService implementation.
* @throws NoClassDefFoundError If Plan is not installed and this class can not be found or if older Plan version is installed.
* @throws IllegalStateException If Plan is installed, but not enabled.
*/
static QueryService getInstance() {
return Optional.ofNullable(QueryService.QueryServiceHolder.service)
.orElseThrow(() -> new IllegalStateException("QueryService has not been initialised yet."));
}
/**
* Get what kind of database is in use.
*
* @return H2, SQLITE or MYSQL
* @throws IllegalStateException If database has not been initialized (Plugin failed to enable)
*/
String getDBType();
/**
* Perform a query against Plan database.
* <p>
* Blocks thread until query is complete.
*
* @param sql SQL String to execute, can contain parameterized queries ({@code ?}).
* @param performQuery set your parameters to the PreparedStatement and execute the query, return results.
* @param <T> Type of results.
* @return The object returned by {@code results}.
* @throws IllegalStateException If something goes wrong with the query. SQLException might be as cause.
*/
<T> T query(
String sql,
ThrowingFunction<PreparedStatement, T> performQuery
) throws IllegalStateException;
/**
* Execute SQL against Plan database.
* <p>
* Does not block thread, SQL is executed in a single transaction to the database.
* <p>
* Differs from {@link QueryService#query(String, ThrowingFunction)} in that no results are returned.
*
* @param sql SQL String to execute, can contain parameterized queries ({@code ?}).
* @param performStatement set your parameters to the PreparedStatement and execute the statement.
* @return A Future that tells when the transaction has completed. Blocks thread if Future#get is called.
* @throws IllegalStateException If something goes wrong with the query. SQLException might be as cause.
*/
Future<?> execute(
String sql,
ThrowingConsumer<PreparedStatement> performStatement
) throws IllegalStateException;
/**
* Used for getting notified about removal of player data.
* <p>
* SQL for removing this player's data should be executed when this occurs.
* <p>
* Example usage:
* subscribeToPlayerRemoveEvent(playerUUID -> { do stuff })
*
* @param eventListener Functional interface that is called on the event.
*/
void subscribeToPlayerRemoveEvent(Consumer<UUID> eventListener);
/**
* Used for getting notified about removal of ALL data.
* <p>
* SQL for removing all extra tables (and data) should be performed
* <p>
* Example usage:
* subscribeDataClearEvent(() -> { do stuff })
*
* @param eventListener Functional interface that is called on the event.
*/
void subscribeDataClearEvent(VoidFunction eventListener);
/**
* Get the UUID of this server.
*
* @return Optinal of the server UUID, empty if server did not start properly.
*/
Optional<UUID> getServerUUID();
/**
* Perform some commonly wanted queries.
*
* @return {@link CommonQueries} implementation.
* @throws IllegalStateException If database has not been initialized (Plugin failed to enable)
*/
CommonQueries getCommonQueries();
/**
* See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
*/
@FunctionalInterface
interface ThrowingConsumer<T> {
void accept(T t) throws SQLException;
}
/**
* See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
*/
@FunctionalInterface
interface ThrowingFunction<T, R> {
R apply(T t) throws SQLException;
}
/**
* See https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
*/
@FunctionalInterface
interface VoidFunction {
void apply();
}
class QueryServiceHolder {
static QueryService service;
private QueryServiceHolder() {
/* Static variable holder */
}
static void set(QueryService service) {
QueryService.QueryServiceHolder.service = service;
}
}
}