02 01 25
Сделал что бы в базу писался msgSubType и поля to (to login, toBlockchainName и т.д.)
This commit is contained in:
parent
eef760d776
commit
dd49c4de00
@ -0,0 +1,32 @@
|
|||||||
|
package blockchain.body;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BodyToFields — дополнительный интерфейс для body, которые "ссылаются" на цель (to-поля).
|
||||||
|
*
|
||||||
|
* Идея:
|
||||||
|
* - Не все body имеют "to".
|
||||||
|
* - Но для индексации и удобства запросов в БД мы хотим единообразно доставать:
|
||||||
|
* toLogin, toBchName, toBlockGlobalNumber, toBlockHashe
|
||||||
|
*
|
||||||
|
* Важно:
|
||||||
|
* - Все методы могут возвращать null.
|
||||||
|
* - toLogin может отсутствовать в самом формате body (например, ReactionBody, TextBody reply/repost),
|
||||||
|
* но в БД мы пишем toLogin "про запас".
|
||||||
|
* Поэтому writer может:
|
||||||
|
* - взять toLogin из body (если есть),
|
||||||
|
* - либо попытаться вычислить из toBchName.
|
||||||
|
*/
|
||||||
|
public interface BodyHasTarget {
|
||||||
|
|
||||||
|
/** login цели (nullable). */
|
||||||
|
String toLogin();
|
||||||
|
|
||||||
|
/** blockchainName цели (nullable). */
|
||||||
|
String toBchName();
|
||||||
|
|
||||||
|
/** globalNumber цели (nullable). */
|
||||||
|
Integer toBlockGlobalNumber();
|
||||||
|
|
||||||
|
/** hash цели в HEX(64) (nullable). */
|
||||||
|
String toBlockHashe();
|
||||||
|
}
|
||||||
@ -42,7 +42,7 @@ import java.util.Objects;
|
|||||||
* ЛИНИЯ:
|
* ЛИНИЯ:
|
||||||
* - строго lineIndex=3 (выделяем отдельную линию под связи).
|
* - строго lineIndex=3 (выделяем отдельную линию под связи).
|
||||||
*/
|
*/
|
||||||
public final class ConnectionBody implements BodyRecord {
|
public final class ConnectionBody implements BodyRecord, BodyHasTarget {
|
||||||
|
|
||||||
public static final short TYPE = 3;
|
public static final short TYPE = 3;
|
||||||
public static final short VER = 1;
|
public static final short VER = 1;
|
||||||
@ -279,4 +279,16 @@ public final class ConnectionBody implements BodyRecord {
|
|||||||
}
|
}
|
||||||
return new String(out);
|
return new String(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* ====================== BodyToFields контракт ========================= */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
@Override public String toLogin() { return toLogin; }
|
||||||
|
|
||||||
|
@Override public String toBchName() { return toBlockchainName; }
|
||||||
|
|
||||||
|
@Override public Integer toBlockGlobalNumber() { return toBlockGlobalNumber; }
|
||||||
|
|
||||||
|
@Override public String toBlockHashe() { return toBlockHashHex(); }
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ import java.util.Objects;
|
|||||||
* - Здесь мы НЕ проверяем, существует ли цель реакции.
|
* - Здесь мы НЕ проверяем, существует ли цель реакции.
|
||||||
* - Мы проверяем только корректность формата и целостность полей.
|
* - Мы проверяем только корректность формата и целостность полей.
|
||||||
*/
|
*/
|
||||||
public final class ReactionBody implements BodyRecord {
|
public final class ReactionBody implements BodyRecord, BodyHasTarget {
|
||||||
|
|
||||||
public static final short TYPE = 2;
|
public static final short TYPE = 2;
|
||||||
public static final short VER = 1;
|
public static final short VER = 1;
|
||||||
@ -172,11 +172,11 @@ public final class ReactionBody implements BodyRecord {
|
|||||||
hash цели (hex) : %s
|
hash цели (hex) : %s
|
||||||
}
|
}
|
||||||
""".formatted(
|
""".formatted(
|
||||||
st,
|
st,
|
||||||
toBlockchainName,
|
toBlockchainName,
|
||||||
toBlockGlobalNumber,
|
toBlockGlobalNumber,
|
||||||
toBlockHashHex()
|
toBlockHashHex()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toBlockHashHex() {
|
public String toBlockHashHex() {
|
||||||
@ -189,4 +189,17 @@ public final class ReactionBody implements BodyRecord {
|
|||||||
}
|
}
|
||||||
return new String(out);
|
return new String(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* ====================== BodyToFields контракт ========================= */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
/** В самом формате ReactionBody login цели не хранится => null. */
|
||||||
|
@Override public String toLogin() { return null; }
|
||||||
|
|
||||||
|
@Override public String toBchName() { return toBlockchainName; }
|
||||||
|
|
||||||
|
@Override public Integer toBlockGlobalNumber() { return toBlockGlobalNumber; }
|
||||||
|
|
||||||
|
@Override public String toBlockHashe() { return toBlockHashHex(); }
|
||||||
}
|
}
|
||||||
@ -41,7 +41,7 @@ import java.util.Objects;
|
|||||||
* - для subType=NEW запрещены поля ссылки и запрещены любые “лишние байты” в хвосте
|
* - для subType=NEW запрещены поля ссылки и запрещены любые “лишние байты” в хвосте
|
||||||
* - для subType=REPLY/REPOST хвост обязан быть ровно по формату и без мусора в конце
|
* - для subType=REPLY/REPOST хвост обязан быть ровно по формату и без мусора в конце
|
||||||
*/
|
*/
|
||||||
public final class TextBody implements BodyRecord {
|
public final class TextBody implements BodyRecord, BodyHasTarget {
|
||||||
|
|
||||||
public static final short TYPE = 1;
|
public static final short TYPE = 1;
|
||||||
public static final short VER = 1;
|
public static final short VER = 1;
|
||||||
@ -219,8 +219,6 @@ public final class TextBody implements BodyRecord {
|
|||||||
|
|
||||||
@Override public short type() { return TYPE; }
|
@Override public short type() { return TYPE; }
|
||||||
@Override public short version() { return VER; }
|
@Override public short version() { return VER; }
|
||||||
|
|
||||||
/** ✅ ВАЖНО: теперь BodyRecord требует subType() */
|
|
||||||
@Override public short subType() { return subType; }
|
@Override public short subType() { return subType; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -363,4 +361,26 @@ public final class TextBody implements BodyRecord {
|
|||||||
}
|
}
|
||||||
return new String(out);
|
return new String(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===================================================================== */
|
||||||
|
/* ====================== BodyToFields контракт ========================= */
|
||||||
|
/* ===================================================================== */
|
||||||
|
|
||||||
|
/** В формате TextBody login цели не хранится => null. */
|
||||||
|
@Override public String toLogin() { return null; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toBchName() {
|
||||||
|
return (subType == SUB_REPLY || subType == SUB_REPOST) ? toBlockchainName : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer toBlockGlobalNumber() {
|
||||||
|
return (subType == SUB_REPLY || subType == SUB_REPOST) ? toBlockGlobalNumber : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toBlockHashe() {
|
||||||
|
return (subType == SUB_REPLY || subType == SUB_REPOST) ? toBlockHashHex() : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -21,6 +21,10 @@ import java.sql.Statement;
|
|||||||
* - ip_geo_cache
|
* - ip_geo_cache
|
||||||
* - blockchain_state (MVP)
|
* - blockchain_state (MVP)
|
||||||
* - blocks (login TEXT, bchName TEXT, PK убран)
|
* - blocks (login TEXT, bchName TEXT, PK убран)
|
||||||
|
*
|
||||||
|
* ОБНОВЛЕНО:
|
||||||
|
* - blocks: добавлено поле msgSubType (сразу после msgType)
|
||||||
|
* - blocks: поля to* остаются nullable
|
||||||
*/
|
*/
|
||||||
public class DatabaseInitializer {
|
public class DatabaseInitializer {
|
||||||
|
|
||||||
@ -195,7 +199,7 @@ public class DatabaseInitializer {
|
|||||||
ON blockchain_state (updated_at_ms);
|
ON blockchain_state (updated_at_ms);
|
||||||
""");
|
""");
|
||||||
|
|
||||||
// 6. blocks — PK удалён полностью, to* теперь nullable
|
// 6. blocks — PK удалён полностью, to* теперь nullable, добавлен msgSubType
|
||||||
st.executeUpdate("""
|
st.executeUpdate("""
|
||||||
CREATE TABLE IF NOT EXISTS blocks (
|
CREATE TABLE IF NOT EXISTS blocks (
|
||||||
login TEXT NOT NULL,
|
login TEXT NOT NULL,
|
||||||
@ -208,6 +212,7 @@ public class DatabaseInitializer {
|
|||||||
blockLinePreHashe TEXT NOT NULL,
|
blockLinePreHashe TEXT NOT NULL,
|
||||||
|
|
||||||
msgType INTEGER NOT NULL,
|
msgType INTEGER NOT NULL,
|
||||||
|
msgSubType INTEGER NOT NULL,
|
||||||
|
|
||||||
blockByte BLOB,
|
blockByte BLOB,
|
||||||
|
|
||||||
|
|||||||
@ -45,12 +45,13 @@ public final class BlocksDAO {
|
|||||||
blockLineNumber,
|
blockLineNumber,
|
||||||
blockLinePreHashe,
|
blockLinePreHashe,
|
||||||
msgType,
|
msgType,
|
||||||
|
msgSubType,
|
||||||
blockByte,
|
blockByte,
|
||||||
to_login,
|
to_login,
|
||||||
toBchName,
|
toBchName,
|
||||||
toBlockGlobalNumber,
|
toBlockGlobalNumber,
|
||||||
toBlockHashe
|
toBlockHashe
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""";
|
""";
|
||||||
|
|
||||||
try (PreparedStatement ps = c.prepareStatement(sql)) {
|
try (PreparedStatement ps = c.prepareStatement(sql)) {
|
||||||
@ -104,6 +105,7 @@ public final class BlocksDAO {
|
|||||||
blockLineNumber,
|
blockLineNumber,
|
||||||
blockLinePreHashe,
|
blockLinePreHashe,
|
||||||
msgType,
|
msgType,
|
||||||
|
msgSubType,
|
||||||
blockByte,
|
blockByte,
|
||||||
to_login,
|
to_login,
|
||||||
toBchName,
|
toBchName,
|
||||||
@ -157,6 +159,7 @@ public final class BlocksDAO {
|
|||||||
blockGlobalPreHashe = ?,
|
blockGlobalPreHashe = ?,
|
||||||
blockLinePreHashe = ?,
|
blockLinePreHashe = ?,
|
||||||
msgType = ?,
|
msgType = ?,
|
||||||
|
msgSubType = ?,
|
||||||
blockByte = ?,
|
blockByte = ?,
|
||||||
to_login = ?,
|
to_login = ?,
|
||||||
toBchName = ?,
|
toBchName = ?,
|
||||||
@ -176,6 +179,7 @@ public final class BlocksDAO {
|
|||||||
ps.setString(i++, nn(e.getBlockGlobalPreHashe()));
|
ps.setString(i++, nn(e.getBlockGlobalPreHashe()));
|
||||||
ps.setString(i++, nn(e.getBlockLinePreHashe()));
|
ps.setString(i++, nn(e.getBlockLinePreHashe()));
|
||||||
ps.setInt(i++, e.getMsgType());
|
ps.setInt(i++, e.getMsgType());
|
||||||
|
ps.setInt(i++, e.getMsgSubType());
|
||||||
|
|
||||||
byte[] bytes = e.getBlockByte();
|
byte[] bytes = e.getBlockByte();
|
||||||
if (bytes != null) ps.setBytes(i++, bytes);
|
if (bytes != null) ps.setBytes(i++, bytes);
|
||||||
@ -270,6 +274,7 @@ public final class BlocksDAO {
|
|||||||
ps.setString(i++, nn(e.getBlockLinePreHashe()));
|
ps.setString(i++, nn(e.getBlockLinePreHashe()));
|
||||||
|
|
||||||
ps.setInt(i++, e.getMsgType());
|
ps.setInt(i++, e.getMsgType());
|
||||||
|
ps.setInt(i++, e.getMsgSubType());
|
||||||
|
|
||||||
byte[] bytes = e.getBlockByte();
|
byte[] bytes = e.getBlockByte();
|
||||||
if (bytes != null) ps.setBytes(i++, bytes);
|
if (bytes != null) ps.setBytes(i++, bytes);
|
||||||
@ -301,6 +306,7 @@ public final class BlocksDAO {
|
|||||||
e.setBlockLinePreHashe(rs.getString("blockLinePreHashe"));
|
e.setBlockLinePreHashe(rs.getString("blockLinePreHashe"));
|
||||||
|
|
||||||
e.setMsgType(rs.getInt("msgType"));
|
e.setMsgType(rs.getInt("msgType"));
|
||||||
|
e.setMsgSubType(rs.getInt("msgSubType"));
|
||||||
|
|
||||||
e.setBlockByte(rs.getBytes("blockByte"));
|
e.setBlockByte(rs.getBytes("blockByte"));
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,9 @@ package shine.db.entities;
|
|||||||
* - toBlockGlobalNumber INTEGER nullable
|
* - toBlockGlobalNumber INTEGER nullable
|
||||||
* - toBlockHashe TEXT nullable
|
* - toBlockHashe TEXT nullable
|
||||||
*
|
*
|
||||||
|
* ДОБАВЛЕНО:
|
||||||
|
* - msgSubType INTEGER (uint16 по смыслу, храним как int)
|
||||||
|
*
|
||||||
* PRIMARY KEY пока убран вообще.
|
* PRIMARY KEY пока убран вообще.
|
||||||
*/
|
*/
|
||||||
public class BlockEntry {
|
public class BlockEntry {
|
||||||
@ -26,6 +29,7 @@ public class BlockEntry {
|
|||||||
private String blockLinePreHashe; // TEXT
|
private String blockLinePreHashe; // TEXT
|
||||||
|
|
||||||
private int msgType; // int16 (храним как int)
|
private int msgType; // int16 (храним как int)
|
||||||
|
private int msgSubType; // int16 (храним как int)
|
||||||
|
|
||||||
private byte[] blockByte; // BLOB
|
private byte[] blockByte; // BLOB
|
||||||
|
|
||||||
@ -44,6 +48,7 @@ public class BlockEntry {
|
|||||||
int blockLineNumber,
|
int blockLineNumber,
|
||||||
String blockLinePreHashe,
|
String blockLinePreHashe,
|
||||||
int msgType,
|
int msgType,
|
||||||
|
int msgSubType,
|
||||||
byte[] blockByte,
|
byte[] blockByte,
|
||||||
String toLogin,
|
String toLogin,
|
||||||
String toBchName,
|
String toBchName,
|
||||||
@ -57,6 +62,7 @@ public class BlockEntry {
|
|||||||
this.blockLineNumber = blockLineNumber;
|
this.blockLineNumber = blockLineNumber;
|
||||||
this.blockLinePreHashe = blockLinePreHashe;
|
this.blockLinePreHashe = blockLinePreHashe;
|
||||||
this.msgType = msgType;
|
this.msgType = msgType;
|
||||||
|
this.msgSubType = msgSubType;
|
||||||
this.blockByte = blockByte;
|
this.blockByte = blockByte;
|
||||||
this.toLogin = toLogin;
|
this.toLogin = toLogin;
|
||||||
this.toBchName = toBchName;
|
this.toBchName = toBchName;
|
||||||
@ -88,6 +94,9 @@ public class BlockEntry {
|
|||||||
public int getMsgType() { return msgType; }
|
public int getMsgType() { return msgType; }
|
||||||
public void setMsgType(int msgType) { this.msgType = msgType; }
|
public void setMsgType(int msgType) { this.msgType = msgType; }
|
||||||
|
|
||||||
|
public int getMsgSubType() { return msgSubType; }
|
||||||
|
public void setMsgSubType(int msgSubType) { this.msgSubType = msgSubType; }
|
||||||
|
|
||||||
public byte[] getBlockByte() { return blockByte; }
|
public byte[] getBlockByte() { return blockByte; }
|
||||||
public void setBlockByte(byte[] blockByte) { this.blockByte = blockByte; }
|
public void setBlockByte(byte[] blockByte) { this.blockByte = blockByte; }
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_utils;
|
package server.logic.ws_protocol.JSON.handlers.blockchain.Net_AddBlock_Handler_utils;
|
||||||
|
|
||||||
import blockchain.BchBlockEntry;
|
import blockchain.BchBlockEntry;
|
||||||
import blockchain.body.ReactionBody;
|
import blockchain.body.BodyHasTarget;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import shine.db.SqliteDbController;
|
import shine.db.SqliteDbController;
|
||||||
@ -281,7 +281,12 @@ public final class BlockchainWriter {
|
|||||||
* Важно:
|
* Важно:
|
||||||
* - blockLinePreHashe = prevLineHashHex (а НЕ prevGlobalHashHex)
|
* - blockLinePreHashe = prevLineHashHex (а НЕ prevGlobalHashHex)
|
||||||
* - msgType = body.type()
|
* - msgType = body.type()
|
||||||
* - Для ReactionBody заполняем toBchName/toBlockGlobalNumber/toBlockHashe (+ to_login если можем).
|
* - msgSubType = body.subType()
|
||||||
|
* - to* поля берём через BodyToFields (если body его поддерживает)
|
||||||
|
*
|
||||||
|
* Про toLogin:
|
||||||
|
* - если body сам даёт toLogin — пишем его
|
||||||
|
* - иначе, если есть toBchName — пробуем вычислить login из имени блокчейна (про запас)
|
||||||
*/
|
*/
|
||||||
private void insertBlockRow(
|
private void insertBlockRow(
|
||||||
Connection c,
|
Connection c,
|
||||||
@ -311,6 +316,7 @@ public final class BlockchainWriter {
|
|||||||
e.setBlockLinePreHashe(linePre);
|
e.setBlockLinePreHashe(linePre);
|
||||||
|
|
||||||
e.setMsgType(block.body.type());
|
e.setMsgType(block.body.type());
|
||||||
|
e.setMsgSubType(block.body.subType());
|
||||||
|
|
||||||
e.setBlockByte(block.toBytes());
|
e.setBlockByte(block.toBytes());
|
||||||
|
|
||||||
@ -320,16 +326,20 @@ public final class BlockchainWriter {
|
|||||||
e.setToBlockGlobalNumber(null);
|
e.setToBlockGlobalNumber(null);
|
||||||
e.setToBlockHashe(null);
|
e.setToBlockHashe(null);
|
||||||
|
|
||||||
// ReactionBody -> target fields
|
// ✅ Универсально: если body поддерживает to-поля — пишем их
|
||||||
if (block.body instanceof ReactionBody rb) {
|
if (block.body instanceof BodyHasTarget tf) {
|
||||||
e.setToBchName(rb.toBlockchainName);
|
|
||||||
e.setToBlockGlobalNumber(rb.toBlockGlobalNumber);
|
e.setToLogin(tf.toLogin());
|
||||||
e.setToBlockHashe(rb.toBlockHashHex());
|
e.setToBchName(tf.toBchName());
|
||||||
|
e.setToBlockGlobalNumber(tf.toBlockGlobalNumber());
|
||||||
|
e.setToBlockHashe(tf.toBlockHashe());
|
||||||
|
|
||||||
// optional: try compute to_login from target chain name (для индекса idx_blocks_to_target)
|
// optional: try compute to_login from target chain name (для индекса idx_blocks_to_target)
|
||||||
String toLogin = BlockchainNameUtil.loginFromBlockchainName(rb.toBlockchainName);
|
if (e.getToLogin() == null && e.getToBchName() != null) {
|
||||||
if (toLogin != null && !toLogin.isBlank()) {
|
String toLogin = BlockchainNameUtil.loginFromBlockchainName(e.getToBchName());
|
||||||
e.setToLogin(toLogin);
|
if (toLogin != null && !toLogin.isBlank()) {
|
||||||
|
e.setToLogin(toLogin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user