Package com.enhancedechest.storage
Interface StorageBackend
- All Known Implementing Classes:
AbstractSqlStorage,MysqlStorage,PostgresStorage,SqliteStorage
public interface StorageBackend
The SQL half of the lazy-load + write-back cache model: the narrow contract
CachedStorage
needs from a database backend. The cache is authoritative for every owner it holds resident,
so the backend is asked to read one player's rows on a cache miss (loadOwner(java.lang.String)),
bulk-write dirty rows back (autosave / quit / shutdown), answer the few
whole-database questions the cache cannot (findExpired(long), countChests(),
findUuidByName(java.lang.String), loadAllPlayers() for the startup name index), snapshot itself for a
backup, and receive the verbatim /ee import copy — there are deliberately no per-row
write operations here; all row-level semantics live in CachedStorage.
All methods execute synchronously on the calling thread; callers keep them off region/main
threads (cache-miss loads run on the DbExecutor, everything else on async timers or the
shutdown flush).
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic final recordPrimary key of oneenderchestsrow, used to flush a deletion.static final recordPrimary key + kind of one expiredenderchestsrow, returned byfindExpired(long).static final recordOne player's full cache-miss load: theirenderchestsrows plus their (nullable)playersrow. -
Method Summary
Modifier and TypeMethodDescriptiondefault voidWrites a consistent snapshot of the entire database totarget(which must not already exist).voidclose()Closes all connections.longTotal number ofenderchestsrows.findExpired(long now) Keys of every row whoseexpires_atis set and at or beforenow.@Nullable StringfindUuidByName(String name) Resolves a stored username to its UUID string, case-insensitively, or null when unknown.voidflushDirty(List<EnderChestStorage.RawChestRow> chestUpserts, List<StorageBackend.ChestKey> chestDeletes, List<EnderChestStorage.RawPlayerRow> playerRows) Writes every dirty row back in one transaction: eachchestUpserts/playerRowsrow replaces whatever the table holds for its key (native dialect upsert), and everychestDeleteskey is removed.int[]importRows(List<EnderChestStorage.RawPlayerRow> players, List<EnderChestStorage.RawChestRow> chests) Bulk-inserts rawplayersandenderchestsrows verbatim into this (fresh) backend, in a single transaction — the DB→DB conversion primitive behind/ee import.voidinit()Creates schema, runs schema migrations, and prepares connections.Reads everyplayersrow verbatim.Reads one player'senderchestsrows andplayersrow verbatim in a single connection acquisition (lazy cache load on first touch — the hottest backend read, so it must not pay for two pool round-trips).default booleanTrue if this backend can produce a file snapshot viabackup(Path).
-
Method Details
-
init
void init()Creates schema, runs schema migrations, and prepares connections. Called once before anything else. -
close
void close()Closes all connections. Safe to call even if init() was not completed. -
supportsBackup
default boolean supportsBackup()True if this backend can produce a file snapshot viabackup(Path). Only the file-based SQLite backend supports it; remote backends (MySQL/MariaDB/Postgres) return false and must be backed up with the database server's own tooling. -
backup
Writes a consistent snapshot of the entire database totarget(which must not already exist). Only valid whensupportsBackup()is true. The caller (CachedStorage) flushes dirty rows first, so the snapshot always contains every in-memory change.- Throws:
Exception- if the snapshot fails; the caller logs it and leaves the live DB untouched.
-
importRows
int[] importRows(List<EnderChestStorage.RawPlayerRow> players, List<EnderChestStorage.RawChestRow> chests) Bulk-inserts rawplayersandenderchestsrows verbatim into this (fresh) backend, in a single transaction — the DB→DB conversion primitive behind/ee import. A duplicate primary key (or any other failure) rolls the whole transaction back and throws.- Returns:
[playersInserted, chestsInserted]
-
loadAllPlayers
List<EnderChestStorage.RawPlayerRow> loadAllPlayers()Reads everyplayersrow verbatim. Used once at startup to build the in-memoryPlayerNameIndex(uuid → username is tiny even for huge rosters); chest data is never bulk-loaded. -
loadOwner
Reads one player'senderchestsrows andplayersrow verbatim in a single connection acquisition (lazy cache load on first touch — the hottest backend read, so it must not pay for two pool round-trips). -
findExpired
Keys of every row whoseexpires_atis set and at or beforenow. Candidates only: the caller re-verifies each hit against the authoritative in-memory row (which may be newer than what was last flushed here). -
countChests
long countChests()Total number ofenderchestsrows. The caller flushes first so pending changes count. -
findUuidByName
Resolves a stored username to its UUID string, case-insensitively, or null when unknown. The caller checks resident (possibly renamed-but-unflushed) owners first. -
flushDirty
void flushDirty(List<EnderChestStorage.RawChestRow> chestUpserts, List<StorageBackend.ChestKey> chestDeletes, List<EnderChestStorage.RawPlayerRow> playerRows) Writes every dirty row back in one transaction: eachchestUpserts/playerRowsrow replaces whatever the table holds for its key (native dialect upsert), and everychestDeleteskey is removed. A single transaction and a single connection acquisition — the flush runs under the cache's flush lock, so its duration directly gates quit write-back latency. A failure rolls the whole flush back and throws, so the caller can re-mark the rows dirty and retry on the next autosave.
-