SHA256
Добавить временную бесплатную загрузку аватаров в Arweave
This commit is contained in:
@@ -264,6 +264,21 @@ public final class DatabaseInitializer {
|
||||
ON ip_geo_cache (updated_at_ms);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS test_free_avatar_uploads (
|
||||
login TEXT NOT NULL PRIMARY KEY COLLATE NOCASE,
|
||||
used_count INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at_ms INTEGER NOT NULL,
|
||||
last_tx_id TEXT NOT NULL DEFAULT '',
|
||||
FOREIGN KEY (login) REFERENCES solana_users(login)
|
||||
);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_test_free_avatar_uploads_updated
|
||||
ON test_free_avatar_uploads (updated_at_ms);
|
||||
""");
|
||||
|
||||
// 5. blockchain_state
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS blockchain_state (
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.sql.Statement;
|
||||
public final class SqliteDbController {
|
||||
|
||||
private static volatile SqliteDbController instance;
|
||||
private static final int LATEST_SCHEMA_VERSION = 7;
|
||||
private static final int LATEST_SCHEMA_VERSION = 8;
|
||||
|
||||
private final String jdbcUrl;
|
||||
|
||||
@@ -90,6 +90,7 @@ public final class SqliteDbController {
|
||||
case 5 -> migrateToV5();
|
||||
case 6 -> migrateToV6();
|
||||
case 7 -> migrateToV7();
|
||||
case 8 -> migrateToV8();
|
||||
default -> throw new RuntimeException("Unknown DB migration target version: " + targetVersion);
|
||||
}
|
||||
}
|
||||
@@ -249,6 +250,25 @@ public final class SqliteDbController {
|
||||
}
|
||||
}
|
||||
|
||||
private void migrateToV8() {
|
||||
try (Connection c = DriverManager.getConnection(jdbcUrl);
|
||||
Statement st = c.createStatement()) {
|
||||
c.setAutoCommit(false);
|
||||
try {
|
||||
ensureTestFreeAvatarUploadsTable(st);
|
||||
setSchemaVersion(c, 8);
|
||||
c.commit();
|
||||
} catch (Exception e) {
|
||||
try { c.rollback(); } catch (Exception ignored) {}
|
||||
throw new RuntimeException("DB migration to v8 failed", e);
|
||||
} finally {
|
||||
try { c.setAutoCommit(true); } catch (Exception ignored) {}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("DB migration to v8 failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ensureChat200StateTables(Statement st) throws SQLException {
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS chat200_state (
|
||||
@@ -432,6 +452,22 @@ public final class SqliteDbController {
|
||||
""");
|
||||
}
|
||||
|
||||
private static void ensureTestFreeAvatarUploadsTable(Statement st) throws SQLException {
|
||||
st.executeUpdate("""
|
||||
CREATE TABLE IF NOT EXISTS test_free_avatar_uploads (
|
||||
login TEXT NOT NULL PRIMARY KEY COLLATE NOCASE,
|
||||
used_count INTEGER NOT NULL DEFAULT 0,
|
||||
updated_at_ms INTEGER NOT NULL,
|
||||
last_tx_id TEXT NOT NULL DEFAULT '',
|
||||
FOREIGN KEY (login) REFERENCES solana_users(login)
|
||||
);
|
||||
""");
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_test_free_avatar_uploads_updated
|
||||
ON test_free_avatar_uploads (updated_at_ms);
|
||||
""");
|
||||
}
|
||||
|
||||
|
||||
private static void createConnectionsStateTable(Statement st) throws SQLException {
|
||||
st.executeUpdate("""
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package shine.db.dao;
|
||||
|
||||
import shine.db.SqliteDbController;
|
||||
import shine.db.entities.TestFreeAvatarUploadEntry;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public final class TestFreeAvatarUploadsDAO {
|
||||
|
||||
private static volatile TestFreeAvatarUploadsDAO instance;
|
||||
private final SqliteDbController db = SqliteDbController.getInstance();
|
||||
|
||||
private TestFreeAvatarUploadsDAO() {
|
||||
}
|
||||
|
||||
public static TestFreeAvatarUploadsDAO getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (TestFreeAvatarUploadsDAO.class) {
|
||||
if (instance == null) instance = new TestFreeAvatarUploadsDAO();
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public TestFreeAvatarUploadEntry getByLogin(Connection c, String login) throws SQLException {
|
||||
String sql = """
|
||||
SELECT login, used_count, updated_at_ms, last_tx_id
|
||||
FROM test_free_avatar_uploads
|
||||
WHERE login = ? COLLATE NOCASE
|
||||
LIMIT 1
|
||||
""";
|
||||
try (PreparedStatement ps = c.prepareStatement(sql)) {
|
||||
ps.setString(1, login);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (!rs.next()) return null;
|
||||
return mapRow(rs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TestFreeAvatarUploadEntry getByLogin(String login) throws SQLException {
|
||||
try (Connection c = db.getConnection()) {
|
||||
return getByLogin(c, login);
|
||||
}
|
||||
}
|
||||
|
||||
public void upsertUsage(Connection c, String login, int usedCount, long updatedAtMs, String lastTxId) throws SQLException {
|
||||
String sql = """
|
||||
INSERT INTO test_free_avatar_uploads (login, used_count, updated_at_ms, last_tx_id)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(login) DO UPDATE SET
|
||||
used_count = excluded.used_count,
|
||||
updated_at_ms = excluded.updated_at_ms,
|
||||
last_tx_id = excluded.last_tx_id
|
||||
""";
|
||||
try (PreparedStatement ps = c.prepareStatement(sql)) {
|
||||
ps.setString(1, login);
|
||||
ps.setInt(2, usedCount);
|
||||
ps.setLong(3, updatedAtMs);
|
||||
ps.setString(4, lastTxId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public void upsertUsage(String login, int usedCount, long updatedAtMs, String lastTxId) throws SQLException {
|
||||
try (Connection c = db.getConnection()) {
|
||||
upsertUsage(c, login, usedCount, updatedAtMs, lastTxId);
|
||||
}
|
||||
}
|
||||
|
||||
private static TestFreeAvatarUploadEntry mapRow(ResultSet rs) throws SQLException {
|
||||
return new TestFreeAvatarUploadEntry(
|
||||
rs.getString("login"),
|
||||
rs.getInt("used_count"),
|
||||
rs.getLong("updated_at_ms"),
|
||||
rs.getString("last_tx_id")
|
||||
);
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package shine.db.entities;
|
||||
|
||||
public class TestFreeAvatarUploadEntry {
|
||||
private String login;
|
||||
private int usedCount;
|
||||
private long updatedAtMs;
|
||||
private String lastTxId;
|
||||
|
||||
public TestFreeAvatarUploadEntry() {
|
||||
}
|
||||
|
||||
public TestFreeAvatarUploadEntry(String login, int usedCount, long updatedAtMs, String lastTxId) {
|
||||
this.login = login;
|
||||
this.usedCount = usedCount;
|
||||
this.updatedAtMs = updatedAtMs;
|
||||
this.lastTxId = lastTxId;
|
||||
}
|
||||
|
||||
public String getLogin() {
|
||||
return login;
|
||||
}
|
||||
|
||||
public void setLogin(String login) {
|
||||
this.login = login;
|
||||
}
|
||||
|
||||
public int getUsedCount() {
|
||||
return usedCount;
|
||||
}
|
||||
|
||||
public void setUsedCount(int usedCount) {
|
||||
this.usedCount = usedCount;
|
||||
}
|
||||
|
||||
public long getUpdatedAtMs() {
|
||||
return updatedAtMs;
|
||||
}
|
||||
|
||||
public void setUpdatedAtMs(long updatedAtMs) {
|
||||
this.updatedAtMs = updatedAtMs;
|
||||
}
|
||||
|
||||
public String getLastTxId() {
|
||||
return lastTxId;
|
||||
}
|
||||
|
||||
public void setLastTxId(String lastTxId) {
|
||||
this.lastTxId = lastTxId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user