Каналы: новый роутинг, поиск, вход-возврат, удаление просмотров и документация

This commit is contained in:
AidarKC
2026-05-08 01:15:54 +03:00
parent 6774c26ea1
commit acdd6c928b
18 changed files with 657 additions and 458 deletions
@@ -360,35 +360,7 @@ public final class DatabaseInitializer {
ON message_stats (to_login);
""");
// 8.0) message_views_state (уникальный просмотр/прочтение сообщения пользователем)
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS message_views_state (
viewer_login TEXT NOT NULL,
to_bch_name TEXT NOT NULL,
to_block_number INTEGER NOT NULL,
to_block_hash BLOB NOT NULL,
first_seen_at_ms INTEGER NOT NULL,
UNIQUE (
viewer_login,
to_bch_name,
to_block_number,
to_block_hash
)
);
""");
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_message_views_state_target
ON message_views_state (to_bch_name, to_block_number, to_block_hash);
""");
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_message_views_state_viewer_channel
ON message_views_state (viewer_login, to_bch_name);
""");
// 8.1) reactions_state (идемпотентный LIKE/UNLIKE per actor/target)
// 8.0) reactions_state (идемпотентный LIKE/UNLIKE per actor/target)
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS reactions_state (
from_login TEXT NOT NULL,
@@ -14,7 +14,7 @@ import java.sql.Statement;
public final class SqliteDbController {
private static volatile SqliteDbController instance;
private static final int LATEST_SCHEMA_VERSION = DatabaseInitializer.SCHEMA_VERSION_1;
private static final int LATEST_SCHEMA_VERSION = 2;
private final String jdbcUrl;
@@ -84,6 +84,7 @@ public final class SqliteDbController {
private void applyMigration(int targetVersion) {
switch (targetVersion) {
case 1 -> migrateToV1();
case 2 -> migrateToV2();
default -> throw new RuntimeException("Unknown DB migration target version: " + targetVersion);
}
}
@@ -123,6 +124,29 @@ public final class SqliteDbController {
}
}
private void migrateToV2() {
try (Connection c = DriverManager.getConnection(jdbcUrl);
Statement st = c.createStatement()) {
c.setAutoCommit(false);
try {
st.execute("PRAGMA foreign_keys = OFF");
st.executeUpdate("DROP TABLE IF EXISTS message_views_state");
st.executeUpdate("DROP INDEX IF EXISTS idx_message_views_state_target");
st.executeUpdate("DROP INDEX IF EXISTS idx_message_views_state_viewer_channel");
setSchemaVersion(c, 2);
st.execute("PRAGMA foreign_keys = ON");
c.commit();
} catch (Exception e) {
try { c.rollback(); } catch (Exception ignored) {}
throw new RuntimeException("DB migration to v2 failed", e);
} finally {
try { c.setAutoCommit(true); } catch (Exception ignored) {}
}
} catch (SQLException e) {
throw new RuntimeException("DB migration to v2 failed", e);
}
}
private int getCurrentSchemaVersion() {
try (Connection c = DriverManager.getConnection(jdbcUrl)) {
if (!tableExists(c, DatabaseInitializer.DB_SCHEMA_VERSION_TABLE)) {
@@ -183,23 +207,6 @@ public final class SqliteDbController {
""");
}
private static void ensureMessageViewsStateTable(Statement st) throws SQLException {
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS message_views_state (
viewer_login TEXT NOT NULL,
to_bch_name TEXT NOT NULL,
to_block_number INTEGER NOT NULL,
to_block_hash BLOB NOT NULL,
first_seen_at_ms INTEGER NOT NULL,
UNIQUE (
viewer_login,
to_bch_name,
to_block_number,
to_block_hash
)
);
""");
}
private static void createConnectionsStateTable(Statement st) throws SQLException {
st.executeUpdate("""
@@ -246,17 +253,6 @@ public final class SqliteDbController {
""");
}
private static void ensureMessageViewsIndexes(Statement st) throws SQLException {
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_message_views_state_target
ON message_views_state (to_bch_name, to_block_number, to_block_hash);
""");
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_message_views_state_viewer_channel
ON message_views_state (viewer_login, to_bch_name);
""");
}
private static void ensureChannelNamesStateTable(Statement st) throws SQLException {
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS channel_names_state (