diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/ConnectionsStateDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/ConnectionsStateDAO.java index bba64f8e..ca0c66d3 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/ConnectionsStateDAO.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/ConnectionsStateDAO.java @@ -1,6 +1,7 @@ package shine.db.dao; import shine.db.DbController; +import shine.db.sql.SolanaUsersSql; import java.sql.Connection; import java.sql.PreparedStatement; @@ -14,10 +15,8 @@ import java.util.List; * * ВАЖНО: * - login в запросах может быть в любом регистре; - * - в ответах возвращаем логины в каноническом регистре через JOIN на solana_users. - * - * ПРИМЕЧАНИЕ: - * Таблица пользователей тут названа "solana_users". Если у тебя иначе — поменяй в SQL. + * - в ответах возвращаем логины в каноническом регистре через прямой lookup + * по актуальным PDA-данным и manual fallback. */ public final class ConnectionsStateDAO { @@ -42,14 +41,17 @@ public final class ConnectionsStateDAO { String sql = """ SELECT COALESCE(u_login.login, u_bch.login, cs.to_login) AS friend_login FROM connections_state cs - LEFT JOIN solana_users u_login + LEFT JOIN %s ON LOWER(u_login.login) = LOWER(cs.to_login) - LEFT JOIN solana_users u_bch + LEFT JOIN %s ON LOWER(u_bch.blockchain_name) = LOWER(cs.to_bch_name) WHERE LOWER(cs.login) = LOWER(?) AND cs.rel_type = ? ORDER BY friend_login - """; + """.formatted( + SolanaUsersSql.usersSubquery("u_login"), + SolanaUsersSql.usersSubquery("u_bch") + ); List out = new ArrayList<>(); try (PreparedStatement ps = c.prepareStatement(sql)) { @@ -72,9 +74,9 @@ public final class ConnectionsStateDAO { String sql = """ SELECT COALESCE(u_actor.login, cs.login) AS friend_login FROM connections_state cs - LEFT JOIN solana_users u_actor + LEFT JOIN %s ON LOWER(u_actor.login) = LOWER(cs.login) - LEFT JOIN solana_users u_target + LEFT JOIN %s ON LOWER(u_target.login) = LOWER(?) WHERE ( LOWER(cs.to_login) = LOWER(?) @@ -82,7 +84,10 @@ public final class ConnectionsStateDAO { ) AND cs.rel_type = ? ORDER BY friend_login - """; + """.formatted( + SolanaUsersSql.usersSubquery("u_actor"), + SolanaUsersSql.usersSubquery("u_target") + ); List out = new ArrayList<>(); try (PreparedStatement ps = c.prepareStatement(sql)) { @@ -106,7 +111,7 @@ public final class ConnectionsStateDAO { String sql = """ SELECT u.login AS friend_login FROM connections_state a - JOIN solana_users u + JOIN %s ON LOWER(u.login) = LOWER(a.to_login) WHERE LOWER(a.login) = LOWER(?) AND a.rel_type = ? @@ -118,7 +123,7 @@ public final class ConnectionsStateDAO { AND b.rel_type = a.rel_type ) ORDER BY u.login - """; + """.formatted(SolanaUsersSql.usersSubquery("u")); List out = new ArrayList<>(); try (PreparedStatement ps = c.prepareStatement(sql)) { diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java index 6ff8ed30..ef0c07f1 100644 --- a/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/dao/SolanaUsersDAO.java @@ -3,6 +3,7 @@ package shine.db.dao; import shine.db.DbController; import shine.db.KeyEncodingUtil; import shine.db.entities.SolanaUserEntry; +import shine.db.sql.SolanaUsersSql; import java.sql.*; import java.util.ArrayList; @@ -80,10 +81,10 @@ public final class SolanaUsersDAO { public boolean existsByLogin(Connection c, String login) throws SQLException { String sql = """ SELECT 1 - FROM solana_users + FROM %s WHERE LOWER(login) = LOWER(?) LIMIT 1 - """; + """.formatted(SolanaUsersSql.usersSubquery("su")); try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, login); @@ -104,10 +105,10 @@ public final class SolanaUsersDAO { public boolean existsByBlockchainName(Connection c, String blockchainName) throws SQLException { String sql = """ SELECT 1 - FROM solana_users + FROM %s WHERE blockchain_name = ? LIMIT 1 - """; + """.formatted(SolanaUsersSql.usersSubquery("su")); try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, blockchainName); @@ -135,9 +136,9 @@ public final class SolanaUsersDAO { solana_key, blockchain_key, client_key - FROM solana_users + FROM %s WHERE LOWER(login) = LOWER(?) - """; + """.formatted(SolanaUsersSql.usersSubquery("su")); try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, login); @@ -164,9 +165,9 @@ public final class SolanaUsersDAO { solana_key, blockchain_key, client_key - FROM solana_users + FROM %s WHERE blockchain_name = ? - """; + """.formatted(SolanaUsersSql.usersSubquery("su")); try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, blockchainName); @@ -193,11 +194,11 @@ public final class SolanaUsersDAO { solana_key, blockchain_key, client_key - FROM solana_users + FROM %s WHERE LOWER(login) LIKE ? ORDER BY login LIMIT 5 - """; + """.formatted(SolanaUsersSql.usersSubquery("su")); List result = new ArrayList<>(); diff --git a/SHiNE-server/shine-server-db/src/main/java/shine/db/sql/SolanaUsersSql.java b/SHiNE-server/shine-server-db/src/main/java/shine/db/sql/SolanaUsersSql.java new file mode 100644 index 00000000..3baadaa9 --- /dev/null +++ b/SHiNE-server/shine-server-db/src/main/java/shine/db/sql/SolanaUsersSql.java @@ -0,0 +1,38 @@ +package shine.db.sql; + +public final class SolanaUsersSql { + + private SolanaUsersSql() {} + + public static String usersSubquery(String alias) { + if (alias == null || alias.isBlank()) { + throw new IllegalArgumentException("alias is blank"); + } + return """ + ( + SELECT + current_users.login AS login, + current_users.blockchain_name AS blockchain_name, + current_users.client_key AS solana_key, + current_users.blockchain_key AS blockchain_key, + current_users.client_key AS client_key + FROM solana_user_pda_current current_users + + UNION ALL + + SELECT + manual.login AS login, + manual.blockchain_name AS blockchain_name, + manual.solana_key AS solana_key, + manual.blockchain_key AS blockchain_key, + manual.client_key AS client_key + FROM solana_users_manual manual + WHERE NOT EXISTS ( + SELECT 1 + FROM solana_user_pda_current current_users + WHERE LOWER(current_users.login) = LOWER(manual.login) + ) + ) %s + """.formatted(alias); + } +} diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/channels/ChannelsReadSupport.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/channels/ChannelsReadSupport.java index c2aa63a6..6daf45c7 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/channels/ChannelsReadSupport.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/channels/ChannelsReadSupport.java @@ -8,6 +8,7 @@ import blockchain.body.TextLineBody; import blockchain.body.TextReplyBody; import shine.db.channels.ChannelNameRules; import shine.db.MsgSubType; +import shine.db.sql.SolanaUsersSql; import java.sql.Connection; import java.sql.PreparedStatement; @@ -30,7 +31,8 @@ final class ChannelsReadSupport { private ChannelsReadSupport() {} static String canonicalLogin(Connection c, String anyCaseLogin) throws SQLException { - String sql = "SELECT login FROM solana_users WHERE LOWER(login) = LOWER(?) LIMIT 1"; + String sql = ("SELECT login FROM " + SolanaUsersSql.usersSubquery("su") + + " WHERE LOWER(login) = LOWER(?) LIMIT 1"); try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, anyCaseLogin); try (ResultSet rs = ps.executeQuery()) { diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java index bf55ee5e..ef0cc877 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_AddCloseFriend_Handler.java @@ -9,6 +9,7 @@ import server.logic.ws_protocol.JSON.handlers.connections.entyties.Net_AddCloseF import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; import server.logic.ws_protocol.WireCodes; import shine.db.MsgSubType; +import shine.db.sql.SolanaUsersSql; import java.sql.Connection; import java.sql.PreparedStatement; @@ -57,7 +58,8 @@ public class Net_AddCloseFriend_Handler implements JsonMessageHandler { } private String findCanonicalLogin(Connection c, String login) throws Exception { - String sql = "SELECT login FROM solana_users WHERE LOWER(login) = LOWER(?) LIMIT 1"; + String sql = "SELECT login FROM " + SolanaUsersSql.usersSubquery("su") + + " WHERE LOWER(login) = LOWER(?) LIMIT 1"; try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, login); try (ResultSet rs = ps.executeQuery()) { diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetFriendsLists_Handler.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetFriendsLists_Handler.java index 96e1599f..42330be7 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetFriendsLists_Handler.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetFriendsLists_Handler.java @@ -13,6 +13,7 @@ import server.logic.ws_protocol.WireCodes; import shine.db.MsgSubType; import shine.db.DbController; import shine.db.dao.ConnectionsStateDAO; +import shine.db.sql.SolanaUsersSql; import java.sql.Connection; import java.sql.PreparedStatement; @@ -26,10 +27,7 @@ import java.util.List; * * ВАЖНО: * - login в запросе может быть любым регистром - * - в ответе возвращаем канонический регистр (как в solana_users.login) - * - * ПРИМЕЧАНИЕ: - * Таблица пользователей тут названа "solana_users". Если у тебя иначе — поменяй SQL. + * - в ответе возвращаем канонический регистр логина. */ public class Net_GetFriendsLists_Handler implements JsonMessageHandler { @@ -99,10 +97,10 @@ public class Net_GetFriendsLists_Handler implements JsonMessageHandler { private String findCanonicalLogin(Connection c, String loginAnyCase) throws Exception { String sql = """ SELECT login - FROM solana_users + FROM %s WHERE LOWER(login) = LOWER(?) LIMIT 1 - """; + """.formatted(SolanaUsersSql.usersSubquery("su")); try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, loginAnyCase); try (ResultSet rs = ps.executeQuery()) { diff --git a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java index 9e9ed1c7..90da70e2 100644 --- a/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java +++ b/SHiNE-server/shine-server-net-protocol/src/main/java/server/logic/ws_protocol/JSON/handlers/connections/Net_GetUserConnectionsGraph_Handler.java @@ -10,6 +10,7 @@ import server.logic.ws_protocol.JSON.utils.NetExceptionResponseFactory; import server.logic.ws_protocol.WireCodes; import shine.db.MsgSubType; import shine.db.dao.ConnectionsStateDAO; +import shine.db.sql.SolanaUsersSql; import java.sql.Connection; import java.sql.PreparedStatement; @@ -113,7 +114,8 @@ public class Net_GetUserConnectionsGraph_Handler implements JsonMessageHandler { } private String findCanonicalLogin(Connection c, String loginAnyCase) throws Exception { - String sql = "SELECT login FROM solana_users WHERE LOWER(login) = LOWER(?) LIMIT 1"; + String sql = "SELECT login FROM " + SolanaUsersSql.usersSubquery("su") + + " WHERE LOWER(login) = LOWER(?) LIMIT 1"; try (PreparedStatement ps = c.prepareStatement(sql)) { ps.setString(1, loginAnyCase); try (ResultSet rs = ps.executeQuery()) { @@ -168,14 +170,14 @@ public class Net_GetUserConnectionsGraph_Handler implements JsonMessageHandler { MAX(CASE WHEN up.param = 'official' THEN up.value END) AS official_value, MAX(CASE WHEN up.param = 'shine' THEN up.value END) AS shine_value, MAX(CASE WHEN up.param = 'ava' THEN up.value END) AS avatar_value - FROM solana_users su + FROM %s LEFT JOIN users_params up ON LOWER(up.login) = LOWER(su.login) AND up.param IN ('gender', 'official', 'shine', 'ava') WHERE LOWER(su.login) IN (%s) GROUP BY su.login ORDER BY su.login - """.formatted(String.join(", ", placeholders)); + """.formatted(SolanaUsersSql.usersSubquery("su"), String.join(", ", placeholders)); try (PreparedStatement ps = c.prepareStatement(sql)) { int i = 1; diff --git a/VERSION.properties b/VERSION.properties index d1394bda..72a433e7 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ client.version=1.2.354 -server.version=1.2.332 +server.version=1.2.333