refactor: перевели хэши на BLOB и добавили поля block_hash / block_signature / edited_by_block_global_number и главное добавили тип блока изменение сообщение и сслку на последнее изменение в табл блокс
100 lines
3.4 KiB
Java
100 lines
3.4 KiB
Java
package shine.db.dao;
|
|
|
|
import shine.db.SqliteDbController;
|
|
import shine.db.entities.BlockchainStateEntry;
|
|
import shine.db.entities.SolanaUserEntry;
|
|
|
|
import java.sql.*;
|
|
|
|
/**
|
|
* UserCreateDAO — атомарное добавление пользователя:
|
|
* - solana_users (login, device_key)
|
|
* - blockchain_state (blockchain_name, login, blockchain_key, size_limit, ... last_global_number=-1 ...)
|
|
*
|
|
* ВАЖНО:
|
|
* - только INSERT/UPSERT
|
|
* - если login или blockchainName заняты — возвращаем false (пользователь уже есть/занято)
|
|
*/
|
|
public final class UserCreateDAO {
|
|
|
|
private static volatile UserCreateDAO instance;
|
|
private final SqliteDbController db = SqliteDbController.getInstance();
|
|
private final SolanaUsersDAO usersDao = SolanaUsersDAO.getInstance();
|
|
private final BlockchainStateDAO stateDao = BlockchainStateDAO.getInstance();
|
|
|
|
private UserCreateDAO() {}
|
|
|
|
public static UserCreateDAO getInstance() {
|
|
if (instance == null) {
|
|
synchronized (UserCreateDAO.class) {
|
|
if (instance == null) instance = new UserCreateDAO();
|
|
}
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* @return true если добавили; false если занято (login уже есть или blockchainName уже существует).
|
|
*/
|
|
public boolean insertUserWithBlockchain(
|
|
String login,
|
|
String deviceKey,
|
|
String blockchainName,
|
|
String blockchainKey,
|
|
long sizeLimit,
|
|
long nowMs
|
|
) throws SQLException {
|
|
|
|
try (Connection c = db.getConnection()) {
|
|
boolean oldAuto = c.getAutoCommit();
|
|
c.setAutoCommit(false);
|
|
|
|
// BEGIN IMMEDIATE — чтобы сразу взять write-lock и не ловить гонки
|
|
try (Statement st = c.createStatement()) {
|
|
st.execute("BEGIN IMMEDIATE");
|
|
}
|
|
|
|
try {
|
|
// 1) user
|
|
SolanaUserEntry u = new SolanaUserEntry(login, deviceKey, deviceKey);
|
|
usersDao.insert(c, u); // если login занят -> constraint
|
|
|
|
// 2) blockchain_state
|
|
BlockchainStateEntry st = new BlockchainStateEntry();
|
|
st.setBlockchainName(blockchainName);
|
|
st.setLogin(login);
|
|
st.setBlockchainKey(blockchainKey);
|
|
st.setSizeLimit(sizeLimit);
|
|
st.setFileSizeBytes(0L);
|
|
|
|
// старт: глобальных блоков ещё нет
|
|
st.setLastGlobalNumber(-1);
|
|
st.setLastGlobalHash(null);
|
|
|
|
for (int line = 0; line < 8; line++) {
|
|
st.setLastLineNumber(line, 0);
|
|
st.setLastLineHash(line, null);
|
|
}
|
|
|
|
st.setUpdatedAtMs(nowMs);
|
|
|
|
stateDao.upsert(c, st); // если blockchainName занят -> constraint (PK)
|
|
|
|
c.commit();
|
|
return true;
|
|
|
|
} catch (SQLException e) {
|
|
c.rollback();
|
|
|
|
String msg = e.getMessage() == null ? "" : e.getMessage().toLowerCase();
|
|
if (msg.contains("constraint")) {
|
|
return false;
|
|
}
|
|
throw e;
|
|
|
|
} finally {
|
|
c.setAutoCommit(oldAuto);
|
|
}
|
|
}
|
|
}
|
|
} |