Phoenixフレームワークでsqliteをデータベースとして使う

# イントロダクション

この記事は https://github.com/jazzyb/sqlite_ecto/wiki/Basic-Sqlite.Ecto-Tutorial にあるチュートリアルに加筆したものです

Elixir+Phoenixがアツいです．ポストRuby on Railsとしての地位を着実に固めつつあるように思います

PhoenixフレームワークのデータベースはデフォルトでPostgreSQLですがPostgreSQLは仰々しいですよね．sqliteは新しいユーザを別途作ったりしなくてもいいし，DBをファイルとして扱えるため手軽だし，大規模なデータを扱わないかぎり十分に高速ですし，個人がちょっと公開するサービス程度であればsqliteを使いたいですよね．

# phoenixでsqlite3を使う
phoenixとelixir環境がすでに構築されていることを前提に話を進めます．

```shell-session
$ mix phoenix.new blog --database sqlite
```

とやればsqliteでプロジェクトが生成されます（コメントありがとうございます）

これで終わるとあれなので，本チュートリアルでは，一度作ってしまったPhoenixプロジェクトのデータベースをsqliteに変更する方法を紹介します．

```shell-session
$ mix phoenix.new blog
```

とやって，新しいPhoenixプロジェクトを作成します．名前はblogとでもしておきます

```shell-session
$ cd blog
```

プロジェクトのディレクトリ内に移動して，この中にある`mix.exs`を以下のように編集します．application関数内にある`:postgrex`と`defp deps`内の`{:postgrex, ">= 0.0.0"}`を以下のように書き換えます．

```ex
def application do
  [applications: [:logger, :sqlite_ecto, :phoenix_ecto]]
end

defp deps do
  [{:sqlite_ecto, "~> 1.0.2"}]
end
```
ectoというのはPhoenixのO/Rマッパーです．RailsでいうところのActiveRecordですね．
編集がおわったら，パッケージのダウンロード・インストールと依存関係を解決します．

```shell-session
$ mix deps.get
```

とやれば，全部自動的にやってくれます．RoRの`bundle install`に相当します．とても楽ですね．

つぎに，新しいectoレポジトリを作ります．ectoレポジトリというのは，データベースの抽象化レイヤのことのようです．Railsでいうところのなんなのかはちょっとわかりませんが，ようは，Phoenixからのデータベース操作はこのectoレポジトリを通ることになります．

```shell-session
$ mix ecto.gen.repo Blog.Repo
```

多分オーバーライドするか？と問われるのでYキーをタイプします

`lib/blog/repo.ex`ファイルが新たにできているので，これを以下のように編集します

```ex
defmodule Blog.Repo do
  use Ecto.Repo, otp_app: :blog, adapter: Sqlite.Ecto
end
```

次に，config/config.exsも編集します．

```ex
config :blog, Blog.Repo,
  adapter: Sqlite.Ecto,
  database: "blog.sqlite3"
```

こんな感じで，database:の部分はsqliteのDBファイル名になりますので，適当に自分の好きなわかり易い名前にしてください．

`config/config.exs`に定義したデータベースの設定は，production環境のみに適用されます．したがって，test環境やdevelopment環境でもsqliteを使いたい場合は`config/test.exs`と`config/dev.exs`も編集するようにします．その時はdatabaseフィールドの部分は別々にする必要があります．

`config/test.exs`の場合はblog_test.sqlite3にする

```ex
config :ttom, Ttom.Repo,
  adapter: Sqlite.Ecto,
  database: "blog_test.sqlite3"
```

`config/dev.exs`の場合はblog_dev.sqlite3にする

```ex
config :ttom, Ttom.Repo,
  adapter: Sqlite.Ecto,
  database: "blog_dev.sqlite3"
```
こんな感じで，databaseフィールドの部分は別々にします．test環境とproduction環境とdevelopment環境が混じってしまったらまずいですからね．次にデータベースを作ります．

```shell-session
$ mix ecto.create
```

とやって，データベースを作りましょう．エラーがでなければ成功です．

## マイグレーションしてみる
sqliteが使えるようになったので，なにかDBスキーマを定義してマイグレーションしてみましょう

```shell-session
$ mix ecto.gen.migration create_users
```

ここではUsersテーブルのマイグレーション定義ファイルを作ってみました．すると，以下の様なファイルが生成されます．

```shell-session
* creating priv/repo/migrations
* creating priv/repo/migrations/20151005085116_create_users.exs
```

ホント，Railsそのまんまですね．Railsが影響与えたWebフレームワークはPhoenix以外にもたくさんありますし，RailsがただのWebフレームワークという位置づけをこえ，新しいWebアプリ開発のパラダイムを作ったということがよくわかります．本当にRailsは偉大だと思います．

とりあえず，string型のnameとemailのフィールドを定義するように，先ほど生成された`priv/repo/migrations/20151005085116_create_users.exs`を以下のように編集します．ココらへんもrailsそのまんま．

```ex
defmodule Blog.Repo.Migrations.CreateUsers do
  use Ecto.Migration

  def change do
    create table(:users) do
      add :name, :string
      add :email, :string
      timestamps
    end
  end
end
```

マイグレーションをして，DB側にテーブルを作ります．

```shell-session
$ mix ecto.migrate

18:50:55.615 [info]  == Running Ttom.Repo.Migrations.CreateUsers.change/0 forward

18:50:55.615 [info]  create table users

18:50:55.620 [info]  == Migrated in 0.0s
```

マイグレーション完了しました．テーブルがdb側にちゃんとあるか確かめてみましょう．

```shell-session
$ sqlite3 blog_dev.sqlite3 .schema
CREATE TABLE "schema_migrations" ("version" BIGINT PRIMARY KEY, "inserted_at" DATETIME);
CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "name" TEXT, "email" TEXT, "inserted_at" DATETIME NOT NULL, "updated_at" DATETIME NOT NULL);
```

ちゃんとできていますね．

以上です