From d26a1899467b99fc678072c10221b987e85802ea Mon Sep 17 00:00:00 2001 From: Zach Daniel Date: Mon, 22 Apr 2024 12:04:16 -0400 Subject: [PATCH] improvement: warn on missing ash-functions at compile time closes #242 --- lib/data_layer.ex | 11 +++++++++-- lib/repo.ex | 42 ++++++++++++++++++++++++++++++++++++++++++ mix.lock | 2 +- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/lib/data_layer.ex b/lib/data_layer.ex index c436791..2a886ec 100644 --- a/lib/data_layer.ex +++ b/lib/data_layer.ex @@ -571,8 +571,15 @@ defmodule AshPostgres.DataLayer do def can?(_, :transact), do: true def can?(_, :composite_primary_key), do: true - def can?(_, {:atomic, :update}), do: true - def can?(_, {:atomic, :upsert}), do: true + + def can?(resource, {:atomic, :update}) do + "ash-functions" in AshPostgres.DataLayer.Info.repo(resource, :mutate).installed_extensions() + end + + def can?(resource, {:atomic, :upsert}) do + "ash-functions" in AshPostgres.DataLayer.Info.repo(resource, :mutate).installed_extensions() + end + def can?(_, :upsert), do: true def can?(_, :changeset_filter), do: true diff --git a/lib/repo.ex b/lib/repo.ex index c2bd183..30bfbb7 100644 --- a/lib/repo.ex +++ b/lib/repo.ex @@ -88,6 +88,9 @@ defmodule AshPostgres.Repo do @agent __MODULE__.AshPgVersion @behaviour AshPostgres.Repo + @warn_on_missing_ash_functions Keyword.get(opts, :warn_on_missing_ash_functions?, true) + @after_compile __MODULE__ + require Logger defoverridable insert: 2, insert: 1, insert!: 2, insert!: 1 @@ -340,6 +343,45 @@ defmodule AshPostgres.Repo do override_migration_type: 1, create?: 0, drop?: 0 + + def __after_compile__(_, _) do + if "ash-functions" in installed_extensions() || !@warn_on_missing_ash_functions do + :ok + else + IO.warn(""" + AshPostgres: You have not installed the `ash-functions` extension. + + The following features will not be available: + + - atomics (using the `raise_ash_error` function) + - `string_trim` (using the `ash_trim_whitespace` function) + - the `||` and `&&` operators (using the `ash_elixir_and` and `ash_elixir_or` functions) + + To address this warning, do one of two things: + + 1. add the `"ash-functions"` extension to your `installed_extensions/0` function, and then generate migrations. + + def installed_extensions do + ["ash-functions"] + end + + If you are *not* using the migration generator, but would like to leverage these features, follow the above instructions, + and then visit the source for `ash_postgres` and copy the latest version of those functions into your own migrations: + + 2. disable this warning, by adding the following to your `use` statement: + + use AshPostgres.Repo, + .. + warn_on_missing_ash_functions?: false + + Keep in mind that if you disable this warning, you will not be able to use the features mentioned above. + If you are in an environment where you cannot define functions, you will have to use the second option. + + + https://github.com/ash-project/ash_postgres/blob/main/lib/migration_generator/ash_functions.ex + """) + end + end end end end diff --git a/mix.lock b/mix.lock index c63676e..c05e02f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ "ash": {:hex, :ash, "3.0.0-rc.27", "b6ff59bd6a78e566536587bb11986107393b42001972dd22fe6e7f2402061ee7", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [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: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 0.6", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a9c5eea5756947aae8ee0131e13fcdb7c9af3ab563b5eb3a04dec924dd195a57"}, - "ash_sql": {:hex, :ash_sql, "0.1.1-rc.7", "a8c6d570ea36d1f2921c130888a3d3973268e900ca02c2da495075af9dc30cd7", [:mix], [{:ash, "~> 3.0.0-rc", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "8135fe4f3ea8948f4d1bbcaf61d5ebcd350957f4873cb5d2d5f8aeb213929d2b"}, + "ash_sql": {:hex, :ash_sql, "0.1.1-rc.8", "0e2aae33919b0e3afdfa81d0830328582b1c3766b30951f2b78a5ca04fc541da", [:mix], [{:ash, "~> 3.0.0-rc", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "e000e0019a6e765c242ee35280fc155d84f740059059a5a6f8aeb8909eedb85d"}, "benchee": {:hex, :benchee, "1.3.0", "f64e3b64ad3563fa9838146ddefb2d2f94cf5b473bdfd63f5ca4d0657bf96694", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "34f4294068c11b2bd2ebf2c59aac9c7da26ffa0068afdf3419f1b176e16c5f81"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, "comparable": {:hex, :comparable, "1.0.0", "bb669e91cedd14ae9937053e5bcbc3c52bb2f22422611f43b6e38367d94a495f", [:mix], [{:typable, "~> 0.1", [hex: :typable, repo: "hexpm", optional: false]}], "hexpm", "277c11eeb1cd726e7cd41c6c199e7e52fa16ee6830b45ad4cdc62e51f62eb60c"},