refactor: перевели хэши на BLOB и добавили поля block_hash / block_signature / edited_by_block_global_number

и главное добавили тип блока изменение сообщение и сслку на последнее изменение в табл блокс
This commit is contained in:
AidarKC
2026-01-07 19:58:50 +03:00
parent 8bcaa192c5
commit 06c77b1c1f
13 changed files with 306 additions and 284 deletions
@@ -1,3 +1,6 @@
// =======================
// BlockchainStateDAO.java (НОВАЯ ВЕРСИЯ)
// =======================
package shine.db.dao;
import shine.db.SqliteDbController;
@@ -71,11 +74,8 @@ public final class BlockchainStateDAO {
/** UPSERT с внешним соединением. Соединение НЕ закрывает. */
public void upsert(Connection c, BlockchainStateEntry e) throws SQLException {
// ВАЖНО:
// Колонок должно быть ровно 24:
// 8 основных + (8 линий * 2 поля) = 8 + 16 = 24
//
// size_bytes УДАЛЁН ИЗ ПРОЕКТА, здесь его быть не должно.
// Колонок ровно 24:
// 8 основных + (8 линий * 2 поля) = 24
String sql = """
INSERT INTO blockchain_state (
@@ -144,12 +144,12 @@ public final class BlockchainStateDAO {
ps.setLong(i++, e.getFileSizeBytes());
ps.setInt(i++, e.getLastGlobalNumber());
ps.setString(i++, nn(e.getLastGlobalHash()));
setBytesNullable(ps, i++, e.getLastGlobalHash());
ps.setLong(i++, e.getUpdatedAtMs());
for (int line = 0; line < 8; line++) {
ps.setInt(i++, e.getLastLineNumber(line));
ps.setString(i++, nn(e.getLastLineHash(line)));
setBytesNullable(ps, i++, e.getLastLineHash(line));
}
ps.executeUpdate();
@@ -204,17 +204,22 @@ public final class BlockchainStateDAO {
e.setFileSizeBytes(rs.getLong("file_size_bytes"));
e.setLastGlobalNumber(rs.getInt("last_global_number"));
e.setLastGlobalHash(rs.getString("last_global_hash"));
e.setLastGlobalHash(rs.getBytes("last_global_hash")); // может быть null
e.setUpdatedAtMs(rs.getLong("updated_at_ms"));
for (int line = 0; line < 8; line++) {
e.setLastLineNumber(line, rs.getInt("line" + line + "_last_number"));
e.setLastLineHash(line, rs.getString("line" + line + "_last_hash"));
e.setLastLineHash(line, rs.getBytes("line" + line + "_last_hash")); // может быть null
}
return e;
}
private static void setBytesNullable(PreparedStatement ps, int index, byte[] b) throws SQLException {
if (b != null) ps.setBytes(index, b);
else ps.setNull(index, Types.BLOB);
}
private static String nn(String s) { return s == null ? "" : s; }
}
@@ -50,8 +50,11 @@ public final class BlocksDAO {
to_login,
to_bch_name,
to_block_global_number,
to_block_hashe
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
to_block_hashe,
block_hash,
block_signature,
edited_by_block_global_number
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""";
try (PreparedStatement ps = c.prepareStatement(sql)) {
@@ -104,7 +107,10 @@ public final class BlocksDAO {
to_login,
to_bch_name,
to_block_global_number,
to_block_hashe
to_block_hashe,
block_hash,
block_signature,
edited_by_block_global_number
FROM blocks
WHERE
login = ?
@@ -145,15 +151,18 @@ public final class BlocksDAO {
String sql = """
UPDATE blocks
SET
block_global_pre_hashe = ?,
block_line_pre_hashe = ?,
msg_type = ?,
msg_sub_type = ?,
block_byte = ?,
to_login = ?,
to_bch_name = ?,
to_block_global_number = ?,
to_block_hashe = ?
block_global_pre_hashe = ?,
block_line_pre_hashe = ?,
msg_type = ?,
msg_sub_type = ?,
block_byte = ?,
to_login = ?,
to_bch_name = ?,
to_block_global_number = ?,
to_block_hashe = ?,
block_hash = ?,
block_signature = ?,
edited_by_block_global_number = ?
WHERE
login = ?
AND bch_name = ?
@@ -165,8 +174,8 @@ public final class BlocksDAO {
try (PreparedStatement ps = c.prepareStatement(sql)) {
int i = 1;
ps.setString(i++, nn(e.getBlockGlobalPreHashe()));
ps.setString(i++, nn(e.getBlockLinePreHashe()));
ps.setBytes(i++, bb(e.getBlockGlobalPreHashe()));
ps.setBytes(i++, bb(e.getBlockLinePreHashe()));
ps.setInt(i++, e.getMsgType());
ps.setInt(i++, e.getMsgSubType());
@@ -183,8 +192,14 @@ public final class BlocksDAO {
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);
if (e.getToBlockHashe() != null) ps.setBytes(i++, e.getToBlockHashe());
else ps.setNull(i++, Types.BLOB);
ps.setBytes(i++, bb(e.getBlockHash()));
ps.setBytes(i++, bb(e.getBlockSignature()));
if (e.getEditedByBlockGlobalNumber() != null) ps.setInt(i++, e.getEditedByBlockGlobalNumber());
else ps.setNull(i++, Types.INTEGER);
ps.setString(i++, e.getLogin());
ps.setString(i++, e.getBchName());
@@ -249,11 +264,11 @@ public final class BlocksDAO {
ps.setString(i++, e.getLogin());
ps.setString(i++, e.getBchName());
ps.setInt(i++, e.getBlockGlobalNumber());
ps.setString(i++, nn(e.getBlockGlobalPreHashe()));
ps.setBytes(i++, bb(e.getBlockGlobalPreHashe()));
ps.setInt(i++, e.getBlockLineIndex());
ps.setInt(i++, e.getBlockLineNumber());
ps.setString(i++, nn(e.getBlockLinePreHashe()));
ps.setBytes(i++, bb(e.getBlockLinePreHashe()));
ps.setInt(i++, e.getMsgType());
ps.setInt(i++, e.getMsgSubType());
@@ -271,8 +286,14 @@ public final class BlocksDAO {
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);
if (e.getToBlockHashe() != null) ps.setBytes(i++, e.getToBlockHashe());
else ps.setNull(i++, Types.BLOB);
ps.setBytes(i++, bb(e.getBlockHash()));
ps.setBytes(i++, bb(e.getBlockSignature()));
if (e.getEditedByBlockGlobalNumber() != null) ps.setInt(i++, e.getEditedByBlockGlobalNumber());
else ps.setNull(i++, Types.INTEGER);
}
private BlockEntry mapRow(ResultSet rs) throws SQLException {
@@ -281,11 +302,11 @@ public final class BlocksDAO {
e.setLogin(rs.getString("login"));
e.setBchName(rs.getString("bch_name"));
e.setBlockGlobalNumber(rs.getInt("block_global_number"));
e.setBlockGlobalPreHashe(rs.getString("block_global_pre_hashe"));
e.setBlockGlobalPreHashe(rs.getBytes("block_global_pre_hashe"));
e.setBlockLineIndex(rs.getInt("block_line_index"));
e.setBlockLineNumber(rs.getInt("block_line_number"));
e.setBlockLinePreHashe(rs.getString("block_line_pre_hashe"));
e.setBlockLinePreHashe(rs.getBytes("block_line_pre_hashe"));
e.setMsgType(rs.getInt("msg_type"));
e.setMsgSubType(rs.getInt("msg_sub_type"));
@@ -301,12 +322,18 @@ public final class BlocksDAO {
Integer toBlockGlobalNumber = (Integer) rs.getObject("to_block_global_number");
e.setToBlockGlobalNumber(toBlockGlobalNumber);
String toBlockHashe = rs.getString("to_block_hashe");
byte[] toBlockHashe = rs.getBytes("to_block_hashe");
if (rs.wasNull()) toBlockHashe = null;
e.setToBlockHashe(toBlockHashe);
e.setBlockHash(rs.getBytes("block_hash"));
e.setBlockSignature(rs.getBytes("block_signature"));
Integer editedBy = (Integer) rs.getObject("edited_by_block_global_number");
e.setEditedByBlockGlobalNumber(editedBy);
return e;
}
private static String nn(String s) { return s == null ? "" : s; }
private static byte[] bb(byte[] b) { return b == null ? new byte[0] : b; }
}
@@ -12,7 +12,7 @@ import java.sql.*;
* - blockchain_state (blockchain_name, login, blockchain_key, size_limit, ... last_global_number=-1 ...)
*
* ВАЖНО:
* - только INSERT
* - только INSERT/UPSERT
* - если login или blockchainName заняты — возвращаем false (пользователь уже есть/занято)
*/
public final class UserCreateDAO {
@@ -69,11 +69,11 @@ public final class UserCreateDAO {
// старт: глобальных блоков ещё нет
st.setLastGlobalNumber(-1);
st.setLastGlobalHash("");
st.setLastGlobalHash(null);
for (int line = 0; line < 8; line++) {
st.setLastLineNumber(line, 0);
st.setLastLineHash(line, "");
st.setLastLineHash(line, null);
}
st.setUpdatedAtMs(nowMs);