Database
MySQL 8 provisioning, connection pooling, and schema ownership rules.
The idea
Player progress lives in one operator-owned MySQL 8 database. The plugin connects and checks that tables exist; it never creates them.
basics
Apply sql/mysql.sql with the ops script, put the JDBC URL in database.yml,
restart. Missing tables fail startup with a pointer at that script.
Everyday
Shared JDBC URL plus username shares one Hikari pool. Keep passwords out of git. Back up MySQL the way you back up any other service.
Advanced
Pool sizing and schema-presence checks are operator tuning, not day-one work.
MySQL 8 only
ModularJobs supports MySQL 8 only. SQLite, PostgreSQL, MariaDB, and Mongo providers are not supported and were removed.
Schema ownership
| Store | Who creates tables? | Who only connects? |
|---|---|---|
| MySQL | Ops / CI / script once | Paper plugin + web/rest-api |
Neither process ever runs DDL. That is intentional: multi-instance servers,
least privilege, reviewable migrations, backups, and upgrades do not belong in
onEnable or the API request path.
- Source of truth:
modularjobs-paper/src/main/resources/sql/mysql.sql - Apply:
./scripts/apply-mysql-schema.sh - Missing schema objects → fail-fast at plugin enable / API boot (
SchemaPresence)
Tables
| Table | Purpose |
|---|---|
job_progression | Active player state: root job key, current node, tree XP |
archive_job_progression | Archived player job state after leaving |
payable_records | Task payables by job / action / context / type |
job_tasks + job_task_payables | Task records with DECIMAL payables |
time_boost_identity + time_boosts | Timed boosts (target, source, expiry) |
player_upgrades | Skill points, unlocked nodes, node levels |
editor_sessions | Secure editor payloads (REST authority) |
Durable money/XP amounts are DECIMAL; key-bearing identifiers use bounded
VARCHAR columns.
Identical pools are shared
Pools with the same jdbc-url + username share one HikariCP connection pool,
so pointing every section at one database costs a single pool:
payable:
type: mysql
jdbc-url: jdbc:mysql://127.0.0.1:3306/modularjobs
username: modularjobs
password: change-me
maximum-pool-size: 10Provision MySQL 8
# Local / CI
export DATABASE_URL=mysql://user:pass@host:3306/modularjobs
./scripts/apply-mysql-schema.sh
# Or, with the MySQL client configured for the target database
mysql --host=host --port=3306 --user=user --password modularjobs \
< paper/src/main/resources/sql/mysql.sqlFor local development, run MySQL 8 externally (Docker/Podman) and apply the schema before starting either process.
Startup behavior
- Open Hikari pool to MySQL.
- Verify required tables exist (
job_progression,job_tasks, …). - Verify migration-sensitive columns, including
current_node_key, exist. - Missing tables or columns → fail enable with the required schema or migration script.
Task data ownership
The plugin does not seed job_tasks. An empty task table remains empty until an
operator creates definitions through the editor/repository path or reviewed SQL.
Live task changes
MySQL is the only runtime source of task data. Back up live rows before bulk
edits or deletes. The fisher → fisherman job-key rename likewise requires an
operator-managed data update before deploying the renamed catalog.