wslでelixir その38

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
ecto、やってみた。

# --sup付きでmix newする。

```
$ mix new friends --sup
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/friends.ex
* creating lib/friends/application.ex
* creating test
* creating test/test_helper.exs
* creating test/friends_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd friends
    mix test

Run "mix help" for more commands.
$ cd friends
$ mix test
Compiling 2 files (.ex)
Generated friends app
..

Finished in 0.07 seconds (0.00s async, 0.07s sync)
1 doctest, 1 test, 0 failures

```

# mix deps.getする。

- mix.exs ファイルにectoとpostgrexパッケージの依存を追加します。

	defp deps do
		[
			{:ecto_sql, "~> 3.2"},
			{:postgrex, "~> 0.15"}
		]
	end

```
$ mix deps.get
Resolving Hex dependencies...
Resolution completed in 0.193s
Unchanged:
  db_connection 2.5.0
  decimal 2.1.1
  ecto 3.10.3
  ecto_sql 3.10.1
  telemetry 1.2.1
New:
  postgrex 0.17.2
* Getting postgrex (Hex package)
```

# mix ecto.gen.repoする。

```
$ mix ecto.gen.repo -r Friends.Repo
==> postgrex
Compiling 68 files (.ex)
Generated postgrex app
==> ecto_sql
Compiling 25 files (.ex)
Generated ecto_sql app
==> friends
* creating lib/friends
* creating lib/friends/repo.ex
lib/friends/repo.ex already exists, overwrite? [Yn] y
* updating config/config.exs
Don't forget to add your new repo to your supervision tree
(typically in lib/friends/application.ex):

    def start(_type, _args) do
      children = [
        Friends.Repo,
      ]

And to add it to the list of Ecto repositories in your
configuration files (so Ecto tasks work as expected):

    config :friends,
      ecto_repos: [Friends.Repo]
```

# mix ecto.createする。

```
$ mix ecto.create
Compiling 3 files (.ex)
Generated friends app
```

# postgresをインストールする。

```
$ sudo apt-get install postgres

$ sudo service postgresql start

$ sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"

```

# mix ecto.gen.migrationする。

```
$ mix ecto.gen.migration create_people
* creating priv/repo/migrations
* creating priv/repo/migrations/20230818024701_create_people.exs
```

# mix ecto.migrateする。

- Repoを組み立てる。

```
defmodule Mydb.Repo.Migrations.CreatePeople do
  use Ecto.Migration
  def change do
		create table(:people) do
			add :name, :string, null: false
			add :age, :integer, default: 0
		end
  end
end
```

```
$ mix ecto.migrate

11:52:02.225 [info]  == Running 20230818024701 Friends.Repo.Migrations.CreatePeople.change/0 forward

11:52:02.240 [info]  create table people

11:52:02.525 [info]  == Migrated 20230818024701 in 0.2s

```

# 使って見る。
新しいスキーマを lib/friends/person.ex に作る。

```
defmodule Friends.Person do
	use Ecto.Schema
	schema "people" do
		field :name, :string
		field :age, :integer, default: 0
	end
end
```
```
$ iex -S mix
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> im = %Friendsmysql.Person{first_name: "im", last_name: "miolab", age: 28}
** (CompileError) iex:1: Friendsmysql.Person.__struct__/1 is undefined, cannot expand struct Friendsmysql.Person. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code

iex(1)> im = %Friends.Person{first_name: "im", last_name: "miolab", age: 28}
** (KeyError) key :first_name not found
    (friends 0.1.0) expanding struct: Friends.Person.__struct__/1
    iex:1: (file)
iex(1)> im = %Friends.Person{name: "im", age: 28}
%Friends.Person{
  __meta__: #Ecto.Schema.Metadata<:built, "people">,
  age: 28,
  id: nil,
  name: "im"
}
iex(2)> Friends.Repo.insert(im)

13:20:43.610 [debug] QUERY OK db=186.1ms decode=43.2ms queue=31.2ms idle=1356.3ms
INSERT INTO "people" ("age","name") VALUES ($1,$2) RETURNING "id" [28, "im"]
{:ok,
 %Friends.Person{
   __meta__: #Ecto.Schema.Metadata<:loaded, "people">,
   age: 28,
   id: 1,
   name: "im"
 }}
iex(3)> Friends.Repo.all(Friends.Person)

13:22:00.219 [debug] QUERY OK source="people" db=31.3ms queue=1.7ms idle=1995.1ms
SELECT p0."id", p0."name", p0."age" FROM "people" AS p0 []
[
  %Friends.Person{
    __meta__: #Ecto.Schema.Metadata<:loaded, "people">,
    age: 28,
    id: 1,
    name: "im"
  }
]
iex(4)>



```

# 永続化を確認。

```
$ iex -S mix
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]

Interactive Elixir (1.13.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Friends.Repo.all(Friends.Person)

14:19:40.209 [debug] QUERY OK source="people" db=3.6ms decode=3.1ms queue=2.2ms idle=544.8ms
SELECT p0."id", p0."name", p0."age" FROM "people" AS p0 []
[
  %Friends.Person{
    __meta__: #Ecto.Schema.Metadata<:loaded, "people">,
    age: 28,
    id: 1,
    name: "im"
  }
]
```


以上。