Files
music_library/priv/repo/seeds.exs
T
Claudio Ortolina 51d18f37bf First pass at seeding database
The task takes the Obsidian record folder as an argument.

It's not idempotent, so it will create duplicates if run multiple times.
2024-09-15 20:28:37 +01:00

58 lines
1.7 KiB
Elixir

# Script for populating the database. You can run it as:
#
# mix run priv/repo/seeds.exs
#
# Inside the script, you can read and write to any of your
# repositories directly:
#
# MusicLibrary.Repo.insert!(%MusicLibrary.SomeSchema{})
#
# We recommend using the bang functions (`insert!`, `update!`
# and so on) as they will fail if something goes wrong.
case System.argv() do
[] ->
IO.puts("Error: requires the path to the obsidian vault record folder")
System.halt(1)
[path] ->
# TODO: validate path
IO.puts("Seeding the database from #{path}")
%{valid: valid, errors: errors} =
Path.wildcard("#{path}/*.md")
|> Enum.reduce(%{valid: [], errors: []}, fn entry, acc ->
file_stat = File.stat!(entry)
case entry
|> File.read!()
|> MusicLibrary.Records.Parser.from_entry_contents() do
{:ok, parsed_entry} ->
inserted_at = file_stat.ctime
|> NaiveDateTime.from_erl!()
|> DateTime.from_naive!("Etc/UTC")
updated_at = file_stat.mtime
|> NaiveDateTime.from_erl!()
|> DateTime.from_naive!("Etc/UTC")
data =
parsed_entry
|> Map.put(:inserted_at, inserted_at)
|> Map.put(:updated_at, updated_at)
%{acc | valid: [data | acc.valid]}
{:error, error} ->
%{acc | errors: [{entry, error} | acc.errors]}
end
end)
IO.puts("Parsed #{length(valid)} entries")
IO.puts("Failed to parse #{length(errors)} entries")
MusicLibrary.Repo.insert_all(MusicLibrary.Records.Record, valid)
_other ->
IO.puts("Error: too many arguments")
System.halt(1)
end