Ещё поправил мелкие детали в библиотеке работы с БД
This commit is contained in:
AidarKC 2025-12-22 12:47:17 +03:00
parent 627321d4ae
commit 7f92dc5f51
5 changed files with 105 additions and 85 deletions

View File

@ -152,45 +152,45 @@ public class DatabaseInitializer {
ON ip_geo_cache (updated_at_ms);
""");
// 5. blockchain_state (MVP) оставляю как было (там уже user_login TEXT)
// 5. blockchain_state (MVP) теперь PK blockchainName + поле login
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS blockchain_state (
blockchain_id INTEGER NOT NULL PRIMARY KEY,
user_login TEXT NOT NULL,
public_key_base64 TEXT NOT NULL,
blockchainName TEXT NOT NULL PRIMARY KEY,
login TEXT NOT NULL,
public_key_base64 TEXT NOT NULL,
size_limit INTEGER NOT NULL,
size_bytes INTEGER NOT NULL,
size_limit INTEGER NOT NULL,
size_bytes INTEGER NOT NULL,
file_size_bytes INTEGER NOT NULL,
file_size_bytes INTEGER NOT NULL,
last_global_number INTEGER NOT NULL,
last_global_hash TEXT NOT NULL,
updated_at_ms INTEGER NOT NULL,
last_global_number INTEGER NOT NULL,
last_global_hash TEXT NOT NULL,
updated_at_ms INTEGER NOT NULL,
-- Линии 0..7 (MVP: максимум 8 линий)
line0_last_number INTEGER NOT NULL,
line0_last_hash TEXT NOT NULL,
line1_last_number INTEGER NOT NULL,
line1_last_hash TEXT NOT NULL,
line2_last_number INTEGER NOT NULL,
line2_last_hash TEXT NOT NULL,
line3_last_number INTEGER NOT NULL,
line3_last_hash TEXT NOT NULL,
line4_last_number INTEGER NOT NULL,
line4_last_hash TEXT NOT NULL,
line5_last_number INTEGER NOT NULL,
line5_last_hash TEXT NOT NULL,
line6_last_number INTEGER NOT NULL,
line6_last_hash TEXT NOT NULL,
line7_last_number INTEGER NOT NULL,
line7_last_hash TEXT NOT NULL
line0_last_number INTEGER NOT NULL,
line0_last_hash TEXT NOT NULL,
line1_last_number INTEGER NOT NULL,
line1_last_hash TEXT NOT NULL,
line2_last_number INTEGER NOT NULL,
line2_last_hash TEXT NOT NULL,
line3_last_number INTEGER NOT NULL,
line3_last_hash TEXT NOT NULL,
line4_last_number INTEGER NOT NULL,
line4_last_hash TEXT NOT NULL,
line5_last_number INTEGER NOT NULL,
line5_last_hash TEXT NOT NULL,
line6_last_number INTEGER NOT NULL,
line6_last_hash TEXT NOT NULL,
line7_last_number INTEGER NOT NULL,
line7_last_hash TEXT NOT NULL
);
""");
st.executeUpdate("""
CREATE INDEX IF NOT EXISTS idx_blockchain_state_user_login
ON blockchain_state (user_login);
CREATE INDEX IF NOT EXISTS idx_blockchain_state_login
ON blockchain_state (login);
""");
st.executeUpdate("""
@ -198,26 +198,26 @@ public class DatabaseInitializer {
ON blockchain_state (updated_at_ms);
""");
// 6. blocks PK удалён полностью
// 6. blocks PK удалён полностью, to* теперь nullable
st.executeUpdate("""
CREATE TABLE IF NOT EXISTS blocks (
login TEXT NOT NULL,
bchName TEXT NOT NULL,
blockGlobalNumber INTEGER NOT NULL,
blockGlobalPreHashe TEXT NOT NULL,
bchName TEXT NOT NULL,
blockGlobalNumber INTEGER NOT NULL,
blockGlobalPreHashe TEXT NOT NULL,
blockLineIndex INTEGER NOT NULL,
blockLineNumber INTEGER NOT NULL,
blockLinePreHashe TEXT NOT NULL,
blockLineIndex INTEGER NOT NULL,
blockLineNumber INTEGER NOT NULL,
blockLinePreHashe TEXT NOT NULL,
msgType INTEGER NOT NULL,
msgType INTEGER NOT NULL,
blockByte BLOB,
blockByte BLOB,
to_login TEXT,
toBchName TEXT NOT NULL,
toBlockGlobalNumber INTEGER NOT NULL,
toBlockHashe TEXT NOT NULL,
to_login TEXT,
toBchName TEXT,
toBlockGlobalNumber INTEGER,
toBlockHashe TEXT,
FOREIGN KEY (login) REFERENCES solana_users(login)
);

View File

@ -21,19 +21,19 @@ public final class BlockchainStateDAO {
return instance;
}
/** Получить по blockchainId без внешнего соединения. Сам открывает/закрывает. */
public BlockchainStateEntry getByBlockchainId(long blockchainId) throws SQLException {
/** Получить по blockchainName без внешнего соединения. Сам открывает/закрывает. */
public BlockchainStateEntry getByBlockchainName(String blockchainName) throws SQLException {
try (Connection c = db.getConnection()) {
return getByBlockchainId(c, blockchainId);
return getByBlockchainName(c, blockchainName);
}
}
/** Получить по blockchainId с внешним соединением. Соединение НЕ закрывает. */
public BlockchainStateEntry getByBlockchainId(Connection c, long blockchainId) throws SQLException {
/** Получить по blockchainName с внешним соединением. Соединение НЕ закрывает. */
public BlockchainStateEntry getByBlockchainName(Connection c, String blockchainName) throws SQLException {
String sql = """
SELECT
blockchain_id,
user_login,
blockchainName,
login,
public_key_base64,
size_limit,
size_bytes,
@ -50,11 +50,11 @@ public final class BlockchainStateDAO {
line7_last_number, line7_last_hash,
updated_at_ms
FROM blockchain_state
WHERE blockchain_id = ?
WHERE blockchainName = ?
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
ps.setLong(1, blockchainId);
ps.setString(1, blockchainName);
try (ResultSet rs = ps.executeQuery()) {
if (!rs.next()) return null;
return mapRow(rs);
@ -73,8 +73,8 @@ public final class BlockchainStateDAO {
public void upsert(Connection c, BlockchainStateEntry e) throws SQLException {
String sql = """
INSERT INTO blockchain_state (
blockchain_id,
user_login,
blockchainName,
login,
public_key_base64,
size_limit,
size_bytes,
@ -102,9 +102,9 @@ public final class BlockchainStateDAO {
?,?,
?
)
ON CONFLICT(blockchain_id)
ON CONFLICT(blockchainName)
DO UPDATE SET
user_login = excluded.user_login,
login = excluded.login,
public_key_base64 = excluded.public_key_base64,
size_limit = excluded.size_limit,
size_bytes = excluded.size_bytes,
@ -132,8 +132,8 @@ public final class BlockchainStateDAO {
try (PreparedStatement ps = c.prepareStatement(sql)) {
int i = 1;
ps.setLong(i++, e.getBlockchainId());
ps.setString(i++, nn(e.getUserLogin()));
ps.setString(i++, e.getBlockchainName());
ps.setString(i++, nn(e.getLogin()));
ps.setString(i++, nn(e.getPublicKeyBase64()));
ps.setInt(i++, e.getSizeLimit());
ps.setInt(i++, e.getSizeBytes());
@ -153,8 +153,8 @@ public final class BlockchainStateDAO {
private BlockchainStateEntry mapRow(ResultSet rs) throws SQLException {
BlockchainStateEntry e = new BlockchainStateEntry();
e.setBlockchainId(rs.getLong("blockchain_id"));
e.setUserLogin(rs.getString("user_login"));
e.setBlockchainName(rs.getString("blockchainName"));
e.setLogin(rs.getString("login"));
e.setPublicKeyBase64(rs.getString("public_key_base64"));
e.setSizeLimit(rs.getInt("size_limit"));

View File

@ -184,9 +184,14 @@ public final class BlocksDAO {
if (e.getToLogin() != null) ps.setString(i++, e.getToLogin());
else ps.setNull(i++, Types.VARCHAR);
ps.setString(i++, nn(e.getToBchName()));
ps.setInt(i++, e.getToBlockGlobalNumber());
ps.setString(i++, nn(e.getToBlockHashe()));
if (e.getToBchName() != null) ps.setString(i++, e.getToBchName());
else ps.setNull(i++, Types.VARCHAR);
if (e.getToBlockGlobalNumber() != null) ps.setInt(i++, e.getToBlockGlobalNumber());
else ps.setNull(i++, Types.INTEGER);
if (e.getToBlockHashe() != null) ps.setString(i++, e.getToBlockHashe());
else ps.setNull(i++, Types.VARCHAR);
ps.setString(i++, e.getLogin());
ps.setString(i++, e.getBchName());
@ -273,9 +278,14 @@ public final class BlocksDAO {
if (e.getToLogin() != null) ps.setString(i++, e.getToLogin());
else ps.setNull(i++, Types.VARCHAR);
ps.setString(i++, nn(e.getToBchName()));
ps.setInt(i++, e.getToBlockGlobalNumber());
ps.setString(i++, nn(e.getToBlockHashe()));
if (e.getToBchName() != null) ps.setString(i++, e.getToBchName());
else ps.setNull(i++, Types.VARCHAR);
if (e.getToBlockGlobalNumber() != null) ps.setInt(i++, e.getToBlockGlobalNumber());
else ps.setNull(i++, Types.INTEGER);
if (e.getToBlockHashe() != null) ps.setString(i++, e.getToBlockHashe());
else ps.setNull(i++, Types.VARCHAR);
}
private BlockEntry mapRow(ResultSet rs) throws SQLException {
@ -295,9 +305,17 @@ public final class BlocksDAO {
e.setBlockByte(rs.getBytes("blockByte"));
e.setToLogin(rs.getString("to_login"));
e.setToBchName(rs.getString("toBchName"));
e.setToBlockGlobalNumber(rs.getInt("toBlockGlobalNumber"));
e.setToBlockHashe(rs.getString("toBlockHashe"));
String toBchName = rs.getString("toBchName");
if (rs.wasNull()) toBchName = null;
e.setToBchName(toBchName);
Integer toBlockGlobalNumber = (Integer) rs.getObject("toBlockGlobalNumber");
e.setToBlockGlobalNumber(toBlockGlobalNumber);
String toBlockHashe = rs.getString("toBlockHashe");
if (rs.wasNull()) toBlockHashe = null;
e.setToBlockHashe(toBlockHashe);
return e;
}

View File

@ -7,7 +7,9 @@ package shine.db.entities;
* - login TEXT NOT NULL
* - bchName TEXT NOT NULL (идёт сразу после login)
* - to_login TEXT nullable
* - toBchName TEXT NOT NULL (идёт сразу после to_login)
* - toBchName TEXT nullable
* - toBlockGlobalNumber INTEGER nullable
* - toBlockHashe TEXT nullable
*
* PRIMARY KEY пока убран вообще.
*/
@ -28,9 +30,9 @@ public class BlockEntry {
private byte[] blockByte; // BLOB
private String toLogin; // TEXT nullable
private String toBchName; // TEXT
private int toBlockGlobalNumber; // int32
private String toBlockHashe; // TEXT
private String toBchName; // TEXT nullable
private Integer toBlockGlobalNumber; // INTEGER nullable
private String toBlockHashe; // TEXT nullable
public BlockEntry() {}
@ -45,7 +47,7 @@ public class BlockEntry {
byte[] blockByte,
String toLogin,
String toBchName,
int toBlockGlobalNumber,
Integer toBlockGlobalNumber,
String toBlockHashe) {
this.login = login;
this.bchName = bchName;
@ -95,8 +97,8 @@ public class BlockEntry {
public String getToBchName() { return toBchName; }
public void setToBchName(String toBchName) { this.toBchName = toBchName; }
public int getToBlockGlobalNumber() { return toBlockGlobalNumber; }
public void setToBlockGlobalNumber(int toBlockGlobalNumber) { this.toBlockGlobalNumber = toBlockGlobalNumber; }
public Integer getToBlockGlobalNumber() { return toBlockGlobalNumber; }
public void setToBlockGlobalNumber(Integer toBlockGlobalNumber) { this.toBlockGlobalNumber = toBlockGlobalNumber; }
public String getToBlockHashe() { return toBlockHashe; }
public void setToBlockHashe(String toBlockHashe) { this.toBlockHashe = toBlockHashe; }

View File

@ -4,13 +4,13 @@ import java.util.Arrays;
/**
* Агрегатная сущность текущего состояния блокчейна.
* 1 строка = 1 blockchainId, плюс состояние линий 0..7.
* 1 строка = 1 blockchainName, плюс состояние линий 0..7.
*/
public final class BlockchainStateEntry {
private long blockchainId;
private String blockchainName;
private String userLogin;
private String login;
private String publicKeyBase64;
private int sizeLimit;
@ -35,8 +35,8 @@ public final class BlockchainStateEntry {
this.lastGlobalHash = "";
}
public BlockchainStateEntry(long blockchainId,
String userLogin,
public BlockchainStateEntry(String blockchainName,
String login,
String publicKeyBase64,
int sizeLimit,
int sizeBytes,
@ -46,8 +46,8 @@ public final class BlockchainStateEntry {
int[] lastLineNumbers,
String[] lastLineHashes,
long updatedAtMs) {
this.blockchainId = blockchainId;
this.userLogin = userLogin;
this.blockchainName = blockchainName;
this.login = login;
this.publicKeyBase64 = publicKeyBase64;
this.sizeLimit = sizeLimit;
this.sizeBytes = sizeBytes;
@ -69,11 +69,11 @@ public final class BlockchainStateEntry {
this.updatedAtMs = updatedAtMs;
}
public long getBlockchainId() { return blockchainId; }
public void setBlockchainId(long blockchainId) { this.blockchainId = blockchainId; }
public String getBlockchainName() { return blockchainName; }
public void setBlockchainName(String blockchainName) { this.blockchainName = blockchainName; }
public String getUserLogin() { return userLogin; }
public void setUserLogin(String userLogin) { this.userLogin = userLogin; }
public String getLogin() { return login; }
public void setLogin(String login) { this.login = login; }
public String getPublicKeyBase64() { return publicKeyBase64; }
public void setPublicKeyBase64(String publicKeyBase64) { this.publicKeyBase64 = publicKeyBase64; }