05 01 25
добавил таблицу message_state и тригеры который считает в ней актуальное количество всех лайков и ответов на сообщения! (и всё рабоатет - тесты проходят)
This commit is contained in:
parent
eb922d918b
commit
93c007b2b9
@ -22,7 +22,7 @@ import java.sql.Statement;
|
||||
* - blockchain_state
|
||||
* - blocks
|
||||
* - connections_state (текущее состояние связей)
|
||||
*
|
||||
* - message_stats (счётчики лайков/ответов на сообщения)
|
||||
*/
|
||||
public class DatabaseInitializer {
|
||||
|
||||
@ -247,7 +247,6 @@ public class DatabaseInitializer {
|
||||
|
||||
FOREIGN KEY (login) REFERENCES solana_users(login),
|
||||
|
||||
-- состояние уникально по пользователю, типу связи и цели
|
||||
UNIQUE (login, relType, to_login)
|
||||
);
|
||||
""");
|
||||
@ -269,15 +268,6 @@ public class DatabaseInitializer {
|
||||
|
||||
// =====================================================================
|
||||
// 8) Trigger: при вставке connection-блоков в blocks — обновлять connections_state
|
||||
//
|
||||
// Правило:
|
||||
// - msgType=3 (ConnectionBody)
|
||||
// - subType 10/20/30 => добавить/обновить запись состояния
|
||||
// - subType 11/21/31 => удалить запись состояния (без ошибок, даже если её нет)
|
||||
//
|
||||
// Примечание:
|
||||
// - "повторное добавление" не должно падать => используем UPSERT (DO UPDATE)
|
||||
// - "удаление того, чего нет" не падает => обычный DELETE
|
||||
// =====================================================================
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_connection_state_ai
|
||||
@ -285,7 +275,6 @@ public class DatabaseInitializer {
|
||||
WHEN NEW.msgType = 3
|
||||
BEGIN
|
||||
|
||||
-- ADD / UPDATE: 10/20/30
|
||||
INSERT INTO connections_state (
|
||||
login, relType, to_login, toBchName, toBlockGlobalNumber, toBlockHashe
|
||||
)
|
||||
@ -305,7 +294,6 @@ public class DatabaseInitializer {
|
||||
toBlockGlobalNumber = excluded.toBlockGlobalNumber,
|
||||
toBlockHashe = excluded.toBlockHashe;
|
||||
|
||||
-- DELETE: 11/21/31 => удалить соответствующую "положительную" связь (10/20/30)
|
||||
DELETE FROM connections_state
|
||||
WHERE login = NEW.login
|
||||
AND to_login = NEW.to_login
|
||||
@ -319,6 +307,111 @@ public class DatabaseInitializer {
|
||||
|
||||
END;
|
||||
""");
|
||||
|
||||
// =====================================================================
|
||||
// 9) message_stats — счётчики лайков/ответов на конкретный блок-цель
|
||||
//
|
||||
// Правило системы:
|
||||
// - to_login берём из toBchName: отрезаем последние 3 символа
|
||||
// =====================================================================
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS message_stats (
|
||||
to_login TEXT NOT NULL,
|
||||
to_bch_name TEXT NOT NULL,
|
||||
to_block_global_number INTEGER NOT NULL,
|
||||
to_block_hash TEXT NOT NULL,
|
||||
|
||||
likes_count INTEGER NOT NULL DEFAULT 0,
|
||||
replies_count INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
UNIQUE (
|
||||
to_login,
|
||||
to_bch_name,
|
||||
to_block_global_number,
|
||||
to_block_hash
|
||||
)
|
||||
);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_message_stats_target
|
||||
ON message_stats (to_bch_name, to_block_global_number, to_block_hash);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_message_stats_login
|
||||
ON message_stats (to_login);
|
||||
""");
|
||||
|
||||
// =====================================================================
|
||||
// 10) Trigger: LIKE (Reaction)
|
||||
// - msgType=2 (REACTION)
|
||||
// - msgSubType=1 (LIKE)
|
||||
// =====================================================================
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_message_stats_like_ai
|
||||
AFTER INSERT ON blocks
|
||||
WHEN NEW.msgType = 2 AND NEW.msgSubType = 1
|
||||
BEGIN
|
||||
INSERT INTO message_stats (
|
||||
to_login,
|
||||
to_bch_name,
|
||||
to_block_global_number,
|
||||
to_block_hash,
|
||||
likes_count,
|
||||
replies_count
|
||||
)
|
||||
SELECT
|
||||
substr(NEW.toBchName, 1, length(NEW.toBchName) - 3),
|
||||
NEW.toBchName,
|
||||
NEW.toBlockGlobalNumber,
|
||||
NEW.toBlockHashe,
|
||||
1,
|
||||
0
|
||||
WHERE NEW.toBchName IS NOT NULL
|
||||
AND length(NEW.toBchName) > 3
|
||||
AND NEW.toBlockGlobalNumber IS NOT NULL
|
||||
AND NEW.toBlockHashe IS NOT NULL
|
||||
ON CONFLICT(to_login, to_bch_name, to_block_global_number, to_block_hash)
|
||||
DO UPDATE SET
|
||||
likes_count = message_stats.likes_count + 1;
|
||||
END;
|
||||
""");
|
||||
|
||||
// =====================================================================
|
||||
// 11) Trigger: REPLY (Text)
|
||||
// - msgType=1 (TEXT)
|
||||
// - msgSubType=2 (REPLY)
|
||||
// =====================================================================
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_message_stats_reply_ai
|
||||
AFTER INSERT ON blocks
|
||||
WHEN NEW.msgType = 1 AND NEW.msgSubType = 2
|
||||
BEGIN
|
||||
INSERT INTO message_stats (
|
||||
to_login,
|
||||
to_bch_name,
|
||||
to_block_global_number,
|
||||
to_block_hash,
|
||||
likes_count,
|
||||
replies_count
|
||||
)
|
||||
SELECT
|
||||
substr(NEW.toBchName, 1, length(NEW.toBchName) - 3),
|
||||
NEW.toBchName,
|
||||
NEW.toBlockGlobalNumber,
|
||||
NEW.toBlockHashe,
|
||||
0,
|
||||
1
|
||||
WHERE NEW.toBchName IS NOT NULL
|
||||
AND length(NEW.toBchName) > 3
|
||||
AND NEW.toBlockGlobalNumber IS NOT NULL
|
||||
AND NEW.toBlockHashe IS NOT NULL
|
||||
ON CONFLICT(to_login, to_bch_name, to_block_global_number, to_block_hash)
|
||||
DO UPDATE SET
|
||||
replies_count = message_stats.replies_count + 1;
|
||||
END;
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,6 @@ import test.it.addBlockUtils.ChainState;
|
||||
import test.it.utils.*;
|
||||
import utils.crypto.Ed25519Util;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Base64;
|
||||
|
||||
@ -98,7 +97,7 @@ public class IT_03_AddBlock_NoAuth {
|
||||
);
|
||||
|
||||
// =========================================================
|
||||
// 3) USER1 блоки (как было раньше в IT_03)
|
||||
// 3) USER1 блоки (под message_stats)
|
||||
// =========================================================
|
||||
if (TestConfig.DEBUG()) {
|
||||
TestLog.titleBlock("""
|
||||
@ -122,21 +121,25 @@ public class IT_03_AddBlock_NoAuth {
|
||||
sender1.send(new HeaderBody(TestConfig.LOGIN()), t);
|
||||
assertTrue(st1.hasHeader());
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#1 (NEW)");
|
||||
// 3 NEW
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#1 (NEW) <- будет LIKE + REPLY");
|
||||
sender1.send(new TextBody(TextBody.SUB_NEW, "Hello #1 (NEW) from IT_03 test"), t);
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#2 (NEW)");
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#2 (NEW) <- будет ONLY LIKE");
|
||||
sender1.send(new TextBody(TextBody.SUB_NEW, "Hello #2 (NEW) from IT_03 test"), t);
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#3 (NEW)");
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#3 (NEW) <- будет ONLY REPLY");
|
||||
sender1.send(new TextBody(TextBody.SUB_NEW, "Hello #3 (NEW) from IT_03 test"), t);
|
||||
|
||||
byte[] text1Hash = st1.getGlobalHash32(1);
|
||||
byte[] text2Hash = st1.getGlobalHash32(2);
|
||||
byte[] text3Hash = st1.getGlobalHash32(3);
|
||||
assertNotNull(text1Hash);
|
||||
assertNotNull(text2Hash);
|
||||
assertNotNull(text3Hash);
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#4 (REPLY -> TEXT#1)");
|
||||
// 2 REPLY
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#4 (REPLY -> TEXT#1) (делает TEXT#1: replies+1)");
|
||||
sender1.send(new TextBody(
|
||||
TextBody.SUB_REPLY,
|
||||
"Reply to TEXT#1",
|
||||
@ -145,19 +148,17 @@ public class IT_03_AddBlock_NoAuth {
|
||||
text1Hash
|
||||
), t);
|
||||
|
||||
byte[] reply1Hash = st1.getGlobalHash32(4);
|
||||
assertNotNull(reply1Hash);
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#5 (REPLY -> TEXT#4)");
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#5 (REPLY -> TEXT#3) (делает TEXT#3: replies+1)");
|
||||
sender1.send(new TextBody(
|
||||
TextBody.SUB_REPLY,
|
||||
"Reply to REPLY (TEXT#4)",
|
||||
"Reply to TEXT#3",
|
||||
TestConfig.BCH_NAME(),
|
||||
4,
|
||||
reply1Hash
|
||||
3,
|
||||
text3Hash
|
||||
), t);
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: REACT#1 (LIKE -> TEXT#1)");
|
||||
// 2 LIKE
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: REACT#1 (LIKE -> TEXT#1) (делает TEXT#1: likes+1)");
|
||||
sender1.send(new ReactionBody(
|
||||
ReactionBody.SUB_LIKE,
|
||||
TestConfig.BCH_NAME(),
|
||||
@ -165,12 +166,12 @@ public class IT_03_AddBlock_NoAuth {
|
||||
text1Hash
|
||||
), t);
|
||||
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: REACT#2 (LIKE -> TEXT#4)");
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: REACT#2 (LIKE -> TEXT#2) (делает TEXT#2: likes+1)");
|
||||
sender1.send(new ReactionBody(
|
||||
ReactionBody.SUB_LIKE,
|
||||
TestConfig.BCH_NAME(),
|
||||
4,
|
||||
reply1Hash
|
||||
2,
|
||||
text2Hash
|
||||
), t);
|
||||
|
||||
assertEquals(7, st1.globalLastNumber(), "USER1: должно быть 8 блоков: globalLastNumber=7");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user