diff --git a/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/MessageCache.java b/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/MessageCache.java index 088fcd91f..9ba7cb72c 100644 --- a/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/MessageCache.java +++ b/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/MessageCache.java @@ -3,6 +3,7 @@ import lombok.extern.slf4j.Slf4j; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.Message.Attachment; import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; import net.dv8tion.jda.api.interactions.components.buttons.Button; import net.javadiscord.javabot.data.config.BotConfig; @@ -25,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Service; @@ -108,7 +110,7 @@ public void cache(Message message) { public void sendUpdatedMessageToLog(Message updated, CachedMessage before) { MessageCacheConfig config = botConfig.get(updated.getGuild()).getMessageCacheConfig(); if (config.getMessageCacheLogChannel() == null) return; - if (updated.getContentRaw().trim().equals(before.getMessageContent())) return; + if (updated.getContentRaw().trim().equals(before.getMessageContent()) && updated.getAttachments().size() == before.getAttachments().size()) return; MessageCreateAction action = config.getMessageCacheLogChannel() .sendMessageEmbeds(buildMessageEditEmbed(updated.getGuild(), updated.getAuthor(), updated.getChannel(), before, updated)) .setActionRow(Button.link(updated.getJumpUrl(), "Jump to Message")); @@ -148,7 +150,7 @@ private EmbedBuilder buildMessageCacheEmbed(MessageChannel channel, User author, } private MessageEmbed buildMessageEditEmbed(Guild guild, User author, MessageChannel channel, CachedMessage before, Message after) { - return buildMessageCacheEmbed(channel, author, before) + EmbedBuilder eb = buildMessageCacheEmbed(channel, author, before) .setTitle("Message Edited") .setColor(Responses.Type.WARN.getColor()) .addField("Before", before.getMessageContent().substring(0, Math.min( @@ -156,18 +158,41 @@ private MessageEmbed buildMessageEditEmbed(Guild guild, User author, MessageChan MessageEmbed.VALUE_MAX_LENGTH)), false) .addField("After", after.getContentRaw().substring(0, Math.min( after.getContentRaw().length(), - MessageEmbed.VALUE_MAX_LENGTH)), false) + MessageEmbed.VALUE_MAX_LENGTH)), false); + if(before.getAttachments().size() != after.getAttachments().size()) { + eb.addField("Deleted Attachments", + before + .getAttachments() + .stream() + .filter(attachment -> after//not present in 'after' + .getAttachments() + .stream() + .map(Attachment::getProxyUrl) + .noneMatch(attachment::equals)) + .collect(Collectors.joining("\n")), + false); + } + return eb .build(); } private MessageEmbed buildMessageDeleteEmbed(Guild guild, User author, MessageChannel channel, CachedMessage message) { - return buildMessageCacheEmbed(channel, author, message) + EmbedBuilder eb = buildMessageCacheEmbed(channel, author, message) .setTitle("Message Deleted") .setColor(Responses.Type.ERROR.getColor()) .addField("Message Content", message.getMessageContent().substring(0, Math.min( message.getMessageContent().length(), - MessageEmbed.VALUE_MAX_LENGTH)), false) + MessageEmbed.VALUE_MAX_LENGTH)), false); + if (!message.getAttachments().isEmpty()) { + eb.addField("Attachments", + message + .getAttachments() + .stream() + .collect(Collectors.joining("\n")), + false); + } + return eb .build(); } diff --git a/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/dao/MessageCacheRepository.java b/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/dao/MessageCacheRepository.java index 9f0e619da..7fe4dde41 100644 --- a/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/dao/MessageCacheRepository.java +++ b/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/dao/MessageCacheRepository.java @@ -6,11 +6,14 @@ import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import java.sql.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; /** * Dao class that represents the QOTW_POINTS SQL Table. @@ -20,20 +23,6 @@ public class MessageCacheRepository { private final JdbcTemplate jdbcTemplate; - /** - * Inserts a new {@link CachedMessage} object. - * - * @param message The Message to insert. - * @return Whether there were rows affected by this process. - * @throws SQLException If an error occurs. - */ - public boolean insert(CachedMessage message) throws DataAccessException { - int rows = jdbcTemplate.update( - "INSERT INTO message_cache (message_id, author_id, message_content) VALUES (?, ?, ?)", - message.getMessageId(), message.getAuthorId(), message.getMessageContent()); - return rows > 0; - } - /** * Inserts a {@link List} of {@link CachedMessage} objects. * @@ -57,31 +46,30 @@ public int getBatchSize() { return messages.size(); } }); - } + List> attachments=new ArrayList<>(); + for (CachedMessage msg : messages) { + for (int i = 0; i < msg.getAttachments().size(); i++) { + attachments.add(Map.entry(msg, i)); + } + } + jdbcTemplate.batchUpdate("MERGE INTO message_cache_attachments (message_id, attachment_index, link) VALUES (?, ?, ?)", + new BatchPreparedStatementSetter() { - /** - * Edit an existing {@link CachedMessage} object. - * - * @param message The new Message object. - * @return Whether there were rows affected by this process. - * @throws SQLException If an error occurs. - */ - public boolean update(@NotNull CachedMessage message) throws DataAccessException { - int rows = jdbcTemplate.update("UPDATE message_cache SET message_content = ? WHERE message_id = ?", - message.getMessageContent(), message.getMessageId()); - return rows > 0; - } + @Override + public void setValues(PreparedStatement stmt, int i) throws SQLException { + Entry entry = attachments.get(i); + CachedMessage msg = entry.getKey(); + Integer attachmentIndex = entry.getValue(); + stmt.setLong(1, msg.getMessageId()); + stmt.setInt(2, attachmentIndex); + stmt.setString(3, msg.getAttachments().get(attachmentIndex)); + } - /** - * Deletes a single {@link CachedMessage} object from the Message Cache. - * - * @param messageId The message's id. - * @return Whether there were rows affected by this process. - * @throws SQLException If an error occurs. - */ - public boolean delete(long messageId) throws DataAccessException { - int rows = jdbcTemplate.update("DELETE FROM message_cache WHERE message_id = ?", messageId); - return rows > 0; + @Override + public int getBatchSize() { + return attachments.size(); + } + }); } /** @@ -91,7 +79,17 @@ public boolean delete(long messageId) throws DataAccessException { * @throws SQLException If anything goes wrong. */ public List getAll() throws DataAccessException { - return jdbcTemplate.query("SELECT * FROM message_cache",(RowMapper) (rs, rowNum) -> this.read(rs)); + List messagesWithLink = jdbcTemplate.query( + "SELECT * FROM message_cache LEFT JOIN message_cache_attachments ON message_cache.message_id = message_cache_attachments.message_id", + (rs, rowNum) -> this.read(rs)); + Map messages=new LinkedHashMap<>(); + for (CachedMessage msg : messagesWithLink) { + CachedMessage previous = messages.putIfAbsent(msg.getMessageId(), msg); + if(previous!=null) { + previous.getAttachments().addAll(msg.getAttachments()); + } + } + return new ArrayList<>(messages.values()); } /** @@ -103,14 +101,22 @@ public List getAll() throws DataAccessException { */ public boolean delete(int amount) throws DataAccessException { int rows = jdbcTemplate.update("DELETE FROM message_cache LIMIT ?", amount); - return rows > 0; + if(rows > 0){ + jdbcTemplate.update("DELETE FROM message_cache_attachments WHERE message_id NOT IN (SELECT message_id FROM message_cache)"); + return true; + } + return false; } private CachedMessage read(ResultSet rs) throws SQLException { CachedMessage cachedMessage = new CachedMessage(); - cachedMessage.setMessageId(rs.getLong("message_id")); + cachedMessage.setMessageId(rs.getLong("message_cache.message_id")); cachedMessage.setAuthorId(rs.getLong("author_id")); cachedMessage.setMessageContent(rs.getString("message_content")); + String attachment = rs.getString("link"); + if(attachment!=null) { + cachedMessage.getAttachments().add(attachment); + } return cachedMessage; } } diff --git a/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/model/CachedMessage.java b/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/model/CachedMessage.java index d90e49388..50e1bf5ce 100644 --- a/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/model/CachedMessage.java +++ b/src/main/java/net/javadiscord/javabot/data/h2db/message_cache/model/CachedMessage.java @@ -1,7 +1,11 @@ package net.javadiscord.javabot.data.h2db.message_cache.model; +import java.util.ArrayList; +import java.util.List; + import lombok.Data; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.Message.Attachment; /** * Represents a cached Message. @@ -11,6 +15,7 @@ public class CachedMessage { private long messageId; private long authorId; private String messageContent; + private List attachments=new ArrayList<>(); /** * Converts a {@link Message} object to a {@link CachedMessage}. @@ -23,6 +28,11 @@ public static CachedMessage of(Message message) { cachedMessage.setMessageId(message.getIdLong()); cachedMessage.setAuthorId(message.getAuthor().getIdLong()); cachedMessage.setMessageContent(message.getContentRaw().trim()); + cachedMessage.attachments = message + .getAttachments() + .stream() + .map(Attachment::getProxyUrl) + .toList(); return cachedMessage; } diff --git a/src/main/resources/database/migrations/02-13-2023_message_cache_links.sql b/src/main/resources/database/migrations/02-13-2023_message_cache_links.sql new file mode 100644 index 000000000..03c55f07c --- /dev/null +++ b/src/main/resources/database/migrations/02-13-2023_message_cache_links.sql @@ -0,0 +1,6 @@ +CREATE TABLE message_cache_attachments ( + message_id BIGINT NOT NULL, + attachment_index INT NOT NULL, + link VARCHAR(255), + PRIMARY KEY(message_id, attachment_index) +) diff --git a/src/main/resources/database/schema.sql b/src/main/resources/database/schema.sql index a4b26eed6..e090aefd9 100644 --- a/src/main/resources/database/schema.sql +++ b/src/main/resources/database/schema.sql @@ -96,6 +96,12 @@ CREATE TABLE message_cache author_id BIGINT NOT NULL, message_content VARCHAR(4000) NOT NULL ); +CREATE TABLE message_cache_attachments ( + message_id BIGINT NOT NULL, + attachment_index INT NOT NULL, + link VARCHAR(255), + PRIMARY KEY(message_id, attachment_index) +) // User Preferences CREATE TABLE user_preferences