リートン で elixir を学ぶ （その6）text ファイルの crud

こちらで行ったことを共通のモジュールを使うように変更しました。
[リートン で elixir を学ぶ （その2）text ファイルの write](https://qiita.com/ekzemplaro/items/3ad1a9b6722ba0f6faa2)
[リートン で elixir を学ぶ （その3）text ファイルの read](https://qiita.com/ekzemplaro/items/b5e4fbccbdcc7b387a84)
[リートン で elixir を学ぶ （その4）text ファイルの update](https://qiita.com/ekzemplaro/items/80aeabfd39b6a167d4c3)
[リートン で elixir を学ぶ （その5）text ファイルの delete](https://qiita.com/ekzemplaro/items/51637034ff2b5c35e616)

## フォルダー構造

```text
$ tree
.
├── Makefile
├── text_create.exs
├── text_delete.exs
├── text_manipulate.exs
├── text_read.exs
└── text_update.exs
```

## 共通モジュール

```elixir:text_manipulate.exs
# ------------------------------------------------------------------
#
#	text_manipulate.exs
#
#						Apr/07/2024
# ------------------------------------------------------------------
defmodule TextManipulate do
# ------------------------------------------------------------------
  def read_file(file_path) do
    file_path
    |> File.stream!()
    |> Enum.reduce(%{}, fn line, acc ->
      process_line(line, acc)
    end)
  end

  defp process_line(line, acc) do
    [key, name, population, date_mod | _] = String.split(line, "\t")
    if String.starts_with?(key, "t") do
      Map.put(acc, key, %{
        name: name,
        population: String.to_integer(population),
        date_mod: String.trim_trailing(date_mod)
      })
    else
      acc
    end
  end

# ------------------------------------------------------------------
  def display(dict_aa) do
    dict_aa
    |> Map.to_list()
    |> Enum.sort()
    |> Enum.each(fn {key, val} ->
      IO.puts("#{key}\t#{val.name}\t#{val.population}\t#{val.date_mod}")
    end)
  end
# ------------------------------------------------------------------
  def text_write_proc(file_out, dict_aa) do
    {:ok, file} = File.open(file_out, [:write, :utf8])

    dict_aa
    |> Enum.each(fn {key, val} ->
      str_out = "#{key}\t#{val.name}\t#{val.population}\t#{val.date_mod}\n"
      IO.write(file, str_out)
    end)

    File.close(file)
  end

# ------------------------------------------------------------------
  def dict_append_proc(dict_aa, key, name, population, date_mod) do
    Map.put(dict_aa, key, %{name: name, population: population, date_mod: date_mod})
  end
# ------------------------------------------------------------------
def update_dict(dict, id, population) do
  date_mod = Date.utc_today()
  name = dict[id].name
  IO.puts name
  Map.update!(dict, id, fn _ -> %{population: population, name: name, date_mod: "#{date_mod}"} end)
end

# ------------------------------------------------------------------
def delete_from_dict(dict, key) do
  Map.delete(dict, key)
end

# ------------------------------------------------------------------
end
# ------------------------------------------------------------------
```

```text:Makefile
Elixir.TextManipulate.beam: text_manipulate.exs
	elixirc text_manipulate.exs
clean:
	rm -f *.beam
 ```

 コンパイル

 ```text
 $ make
elixirc text_manipulate.exs
```

Elixir.TextManipulate.beam が作成されます。

## Create

```elixir:text_create.exs
#! /usr/bin/elixir
#
defmodule TextCreate do
  # 初期データを準備する
  def data_prepare_proc do
    dict_aa = %{}
    |> TextManipulate.dict_append_proc("t2381", "名古屋", 52761, "2003-4-30")
    |> TextManipulate.dict_append_proc("t2382", "豊橋", 47195, "2003-5-10")
    |> TextManipulate.dict_append_proc("t2383", "岡崎", 83795, "2003-8-20")
    |> TextManipulate.dict_append_proc("t2384", "一宮", 38495, "2003-7-15")
    |> TextManipulate.dict_append_proc("t2385", "蒲郡", 26395, "2003-3-18")
    |> TextManipulate.dict_append_proc("t2386", "常滑", 57892, "2003-2-9")
    |> TextManipulate.dict_append_proc("t2387", "大府", 27198, "2003-1-5")
    |> TextManipulate.dict_append_proc("t2388", "瀬戸", 58429, "2003-10-14")
    |> TextManipulate.dict_append_proc("t2389", "犬山", 74192, "2003-12-11")

    dict_aa
  end
#
end

IO.puts :stderr,"*** 開始 ***"
[file_out | _] = System.argv()
IO.puts :stderr,file_out
#

dict_aa = TextCreate.data_prepare_proc()
TextManipulate.text_write_proc(file_out,dict_aa)
IO.puts :stderr,"*** 終了 ***"
```

実行結果

```text
$ ./text_create.exs cities.txt
*** 開始 ***
cities.txt
*** 終了 ***
```

## Read

```elixir:text_read.exs
#! /usr/bin/elixir
#
IO.puts :stderr,"*** 開始 ***"
[file_in | _] = System.argv()
IO.puts :stderr,file_in

dict_aa = TextManipulate.read_file(file_in)
TextManipulate.display(dict_aa)
IO.puts :stderr,"*** 終了 ***"
```

実行結果

```text
$ ./text_read.exs cities.txt 
*** 開始 ***
cities.txt
t2381	名古屋	52761	2003-4-30
t2382	豊橋	47195	2003-5-10
t2383	岡崎	83795	2003-8-20
t2384	一宮	38495	2003-7-15
t2385	蒲郡	26395	2003-3-18
t2386	常滑	57892	2003-2-9
t2387	大府	27198	2003-1-5
t2388	瀬戸	58429	2003-10-14
t2389	犬山	74192	2003-12-11
*** 終了 ***
```

## Update

```elixir:text_update.exs
#! /usr/bin/elixir

#
IO.puts :stderr,"*** 開始 ***"
[file_in, id_in, population_in_str]  = System.argv()
IO.puts :stderr,file_in

population_in = String.to_integer(population_in_str)

IO.puts("#{id_in}\t#{population_in}")

dict_aa = TextManipulate.read_file(file_in)

# IO.inspect(dict_aa)

dict_bb = TextManipulate.update_dict(dict_aa, id_in, population_in)


# IO.inspect(dict_bb)

TextManipulate.text_write_proc(file_in, dict_bb)

IO.puts :stderr,"*** 終了 ***"
```

実行結果

```text
$ ./text_update.exs cities.txt t2387 10000
*** 開始 ***
cities.txt
t2387	10000
大府
*** 終了 ***
```

## Delete

```elixir:text_delete.exs
#! /usr/bin/elixir

# -------------------------------------------------------------------------
IO.puts :stderr,"*** 開始 ***"
[file_in, id_in]  = System.argv()
IO.puts :stderr,file_in

IO.puts("#{id_in}")

dict_aa = TextManipulate.read_file(file_in)

dict_bb = TextManipulate.delete_from_dict(dict_aa, id_in)
# IO.inspect(dict_bb)

TextManipulate.text_write_proc(file_in, dict_bb)

IO.puts :stderr,"*** 終了 ***"
# -------------------------------------------------------------------------
```

実行結果

```text
$ ./text_delete.exs cities.txt t2382
t2382
*** 開始 ***
cities.txt
*** 終了 ***
```