SHiNE-server/shine-server-db/src/main/java/shine/db/DatabaseInitializer.java
2025-12-04 12:20:47 +03:00

127 lines
4.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package shine.db;
import utils.config.AppConfig;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class DatabaseInitializer {
public static void createNewDB(String[] args) {
AppConfig config = AppConfig.getInstance();
String dbPath = config.getParam("db.path");
if (dbPath == null || dbPath.isBlank()) {
System.err.println("Параметр db.path не задан в application.properties");
return;
}
Path dbFile = Paths.get(dbPath);
try {
// создаём директорию, если нужно
Path parent = dbFile.getParent();
if (parent != null && !Files.exists(parent)) {
Files.createDirectories(parent);
}
if (Files.exists(dbFile)) {
System.out.println("Файл базы данных уже существует: " + dbFile.toAbsolutePath());
System.out.print("Пересоздать БД (СТАРАЯ БУДЕТ УДАЛЕНА)? [y/N]: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String answer = reader.readLine();
if (!"y".equalsIgnoreCase(answer) && !"yes".equalsIgnoreCase(answer)) {
System.out.println("Операция отменена. БД не изменена.");
return;
}
Files.delete(dbFile);
System.out.println("Старый файл БД удалён.");
}
createSchema("jdbc:sqlite:" + dbPath);
System.out.println("Новая БД успешно создана по пути: " + dbFile.toAbsolutePath());
} catch (IOException e) {
System.err.println("Ошибка работы с файлом БД: " + e.getMessage());
} catch (SQLException e) {
System.err.println("Ошибка создания схемы БД: " + e.getMessage());
}
}
private static void createSchema(String jdbcUrl) throws SQLException {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException e) {
throw new RuntimeException("SQLite JDBC driver not found", e);
}
try (Connection conn = DriverManager.getConnection(jdbcUrl);
Statement st = conn.createStatement()) {
// включаем внешние ключи на этом соединении (для инициализации тоже)
st.execute("PRAGMA foreign_keys = ON");
// 1. Таблица solana_users
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS solana_users (
login TEXT NOT NULL,
loginId INTEGER NOT NULL PRIMARY KEY,
bchId INTEGER NOT NULL,
pubkey0 TEXT,
pubkey1 TEXT,
bchLimit INTEGER -- может быть NULL
);
""");
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_solana_users_login
ON solana_users (login);
""");
// 2. Таблица active_sessions
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS active_sessions (
sessionId INTEGER NOT NULL PRIMARY KEY,
session_pwd TEXT NOT NULL,
loginId INTEGER NOT NULL,
time_ms INTEGER NOT NULL,
pubkey_num INTEGER NOT NULL,
push_endpoint TEXT,
push_p256dh_key TEXT,
push_auth_key TEXT,
FOREIGN KEY (loginId) REFERENCES solana_users(loginId)
);
""");
// 3. Таблица users_params
// Важно: пара (loginId, param) должна быть уникальна
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS users_params (
loginId INTEGER NOT NULL,
param TEXT NOT NULL,
bch_channel_id INTEGER NOT NULL DEFAULT 0,
value TEXT,
time_ms INTEGER NOT NULL,
pubkey_num INTEGER NOT NULL,
signature TEXT,
FOREIGN KEY (loginId) REFERENCES solana_users(loginId),
UNIQUE (loginId, param)
);
""");
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_users_params_loginId
ON users_params (loginId);
""");
}
}
}