Merge remote-tracking branch 'origin/develop' into Sidebar-Menu

# Conflicts:
#	src/main/java/org/to/telegramfinalproject/Client/ActionHandler.java
#	src/main/java/org/to/telegramfinalproject/Database/ContactDatabase.java
#	src/main/java/org/to/telegramfinalproject/Database/MessageDatabase.java
#	src/main/java/org/to/telegramfinalproject/Models/ContactEntry.java
#	src/main/java/org/to/telegramfinalproject/Models/Message.java
#	src/main/java/org/to/telegramfinalproject/Server/ClientHandler.java
#	src/main/resources/init.sql
This commit is contained in:
Asal Lotfi
2025-08-11 13:10:18 +03:30
16 changed files with 1939 additions and 220 deletions
@@ -6,6 +6,7 @@ import org.to.telegramfinalproject.Models.Message;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -76,7 +77,7 @@ public class MessageDatabase {
}
public static void logDeletedMessagesFor(UUID chatId, UUID userId) {
List<Message> messages = MessageDatabase.privateChatHistory(chatId);
List<Message> messages = MessageDatabase.privateChatHistory(chatId, userId);
for (Message message : messages) {
if (!isMessageDeleted(message.getMessage_id(), userId)) {
String sql = """
@@ -110,6 +111,258 @@ public class MessageDatabase {
}
}
public static List<Message> getMessagesForChat(UUID chatId, String chatType, UUID currentUserId, int offset, int limit) {
List<Message> messages = new ArrayList<>();
String sql = """
SELECT * FROM messages m
WHERE m.receiver_type = ?
AND m.receiver_id = ?
AND m.is_deleted_globally = FALSE
AND NOT EXISTS (
SELECT 1 FROM deleted_messages d
WHERE d.message_id = m.message_id
AND d.user_id = ?
)
ORDER BY m.send_at DESC
LIMIT ? OFFSET ?
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, chatType);
ps.setObject(2, chatId);
ps.setObject(3, currentUserId);
ps.setInt(4, limit);
ps.setInt(5, offset);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
Message msg = new Message(
UUID.fromString(rs.getString("message_id")),
UUID.fromString(rs.getString("sender_id")),
rs.getString("receiver_type"),
UUID.fromString(rs.getString("receiver_id")),
rs.getString("content"),
rs.getString("message_type"),
rs.getTimestamp("send_at").toLocalDateTime(),
rs.getString("status"),
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
rs.getBoolean("is_edited"),
rs.getBoolean("is_deleted_globally"),
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null,
rs.getTimestamp("edited_at") != null
? rs.getTimestamp("edited_at").toLocalDateTime()
: null
);
messages.add(msg);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
return messages;
}
public static Message findById(UUID messageId) {
String sql = "SELECT * FROM messages WHERE message_id = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, messageId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
return new Message(
UUID.fromString(rs.getString("message_id")),
UUID.fromString(rs.getString("sender_id")),
rs.getString("receiver_type"),
UUID.fromString(rs.getString("receiver_id")),
rs.getString("content"),
rs.getString("message_type"),
rs.getTimestamp("send_at").toLocalDateTime(),
rs.getString("status"),
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
rs.getBoolean("is_edited"),
rs.getBoolean("is_deleted_globally"),
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null
);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static boolean markAsDeletedForUser(UUID messageId, UUID userId) {
String sql = "INSERT INTO deleted_messages (message_id, user_id) VALUES (?, ?) ON CONFLICT DO NOTHING";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, messageId);
ps.setObject(2, userId);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static boolean markAsGloballyDeleted(UUID messageId) {
String sql = "UPDATE messages SET is_deleted_globally = true WHERE message_id = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, messageId);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static boolean updateContentAndMarkEdited(UUID messageId, String newContent) {
String sql = """
UPDATE messages
SET content = ?, is_edited = TRUE, edited_at = CURRENT_TIMESTAMP
WHERE message_id = ?
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, newContent);
ps.setObject(2, messageId);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static boolean saveReplyMessage(Message message) {
String sql = """
INSERT INTO messages (
message_id, sender_id, receiver_type, receiver_id, content, message_type,
send_at, status, reply_to_id, is_edited, is_deleted_globally,
original_message_id, forwarded_by, forwarded_from, edited_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, message.getMessage_id());
ps.setObject(2, message.getSender_id());
ps.setString(3, message.getReceiver_type());
ps.setObject(4, message.getReceiver_id());
ps.setString(5, message.getContent());
ps.setString(6, message.getMessage_type());
ps.setTimestamp(7, Timestamp.valueOf(message.getSend_at()));
ps.setString(8, message.getStatus());
ps.setObject(9, message.getReply_to_id()); //Important part because of reply message id
ps.setBoolean(10, message.isIs_edited());
ps.setBoolean(11, message.isIs_deleted_globally());
ps.setObject(12, message.getOriginal_message_id());
ps.setObject(13, message.getForwarded_by());
ps.setObject(14, message.getForwarded_from());
ps.setTimestamp(15, message.getEdited_at() != null ? Timestamp.valueOf(message.getEdited_at()) : null);
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static boolean saveForwardedMessage(Message message) {
String sql = """
INSERT INTO messages (
message_id, sender_id, receiver_type, receiver_id,
content, message_type, send_at, status,
reply_to_id, is_edited, is_deleted_globally,
original_message_id, forwarded_by, forwarded_from
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, message.getMessage_id());
ps.setObject(2, message.getSender_id());
ps.setString(3, message.getReceiver_type());
ps.setObject(4, message.getReceiver_id());
ps.setString(5, message.getContent());
ps.setString(6, message.getMessage_type());
ps.setTimestamp(7, Timestamp.valueOf(message.getSend_at()));
ps.setString(8, message.getStatus());
ps.setObject(9, message.getReply_to_id());
ps.setBoolean(10, message.isIs_edited());
ps.setBoolean(11, message.isIs_deleted_globally());
ps.setObject(12, message.getOriginal_message_id()); //original id
ps.setObject(13, message.getForwarded_by()); //forwarded by
ps.setObject(14, message.getForwarded_from()); //forwarded from
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static String getExcerpt(UUID messageId) {
return getExcerpt(messageId, 80);
}
public static String getExcerpt(UUID messageId, int maxLen) {
String sql = "SELECT content, message_type, is_deleted_globally FROM messages WHERE message_id = ?";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, messageId);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return "Message isn't available";
String content = rs.getString("content");
String type = rs.getString("message_type"); // e.g. TEXT, IMAGE, VIDEO, AUDIO, FILE, STICKER...
boolean deleted = rs.getBoolean("is_deleted_globally");
if (deleted) return "This message was deleted";
if (type == null || type.equalsIgnoreCase("TEXT")) {
if (content == null || content.isBlank()) return "(empty)";
return shorten(content, maxLen);
}
//for media
switch (type.toUpperCase()) {
case "IMAGE": return "[Photo]";
case "VIDEO": return "[Video]";
case "AUDIO": return "[Audio]";
case "VOICE": return "[Voice]";
case "FILE": return "[File]";
case "STICKER":return "[Sticker]";
default: return "[" + type + "]";
}
}
} catch (SQLException e) {
e.printStackTrace();
return "Error";
}
}
private static String shorten(String s, int maxLen) {
if (s.length() <= maxLen) return s;
return s.substring(0, Math.max(0, maxLen - 1)).trim() + "";
}
@@ -128,38 +381,43 @@ public class MessageDatabase {
public static List<Message> getUnreadMessages(UUID userId) {
List<Message> messages = new ArrayList<>();
String sql = """
SELECT m.* FROM messages m
SELECT m.*
FROM messages m
LEFT JOIN message_receipts r ON m.message_id = r.message_id AND r.user_id = ?
LEFT JOIN deleted_messages d ON m.message_id = d.message_id AND d.user_id = ?
WHERE r.user_id IS NULL
AND (
(m.receiver_type = 'private' AND m.receiver_id = ?)
OR
(m.receiver_type = 'group' AND EXISTS (
SELECT 1 FROM group_members gm WHERE gm.group_id = m.receiver_id AND gm.user_id = ?
))
OR
(m.receiver_type = 'channel' AND EXISTS (
SELECT 1 FROM channel_subscribers cs WHERE cs.channel_id = m.receiver_id AND cs.user_id = ?
))
)
AND d.message_id IS NULL
AND m.is_deleted_globally = FALSE
AND (
(m.receiver_type = 'private' AND m.receiver_id = ?)
OR
(m.receiver_type = 'group' AND EXISTS (
SELECT 1 FROM group_members gm WHERE gm.group_id = m.receiver_id AND gm.user_id = ?
))
OR
(m.receiver_type = 'channel' AND EXISTS (
SELECT 1 FROM channel_subscribers cs WHERE cs.channel_id = m.receiver_id AND cs.user_id = ?
))
)
ORDER BY m.send_at DESC
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, userId);
stmt.setObject(2, userId);
stmt.setObject(3, userId);
stmt.setObject(4, userId);
stmt.setObject(1, userId); // for message_receipts
stmt.setObject(2, userId); // for deleted_messages
stmt.setObject(3, userId); // for private messages
stmt.setObject(4, userId); // for group members
stmt.setObject(5, userId); // for channel subscribers
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
messages.add(new Message(
Message message = new Message(
UUID.fromString(rs.getString("message_id")),
rs.getObject("sender_id") != null ? UUID.fromString(rs.getString("sender_id")) : null,
rs.getString("receiver_type"),
@@ -170,12 +428,15 @@ public class MessageDatabase {
rs.getString("status"),
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
rs.getBoolean("is_edited"),
rs.getBoolean("is_deleted_globally"),
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null,
rs.getBoolean("is_deleted_globally"),
rs.getTimestamp("edited_at") != null ? rs.getTimestamp("edited_at").toLocalDateTime() : null
));
messages.add(message);
}
} catch (SQLException e) {
@@ -185,6 +446,8 @@ public class MessageDatabase {
return messages;
}
public static List<FileAttachment> getAttachments(UUID messageId) {
List<FileAttachment> attachments = new ArrayList<>();
String sql = "SELECT file_url, file_type FROM message_attachments WHERE message_id = ?";
@@ -283,45 +546,129 @@ public class MessageDatabase {
// public static List<Message> searchMessagesForUser(UUID userId, String keyword) {
// List<Message> result = new ArrayList<>();
// String sql = """
// SELECT * FROM messages
// WHERE receiver_type = 'private'
// AND (sender_id = ? OR receiver_id = ?)
// AND content ILIKE ?
// ORDER BY send_at DESC
// """;
//
// try (Connection conn = ConnectionDb.connect();
// PreparedStatement stmt = conn.prepareStatement(sql)) {
// stmt.setObject(1, userId);
// stmt.setObject(2, userId);
// stmt.setString(3, "%" + keyword + "%");
//
// ResultSet rs = stmt.executeQuery();
// while (rs.next()) {
// result.add(extractMessage(rs));
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// return result;
// }
public static List<Message> searchMessagesForUser(UUID userId, String keyword) {
String sql = """
SELECT * FROM messages m
WHERE m.receiver_type = 'private'
AND m.content ILIKE ?
AND m.is_deleted_globally = FALSE
AND (m.sender_id = ? OR m.receiver_id = ?)
AND NOT EXISTS (
SELECT 1 FROM deleted_messages d
WHERE d.message_id = m.message_id AND d.user_id = ?
)
ORDER BY m.send_at DESC
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "%" + keyword + "%");
ps.setObject(2, userId); // m.sender_id
ps.setObject(3, userId); // m.receiver_id
ps.setObject(4, userId); // deleted_messages
ResultSet rs = ps.executeQuery();
List<Message> messages = new ArrayList<>();
while (rs.next()) {
messages.add(mapResultSetToMessage(rs));
}
return messages;
} catch (SQLException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
private static Message mapResultSetToMessage(ResultSet rs) throws SQLException {
return new Message(
UUID.fromString(rs.getString("message_id")),
rs.getObject("sender_id") != null ? UUID.fromString(rs.getString("sender_id")) : null,
rs.getString("receiver_type"),
UUID.fromString(rs.getString("receiver_id")),
rs.getString("content"),
rs.getString("message_type"),
rs.getTimestamp("send_at").toLocalDateTime(),
rs.getString("status"),
rs.getObject("reply_to_id") != null ? UUID.fromString(rs.getString("reply_to_id")) : null,
rs.getBoolean("is_edited"),
rs.getBoolean("is_deleted_globally"),
rs.getObject("original_message_id") != null ? UUID.fromString(rs.getString("original_message_id")) : null,
rs.getObject("forwarded_by") != null ? UUID.fromString(rs.getString("forwarded_by")) : null,
rs.getObject("forwarded_from") != null ? UUID.fromString(rs.getString("forwarded_from")) : null
);
}
// public static List<Message> privateChatHistory(UUID chatId) {
// List<Message> result = new ArrayList<>();
// String sql = """
// SELECT * FROM messages
// WHERE receiver_type = 'private'
// AND receiver_id = ?
// ORDER BY send_at
// """;
//
// try (Connection conn = ConnectionDb.connect();
// PreparedStatement stmt = conn.prepareStatement(sql)) {
// stmt.setObject(1, chatId);
// ResultSet rs = stmt.executeQuery();
// while (rs.next()) {
// result.add(extractMessage(rs));
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
// return result;
// }
public static List<Message> privateChatHistory(UUID chatId, UUID userId) {
List<Message> result = new ArrayList<>();
String sql = """
SELECT * FROM messages
WHERE receiver_type = 'private'
AND (sender_id = ? OR receiver_id = ?)
AND content ILIKE ?
ORDER BY send_at DESC
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, userId);
stmt.setObject(2, userId);
stmt.setString(3, "%" + keyword + "%");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractMessage(rs));
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
public static List<Message> privateChatHistory(UUID chatId) {
List<Message> result = new ArrayList<>();
String sql = """
SELECT * FROM messages
WHERE receiver_type = 'private'
AND receiver_id = ?
AND receiver_id = ?
AND is_deleted_globally = FALSE
AND message_id NOT IN (
SELECT message_id FROM deleted_messages WHERE user_id = ?
)
ORDER BY send_at
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, chatId);
stmt.setObject(2, userId);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractMessage(rs));
@@ -335,17 +682,47 @@ public class MessageDatabase {
public static List<Message> groupChatHistory(UUID groupId) {
// public static List<Message> groupChatHistory(UUID groupId) {
// List<Message> result = new ArrayList<>();
// String sql = """
// SELECT * FROM messages
// WHERE receiver_type = 'group' AND receiver_id = ?
// ORDER BY send_at
// """;
//
// try (Connection conn = ConnectionDb.connect();
// PreparedStatement stmt = conn.prepareStatement(sql)) {
// stmt.setObject(1, groupId);
// ResultSet rs = stmt.executeQuery();
// while (rs.next()) {
// result.add(extractMessage(rs));
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
// return result;
// }
public static List<Message> groupChatHistory(UUID groupId,UUID userId) {
List<Message> result = new ArrayList<>();
String sql = """
SELECT * FROM messages
WHERE receiver_type = 'group' AND receiver_id = ?
SELECT * FROM messages
WHERE receiver_type = 'group'
AND receiver_id = ?
AND is_deleted_globally = FALSE
AND message_id NOT IN (
SELECT message_id FROM deleted_messages WHERE user_id = ?
)
ORDER BY send_at
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, groupId);
stmt.setObject(2, userId);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractMessage(rs));
@@ -357,17 +734,48 @@ public class MessageDatabase {
}
public static List<Message> channelChatHistory(UUID channelId) {
// public static List<Message> channelChatHistory(UUID channelId) {
// List<Message> result = new ArrayList<>();
// String sql = """
// SELECT * FROM messages
// WHERE receiver_type = 'channel' AND receiver_id = ?
// ORDER BY send_at
// """;
//
// try (Connection conn = ConnectionDb.connect();
// PreparedStatement stmt = conn.prepareStatement(sql)) {
// stmt.setObject(1, channelId);
// ResultSet rs = stmt.executeQuery();
// while (rs.next()) {
// result.add(extractMessage(rs));
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
// return result;
// }
public static List<Message> channelChatHistory(UUID channelId, UUID userId) {
List<Message> result = new ArrayList<>();
String sql = """
SELECT * FROM messages
WHERE receiver_type = 'channel' AND receiver_id = ?
SELECT * FROM messages
WHERE receiver_type = 'channel'
AND receiver_id = ?
AND is_deleted_globally = FALSE
AND message_id NOT IN (
SELECT message_id FROM deleted_messages WHERE user_id = ?
)
ORDER BY send_at
""";
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, channelId);
stmt.setObject(2, userId);
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractMessage(rs));
@@ -379,32 +787,75 @@ public class MessageDatabase {
}
public static List<Message> searchMessagesInGroups(List<UUID> groupIds, String keyword) {
// public static List<Message> searchMessagesInGroups(List<UUID> groupIds, String keyword) {
// List<Message> result = new ArrayList<>();
// if (groupIds.isEmpty()) return result;
//
// String placeholders = groupIds.stream().map(id -> "?").collect(Collectors.joining(", "));
// String sql = """
// SELECT * FROM messages
// WHERE receiver_type = 'group'
// AND receiver_id IN (%s)
// AND content ILIKE ?
// ORDER BY send_at DESC
// """.formatted(placeholders);
//
// try (Connection conn = ConnectionDb.connect();
// PreparedStatement stmt = conn.prepareStatement(sql)) {
//
// int i = 1;
// for (UUID id : groupIds) {
// stmt.setObject(i++, id);
// }
// stmt.setString(i, "%" + keyword + "%");
//
// ResultSet rs = stmt.executeQuery();
// while (rs.next()) {
// result.add(extractMessage(rs));
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// return result;
// }
public static List<Message> searchMessagesInGroups(List<UUID> groupIds, String keyword, UUID userId) {
List<Message> result = new ArrayList<>();
if (groupIds.isEmpty()) return result;
String placeholders = groupIds.stream().map(id -> "?").collect(Collectors.joining(", "));
String sql = """
SELECT * FROM messages
WHERE receiver_type = 'group'
AND receiver_id IN (%s)
AND content ILIKE ?
ORDER BY send_at DESC
SELECT m.*
FROM messages m
LEFT JOIN deleted_messages d ON m.message_id = d.message_id AND d.user_id = ?
WHERE m.receiver_type = 'group'
AND m.receiver_id IN (%s)
AND d.message_id IS NULL
AND m.is_deleted_globally = FALSE
AND m.content ILIKE ?
ORDER BY m.send_at DESC
""".formatted(placeholders);
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
int i = 1;
for (UUID id : groupIds) {
stmt.setObject(i++, id);
stmt.setObject(i++, userId);
for (UUID groupId : groupIds) {
stmt.setObject(i++, groupId);
}
stmt.setString(i, "%" + keyword + "%");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractMessage(rs));
result.add(mapResultSetToMessage(rs));
}
} catch (SQLException e) {
e.printStackTrace();
}
@@ -413,32 +864,71 @@ public class MessageDatabase {
}
// public static List<Message> searchMessagesInChannels(List<UUID> channelIds, String keyword) {
// List<Message> result = new ArrayList<>();
// if (channelIds.isEmpty()) return result;
//
// String placeholders = channelIds.stream().map(id -> "?").collect(Collectors.joining(", "));
// String sql = """
// SELECT * FROM messages
// WHERE receiver_type = 'channel'
// AND receiver_id IN (%s)
// AND content ILIKE ?
// ORDER BY send_at DESC
// """.formatted(placeholders);
//
// try (Connection conn = ConnectionDb.connect();
// PreparedStatement stmt = conn.prepareStatement(sql)) {
//
// int i = 1;
// for (UUID id : channelIds) {
// stmt.setObject(i++, id);
// }
// stmt.setString(i, "%" + keyword + "%");
//
// ResultSet rs = stmt.executeQuery();
// while (rs.next()) {
// result.add(extractMessage(rs));
// }
// } catch (SQLException e) {
// e.printStackTrace();
// }
//
// return result;
// }
public static List<Message> searchMessagesInChannels(List<UUID> channelIds, String keyword) {
List<Message> result = new ArrayList<>();
if (channelIds.isEmpty()) return result;
String placeholders = channelIds.stream().map(id -> "?").collect(Collectors.joining(", "));
String sql = """
SELECT * FROM messages
WHERE receiver_type = 'channel'
AND receiver_id IN (%s)
AND content ILIKE ?
ORDER BY send_at DESC
SELECT m.*
FROM messages m
WHERE m.receiver_type = 'channel'
AND m.receiver_id IN (%s)
AND m.is_deleted_globally = FALSE
AND m.content ILIKE ?
ORDER BY m.send_at DESC
""".formatted(placeholders);
try (Connection conn = ConnectionDb.connect();
PreparedStatement stmt = conn.prepareStatement(sql)) {
int i = 1;
for (UUID id : channelIds) {
stmt.setObject(i++, id);
for (UUID channelId : channelIds) {
stmt.setObject(i++, channelId);
}
stmt.setString(i, "%" + keyword + "%");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
result.add(extractMessage(rs));
result.add(mapResultSetToMessage(rs));
}
} catch (SQLException e) {
e.printStackTrace();
}
@@ -484,6 +974,37 @@ public class MessageDatabase {
return messages;
}
public static List<Message> getMessages(UUID chatId, UUID userId) {
String sql = """
SELECT * FROM messages
WHERE receiver_id = ?
AND is_deleted_globally = false
AND message_id NOT IN (
SELECT message_id FROM deleted_messages
WHERE user_id = ?
)
ORDER BY send_at
""";
List<Message> messages = new ArrayList<>();
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, chatId);
ps.setObject(2, userId);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Message m = extractMessage(rs);
messages.add(m);
}
} catch (SQLException e) {
e.printStackTrace();
}
return messages;
}
public static boolean insertSavedMessage(Message message) {
String sql = "INSERT INTO messages (message_id, sender_id, receiver_type, receiver_id, content, message_type, send_at, status, reply_to_id, is_edited, edited_at," +
" original_message_id, forwarded_by, forwarded_from, is_deleted_globally) " +
@@ -537,5 +1058,4 @@ public class MessageDatabase {
}
}
}