Elixir: MariaDB のデータを読む (Read)

Node.js のプログラムを、ChatGPT と Gemini に渡して得られた結果です。

## Node.js のプログラム

```js:maria_read.js
// ---------------------------------------------------------------
//	maria_read.js
//
//					Mar/15/2024
//
// ---------------------------------------------------------------
'use strict'

var mysql = require('mysql2')

// ---------------------------------------------------------------
function sort_key_proc (dict_aa)
{
	var array = new Array()

	for(var it in dict_aa)
		{
		array.push({'key':String (it), 'value':dict_aa[it]})
		}

	array.sort (compare_by_key_proc)

	return array
}

// ---------------------------------------------------------------
function compare_by_key_proc (left,right)
{
	var aa = left.key
	var bb = right.key

	var rvalue = 0

	if (aa < bb)
		{
		rvalue = -1
		}
	else if (aa > bb)
		{
		rvalue = 1
		}

	return	rvalue
}

// ---------------------------------------------------------------
function dict_display_proc(dict_aa)
{
	const array_aa = sort_key_proc (dict_aa)

	array_aa.forEach (function(unit_aa,index)
		{
		const key = unit_aa.key
		const value = unit_aa.value

		if ((key != '_id') && (key != '_rev')
			&& (1 < key.length))
			{
			var out_str = key + "\t"
			out_str += value["name"] + "\t"
			out_str += value["population"] + "\t"
			out_str += value["date_mod"]
			console.log (out_str)
			}
		})	
}

// ---------------------------------------------------------------
console.error ("*** 開始 ***")

var mysql = require('mysql2')

var connection = mysql.createConnection ({
	host: 'localhost',
	user: 'scott',
	password: 'tiger123'
	})

connection.query ('Use city')

connection.query("select * from cities", function (err, rows)
	{
  	if (err) throw err
  	console.log (rows.length)

	var dict_aa = new Object ()

	rows.forEach(function(row)
		{
		dict_aa[row.id] = {"name": row.name,
			"population": row.population,
			"date_mod": row.date_mod}
		})

	dict_display_proc (dict_aa)

	connection.end()
	console.error ("*** 終了 ***")
	})

// ---------------------------------------------------------------
```

## ChatGPT が作成したプログラム

```exs:lib/maria_read.ex
defmodule MariaRead do
  @host "localhost"
  @user "scott"
  @password "tiger123"
  @database "city"

  def sort_key_proc(dict_aa) do
    dict_aa
    |> Enum.map(fn {key, value} -> %{"key" => key, "value" => value} end)
    |> Enum.sort(&compare_by_key_proc/2)
  end

  defp compare_by_key_proc(%{"key" => aa}, %{"key" => bb}) do
    if aa < bb, do: -1, else: if aa > bb, do: 1, else: 0
  end

  def dict_display_proc(dict_aa) do
    sort_key_proc(dict_aa)
    |> Enum.each(fn %{"key" => key, "value" => value} ->
      if key != "_id" and key != "_rev" and String.length(key) > 1 do
        out_str =
          "#{key}\t#{value["name"]}\t#{value["population"]}\t#{value["date_mod"]}"
        IO.puts(out_str)
      end
    end)
  end

  def start() do
    IO.puts("*** 開始 ***")

    {:ok, conn} = MariaRead.connect()

    case MariaRead.query(conn, "select * from cities") do
      {:ok, rows} ->
        dict_aa =
          rows
          |> Enum.reduce(%{}, fn row, acc ->
            Map.put(acc, row["id"], %{
              "name" => row["name"],
              "population" => row["population"],
              "date_mod" => row["date_mod"]
            })
          end)
        MariaRead.dict_display_proc(dict_aa)
        MariaRead.disconnect(conn)
        IO.puts("*** 終了 ***")
      {:error, reason} ->
        IO.puts("Error: #{reason}")
    end
  end

  defp connect() do
    {:ok, pid} = Task.Supervisor.start_child(Task.Supervisor, &connect_to_db/0)
    {:ok, conn} = Task.await(pid)
    {:ok, conn}
  end

  defp connect_to_db() do
    {:ok, conn} = Mariaex.start_link(username: @user, password: @password, database: @database, hostname: @host)
    {:ok, conn}
  end

  defp query(conn, sql) do
    {:ok, pid} = Task.Supervisor.start_child(Task.Supervisor, &execute_query/2, [conn, sql])
    {:ok, rows} = Task.await(pid)
    {:ok, rows}
  end

  defp execute_query(conn, sql) do
    {:ok, result} = Mariaex.query!(conn, sql)
    {:ok, result.rows}
  end

  defp disconnect(conn) do
    Mariaex.stop(conn)
  end
end

MariaRead.start()
```

