From 4a2f819dba792b49247f863a65f07821eefe64b5 Mon Sep 17 00:00:00 2001 From: Sergey Krylov Date: Mon, 9 Mar 2026 11:46:01 +0300 Subject: [PATCH] feat: add sorting --- resources/WEB-INF/jsp/profiles.jsp | 112 ++++++++++++++++-- src/ru/charm/back/dao/ProfileDao.java | 27 ++++- src/ru/charm/back/dto/ProfileFilter.java | 1 + .../back/dto/ProfileSelectQueryBuilder.java | 5 + .../mapper/RequestToProfileFilterMapper.java | 6 +- 5 files changed, 142 insertions(+), 9 deletions(-) diff --git a/resources/WEB-INF/jsp/profiles.jsp b/resources/WEB-INF/jsp/profiles.jsp index 0974fc8..400793a 100644 --- a/resources/WEB-INF/jsp/profiles.jsp +++ b/resources/WEB-INF/jsp/profiles.jsp @@ -4,11 +4,42 @@ Charm Profiles <%@ include file="style.html" %> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <%@ include file="header.jsp" %>
+
@@ -73,12 +104,76 @@ - - - - - - + + + + + + + @@ -104,9 +199,12 @@ - + + + +

id

${wordBundle.getWord("email")}

${wordBundle.getWord("name")}

${wordBundle.getWord("surname")}

${wordBundle.getWord("age")}

${wordBundle.getWord("status")}

+ +

+ id + + ^ + +

+
+
+ +

+ ${wordBundle.getWord("email")} + + ^ + +

+
+
+ +

+ ${wordBundle.getWord("name")} + + ^ + +

+
+
+ +

+ ${wordBundle.getWord("surname")} + + ^ + +

+
+
+ +

+ ${wordBundle.getWord("age")} + + ^ + +

+
+
+ +

+ ${wordBundle.getWord("status")} + + ^ + +

+
+
+ +

+ ${wordBundle.getWord("role")} + + ^ + +

+
+

${profile.role}

diff --git a/src/ru/charm/back/dao/ProfileDao.java b/src/ru/charm/back/dao/ProfileDao.java index 3080d86..dbb4fea 100644 --- a/src/ru/charm/back/dao/ProfileDao.java +++ b/src/ru/charm/back/dao/ProfileDao.java @@ -27,6 +27,7 @@ public class ProfileDao { public static final String INSERT = "INSERT INTO profile (email, password) VALUES (?, ?)"; private static final ProfileDao INSTANCE = new ProfileDao(); + private Set validColumns; @SneakyThrows public static ProfileDao getInstance() { @@ -85,7 +86,7 @@ public class ProfileDao { .addStatus(filter.getStatus()) .addLTAge(filter.getLtAge()) .addGTEAge(filter.getGteAge()) - .build(); + .build(getValidSort(filter.getSort())); try ( Connection connection = ConnectionManager.getConnection(); @@ -108,6 +109,30 @@ public class ProfileDao { } } + private String getValidSort(String sort) { + if (validColumns == null) { + validColumns = new HashSet<>(); + try (Connection conn = getConnection();) { + ResultSet rs = conn.getMetaData().getColumns(null, null, "profile", null); + + while(rs.next()) { + String comment = rs.getString("REMARKS"); + if("sortable".equals(comment)) { + validColumns.add(rs.getString("COLUMN_NAME")); + } + } + + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + if (validColumns.contains(sort)) { + return sort; + } else { + return "id"; + } + } + public void update(Profile profile) { Query query = new ProfileUpdateQueryBuilder() .addEmail(profile.getEmail()) diff --git a/src/ru/charm/back/dto/ProfileFilter.java b/src/ru/charm/back/dto/ProfileFilter.java index d041066..37f8e01 100644 --- a/src/ru/charm/back/dto/ProfileFilter.java +++ b/src/ru/charm/back/dto/ProfileFilter.java @@ -14,4 +14,5 @@ public class ProfileFilter { Integer ltAge; Integer gteAge; Status status; + String sort; } diff --git a/src/ru/charm/back/dto/ProfileSelectQueryBuilder.java b/src/ru/charm/back/dto/ProfileSelectQueryBuilder.java index 396bedd..72099f8 100644 --- a/src/ru/charm/back/dto/ProfileSelectQueryBuilder.java +++ b/src/ru/charm/back/dto/ProfileSelectQueryBuilder.java @@ -112,4 +112,9 @@ public class ProfileSelectQueryBuilder { public Query build() { return new Query(sb.toString(), args); } + + public Query build(String sort) { + sb.append(" ORDER BY ").append(sort).append(" ASC"); + return new Query(sb.toString(), args); + } } diff --git a/src/ru/charm/back/mapper/RequestToProfileFilterMapper.java b/src/ru/charm/back/mapper/RequestToProfileFilterMapper.java index cc84a61..a67e5fd 100644 --- a/src/ru/charm/back/mapper/RequestToProfileFilterMapper.java +++ b/src/ru/charm/back/mapper/RequestToProfileFilterMapper.java @@ -49,6 +49,10 @@ public class RequestToProfileFilterMapper implements Mapper