ModularJobs
Guides

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

Advanced — you do not need this to get started.

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

StoreWho creates tables?Who only connects?
MySQLOps / CI / script oncePaper 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

TablePurpose
job_progressionActive player state: root job key, current node, tree XP
archive_job_progressionArchived player job state after leaving
payable_recordsTask payables by job / action / context / type
job_tasks + job_task_payablesTask records with DECIMAL payables
time_boost_identity + time_boostsTimed boosts (target, source, expiry)
player_upgradesSkill points, unlocked nodes, node levels
editor_sessionsSecure 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: 10

Provision 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.sql

For local development, run MySQL 8 externally (Docker/Podman) and apply the schema before starting either process.

Startup behavior

  1. Open Hikari pool to MySQL.
  2. Verify required tables exist (job_progression, job_tasks, …).
  3. Verify migration-sensitive columns, including current_node_key, exist.
  4. 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.

On this page