Database
DaisyFilter persists through SculkData/HikariCP. SQLite is the default; MariaDB, MySQL and PostgreSQL are supported. DaisyFilter does not add Exposed.
Configuration
Section titled “Configuration”storage.yml selects the backend and carries the connection details:
backend: sqlite # sqlite | mysql | mariadb | postgresfile: data.db # sqlite only, relative to the plugin folderpool-size: 10remote: # everything below is ignored on sqlite host: localhost port: 3306 database: minecraft username: root password: ${DB_PASSWORD:-} use-ssl: falseThe password supports ${ENV_VAR} and ${ENV_VAR:-default} substitution, so the
real secret need not be written into the file. Note that a file containing a
placeholder is never rewritten, so it does not gain new keys automatically.
DaisyFilter’s own privacy, retention and queue settings live separately in
moderation-storage.yml. Switching the backend requires a restart.
Tables
Section titled “Tables”df_schema_metadf_records— one row per logged violation (metadata; optional encrypted raw).df_staff_actions— privacy-safe audit trail for external punishment commands.df_rule_hitsdf_player_stats— coalesced per-player aggregates.df_warningsdf_staff_notesdf_staff_preferences
df_records is indexed by created-at, player uuid, player name, and surface for
dashboard queries and keyset pagination; df_staff_actions by record, staff and
created-at. Columns are named exactly as the entity properties are (playerUuid,
createdAt), and indexes are declared on the entity rather than created by hand.
Write path
Section titled “Write path”Writes never block the event thread:
- a bounded append queue batches record writes off-thread;
- player statistics use Sculk’s write-behind store, coalescing repeated updates into one row per flush;
- queue depth, failures, retries, and dropped operations are counted and surfaced
in
/daisyfilter status; - on shutdown the queues flush within a deadline.
If the database is unavailable, filtering continues in a degraded mode — matches are still censored/blocked and players still warned — while persistence retries. Errors are rate-limited and never include raw content.
Retention and purge
Section titled “Retention and purge”Records expire after a configurable retention period (default 30 days). A daily
job purges expired rows in bounded batches. You can also purge manually with
/daisyfilter purge <days> confirm.
See privacy.md for raw-content encryption and key handling.