> 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/edcoinflip/getting-started/storage.md).

# Storage & MySQL

Open coinflips (their bets are held until someone joins) and unpaid payouts are stored. Pick where in `config.yml`:

```yaml
storage:
  type: yaml               # yaml = plugins/EdCoinflip/data.yml (default), mysql = MySQL / MariaDB
  server-id: 'default'     # MySQL: this server's name; give every server its own
  mysql:
    host: 'localhost'
    port: 3306
    database: 'minecraft'
    username: 'root'
    password: ''
    table-prefix: 'edcoinflip_'
    use-ssl: false
    properties: 'useUnicode=true&characterEncoding=utf8&serverTimezone=UTC'
```

`storage.type` is read when the server starts (a restart is needed to change it). Paper and Spigot already ship the MySQL driver; the MariaDB driver is used when only that one is there.

## How data is saved

* Every read and write runs on one background thread, in order, so writes never overtake each other and the main thread never waits for the disk or the database.
* `data.yml` is written once per burst of changes, to a temp file that is synced and atomically moved, so it is never half written. If it can't be read at start, EdCoinflip stays disabled instead of overwriting it.
* A win or refund is stored before it is paid and removed when it is paid. A player's payouts are read from the storage every time they join.
* On a server stop every queued write is finished first.

## MySQL

Tables (created on the first start, InnoDB, utf8mb4):

| Table             |                                                                                                        |
| ----------------- | ------------------------------------------------------------------------------------------------------ |
| `<prefix>games`   | open coinflips: `server`, `id`, `creator`, `creator_name`, `currency`, `amount`, `created`             |
| `<prefix>payouts` | money owed: `id`, `uuid`, `server`, `currency`, `amount`, `reason` (win / refund / expired), `created` |
| `<prefix>global`  | `setting_key` / `setting_value` (the next coinflip id of each server)                                  |

Amounts are stored as exact decimal text. The connection is checked before use and opened again when it dropped.

If MySQL can't be reached when the server starts, EdCoinflip logs a clear error (host, port and database, never the password) and uses `data.yml` instead, so the server still runs. Fix `storage.mysql` and restart.

### Several servers on one database

* Open coinflips belong to the server they were created on (`server-id`): each server lists and plays its own.
* Payouts follow the player: a coinflip won while offline is paid on whichever server they join next.
* The same player should not be online on two servers at once.

## Moving data: `/cf migrate <from> <to>`

`/cf migrate yaml mysql` or `/cf migrate mysql yaml` copies every open coinflip of this server and every payout to the other storage, in the background, after all pending writes, and reports how many were copied. The target must be the storage that is **not** in use; what it held for this server is replaced.

Switching from `data.yml` to MySQL:

1. Fill in `storage.mysql` (keep `type: yaml`).
2. Run `/cf migrate yaml mysql` and wait for the "Copied ..." message.
3. Set `type: mysql` and restart.

Going back works the same way with `/cf migrate mysql yaml`. Copy right before you switch: anything that happens after the copy stays only in the storage in use.
