> For the complete documentation index, see [llms.txt](https://edseries-plugins.gitbook.io/p/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://edseries-plugins.gitbook.io/p/pinnagiveaways/features/storage.md).

# Storage & MySQL

PinnaGiveaways saves:

* per server: when each automatic giveaway runs next, its last winners, and the sponsored giveaways waiting to run;
* per player: whether they hid the animation, and the payouts they are still owed (prizes, refunds and `give-eco` rewards that couldn't be paid at once).

## Choosing the storage

```yaml
storage:
  type: yaml          # yaml (default) or mysql
  mysql:
    host: 'localhost'
    port: 3306
    database: 'minecraft'
    username: 'root'
    password: ''
    table-prefix: 'pgw_'
    use-ssl: false
    properties: 'useUnicode=true&characterEncoding=utf8&serverTimezone=UTC'
    server-id: 'default'
```

| Type    | Where the data goes                                                |
| ------- | ------------------------------------------------------------------ |
| `yaml`  | `plugins/PinnaGiveaways/data.yml`. The default; nothing to set up. |
| `mysql` | A MySQL or MariaDB database. Several servers can share it.         |

`storage` is read once at startup: restart after changing it (`/giveaway reload` doesn't switch it).

### MySQL

* No extra download: the plugin uses the MySQL driver that Paper ships (or the MariaDB driver if that one is missing).
* The tables are created on start: `<prefix>state`, `<prefix>queue`, `<prefix>players` and `<prefix>payouts` (InnoDB, utf8mb4, players keyed by UUID).
* `table-prefix` may only contain letters, digits and `_`. `properties` are extra JDBC URL parameters; a 5 second connect timeout and a 30 second socket timeout are added unless you set them.
* **If the plugin can't connect on start**, it logs a clear error with the host, port and database and uses `data.yml` instead, so the server still runs. Fix the settings and restart.
* If the connection drops while the server runs, it is reopened on the next use.

## How data is loaded and saved

* The server state is loaded at startup and saved every `save-interval-seconds` when it changed, and when the server stops.
* A player's data is loaded when they join and dropped when they leave. Every change (the animation toggle, a payout added or paid) is written right away.
* Every save and every database call runs on one background thread, in order, never on the main thread.

## Several servers on one database

* Each server keeps its own timers, last winners and sponsor queue under `server-id`: give every server its own.
* Player settings and payouts are shared: a prize won on one server is paid on whichever server the player joins next (if that server has the currency).
* Payouts are only ever added and removed one by one, so two servers never overwrite each other's.
* The same player should not be online on two servers sharing the database at the same time (a normal proxy already keeps a player on one server).

## Moving data between YAML and MySQL

```
/giveaway migrate yaml mysql
/giveaway migrate mysql yaml
```

The command copies this server's state and every stored player from the first storage to the second, in the background, and reports how many players it copied. The current state is saved first. The MySQL settings come from the current `config.yml`, so you can fill the database before switching. Players in the target storage are overwritten; nothing is deleted from the source.

Switching from YAML to MySQL:

1. Fill in `storage.mysql` (keep `type: yaml`).
2. Run `/giveaway migrate yaml mysql` and wait for the "Copied the data of N player(s)" message.
3. Set `storage.type: mysql` and restart.

Do it while the server is quiet: changes made between the migration and the restart stay in the old storage. `data.yml` stays as a backup.
