22
33import java .sql .ResultSet ;
44import java .sql .SQLException ;
5+ import java .time .LocalDate ;
56import java .util .List ;
67import java .util .Optional ;
78
8- import org .jetbrains .annotations .NotNull ;
99import org .springframework .dao .DataAccessException ;
1010import org .springframework .dao .EmptyResultDataAccessException ;
1111import org .springframework .jdbc .core .JdbcTemplate ;
1212import org .springframework .stereotype .Repository ;
1313
1414import lombok .RequiredArgsConstructor ;
15- import lombok .extern .slf4j .Slf4j ;
1615import net .javadiscord .javabot .systems .qotw .model .QOTWAccount ;
1716
1817/**
1918 * Dao class that represents the QOTW_POINTS SQL Table.
2019 */
21- @ Slf4j
2220@ RequiredArgsConstructor
2321@ Repository
2422public class QuestionPointsRepository {
2523 private final JdbcTemplate jdbcTemplate ;
2624
2725 /**
28- * Inserts a new {@link QOTWAccount} if none exists .
26+ * Returns a {@link QOTWAccount} based on the given user Id .
2927 *
30- * @param account The account to insert.
28+ * @param userId The discord Id of the user.
29+ * @param startDate The earliest date where points are counted
30+ * @return The {@link QOTWAccount} object.
3131 * @throws DataAccessException If an error occurs.
3232 */
33- public void insert (QOTWAccount account ) throws DataAccessException {
34- int rows = jdbcTemplate .update ("INSERT INTO qotw_points (user_id, points) VALUES (?, ?)" ,
35- account .getUserId (),account .getPoints ());
36- if (rows == 0 ) throw new DataAccessException ("User was not inserted." ) {};
37- log .info ("Inserted new QOTW-Account: {}" , account );
33+ public Optional <QOTWAccount > getByUserId (long userId , LocalDate startDate ) throws DataAccessException {
34+ try {
35+ return Optional .of (jdbcTemplate .queryForObject ("SELECT SUM(points) AS points FROM qotw_points WHERE user_id = ? AND obtained_at >= ?" ,
36+ (rs , row )->{
37+ QOTWAccount acc =new QOTWAccount ();
38+ acc .setUserId (userId );
39+ acc .setPoints (rs .getLong (1 ));
40+ return acc ;
41+ },
42+ userId , startDate ));
43+ }catch (EmptyResultDataAccessException e ) {
44+ return Optional .empty ();
45+ }
3846 }
3947
4048 /**
41- * Returns a {@link QOTWAccount} based on the given user Id .
49+ * Gets the number points given to a user at a certain date .
4250 *
43- * @param userId The discord Id of the user.
44- * @return The {@link QOTWAccount} object.
45- * @throws DataAccessException If an error occurs.
51+ * @param userId the ID of the user
52+ * @param date the date where the points are given to that user
53+ * @return the number of points the user obtained at the given date
4654 */
47- public Optional < QOTWAccount > getByUserId (long userId ) throws DataAccessException {
55+ public int getPointsAtDate (long userId , LocalDate date ) {
4856 try {
49- return Optional .of (jdbcTemplate .queryForObject ("SELECT * FROM qotw_points WHERE user_id = ?" , (rs , row )->this .read (rs ),userId ));
57+ return jdbcTemplate .queryForObject ("SELECT SUM(points) FROM qotw_points WHERE user_id = ? AND obtained_at >= ?" ,
58+ (rs , row ) -> rs .getInt (1 ),
59+ userId , date );
5060 }catch (EmptyResultDataAccessException e ) {
51- return Optional . empty () ;
61+ return 0 ;
5262 }
5363 }
5464
5565 /**
56- * Updates a single QOTW Account .
66+ * Sets the points of a user at a certain date .
5767 *
58- * @param account The updated QOTW Account.
59- * @return Whether the update affected rows.
60- * @throws DataAccessException If an error occurs.
68+ * @param userId the id of the user to set to points of
69+ * @param date the date when the points should be marked as set
70+ * @param points the (new) number of points the user got at that date
71+ * @return {@code true} if a change was made, else {@code false}
6172 */
62- public boolean update ( @ NotNull QOTWAccount account ) throws DataAccessException {
63- return jdbcTemplate .update ("UPDATE qotw_points SET points = ? WHERE user_id = ? " ,
64- account . getPoints (), account . getUserId () ) > 0 ;
73+ public boolean setPointsAtDate ( long userId , LocalDate date , long points ) {
74+ return jdbcTemplate .update ("MERGE INTO qotw_points (user_id,obtained_at, points) KEY( user_id,obtained_at) VALUES (?,?,?) " ,
75+ userId , date , points ) > 0 ;
6576 }
6677
6778 /**
6879 * Gets all {@link QOTWAccount} and sorts them by their points.
6980 *
81+ * @param startDate the minimum date points are considered
7082 * @return A {@link List} that contains all {@link QOTWAccount}s sorted by their points.
7183 * @throws DataAccessException If an error occurs.
7284 */
73- public List <QOTWAccount > sortByPoints () throws DataAccessException {
74- return jdbcTemplate .query ("SELECT * FROM qotw_points ORDER BY points DESC" , (rs , row )->this .read (rs ));
85+ public List <QOTWAccount > sortByPoints (LocalDate startDate ) throws DataAccessException {
86+ return jdbcTemplate .query ("SELECT user_id, SUM(points) FROM qotw_points WHERE obtained_at >= ? GROUP BY user_id ORDER BY SUM(points) DESC" ,
87+ (rs , row )->this .read (rs ),
88+ startDate );
7589 }
7690
7791 /**
7892 * Gets a specified amount of {@link QOTWAccount}s.
7993 *
80- * @param page The page.
81- * @param size The amount of {@link QOTWAccount}s to return.
94+ * @param startDate the minimum date points are considered
95+ * @param page The page.
96+ * @param size The amount of {@link QOTWAccount}s to return.
8297 * @return A {@link List} containing the specified amount of {@link QOTWAccount}s.
8398 * @throws DataAccessException If an error occurs.
8499 */
85- public List <QOTWAccount > getTopAccounts (int page , int size ) throws DataAccessException {
86- return jdbcTemplate .query ("SELECT * FROM qotw_points WHERE points > 0 ORDER BY points DESC LIMIT ? OFFSET ?" , (rs ,row )->this .read (rs ),
87- size , Math .max (0 , (page * size ) - size ));
100+ public List <QOTWAccount > getTopAccounts (LocalDate startDate , int page , int size ) throws DataAccessException {
101+ return jdbcTemplate .query ("SELECT user_id, SUM(points) FROM qotw_points WHERE obtained_at >= ? AND points > 0 GROUP BY user_id ORDER BY SUM(points) DESC LIMIT ? OFFSET ?" ,
102+ (rs ,row )->this .read (rs ),
103+ startDate , size , Math .max (0 , (page * size ) - size ));
104+ }
105+
106+ /**
107+ * Gets all users with a specific score starting from a specific date.
108+ * @param startDate the minimum date points are considered
109+ * @param score the score users should have in order to be considered
110+ * @return A {@link List} of all users with a specific total QOTW score
111+ */
112+ public List <Long > getUsersWithSpecificScore (LocalDate startDate , long score ){
113+ return jdbcTemplate .query ("SELECT user_id FROM qotw_points WHERE obtained_at >= ? GROUP BY user_id HAVING SUM(points)=?" ,
114+ (rs ,row )->rs .getLong (1 ),
115+ startDate , score );
88116 }
89117
90118 /**
@@ -96,8 +124,8 @@ public List<QOTWAccount> getTopAccounts(int page, int size) throws DataAccessExc
96124 */
97125 private QOTWAccount read (ResultSet rs ) throws SQLException {
98126 QOTWAccount account = new QOTWAccount ();
99- account .setUserId (rs .getLong ("user_id" ));
100- account .setPoints (rs .getLong ("points" ));
127+ account .setUserId (rs .getLong (1 ));
128+ account .setPoints (rs .getLong (2 ));
101129 return account ;
102130 }
103131}
0 commit comments