From 5128691190cbcba2251955780531c318bde2e1ca Mon Sep 17 00:00:00 2001 From: kjubybot Date: Mon, 10 Mar 2025 18:00:33 +0400 Subject: [PATCH] add helper for loading clans from csv --- .../lib/codebattle/utils/populate_clans.ex | 35 +++++++++++++++++++ .../codebattle/utils/populate_clans_test.exs | 18 ++++++++++ 2 files changed, 53 insertions(+) create mode 100644 services/app/apps/codebattle/lib/codebattle/utils/populate_clans.ex create mode 100644 services/app/apps/codebattle/test/codebattle/utils/populate_clans_test.exs diff --git a/services/app/apps/codebattle/lib/codebattle/utils/populate_clans.ex b/services/app/apps/codebattle/lib/codebattle/utils/populate_clans.ex new file mode 100644 index 000000000..a81a600cf --- /dev/null +++ b/services/app/apps/codebattle/lib/codebattle/utils/populate_clans.ex @@ -0,0 +1,35 @@ +defmodule Codebattle.Utils.PopulateClans do + @moduledoc false + + @doc """ + Populates clans table from csv file. The file is expected to + have two fields in following order: long name, short name. + """ + def from_csv!(file) do + utc_now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second) + + file + |> File.stream!() + |> NimbleCSV.RFC4180.parse_stream() + |> Stream.chunk_every(500) + |> Enum.each(&process_batch(&1, utc_now)) + end + + defp process_batch(clans, now) do + clans = Enum.map(clans, &row_to_clan(&1, now)) + + Codebattle.Repo.insert_all(Codebattle.Clan, clans, + on_conflict: {:replace, [:long_name]}, + conflict_target: [:name] + ) + end + + defp row_to_clan([long_name, name], now) do + %{ + name: name, + long_name: long_name, + inserted_at: now, + updated_at: now + } + end +end diff --git a/services/app/apps/codebattle/test/codebattle/utils/populate_clans_test.exs b/services/app/apps/codebattle/test/codebattle/utils/populate_clans_test.exs new file mode 100644 index 000000000..43789a830 --- /dev/null +++ b/services/app/apps/codebattle/test/codebattle/utils/populate_clans_test.exs @@ -0,0 +1,18 @@ +defmodule Codebattle.Utils.PopulateClansTest do + use Codebattle.DataCase, async: true + + test "from_csv" do + csv = """ + long,short + "the first clan",first_clan + secondclan,clan2 + """ + + {fd, path} = Temp.open!() + IO.write(fd, csv) + File.close(fd) + + assert :ok = Codebattle.Utils.PopulateClans.from_csv!(path) + assert %{long_name: "the first clan"} = Codebattle.Clan.get_by_name!("first_clan") + end +end