summaryrefslogtreecommitdiff
path: root/lib/silmataivas/release.ex
blob: 4fc9e93a971b21a74bea646caff6e1a03813a5ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
defmodule Silmataivas.Release do
  @moduledoc """
  Release tasks for Silmataivas application.

  This module provides functions to run Ecto migrations in a 
  compiled release, supporting both SQLite and PostgreSQL backends.
  """

  @app :silmataivas

  @doc """
  Creates a new user with optional user ID and role.

  ## Parameters
    * `user_id` - An optional user ID to use. If not provided, a UUID will be generated.
    * `role` - An optional role, must be either "user" or "admin". Defaults to "user".

  ## Examples
      Silmataivas.Release.new_user()
      Silmataivas.Release.new_user("custom_user_id")
      Silmataivas.Release.new_user("custom_user_id", "admin")
  """
  def new_user(user_id \\ nil, role \\ "user") do
    # Create the new user
    load_app()
    start_repos()

    # Validate role
    unless role in ["user", "admin"] do
      IO.puts("\n❌ Invalid role: #{role}. Role must be either \"user\" or \"admin\".")
      exit({:shutdown, 1})
    end

    user_id = user_id || Ecto.UUID.generate()
    user_params = %{user_id: user_id, role: role}

    case Silmataivas.Users.create_user(user_params) do
      {:ok, user} ->
        IO.puts("\n✅ User created successfully!")
        IO.puts("   User ID (API token): #{user.user_id}")
        IO.puts("   Role: #{user.role}")

      {:error, changeset} ->
        IO.puts("\n❌ Failed to create user:")
        IO.inspect(changeset.errors)
    end
  end

  def migrate do
    load_app()

    for repo <- repos() do
      {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
    end
  end

  def rollback(repo, version) do
    load_app()

    {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
  end

  def create_db do
    load_app()

    for repo <- repos() do
      # Create the database if it doesn't exist
      adapter = get_repo_adapter(repo)

      case adapter.storage_up(repo.config()) do
        :ok ->
          IO.puts("Database for #{inspect(repo)} created successfully")

        {:error, :already_up} ->
          IO.puts("Database for #{inspect(repo)} already exists")

        {:error, reason} ->
          IO.warn("Database for #{inspect(repo)} failed to create: #{inspect(reason)}")
      end
    end
  end

  def setup do
    # Create the database and then run migrations
    create_db()
    migrate()
  end

  def db_info do
    load_app()

    for repo <- repos() do
      adapter = get_repo_adapter(repo)
      config = repo.config()

      IO.puts("Repository: #{inspect(repo)}")
      IO.puts("Adapter: #{inspect(adapter)}")

      case adapter do
        Ecto.Adapters.SQLite3 ->
          db_path = config[:database] || "default.db"
          IO.puts("Database path: #{db_path}")

        Ecto.Adapters.Postgres ->
          hostname = config[:hostname] || "localhost"
          database = config[:database] || "default"
          IO.puts("Host: #{hostname}, Database: #{database}")

        _ ->
          IO.puts("Config: #{inspect(config)}")
      end

      IO.puts("---")
    end
  end

  defp get_repo_adapter(repo) do
    repo.config()[:adapter]
  end

  defp start_repos do
    {:ok, _} = Application.ensure_all_started(:ecto_sql)

    for repo <- repos() do
      {:ok, _} = repo.start_link(pool_size: 2)
    end
  end

  defp repos do
    Application.fetch_env!(@app, :ecto_repos)
  end

  defp load_app do
    Application.load(@app)
  end
end