Merge branch 'develop' into SendMessage

# Conflicts:
#	src/main/java/org/to/telegramfinalproject/Client/ActionHandler.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
This commit is contained in:
2025-08-11 17:06:57 +03:30
22 changed files with 1523 additions and 213 deletions
@@ -5,6 +5,7 @@ import org.to.telegramfinalproject.Models.ContactEntry;
import org.to.telegramfinalproject.Models.User;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -46,7 +47,7 @@ public class ContactDatabase {
public boolean removeContact(UUID user_id, UUID contact_id) {
public static boolean removeContact(UUID user_id, UUID contact_id) {
String sql = "DELETE FROM contacts WHERE user_id = ? AND contact_id = ?";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
@@ -172,35 +173,6 @@ public class ContactDatabase {
return false;
}
public List<Contact> searchContacts(UUID user_id, String searchTerm) {
List<Contact> results = new ArrayList<>(); //ILIKE case-insensitive
String sql = """
SELECT c.contact_id, c.added_at, c.is_blocked
FROM contacts c
JOIN users u ON c.contact_id = u.internal_uuid
WHERE c.user_id = ? AND (u.user_id ILIKE ? OR u.profile_name ILIKE ?)
""";
try (Connection connection = getConnection()) {
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setObject(1, user_id);
stmt.setString(2, "%" + searchTerm + "%");
stmt.setString(3, "%" + searchTerm + "%");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
UUID contactId = (UUID) rs.getObject("contact_id");
boolean isBlocked = rs.getBoolean("is_blocked");
Timestamp addedAt = rs.getTimestamp("added_at");
Contact contact = new Contact(user_id, contactId);
contact.setIs_blocked(isBlocked);
contact.setAdd_at(addedAt.toLocalDateTime());
results.add(contact);
}
} catch (SQLException e) {
e.printStackTrace();
}
return results;
}
public static boolean deleteChatOneSide(UUID currentUserId, UUID otherUserId) {
String sql = """
@@ -306,6 +278,50 @@ public class ContactDatabase {
return entries;
}
public static List<ContactEntry> searchContacts(UUID userId, String searchTerm) {
List<ContactEntry> results = new ArrayList<>();
String sql = """
SELECT u.internal_uuid, u.user_id, c.is_blocked
FROM contacts c
JOIN users u ON c.contact_id = u.internal_uuid
WHERE c.user_id = ?
AND (u.user_id ILIKE ? OR u.profile_name ILIKE ?)
""";
try (Connection connection = getConnection();
PreparedStatement stmt = connection.prepareStatement(sql)) {
stmt.setObject(1, userId);
stmt.setString(2, "%" + searchTerm + "%");
stmt.setString(3, "%" + searchTerm + "%");
ResultSet rs = stmt.executeQuery();
userDatabase userDB = new userDatabase();
while (rs.next()) {
UUID contactId = (UUID) rs.getObject("internal_uuid");
String displayId = rs.getString("user_id");
String contact_displayId = userDB.getUserId(contactId);
String profileName = userDB.getProfileName(contactId);
String imageUrl = userDB.getProfilePicture(contactId);
boolean isBlocked = rs.getBoolean("is_blocked");
String lastSeenString = userDB.getLastSeen(contactId);
// Convert to LocalDateTime
LocalDateTime lastSeen = null;
if (!"Unknown".equals(lastSeenString)) {
lastSeen = LocalDateTime.parse(lastSeenString);
}
results.add(new ContactEntry(contactId, displayId, contact_displayId, profileName, imageUrl, isBlocked, lastSeen));
}
} catch (SQLException e) {
e.printStackTrace();
}
return results;
}
}
@@ -505,25 +505,27 @@ public class MessageDatabase {
stmt.setObject(i++, userId); // 5) group: gm.user_id
stmt.setObject(i++, userId); // 6) channel: cs.user_id
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
messages.add(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
));
}
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
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"),
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.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) {
e.printStackTrace();
@@ -626,7 +628,6 @@ public class MessageDatabase {
rs.getString("status"),
(UUID) rs.getObject("reply_to_id"),
rs.getBoolean("is_edited"),
// rs.getBoolean("is_deleted_globally"),
(UUID) rs.getObject("original_message_id"),
(UUID) rs.getObject("forwarded_by"),
(UUID) rs.getObject("forwarded_from"),
@@ -1096,8 +1097,57 @@ public class MessageDatabase {
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) " +
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
try (Connection conn = ConnectionDb.connect();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setObject(1, message.getMessage_id()); // message_id
ps.setObject(2, message.getSender_id()); // sender_id
ps.setString(3, message.getReceiver_type()); // receiver_type (private)
ps.setObject(4, message.getReceiver_id()); // receiver_id (same as sender_id for saved messages)
ps.setString(5, message.getContent()); // content
ps.setString(6, message.getMessage_type()); // message_type
ps.setTimestamp(7, Timestamp.valueOf(message.getSend_at())); // send_at
ps.setString(8, message.getStatus()); // status
if (message.getReply_to_id() != null)
ps.setObject(9, message.getReply_to_id()); // reply_to_id
else
ps.setNull(9, Types.OTHER);
ps.setBoolean(10, message.isIs_edited()); // is_edited
if (message.getEdited_at() != null)
ps.setTimestamp(11, Timestamp.valueOf(message.getEdited_at())); // edited_at
else
ps.setNull(11, Types.TIMESTAMP);
if (message.getOriginal_message_id() != null)
ps.setObject(12, message.getOriginal_message_id()); // original_message_id
else
ps.setNull(12, Types.OTHER);
if (message.getForwarded_by() != null)
ps.setObject(13, message.getForwarded_by()); // forwarded_by
else
ps.setNull(13, Types.OTHER);
if (message.getForwarded_from() != null)
ps.setObject(14, message.getForwarded_from()); // forwarded_from
else
ps.setNull(14, Types.OTHER);
ps.setBoolean(15, message.getIs_deleted_globally()); // is_deleted_globally
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
}
@@ -7,6 +7,10 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
public class PrivateChatDatabase {
@@ -29,6 +33,34 @@ public class PrivateChatDatabase {
return new ArrayList<>();
}
public static UUID getOrCreateSavedMessagesChat(UUID userId) {
String query = "SELECT chat_id FROM private_chat WHERE user1_id = ? AND user2_id = ?";
try (Connection conn = ConnectionDb.connect()) {
PreparedStatement stmt = conn.prepareStatement(query);
stmt.setObject(1, userId);
stmt.setObject(2, userId); // Saved Messages is self-chat
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
return (UUID) rs.getObject("chat_id"); // Chat already exists
} else {
// Create a new chat
UUID chatId = UUID.randomUUID();
String insert = "INSERT INTO private_chat (chat_id, user1_id, user2_id) VALUES (?, ?, ?)";
try (PreparedStatement insertStmt = conn.prepareStatement(insert)) {
insertStmt.setObject(1, chatId);
insertStmt.setObject(2, userId);
insertStmt.setObject(3, userId);
insertStmt.executeUpdate();
return chatId;
}
}
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
public static UUID findChatIdByUsers(UUID user1, UUID user2) {
UUID u1 = user1.compareTo(user2) < 0 ? user1 : user2;
@@ -152,7 +152,7 @@ public class userDatabase {
}
public boolean save(User user) {
String query = "INSERT INTO users (user_id, internal_uuid, username, password, profile_name) VALUES (?, ?, ?, ?, ?)";
String query = "INSERT INTO users (user_id, internal_uuid, username, password, profile_name, bio, image_url) VALUES (?, ?, ?, ?, ?, ?, ?)";
try {
boolean var5;
@@ -165,6 +165,8 @@ public class userDatabase {
stmt.setString(3, user.getUsername());
stmt.setString(4, user.getPassword());
stmt.setString(5, user.getProfile_name());
stmt.setString(6, user.getBio());
stmt.setString(7, user.getImage_url());
var5 = stmt.executeUpdate() > 0;
}
@@ -223,7 +225,7 @@ public class userDatabase {
}
private User extractUser(ResultSet rs) throws SQLException {
return new User(rs.getString("user_id"), UUID.fromString(rs.getString("internal_uuid")), rs.getString("username"), rs.getString("password"), rs.getString("profile_name"));
return new User(rs.getString("user_id"), UUID.fromString(rs.getString("internal_uuid")), rs.getString("username"), rs.getString("password"), rs.getString("profile_name"), rs.getString("bio"), rs.getString("image_url"));
}
public boolean deleteByUUID(UUID uuid) {
@@ -288,7 +290,9 @@ public class userDatabase {
UUID.fromString(rs.getString("internal_uuid")),
rs.getString("username"),
rs.getString("password"),
rs.getString("profile_name")
rs.getString("profile_name"),
rs.getString("bio"),
rs.getString("image_url")
);
user.setBio(rs.getString("bio"));
@@ -349,6 +353,61 @@ public class userDatabase {
}
}
public static String getProfileName(UUID userId) {
String sql = "SELECT profile_name FROM users WHERE internal_uuid = ?";
try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, userId);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
String profileName = rs.getString("profile_name");
return profileName;
}
} catch (SQLException e) {
e.printStackTrace();
}
return "Unknown";
}
public static String getProfilePicture(UUID userId) {
String sql = "SELECT image_url FROM users WHERE internal_uuid = ?";
try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, userId);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
String imageUrl = rs.getString("image_url");
return imageUrl;
}
} catch (SQLException e) {
e.printStackTrace();
}
return "Unknown";
}
public static String getUserId(UUID userId) {
String sql = "SELECT user_id FROM users WHERE internal_uuid = ?";
try (Connection conn = getConnection();
PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setObject(1, userId);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
String user_id = rs.getString("user_id");
return user_id;
}
} catch (SQLException e) {
e.printStackTrace();
}
return "Unknown";
}
}