golang-migrateの導入

# golang-migrate
Go製のマイグレーションツール`golang-migrate`を扱います。

https://github.com/golang-migrate/migrate

## インストール
```bash
brew install golang-migrate
```

```bash
$ $ migrate -h
Usage: migrate OPTIONS COMMAND [arg...]
       migrate [ -version | -help ]

Options:
  -source          Location of the migrations (driver://url)
  -path            Shorthand for -source=file://path
  -database        Run migrations against this database (driver://url)
  -prefetch N      Number of migrations to load in advance before executing (default 10)
  -lock-timeout N  Allow N seconds to acquire database lock (default 15)
  -verbose         Print verbose logging
  -version         Print version
  -help            Print usage

Commands:
  create [-ext E] [-dir D] [-seq] [-digits N] [-format] [-tz] NAME
	   Create a set of timestamped up/down migrations titled NAME, in directory D with extension E.
	   Use -seq option to generate sequential up/down migrations with N digits.
	   Use -format option to specify a Go time format string. Note: migrations with the same time cause "duplicate migration version" error.
           Use -tz option to specify the timezone that will be used when generating non-sequential migrations (defaults: UTC).

  goto V       Migrate to version V
  up [N]       Apply all or N up migrations
  down [N] [-all]    Apply all or N down migrations
	Use -all to apply all down migrations
  drop [-f]    Drop everything inside database
	Use -f to bypass confirmation
  force V      Set version V but don't run migration (ignores dirty state)
  version      Print current migration version

Source drivers: file, bitbucket, go-bindata, github, github-ee, gitlab, godoc-vfs, s3, gcs
Database drivers: mysql, pgx5, yugabytedb, mongodb+srv, cassandra, pgx4, crdb-postgres, postgres, mongodb, firebirdsql, spanner, stub, clickhouse, pgx, cockroach, cockroachdb, yugabyte, postgresql, redshift, ysql, firebird, neo4j, sqlserver
```

## マイグレーションファイルを生成する
```bash
$ migrate create -ext sql -dir ./migrations -seq create_posts
./migrations/000001_create_posts.up.sql
./migrations/000001_create_posts.down.sql
```

生成するファイルの拡張子、ディレクトリ、ファイル名をオプションで指定。
`upgrade`と`downgrade`それぞれの処理を書くファイルが生成されます。

中身は空なので自分で書く必要があります。
```bash
$ cat migrations/000001_create_posts.up.sql
```

このように。
```sql:migrations/000001_create_posts.up.sql
CREATE TABLE posts (
    id INT PRIMARY KEY,
    title VARCHAR(255),
    content TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

```sql:migrations/000001_create_posts.down.sql
DROP TABLE IF EXISTS posts;
```

## migration実行
docker-composeの抜粋です。mariadbは以下のようにコンテナを作成しています。
```yml:docker-comose.yml
mysql:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: golang
      MYSQL_USER: golang
      MYSQL_PASSWORD: golang
    restart: always
    ports:
      - "3310:3306"
    volumes:
      - ./mysql:/var/lib/mysql
```

マイグレーションコマンドは以下のようになります。
```bash
$ migrate -path ./migrations -database "mysql://golang:golang@tcp(localhost:3310)/golang" up
1/u create_posts (37.739166ms)
```

作成できていますね。
```bash
$ mysql -ugolang -pgolang -P3310
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.9.3-MariaDB-1:10.9.3+maria~ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use golang
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [golang]> show tables;
+-------------------+
| Tables_in_golang  |
+-------------------+
| posts             |
| schema_migrations |
| users             |
+-------------------+
3 rows in set (0.016 sec)

MariaDB [golang]> describe posts;
+------------+--------------+------+-----+---------------------+-------+
| Field      | Type         | Null | Key | Default             | Extra |
+------------+--------------+------+-----+---------------------+-------+
| id         | int(11)      | NO   | PRI | NULL                |       |
| title      | varchar(255) | YES  |     | NULL                |       |
| content    | text         | YES  |     | NULL                |       |
| created_at | timestamp    | NO   |     | current_timestamp() |       |
+------------+--------------+------+-----+---------------------+-------+
4 rows in set (0.024 sec)

MariaDB [golang]>
```

## ロールバック
末尾の`up`を`down`にするだけです。
```
$ migrate -path ./migrations -database "mysql://golang:golang@tcp(localhost:3310)/golang" down
Are you sure you want to apply all down migrations? [y/N]
y
Applying all down migrations
1/d create_posts (48.707375ms)
```

```bash
$ mysql -ugolang -pgolang -P3310
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 6
Server version: 10.9.3-MariaDB-1:10.9.3+maria~ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show tables;
ERROR 1046 (3D000): No database selected
MariaDB [(none)]> use golang;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [golang]> show tables;
+-------------------+
| Tables_in_golang  |
+-------------------+
| schema_migrations |
| users             |
+-------------------+
2 rows in set (0.011 sec)

MariaDB [golang]>
```
削除されています。