Skip to content

Commit c8aa2a8

Browse files
committed
improvement: add value_to_postgres_default/3 and AshPostgres.Type
1 parent d364573 commit c8aa2a8

File tree

8 files changed

+59
-12
lines changed

8 files changed

+59
-12
lines changed

lib/migration.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ defmodule AshPostgres.Migration do
4242
4343
Keep in mind, that if you want to create a custom enum type, you will want to add
4444
```elixir
45-
def storage_type, do: :my_type_name
45+
def storage_type(_), do: :my_type_name
4646
```
4747
"""
48-
def create_enum(type) do
49-
if type.storage_type() == :string do
48+
def create_enum(type, constraints \\ []) do
49+
if type.storage_type(constraints) == :string do
5050
raise "Must customize the storage_type for #{type} in order to create an enum"
5151
end
5252

lib/migration_generator/migration_generator.ex

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,7 +2735,7 @@ defmodule AshPostgres.MigrationGenerator do
27352735
Ash.Type.NewType.constraints(type, constraints)
27362736
)
27372737
else
2738-
migration_type_from_storage_type(Ash.Type.storage_type(other))
2738+
migration_type_from_storage_type(Ash.Type.storage_type(other, constraints))
27392739
end
27402740
end
27412741

@@ -2829,8 +2829,37 @@ defmodule AshPostgres.MigrationGenerator do
28292829
defp default(%{name: name, default: default}, resource, _) when default == %{},
28302830
do: configured_default(resource, name) || "%{}"
28312831

2832-
defp default(%{name: name, default: value}, resource, _),
2833-
do: configured_default(resource, name) || EctoMigrationDefault.to_default(value)
2832+
defp default(%{name: name, default: value, type: type} = attr, resource, _) do
2833+
case configured_default(resource, name) do
2834+
nil ->
2835+
case migration_default(type, Map.get(attr, :constraints, []), value) do
2836+
{:ok, default} ->
2837+
default
2838+
2839+
:error ->
2840+
EctoMigrationDefault.to_default(value)
2841+
end
2842+
2843+
default ->
2844+
default
2845+
end
2846+
end
2847+
2848+
defp migration_default(type, constraints, value) do
2849+
type =
2850+
type
2851+
|> unwrap_type()
2852+
|> Ash.Type.get_type()
2853+
2854+
if function_exported?(type, :value_to_postgres_default, 3) do
2855+
type.value_to_postgres_default(type, constraints, value)
2856+
else
2857+
:error
2858+
end
2859+
end
2860+
2861+
defp unwrap_type({:array, type}), do: unwrap_type(type)
2862+
defp unwrap_type(type), do: type
28342863

28352864
defp configured_default(resource, attribute) do
28362865
AshPostgres.DataLayer.Info.migration_defaults(resource)[attribute]

lib/type.ex

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
defmodule AshPostgres.Type do
2+
@moduledoc """
3+
Postgres specific callbacks for `Ash.Type`.
4+
5+
Use this in addition to `Ash.Type`.
6+
"""
7+
8+
@callback value_to_postgres_default(Ash.Type.t(), Ash.Type.constraints(), term) ::
9+
{:ok, String.t()} | :error
10+
11+
defmacro __using__(_) do
12+
quote do
13+
def value_to_postgres_default(_, _, _), do: :error
14+
15+
defoverridable value_to_postgres_default: 3
16+
end
17+
end
18+
end

lib/types/ci_string_wrapper copy.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule Ash.Type.CiStringWrapper do
33
use Ash.Type
44

55
@impl true
6-
def storage_type, do: :citext
6+
def storage_type(_), do: :citext
77

88
@impl true
99
defdelegate cast_input(value, constraints), to: Ash.Type.CiString

lib/types/ci_string_wrapper.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule Ash.Type.StringWrapper do
33
use Ash.Type
44

55
@impl true
6-
def storage_type, do: :text
6+
def storage_type(_), do: :text
77

88
@impl true
99
defdelegate cast_input(value, constraints), to: Ash.Type.String

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ defmodule AshPostgres.MixProject do
161161
{:ecto, "~> 3.9"},
162162
{:jason, "~> 1.0"},
163163
{:postgrex, ">= 0.0.0"},
164-
{:ash, ash_version("~> 2.13")},
164+
{:ash, ash_version("~> 2.14 and >= 2.14.2")},
165165
{:git_ops, "~> 2.5", only: [:dev, :test]},
166166
{:ex_doc, "~> 0.22", only: [:dev, :test], runtime: false},
167167
{:ex_check, "~> 0.14", only: [:dev, :test]},

mix.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%{
2-
"ash": {:hex, :ash, "2.13.3", "0ab95342148636c97833224b67543a9652b5bb1fe14cf5cd30155da772f0c0fd", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 1.1.20 and < 2.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "42fb2cbaac7e4a98e56adebbf97e641135bef4e73129c1148d42e93cbf59a3a0"},
2+
"ash": {:hex, :ash, "2.14.2", "111829b1db52e43c28c0660b2da8f1bfc76199dd8e15289f86f5998c07fb8d36", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:earmark, "~> 1.4", [hex: :earmark, repo: "hexpm", optional: true]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: false]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:spark, ">= 1.1.20 and < 2.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.5.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e6e5924ccb3f8b0ab5de15b22006a4a18c0f002aadadd7aa9dfa39d53cff0b9a"},
33
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
44
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
55
"comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"},
@@ -34,7 +34,7 @@
3434
"postgrex": {:hex, :postgrex, "0.17.0", "1ea81cb0820079bcedd880379357cfc9faf70bc8fee3a87054b13fcb646c6150", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "ea670562ed62a5ca40aa4689290167a97b0712f59f7e318d6ce9eb253f52e02e"},
3535
"sobelow": {:hex, :sobelow, "0.11.1", "23438964486f8112b41e743bbfd402da3e5b296fdc9eacab29914b79c48916dd", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9897363a7eff96f4809304a90aad819e2ad5e5d24db547af502885146746a53c"},
3636
"sourceror": {:hex, :sourceror, "0.12.3", "a2ad3a1a4554b486d8a113ae7adad5646f938cad99bf8bfcef26dc0c88e8fade", [:mix], [], "hexpm", "4d4e78010ca046524e8194ffc4683422f34a96f6b82901abbb45acc79ace0316"},
37-
"spark": {:hex, :spark, "1.1.21", "8d09983e628d26edf358e7e8c0fa922667a049c4cfea6895d4b0820fc9bc1261", [:mix], [{:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "588dda298d6ea0a1d3f06c7978145ee799281bf8bcb0b418b7dae4b3d0be2e59"},
37+
"spark": {:hex, :spark, "1.1.22", "68ba00f9acb4c8bc2c93ef82249493687ddf0f0a4f7e79c3c0e22b06719add56", [:mix], [{:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:sourceror, "~> 0.1", [hex: :sourceror, repo: "hexpm", optional: false]}], "hexpm", "b798b95990eed8f2409df47b818b5dbcd00e9b5c30d0355465d0b04bbf9b5c4c"},
3838
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
3939
"stream_data": {:hex, :stream_data, "0.5.0", "b27641e58941685c75b353577dc602c9d2c12292dd84babf506c2033cd97893e", [:mix], [], "hexpm", "012bd2eec069ada4db3411f9115ccafa38540a3c78c4c0349f151fc761b9e271"},
4040
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},

test/support/types/point.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule AshPostgres.Test.Point do
22
@moduledoc false
33
use Ash.Type
44

5-
def storage_type, do: {:array, :float}
5+
def storage_type(_), do: {:array, :float}
66

77
def cast_input(nil, _), do: {:ok, nil}
88

0 commit comments

Comments
 (0)