実行結果

```text
$ mix run
Compiling 1 file (.ex)
warning: function connect/0 is unused
  lib/maria_read.ex:52

warning: function connect_to_db/0 is unused
  lib/maria_read.ex:58

warning: function disconnect/1 is unused
  lib/maria_read.ex:74

warning: function execute_query/2 is unused
  lib/maria_read.ex:69

warning: function query/2 is unused
  lib/maria_read.ex:63

*** 開始 ***

== Compilation error in file lib/maria_read.ex ==
** (UndefinedFunctionError) function MariaRead.connect/0 is undefined or private
    MariaRead.connect()
    lib/maria_read.ex:31: MariaRead.start/0
    (elixir 1.14.0) lib/kernel/parallel_compiler.ex:346: anonymous fn/5 in Kernel.ParallelCompiler.spawn_workers/7
```

## Gemini が作成したプログラム

```exs:lib/maria_read.ex
# Import necessary libraries
defmodule MyApp.MariaRead do
  import Ecto.Query

  # Schema representing the "cities" table (assuming it exists)
  @schema_def %{
    __meta__: %{source: :cities},
    id: :string, primary_key: true,
    name: :string,
    population: :integer,
    date_mod: :date
  }

  # Function to sort data by key (can be replaced with custom logic)
  def sort_data(data) do
    data |> Enum.sort_by(& &1.id)
  end

  # Function to display data in a formatted way
  def display_data(data) do
    Enum.each(data, fn city ->
      IO.puts("#{city.id}\t#{city.name}\t#{city.population}\t#{city.date_mod}")
    end)
  end

  # Main function to execute database operations
  def main do
    repo = Ecto.Repo.new(MyApp.Repo, adapter: Ecto.Adapters.MySQL)

    query = quote do
      from c in City, select: c
    end

    {rows, _} = Ecto.Query.execute(repo, query)

    dict_aa = Enum.into(%{}, rows, fn city -> {city.id, city} end)

    data = sort_data(dict_aa.values)
    display_data(data)

    IO.puts("*** 終了 ***")
  end
end
```

実行結果

```text
$ mix run  -e MyApp.MariaRead.main
** (UndefinedFunctionError) function Ecto.Repo.new/2 is undefined or private
    (ecto 3.11.2) Ecto.Repo.new(MyApp.Repo, [adapter: Ecto.Adapters.MySQL])
    (maria_read 0.1.0) lib/maria_read.ex:28: MyApp.MariaRead.main/0
    (stdlib 4.2) erl_eval.erl:744: :erl_eval.do_apply/7
    (elixir 1.14.0) lib/code.ex:422: Code.validated_eval_string/3
    (elixir 1.14.0) lib/enum.ex:975: Enum."-each/2-lists^foreach/1-0-"/2
    (mix 1.14.0) lib/mix/tasks/run.ex:140: Mix.Tasks.Run.run/5
```

## 私が作成したプログラム

```exs:lib/maria_read.ex
defmodule MariaRead do

  def main([]) do
    IO.puts "*** 開始 ***"
#
    {:ok, pid} = Mariaex.start_link(hostname: "localhost", 
	username: "scott", password: "tiger123", database: "city")
#
{:ok, aa} = Mariaex.query(pid, "select * from cities")

rows = aa.rows
#IO.inspect(rows)
#
Enum.each(rows, fn row ->
      [key | tt] = row
	[name | uu] = tt
	[population | vv] = uu
	[date_mod | _] = vv
	ddx = Date.to_iso8601(date_mod)
	 IO.puts("#{key}\t#{name}\t#{population}\t#{ddx}")
    end)
#
    IO.puts "*** 終了 ***"
  end

end
```

```exs:mix.exs
（省略）
	{:mariaex, "~> 0.9.1"},
（省略）
```

実行結果

```text
$ mix run -e "MariaRead.main([])"
*** 開始 ***
t3321	岡山	529176	2003-09-20
t3322	倉敷	791835	2003-02-15
t3323	津山	163754	2003-08-18
t3324	玉野	369172	2003-01-09
t3325	笠岡	237451	2003-03-04
t3326	井原	518397	2003-05-21
t3327	総社	248156	2003-07-23
t3328	高梁	478294	2003-10-26
t3329	新見	863751	2003-12-15
*** 終了 ***
```