golang-migrateでSQLiteのマイグレーションをやってみる

SQLiteでgolang-migrateを試した際のメモです。

<details><summary>実行環境</summary>

```
> wsl --version
WSL バージョン: 2.1.5.0
カーネル バージョン: 5.15.146.1-2
WSLg バージョン: 1.0.60
MSRDC バージョン: 1.2.5105
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22631.3527
```
```
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy
```
</details>

go-migrateの使用方法には自作のGoプロジェクトに組み込む方法とCLIで使用する方法がありますが、今回はCLI版を試します。
[CLI版のReadme](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate)に従って、pre-buildされた実行ファイルをインストールします。
```
$ curl -L https://github.com/golang-migrate/migrate/releases/download/v4.17.1/migrate.linux-amd64.tar.gz | tar xvz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0LICENSE
README.md
migrate
100 14.9M  100 14.9M    0     0  4147k      0  0:00:03  0:00:03 --:--:-- 4771k
```

[Getting Started](https://github.com/golang-migrate/migrate/blob/master/GETTING_STARTED.md)のとおりにマイグレーション用のファイルを生成し、テーブル作成のSQLを記載します。
```
$ ./migrate create -ext sql -dir db/migrations -seq create_table
/home/xxxx/go-migrate/db/migrations/000001_create_table.up.sql
/home/xxxx/go-migrate/db/migrations/000001_create_table.down.sql
```

```000001_create_table.up.sql
CREATE TABLE pets (
  name string
);
```

```000001_create_table.down.sql
DROP TABLE IF EXISTS pets;
```

マイグレーション実行のコマンドは```migrate -database YOUR_DATABASE_URL -path PATH_TO_YOUR_MIGRATIONS up```です。
SQLiteをマイグレーションする場合、```YOUR_DATABASE_URL```は先頭が```sqlite://```と```sqlite3://```の二種類あり、これは使用するドライバーを指しています。```sqlite://```は```modernc.org/sqlite```、```sqlite3://```は```github.com/mattn/go-sqlite3```を使用します。

今回は```modernc.org/sqlite```を使います。

```
$ ./migrate -database sqlite://db.sqlite -path db/migrations up
error: database driver: unknown driver sqlite (forgotten import?)
```
マイグレーションを実行したところdriver sqliteが見つからないエラーが発生。

[Issueをみると](https://github.com/golang-migrate/migrate/issues/899)、pre-buildされた実行ファイルにはSQLiteが含まれていないとのこと。
>SQLite isn't built by default.
For SQLite CLI support, you'll need to install the CLI via the Go toolchain

[CLI版のReadme](https://github.com/golang-migrate/migrate/tree/master/cmd/migrate)のとおり、```go install```で再インストールします。
```
$ go install -tags 'sqlite' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
```

無事SQLiteでマイグレーションできるようになりました。
```
$ migrate -database sqlite://db.sqlite -path db/migrations up
1/u create_table (7.850289ms)
```

データベースのスキーマを確認します。```000001_create_table.up.sql```のとおりにテーブルが作成されていますね。
```
$ sqlite3 db.sqlite
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE schema_migrations (version uint64,dirty bool);
CREATE UNIQUE INDEX version_unique ON schema_migrations (version);
CREATE TABLE pets (
  name string
);
```

試しにカラムを追加してみます。
```
$ migrate create -ext sql -dir db/migrations -seq alter_table
```
```000002_alter_table.up.sql
ALTER TABLE pets ADD predator bool;
```
```000002_alter_table.down.sql
ALTER TABLE pets DROP COLUMN predator;
```

マイグレーションを実行し、```predator```カラムが追加されました。
```
$ migrate -database sqlite://db.sqlite -path db/migrations up
2/u alter_table (7.158102ms)

$ sqlite3 db.sqlite 
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE schema_migrations (version uint64,dirty bool);
CREATE UNIQUE INDEX version_unique ON schema_migrations (version);
CREATE TABLE pets (
  name string
, predator bool);
```

データベースのバージョンを1つ下げてみます。マイグレーションを実行し、```predator```カラムが削除されました。
```
$ migrate -database sqlite://db.sqlite -path db/migrations down 1
2/d alter_table (8.172232ms)

sqlite> .schema
CREATE TABLE schema_migrations (version uint64,dirty bool);
CREATE UNIQUE INDEX version_unique ON schema_migrations (version);
CREATE TABLE pets (
  name string
);
```