Skip to content

Commit 91fac05

Browse files
committed
feat: release 1.1.7
add ash resource generation
1 parent 00297e1 commit 91fac05

5 files changed

Lines changed: 115 additions & 17 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
[![Last Updated](https://img.shields.io/github/last-commit/mithereal/ex_dbmigrate.svg)](https://github.com/mithereal/ex_dbmigrate/commits/master)
66
[![Build Status](https://circleci.com/gh/mithereal/ex_dbmigrate.svg?style=svg)](https://github.com/mithereal/ex_dbmigrate)
77

8-
**Generate phoenix schemas, html, json and live from existing database**
8+
**Generate ash resources, phoenix schemas, html, json and live from existing database**
99

1010
## Installation
1111

@@ -51,6 +51,7 @@ mix ExDbmigrate.Gen.Schema
5151
mix ExDbmigrate.Gen.Html
5252
mix ExDbmigrate.Gen.Json
5353
mix ExDbmigrate.Gen.Live
54+
mix ExDbmigrate.Gen.Resource
5455
```
5556

5657
## Usage Inside iex: (/priv/json.txt will be created)

lib/ex_dbmigrate.ex

Lines changed: 86 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,36 @@ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='#{table}';
188188
end
189189
end
190190

191+
@doc """
192+
Generate ash resource from schema.
193+
194+
## Examples
195+
196+
iex> ExDbmigrate.resource()
197+
["mix ash.gen.resource Helpdesk.Support.Ticket \
198+
--default-actions read \
199+
--uuid-primary-key id \
200+
--attribute subject:string:required:public \
201+
--relationship belongs_to:representative:Helpdesk.Support.Representative \
202+
--timestamps \
203+
--extend postgres"]
204+
205+
"""
206+
def resource(schema \\ "public", mode \\ :read, filename \\ "db_migrate") do
207+
results = fetch_results(schema)
208+
209+
map =
210+
Enum.map(results.rows, fn [r] ->
211+
application_table_data(r)
212+
|> generate_resources_command(r)
213+
end)
214+
215+
case mode do
216+
:read -> map
217+
:write -> map |> write_file(filename)
218+
end
219+
end
220+
191221
@doc """
192222
Generate schema from config.
193223
@@ -229,6 +259,10 @@ WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='#{table}';
229259
Ecto.Adapters.SQL.query!(@repo, query, [])
230260
end
231261

262+
def application_table_data(name) do
263+
ExDbmigrate.Table.Server.show(name)
264+
end
265+
232266
def fetch_table_data(r, schema \\ "public") do
233267
query =
234268
"SELECT column_name, is_nullable, data_type, ordinal_position, character_maximum_length FROM information_schema.columns
@@ -252,6 +286,24 @@ WHERE table_schema = '#{schema}'
252286
"mix phx.gen.json #{module} #{module_name} #{table} #{migration_string}"
253287
end
254288

289+
def generate_resources_command(data, table_name, extends \\ "postgres") do
290+
name = migration_module(table_name) |> singularize()
291+
292+
attributes =
293+
build_attributes(data) |> Enum.map(fn x -> "--attribute #{x}" end) |> Enum.join(" ")
294+
295+
relationships =
296+
build_relationships(data) |> Enum.map(fn x -> "--relationship #{x}" end) |> Enum.join(" ")
297+
298+
"mix ash.gen.resource #{name} \
299+
--default-actions read \
300+
--uuid-primary-key id \
301+
#{attributes} \
302+
#{relationships} \
303+
--timestamps \
304+
--extend #{extends}"
305+
end
306+
255307
def generate_lives_command(data, [migration_name]) do
256308
migration_string = migration_string(data)
257309

@@ -275,14 +327,34 @@ WHERE table_schema = '#{schema}'
275327

276328
def migration_string(data) do
277329
data.rows
330+
|> build_attributes()
331+
|> Enum.join(" ")
332+
|> String.trim()
333+
end
334+
335+
def build_relationships(data) do
336+
data.links
337+
|> Enum.map(fn %{
338+
column_name: column_name,
339+
references: %{
340+
ref_table: foreign_table_name,
341+
ref_column: foreign_column_name,
342+
type: type
343+
}
344+
} ->
345+
relation_module_name = migration_module(foreign_table_name) |> singularize()
346+
"#{type}:#{foreign_table_name}:#{relation_module_name}"
347+
end)
348+
end
349+
350+
def build_attributes(data) do
351+
data
278352
|> Enum.map(fn [id, _is_null, type, _position, _max_length] ->
279353
unless id == "id" || id == "inserted_at" || id == "updated_at" do
280354
type = type_select(type)
281355
"#{id}:#{type}"
282356
end
283357
end)
284-
|> Enum.join(" ")
285-
|> String.trim()
286358
end
287359

288360
def table_name(migration_name) do
@@ -402,17 +474,18 @@ WHERE table_schema = '#{schema}'
402474
target = String.split(file, "/")
403475

404476
if is_list(target) do
405-
target = case Enum.count(target) do
406-
1 ->
407-
Path.join(File.cwd!(), "/priv/#{file}")
408-
409-
0 ->
410-
Path.join(File.cwd!(), "/priv/db_migrate.txt")
411-
412-
_ ->
413-
filename = "#{timestamp()}_#{List.last(target)}"
414-
Path.join(File.cwd!(), "/priv/#{filename}")
415-
end
477+
target =
478+
case Enum.count(target) do
479+
1 ->
480+
Path.join(File.cwd!(), "/priv/#{file}")
481+
482+
0 ->
483+
Path.join(File.cwd!(), "/priv/db_migrate.txt")
484+
485+
_ ->
486+
filename = "#{timestamp()}_#{List.last(target)}"
487+
Path.join(File.cwd!(), "/priv/#{filename}")
488+
end
416489

417490
data = Enum.join(data, "\n")
418491
target |> File.write(data)

lib/migration.exs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,11 @@ defmodule ExDbmigrate.Util.Migration do
1919
end
2020
end
2121
end
22+
23+
# mix ash.gen.resource Helpdesk.Support.Ticket \
24+
# --default-actions read \
25+
# --uuid-primary-key id \
26+
# --attribute subject:string:required:public \
27+
# --relationship belongs_to:representative:Helpdesk.Support.Representative \
28+
# --timestamps \
29+
# --extend postgres,graphql

lib/mix/tasks/resource.ex

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
defmodule Mix.Tasks.ExDbmigrate.Gen.Resource do
2+
use Mix.Task
3+
4+
@moduledoc """
5+
After configuring your default ecto repo in `:ecto_repos`
6+
Run mix ExDbmigrate.resource to generates an ash resource.
7+
"""
8+
9+
def run(_args) do
10+
{:ok, _} = Application.ensure_all_started(:ex_dbmigrate)
11+
Mix.shell().info("ExDbmigrate v#{Application.spec(:ex_dbmigrate, :vsn)}")
12+
13+
ExDbmigrate.resource()
14+
|> Enum.join(", ")
15+
end
16+
end

mix.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule ExDbmigrate.MixProject do
22
use Mix.Project
3-
@version "1.1.6"
3+
@version "1.1.7"
44
@source_url "https://github.com/mithereal/ExDbmigrate"
55

66
def project do
@@ -17,7 +17,7 @@ defmodule ExDbmigrate.MixProject do
1717
name: "ex_dbmigrate",
1818
source_url: @source_url,
1919
test_coverage: [tool: ExCoveralls],
20-
preferred_cli_env: [
20+
cli: [
2121
coveralls: :test,
2222
"coveralls.detail": :test,
2323
"coveralls.post": :test,
@@ -30,7 +30,7 @@ defmodule ExDbmigrate.MixProject do
3030
# Run "mix help compile.app" to learn about applications.
3131
def application do
3232
[
33-
extra_applications: [:logger],
33+
extra_applications: [:logger, :observer, :debugger, :runtime_tools, :wx],
3434
mod: {ExDbmigrate.Application, []}
3535
]
3636
end

0 commit comments

Comments
 (0)