Implemented a bunch of new placeholders:

%plan_top_{category}_{timespan}_{i}%

categories: playtime, active_playtime
timespans: month, week, day, total
i: 1 to 10

Affects issues:
- Close #1884
This commit is contained in:
Risto Lahtela 2021-09-10 19:14:32 +03:00
parent 0921d1550f
commit 950cee9e9f
3 changed files with 160 additions and 0 deletions

View File

@ -22,10 +22,18 @@ import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.analysis.TopListQueries;
import com.djrapitops.plan.storage.database.queries.objects.TPSQueries;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import static com.djrapitops.plan.utilities.MiscUtils.*;
@ -140,5 +148,55 @@ public class ServerPlaceHolders implements Placeholders {
placeholders.registerStatic("server_uuid",
serverInfo::getServerUUID);
registerDynamicCategoryPlaceholders(placeholders, database);
}
private void registerDynamicCategoryPlaceholders(PlanPlaceholders placeholders, Database database) {
List<TopCategoryQuery> queries = new ArrayList<>();
queries.addAll(createCategoryQueriesForAllTimespans("playtime", (index, timespan) -> TopListQueries.fetchNthTop10PlaytimePlayerOn(serverInfo.getServerUUID(), index, System.currentTimeMillis() - timespan, System.currentTimeMillis())));
queries.addAll(createCategoryQueriesForAllTimespans("active_playtime", (index, timespan) -> TopListQueries.fetchNthTop10ActivePlaytimePlayerOn(serverInfo.getServerUUID(), index, System.currentTimeMillis() - timespan, System.currentTimeMillis())));))
for (int i = 0; i < 10; i++) {
for (TopCategoryQuery query : queries) {
final int nth = i;
placeholders.registerStatic(String.format("top_%s_%s_%s", query.getCategory(), query.getTimeSpan(), nth),
() -> database.query(query.getQuery(nth)));
}
}
}
private List<TopCategoryQuery> createCategoryQueriesForAllTimespans(String category, BiFunction<Integer, Long, Query<Optional<String>>> queryCreator) {
return Arrays.asList(
new TopCategoryQuery(category, queryCreator, "month", TimeUnit.DAYS.toMillis(30)),
new TopCategoryQuery(category, queryCreator, "week", TimeUnit.DAYS.toMillis(7)),
new TopCategoryQuery(category, queryCreator, "day", TimeUnit.DAYS.toMillis(1)),
new TopCategoryQuery(category, queryCreator, "total", System.currentTimeMillis())
);
}
public static class TopCategoryQuery {
private final String category;
private final BiFunction<Integer, Long, Query<Optional<String>>> queryCreator;
private final String timeSpan;
private final long timeSpanMillis;
public TopCategoryQuery(String category, BiFunction<Integer, Long, Query<Optional<String>>> queryCreator, String timeSpan, long timespan) {
this.category = category;
this.queryCreator = queryCreator;
this.timeSpan = timeSpan;
this.timeSpanMillis = timespan;
}
public String getCategory() {
return category;
}
public String getTimeSpan() {
return timeSpan;
}
public Query<String> getQuery(int i) {
return queryCreator.apply(i, timeSpanMillis);
}
}
}

View File

@ -0,0 +1,100 @@
/*
* 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.storage.database.queries.analysis;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
public class TopListQueries {
private TopListQueries() {
// Static query generation class
}
public static Query<Optional<String>> fetchNthTop10PlaytimePlayerOn(ServerUUID serverUUID, int n, long after, long before) {
String sql = SELECT + UsersTable.USER_NAME + ", " +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=s." + SessionsTable.USER_UUID +
WHERE + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SESSION_START + ">?" +
AND + SessionsTable.SESSION_END + "<?" +
ORDER_BY + "playtime DESC" +
LIMIT + "10" +
OFFSET + "?";
return new QueryStatement<Optional<String>>(sql, 10) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
statement.setLong(2, after);
statement.setLong(3, before);
statement.setInt(4, n);
}
@Override
public Optional<String> processResults(ResultSet set) throws SQLException {
if (set.next()) {
return Optional.of(set.getString(UsersTable.USER_NAME));
}
return Optional.empty();
}
};
}
public static Query<Optional<String>> fetchNthTop10ActivePlaytimePlayerOn(ServerUUID serverUUID, int n, long after, long before) {
String sql = SELECT + UsersTable.USER_NAME + ", " +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=s." + SessionsTable.USER_UUID +
WHERE + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SESSION_START + ">?" +
AND + SessionsTable.SESSION_END + "<?" +
ORDER_BY + "active_playtime DESC" +
LIMIT + "10" +
OFFSET + "?";
return new QueryStatement<Optional<String>>(sql, 10) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
statement.setLong(2, after);
statement.setLong(3, before);
statement.setInt(4, n);
}
@Override
public Optional<String> processResults(ResultSet set) throws SQLException {
if (set.next()) {
return Optional.of(set.getString(UsersTable.USER_NAME));
}
return Optional.empty();
}
};
}
}

View File

@ -48,6 +48,8 @@ public abstract class Sql {
public static final String OR = " OR ";
public static final String IS_NULL = " IS NULL";
public static final String IS_NOT_NULL = " IS NOT NULL";
public static final String LIMIT = " LIMIT ";
public static final String OFFSET = " OFFSET ";
private static final String FLOOR = "FLOOR(";
private static final String MIN = "MIN(";