Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 8 additions & 65 deletions lib/ash/domain/info/diagram.ex
Original file line number Diff line number Diff line change
Expand Up @@ -106,70 +106,14 @@ defmodule Ash.Domain.Info.Diagram do
relationships is far too noisy.
"""

def mermaid_er_diagram(domain, opts \\ @default_opts)

def mermaid_er_diagram(domains, opts) when is_list(domains) do
indent = opts[:indent] || @indent
show_private? = Access.get(opts, :show_private?, @show_private?)

resources =
for domain <- domains do
for resource <- Ash.Domain.Info.resources(domain) do
{attrs, calcs, aggs} =
if show_private? do
{
Ash.Resource.Info.attributes(resource),
Ash.Resource.Info.calculations(resource),
Ash.Resource.Info.aggregates(resource)
}
else
{
Ash.Resource.Info.public_attributes(resource),
Ash.Resource.Info.public_calculations(resource),
Ash.Resource.Info.public_aggregates(resource)
}
end

contents =
[
join_template(attrs, indent, &"#{short_type(&1.type, opts)} #{&1.name}"),
join_template(calcs, indent, &"#{short_type(&1.type, opts)} #{&1.name}"),
join_template(aggs, indent, &"#{aggregate_type(resource, &1, opts)} #{&1.name}")
]
|> Enum.reject(&(&1 == ""))
|> Enum.join("\n")

"""
#{indent}#{resource_name(resource, opts)} {
#{indent}#{indent}Domain: #{domain_name(domain, opts)}#{source_link(resource, indent, opts)}
#{contents}
#{indent}}
"""
end
|> Enum.join()
end

relationships =
for domain <- domains,
{src, dest} <- normalise_relationships(domain) do
~s(#{indent}#{resource_name(src, opts)} #{rel_type()} #{resource_name(dest, opts)} : "")
end
|> Enum.join("\n")

domains =
Enum.map_join(domains, "\n", fn domain ->
~s(#{indent}#{domain_name(domain, opts)})
end)

def mermaid_er_diagram(domains, opts \\ @default_opts) do
"""
erDiagram
#{domains}
#{resources}
#{relationships}
#{domains |> List.wrap() |> Enum.map(&mermaid_er_domain_section(&1, opts))}\
"""
end

def mermaid_er_diagram(domain, opts) do
defp mermaid_er_domain_section(domain, opts) do
indent = opts[:indent] || @indent
show_private? = Access.get(opts, :show_private?, @show_private?)

Expand All @@ -192,15 +136,15 @@ defmodule Ash.Domain.Info.Diagram do

contents =
[
join_template(attrs, indent, &"#{short_type(&1.type, opts)} #{&1.name}"),
join_template(calcs, indent, &"#{short_type(&1.type, opts)} #{&1.name}"),
join_template(aggs, indent, &"#{aggregate_type(resource, &1, opts)} #{&1.name}")
join_template(attrs, indent, &"#{short_type(&1.type, [])} #{&1.name}"),
join_template(calcs, indent, &"#{short_type(&1.type, [])} #{&1.name}"),
join_template(aggs, indent, &"#{aggregate_type(resource, &1, [])} #{&1.name}")
]
|> Enum.reject(&(&1 == ""))
|> Enum.join("\n")

"""
#{indent}#{resource_name(resource, opts)} {
#{indent}#{inspect(resource_name(resource, opts))} {
#{contents}
#{indent}}
"""
Expand All @@ -209,12 +153,11 @@ defmodule Ash.Domain.Info.Diagram do

relationships =
for {src, dest} <- normalise_relationships(domain) do
~s(#{indent}#{resource_name(src, opts)} #{rel_type()} #{resource_name(dest, opts)} : "")
~s(#{indent}#{inspect(resource_name(src, opts))} #{rel_type()} #{inspect(resource_name(dest, opts))} : "")
end
|> Enum.join("\n")

"""
erDiagram
#{resources}
#{relationships}
"""
Expand Down
31 changes: 25 additions & 6 deletions test/domain/diagram_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ defmodule Ash.Test.Domain.Info.DiagramTest do
test "generate a mermaid entity relationship diagram from a domain" do
assert Ash.Domain.Info.Diagram.mermaid_er_diagram(Ash.Test.Flow.Domain) == """
erDiagram
User {
"User" {
UUID id
String first_name
String last_name
String email
}
Org {
"Org" {
UUID id
String name
}

Org ||--|| User : ""
"Org" ||--|| "User" : ""
"""
end

Expand Down Expand Up @@ -57,20 +57,39 @@ defmodule Ash.Test.Domain.Info.DiagramTest do
assert Ash.Domain.Info.Diagram.mermaid_er_diagram(Ash.Test.Flow.Domain, show_private?: true) ==
"""
erDiagram
User {
"User" {
UUID id
String first_name
String last_name
String email
Boolean approved
UUID org_id
}
Org {
"Org" {
UUID id
String name
}

Org ||--|| User : ""
"Org" ||--|| "User" : ""
"""
end

test "include long names in mermaid entity relationship diagram if specified" do
assert Ash.Domain.Info.Diagram.mermaid_er_diagram([Ash.Test.Flow.Domain], name: :full) ==
"""
erDiagram
"Ash.Test.Flow.User" {
UUID id
String first_name
String last_name
String email
}
"Ash.Test.Flow.Org" {
UUID id
String name
}

"Ash.Test.Flow.Org" ||--|| "Ash.Test.Flow.User" : ""
"""
end

Expand Down
6 changes: 3 additions & 3 deletions test/domain/livebook_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ defmodule Ash.Test.Domain.Info.LivebookTest do

```mermaid
erDiagram
User {
"User" {
UUID id
String first_name
String last_name
String email
}
Org {
"Org" {
UUID id
String name
}

Org ||--|| User : ""
"Org" ||--|| "User" : ""
```

### Resources
Expand Down
Loading