Class AbstractSqlStorage
- All Implemented Interfaces:
StorageBackend
- Direct Known Subclasses:
MysqlStorage,PostgresStorage,SqliteStorage
StorageBackend shared by all three dialects.
Since the in-memory CachedStorage became the authoritative store, this class holds
no per-row write DML: its job is schema creation/migration, per-player reads on a cache miss,
the batched flush of dirty rows (autosave/quit/shutdown), the handful of whole-database read
questions the cache cannot answer alone (expiry candidates, chest count, name resolution), and the
verbatim /ee import copy. All SQL below is standard and valid for SQLite, MySQL/MariaDB and
PostgreSQL except the flush upserts, whose conflict clause is dialect-specific and selected by the
AbstractSqlStorage.UpsertSyntax the subclass passes in (a native upsert is one B-tree mutation per row and one
batch execution, versus two of each for the portable delete-then-insert it replaced — the flush
runs under the cache's flush lock, so this directly gates quit write-back latency).
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static enumWhich native upsert conflict clause the dialect speaks.Nested classes/interfaces inherited from interface com.enhancedechest.storage.StorageBackend
StorageBackend.ChestKey, StorageBackend.ExpiredKey, StorageBackend.OwnerRows -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final com.zaxxer.hikari.HikariDataSourceprotected final StringPrepended to every table name (seePluginConfig.getTablePrefix()). -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedAbstractSqlStorage(com.zaxxer.hikari.HikariConfig config, String tablePrefix, AbstractSqlStorage.UpsertSyntax upsertSyntax, String... schemaStatements) -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()Closes all connections.longTotal number ofenderchestsrows.findExpired(long now) Keys of every row whoseexpires_atis set and at or beforenow.findUuidByName(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).Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.enhancedechest.storage.StorageBackend
backup, supportsBackup
-
Field Details
-
dataSource
protected final com.zaxxer.hikari.HikariDataSource dataSource -
tablePrefix
Prepended to every table name (seePluginConfig.getTablePrefix()).
-
-
Constructor Details
-
AbstractSqlStorage
protected AbstractSqlStorage(com.zaxxer.hikari.HikariConfig config, String tablePrefix, AbstractSqlStorage.UpsertSyntax upsertSyntax, String... schemaStatements)
-
-
Method Details
-
init
public void init()Description copied from interface:StorageBackendCreates schema, runs schema migrations, and prepares connections. Called once before anything else.- Specified by:
initin interfaceStorageBackend
-
close
public void close()Description copied from interface:StorageBackendCloses all connections. Safe to call even if init() was not completed.- Specified by:
closein interfaceStorageBackend
-
loadAllPlayers
Description copied from interface:StorageBackendReads 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.- Specified by:
loadAllPlayersin interfaceStorageBackend
-
loadOwner
Description copied from interface:StorageBackendReads 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).- Specified by:
loadOwnerin interfaceStorageBackend
-
findExpired
Description copied from interface:StorageBackendKeys 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).- Specified by:
findExpiredin interfaceStorageBackend
-
countChests
public long countChests()Description copied from interface:StorageBackendTotal number ofenderchestsrows. The caller flushes first so pending changes count.- Specified by:
countChestsin interfaceStorageBackend
-
findUuidByName
Description copied from interface:StorageBackendResolves a stored username to its UUID string, case-insensitively, or null when unknown. The caller checks resident (possibly renamed-but-unflushed) owners first.- Specified by:
findUuidByNamein interfaceStorageBackend
-
flushDirty
public void flushDirty(List<EnderChestStorage.RawChestRow> chestUpserts, List<StorageBackend.ChestKey> chestDeletes, List<EnderChestStorage.RawPlayerRow> playerRows) Description copied from interface:StorageBackendWrites 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.- Specified by:
flushDirtyin interfaceStorageBackend
-
importRows
public int[] importRows(List<EnderChestStorage.RawPlayerRow> players, List<EnderChestStorage.RawChestRow> chests) Description copied from interface:StorageBackendBulk-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.- Specified by:
importRowsin interfaceStorageBackend- Returns:
[playersInserted, chestsInserted]
-