05 01 25
добавил таблицу connections_state и тригер который ведёт в ней актуальное состояние всех связей! (и всё рабоатет - тесты проходят)
This commit is contained in:
parent
7ba333bf6c
commit
eb922d918b
@ -96,6 +96,31 @@ toBchName — TEXT NULL — целевой блокчейн.
|
||||
toBlockGlobalNumber — INTEGER NULL — целевой глобальный номер.
|
||||
toBlockHashe — TEXT NULL — хэш целевого блока.
|
||||
|
||||
connections_state ⭐
|
||||
Текущее состояние связей пользователя.
|
||||
login — TEXT NOT NULL — владелец связи.
|
||||
relType — INTEGER NOT NULL — тип связи:
|
||||
10 = FRIEND, 20 = CONTACT, 30 = FOLLOW.
|
||||
to_login — TEXT NOT NULL — с кем связь.
|
||||
toBchName — TEXT NOT NULL — блокчейн цели.
|
||||
toBlockGlobalNumber — INTEGER NULL — последний известный номер блока цели.
|
||||
toBlockHashe — TEXT NULL — последний известный хэш блока цели.
|
||||
Ограничение:
|
||||
UNIQUE(login, relType, to_login) — одно актуальное состояние связи.
|
||||
|
||||
3) Триггер логики связей
|
||||
|
||||
Триггер trg_blocks_connection_state_ai срабатывает AFTER INSERT ON blocks:
|
||||
если msgType = 3 (ConnectionBody)
|
||||
msgSubType IN (10,20,30) →
|
||||
добавить или обновить запись в connections_state
|
||||
msgSubType IN (11,21,31) →
|
||||
удалить соответствующую связь (10/20/30)
|
||||
повторные добавления и удаления не вызывают ошибок
|
||||
Таким образом:
|
||||
blocks — журнал событий
|
||||
connections_state — всегда актуальное состояние
|
||||
|
||||
Индексы (кратко, чтобы было понятно зачем)
|
||||
idx_solana_users_login(login) — быстрый поиск по логину.
|
||||
idx_active_sessions_login(login) — быстро получить сессии пользователя.
|
||||
|
||||
@ -15,16 +15,14 @@ import java.sql.Statement;
|
||||
* DatabaseInitializer — создание новой SQLite-БД по схеме SHiNE.
|
||||
*
|
||||
* Таблицы:
|
||||
* - solana_users (login TEXT PK, deviceKey TEXT, solanaKey TEXT)
|
||||
* - active_sessions (login TEXT FK)
|
||||
* - users_params (login TEXT FK, UNIQUE(login,param))
|
||||
* - solana_users
|
||||
* - active_sessions
|
||||
* - users_params
|
||||
* - ip_geo_cache
|
||||
* - blockchain_state (MVP)
|
||||
* - blocks (login TEXT, bchName TEXT, PK убран)
|
||||
* - blockchain_state
|
||||
* - blocks
|
||||
* - connections_state (текущее состояние связей)
|
||||
*
|
||||
* ОБНОВЛЕНО:
|
||||
* - blocks: добавлено поле msgSubType (сразу после msgType)
|
||||
* - blocks: поля to* остаются nullable
|
||||
*/
|
||||
public class DatabaseInitializer {
|
||||
|
||||
@ -153,7 +151,7 @@ public class DatabaseInitializer {
|
||||
ON ip_geo_cache (updated_at_ms);
|
||||
""");
|
||||
|
||||
// 5. blockchain_state (MVP) — теперь PK blockchainName + поле login
|
||||
// 5. blockchain_state
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS blockchain_state (
|
||||
blockchainName TEXT NOT NULL PRIMARY KEY,
|
||||
@ -198,7 +196,7 @@ public class DatabaseInitializer {
|
||||
ON blockchain_state (updated_at_ms);
|
||||
""");
|
||||
|
||||
// 6. blocks — PK удалён полностью, to* теперь nullable, добавлен msgSubType
|
||||
// 6. blocks
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS blocks (
|
||||
login TEXT NOT NULL,
|
||||
@ -234,6 +232,93 @@ public class DatabaseInitializer {
|
||||
CREATE INDEX IF NOT EXISTS idx_blocks_to_target
|
||||
ON blocks (to_login, toBchName, toBlockGlobalNumber);
|
||||
""");
|
||||
|
||||
// =====================================================================
|
||||
// 7) connections_state — текущее состояние "кто с кем и какая связь"
|
||||
// =====================================================================
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS connections_state (
|
||||
login TEXT NOT NULL,
|
||||
relType INTEGER NOT NULL, -- 10/20/30 (FRIEND/CONTACT/FOLLOW)
|
||||
to_login TEXT NOT NULL,
|
||||
toBchName TEXT NOT NULL,
|
||||
toBlockGlobalNumber INTEGER,
|
||||
toBlockHashe TEXT,
|
||||
|
||||
FOREIGN KEY (login) REFERENCES solana_users(login),
|
||||
|
||||
-- состояние уникально по пользователю, типу связи и цели
|
||||
UNIQUE (login, relType, to_login)
|
||||
);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_connections_state_login
|
||||
ON connections_state (login);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_connections_state_to_login
|
||||
ON connections_state (to_login);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_connections_state_pair
|
||||
ON connections_state (login, to_login);
|
||||
""");
|
||||
|
||||
// =====================================================================
|
||||
// 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
|
||||
AFTER INSERT ON blocks
|
||||
WHEN NEW.msgType = 3
|
||||
BEGIN
|
||||
|
||||
-- ADD / UPDATE: 10/20/30
|
||||
INSERT INTO connections_state (
|
||||
login, relType, to_login, toBchName, toBlockGlobalNumber, toBlockHashe
|
||||
)
|
||||
SELECT
|
||||
NEW.login,
|
||||
NEW.msgSubType,
|
||||
NEW.to_login,
|
||||
NEW.toBchName,
|
||||
NEW.toBlockGlobalNumber,
|
||||
NEW.toBlockHashe
|
||||
WHERE NEW.msgSubType IN (10, 20, 30)
|
||||
AND NEW.to_login IS NOT NULL
|
||||
AND NEW.toBchName IS NOT NULL
|
||||
ON CONFLICT(login, relType, to_login)
|
||||
DO UPDATE SET
|
||||
toBchName = excluded.toBchName,
|
||||
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
|
||||
AND relType = CASE NEW.msgSubType
|
||||
WHEN 11 THEN 10
|
||||
WHEN 21 THEN 20
|
||||
WHEN 31 THEN 30
|
||||
ELSE relType
|
||||
END
|
||||
AND NEW.msgSubType IN (11, 21, 31);
|
||||
|
||||
END;
|
||||
""");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user