Skip to content

Commit 2ddc538

Browse files
committed
improvement: dynamically select and allow setting a repo
1 parent cba3966 commit 2ddc538

File tree

3 files changed

+99
-15
lines changed

3 files changed

+99
-15
lines changed

lib/data_layer.ex

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2685,9 +2685,10 @@ defmodule AshPostgres.DataLayer do
26852685
@impl true
26862686
def update(resource, changeset) do
26872687
source = resolve_source(resource, changeset)
2688+
26882689
modifying =
2689-
Map.keys(changeset.attributes) ++
2690-
Keyword.keys(changeset.atomics) ++ Ash.Resource.Info.primary_key(resource)
2690+
Map.keys(changeset.attributes) ++
2691+
Keyword.keys(changeset.atomics) ++ Ash.Resource.Info.primary_key(resource)
26912692

26922693
query =
26932694
from(row in source, as: ^0)
@@ -2945,15 +2946,24 @@ defmodule AshPostgres.DataLayer do
29452946
end
29462947
end
29472948

2948-
def install(igniter, module, Ash.Resource, _path, _argv) do
2949+
def install(igniter, module, Ash.Resource, _path, argv) do
29492950
table_name =
29502951
module
29512952
|> Module.split()
29522953
|> List.last()
29532954
|> Macro.underscore()
29542955
|> Inflex.pluralize()
29552956

2956-
repo = Igniter.Code.Module.module_name("Repo")
2957+
{options, _, _} = OptionParser.parse(argv, switches: [repo: :string])
2958+
2959+
repo =
2960+
case options[:repo] do
2961+
nil ->
2962+
Igniter.Code.Module.module_name("Repo")
2963+
2964+
repo ->
2965+
Igniter.Code.Module.parse(repo)
2966+
end
29572967

29582968
igniter
29592969
|> Spark.Igniter.set_option(module, [:postgres, :table], table_name)

lib/igniter.ex

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
defmodule AshPostgres.Igniter do
2+
@moduledoc "Codemods and utilities for working with AshPostgres & Igniter"
3+
4+
@doc false
5+
def default_repo_contents(otp_app) do
6+
"""
7+
use AshPostgres.Repo, otp_app: #{inspect(otp_app)}
8+
9+
def installed_extensions do
10+
# Add extensions here, and the migration generator will install them.
11+
["ash-functions"]
12+
end
13+
"""
14+
end
15+
16+
def add_postgres_extension(igniter, repo_name, extension) do
17+
Igniter.Code.Module.find_and_update_module!(igniter, repo_name, fn zipper ->
18+
case Igniter.Code.Function.move_to_def(zipper, :installed_extensions, 0) do
19+
{:ok, zipper} ->
20+
case Igniter.Code.List.append_new_to_list(zipper, extension) do
21+
{:ok, zipper} ->
22+
{:ok, zipper}
23+
24+
_ ->
25+
{:warning,
26+
"Could not add installed extension #{inspect(extension)} to #{inspect(repo_name)}.installed_extensions/0"}
27+
end
28+
29+
_ ->
30+
zipper = Sourceror.Zipper.rightmost(zipper)
31+
32+
code = """
33+
def installed_extensions do
34+
[#{inspect(extension)}]
35+
end
36+
"""
37+
38+
{:ok, Igniter.Code.Common.add_code(zipper, code)}
39+
end
40+
end)
41+
end
42+
43+
def select_repo(igniter, opts \\ []) do
44+
label = Keyword.get(opts, :label, "Which repo should be used?")
45+
generate = Keyword.get(opts, :generate?, false)
46+
47+
case list_repos(igniter) do
48+
{igniter, []} ->
49+
if generate do
50+
repo = Igniter.Code.Module.module_name("Repo")
51+
otp_app = Igniter.Project.Application.app_name()
52+
53+
igniter =
54+
Igniter.Code.Module.create_module(igniter, repo, default_repo_contents(otp_app))
55+
56+
{igniter, repo}
57+
else
58+
{igniter, nil}
59+
end
60+
61+
{igniter, [repo]} ->
62+
{igniter, repo}
63+
64+
{igniter, repos} ->
65+
{igniter, Owl.IO.select(repos, label: label, render_as: &inspect/1)}
66+
end
67+
end
68+
69+
def list_repos(igniter) do
70+
Igniter.Code.Module.find_all_matching_modules(igniter, fn _mod, zipper ->
71+
move_to_repo_use(zipper) != :error
72+
end)
73+
end
74+
75+
defp move_to_repo_use(zipper) do
76+
Igniter.Code.Function.move_to_function_call(zipper, :use, 2, fn zipper ->
77+
Igniter.Code.Function.argument_equals?(
78+
zipper,
79+
0,
80+
AshPostgres.Repo
81+
)
82+
end)
83+
end
84+
end

lib/mix/tasks/ash_postgres.install.ex

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -250,20 +250,10 @@ defmodule Mix.Tasks.AshPostgres.Install do
250250
end
251251

252252
defp setup_repo_module(igniter, otp_app, repo) do
253-
default_repo_contents =
254-
"""
255-
use AshPostgres.Repo, otp_app: #{inspect(otp_app)}
256-
257-
def installed_extensions do
258-
# Add extensions here, and the migration generator will install them.
259-
["ash-functions"]
260-
end
261-
"""
262-
263253
Igniter.Code.Module.find_and_update_or_create_module(
264254
igniter,
265255
repo,
266-
default_repo_contents,
256+
AshPostgres.Igniter.default_repo_contents(otp_app),
267257
fn zipper ->
268258
zipper
269259
|> set_otp_app(otp_app)

0 commit comments

Comments
 (0)