mirror of
https://github.com/HangarMC/Hangar.git
synced 2024-11-21 01:21:54 +08:00
fix: rewrite versions queries to hopefully suck less
This commit is contained in:
parent
df51435da8
commit
723c511337
@ -5,7 +5,6 @@ import io.papermc.hangar.controller.extras.pagination.annotations.ApplicableFilt
|
||||
import io.papermc.hangar.controller.extras.pagination.annotations.ConfigurePagination;
|
||||
import io.papermc.hangar.controller.extras.pagination.filters.versions.VersionChannelFilter;
|
||||
import io.papermc.hangar.controller.extras.pagination.filters.versions.VersionPlatformFilter;
|
||||
import io.papermc.hangar.controller.extras.pagination.filters.versions.VersionPlatformVersionFilter;
|
||||
import io.papermc.hangar.controller.internal.config.VersionControllerConfig;
|
||||
import io.papermc.hangar.model.api.PaginatedResult;
|
||||
import io.papermc.hangar.model.api.project.version.UploadedVersion;
|
||||
@ -70,7 +69,7 @@ public class VersionsController implements IVersionsController {
|
||||
|
||||
@Override
|
||||
@VisibilityRequired(type = VisibilityRequired.Type.PROJECT, args = "{#slug}")
|
||||
@ApplicableFilters({VersionChannelFilter.class, VersionPlatformFilter.class, VersionPlatformVersionFilter.class})
|
||||
@ApplicableFilters({VersionChannelFilter.class, VersionPlatformFilter.class})
|
||||
public PaginatedResult<Version> getVersions(final String slug,
|
||||
@ConfigurePagination(defaultLimitString = "@hangarConfig.projects.initVersionLoad", maxLimit = 25) final @NotNull RequestPagination pagination,
|
||||
@RequestParam(required = false, defaultValue = "true") final boolean includeHiddenChannels) {
|
||||
|
@ -52,6 +52,12 @@ public class VersionPlatformFilter implements Filter<VersionPlatformFilterInstan
|
||||
|
||||
@Override
|
||||
public void createSql(final StringBuilder sb, final SqlStatement<?> q) {
|
||||
if (this.platforms.length == Platform.values().length) {
|
||||
return;
|
||||
}
|
||||
|
||||
q.define("platformfilter", true);
|
||||
|
||||
sb.append(" AND (");
|
||||
for (int i = 0; i < this.platforms.length; i++) {
|
||||
sb.append(":__platform_").append(i).append(" = ANY(sq.platforms)");
|
||||
|
@ -1,63 +0,0 @@
|
||||
package io.papermc.hangar.controller.extras.pagination.filters.versions;
|
||||
|
||||
import io.papermc.hangar.controller.extras.pagination.Filter;
|
||||
import io.papermc.hangar.controller.extras.pagination.filters.versions.VersionPlatformVersionFilter.VersionPlatformVersionFilterInstance;
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import org.jdbi.v3.core.statement.SqlStatement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
@Component
|
||||
public class VersionPlatformVersionFilter implements Filter<VersionPlatformVersionFilterInstance, String[]> {
|
||||
|
||||
@Override
|
||||
public Set<String> getQueryParamNames() {
|
||||
return Set.of("platformVersion");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "A platform version to filter for";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getValue(final NativeWebRequest webRequest) {
|
||||
return webRequest.getParameterValues(this.getSingleQueryParam());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull VersionPlatformVersionFilterInstance create(final NativeWebRequest webRequest) {
|
||||
return new VersionPlatformVersionFilterInstance(this.getValue(webRequest));
|
||||
}
|
||||
|
||||
static class VersionPlatformVersionFilterInstance implements Filter.FilterInstance {
|
||||
|
||||
private final String[] platformVersions;
|
||||
|
||||
public VersionPlatformVersionFilterInstance(final String[] platformVersions) {
|
||||
this.platformVersions = platformVersions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createSql(final StringBuilder sb, final SqlStatement<?> q) {
|
||||
sb.append(" AND (");
|
||||
for (int i = 0; i < this.platformVersions.length; i++) {
|
||||
sb.append(":__platform_version_").append(i).append(" = ANY(sq.versions)");
|
||||
q.bind("__platform_version_" + i, this.platformVersions[i]);
|
||||
if (i + 1 != this.platformVersions.length) {
|
||||
sb.append(" OR ");
|
||||
}
|
||||
}
|
||||
sb.append(')');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "VersionPlatformVersionFilterInstance{" +
|
||||
"platformVersions=" + Arrays.toString(this.platformVersions) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
@ -112,6 +112,12 @@ public interface VersionsApiDAO {
|
||||
@KeyColumn("id")
|
||||
@RegisterColumnMapper(VersionStatsMapper.class)
|
||||
@SqlQuery("""
|
||||
<if(platformfilter)>
|
||||
WITH sq AS (SELECT array_agg(DISTINCT plv.platform) platforms, array_agg(DISTINCT plv.version) versions, pvpd.version_id
|
||||
FROM project_version_platform_dependencies pvpd
|
||||
JOIN platform_versions plv ON pvpd.platform_version_id = plv.id
|
||||
GROUP BY pvpd.version_id)
|
||||
<endif>
|
||||
SELECT pv.id,
|
||||
pv.created_at,
|
||||
pv.version_string,
|
||||
@ -119,7 +125,7 @@ public interface VersionsApiDAO {
|
||||
pv.description,
|
||||
coalesce((SELECT sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id), 0) vs_totalDownloads,
|
||||
(select array_agg(d) from (SELECT pvd.platform, sum(pvd.downloads) FROM project_versions_downloads pvd WHERE p.id = pvd.project_id AND pv.id = pvd.version_id GROUP BY pvd.platform) d) vs_platformDownloads,
|
||||
u.name author,
|
||||
(select u.name from users u where u.id = pv.author_id) as author,
|
||||
pv.review_state,
|
||||
pc.created_at pc_created_at,
|
||||
pc.name pc_name,
|
||||
@ -134,12 +140,7 @@ public interface VersionsApiDAO {
|
||||
FROM project_versions pv
|
||||
JOIN projects p ON pv.project_id = p.id
|
||||
JOIN project_channels pc ON pv.channel_id = pc.id
|
||||
LEFT JOIN users u ON pv.author_id = u.id
|
||||
INNER JOIN (SELECT array_agg(DISTINCT plv.platform) platforms, array_agg(DISTINCT plv.version) versions, pvpd.version_id
|
||||
FROM project_version_platform_dependencies pvpd
|
||||
JOIN platform_versions plv ON pvpd.platform_version_id = plv.id
|
||||
GROUP BY pvpd.version_id
|
||||
) sq ON pv.id = sq.version_id
|
||||
<if(platformfilter)>INNER JOIN sq ON pv.id = sq.version_id<endif>
|
||||
WHERE TRUE <filters>
|
||||
<if(!canSeeHidden)>
|
||||
AND (pv.visibility = 0
|
||||
@ -148,27 +149,30 @@ public interface VersionsApiDAO {
|
||||
<endif>)
|
||||
<endif>
|
||||
AND lower(p.slug) = lower(:slug)
|
||||
GROUP BY pv.id, p.id, u.name, pc.id, pv.created_at ORDER BY pv.created_at DESC <offsetLimit>
|
||||
ORDER BY pv.created_at DESC <offsetLimit>
|
||||
""")
|
||||
SortedMap<Long, Version> getVersions(String slug, @Define boolean canSeeHidden, @Define Long userId, @BindPagination RequestPagination pagination);
|
||||
|
||||
@SqlQuery("SELECT count(DISTINCT pv.id)" +
|
||||
" FROM project_versions pv" +
|
||||
" JOIN projects p ON pv.project_id = p.id" +
|
||||
" JOIN project_channels pc ON pv.channel_id = pc.id" +
|
||||
" INNER JOIN (SELECT array_agg(DISTINCT plv.platform) platforms, array_agg(DISTINCT plv.version) versions, pvpd.version_id" +
|
||||
" FROM project_version_platform_dependencies pvpd" +
|
||||
" JOIN platform_versions plv ON pvpd.platform_version_id = plv.id" +
|
||||
" GROUP BY pvpd.version_id" +
|
||||
" ) sq ON pv.id = sq.version_id" +
|
||||
" WHERE TRUE <filters> " +
|
||||
" <if(!canSeeHidden)>" +
|
||||
" AND (pv.visibility = 0 " +
|
||||
" <if(userId)>" +
|
||||
" OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4)" +
|
||||
" <endif>)" +
|
||||
" <endif> " +
|
||||
" AND lower(p.slug) = lower(:slug)")
|
||||
@SqlQuery("""
|
||||
<if(platformfilter)>
|
||||
WITH sq AS (SELECT array_agg(DISTINCT plv.platform) platforms, array_agg(DISTINCT plv.version) versions, pvpd.version_id
|
||||
FROM project_version_platform_dependencies pvpd
|
||||
JOIN platform_versions plv ON pvpd.platform_version_id = plv.id
|
||||
GROUP BY pvpd.version_id)
|
||||
<endif>
|
||||
SELECT count(DISTINCT pv.id)
|
||||
FROM project_versions pv
|
||||
JOIN projects p ON pv.project_id = p.id
|
||||
JOIN project_channels pc ON pv.channel_id = pc.id
|
||||
<if(platformfilter)>INNER JOIN sq ON pv.id = sq.version_id<endif>
|
||||
WHERE TRUE <filters>
|
||||
<if(!canSeeHidden)>
|
||||
AND (pv.visibility = 0
|
||||
<if(userId)>
|
||||
OR (<userId> IN (SELECT pm.user_id FROM project_members_all pm WHERE pm.id = p.id) AND pv.visibility != 4)
|
||||
<endif>)
|
||||
<endif>
|
||||
AND lower(p.slug) = lower(:slug)""")
|
||||
Long getVersionCount(String slug, @Define boolean canSeeHidden, @Define Long userId, @BindPagination(isCount = true) RequestPagination pagination);
|
||||
|
||||
@SqlQuery("SELECT " +
|
||||
|
Loading…
Reference in New Issue
Block a user