Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use after_verify callback and reduce compile-time work #4552

Merged
merged 6 commits into from
Nov 28, 2024
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
10 changes: 5 additions & 5 deletions examples/friends/mix.lock
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
%{
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"},
"decimal": {:hex, :decimal, "2.2.0", "df3d06bb9517e302b1bd265c1e7f16cda51547ad9d99892049340841f3e15836", [:mix], [], "hexpm", "af8daf87384b51b7e611fb1a1f2c4d4876b65ef968fa8bd3adf44cff401c7f21"},
"ecto": {:hex, :ecto, "2.0.1", "cf97a4d353e14af3d3cc3b4452cfbd18b3aeee1fb4075475efeccec3853444a9", [:mix], [{:poison, "~> 1.5 or ~> 2.0", [hex: :poison, optional: true]}, {:sbroker, "~> 1.0-beta", [hex: :sbroker, optional: true]}, {:mariaex, "~> 0.7.7", [hex: :mariaex, optional: true]}, {:postgrex, "~> 0.11.2", [hex: :postgrex, optional: true]}, {:db_connection, "~> 1.0-rc.2", [hex: :db_connection, optional: true]}, {:decimal, "~> 1.0", [hex: :decimal, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: false]}]},
"ecto_sql": {:hex, :ecto_sql, "3.11.3", "4eb7348ff8101fbc4e6bbc5a4404a24fecbe73a3372d16569526b0cf34ebc195", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e5f36e3d736b99c7fee3e631333b8394ade4bafe9d96d35669fca2d81c2be928"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
"poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"},
"poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [], [], "hexpm"},
"postgrex": {:hex, :postgrex, "0.18.0", "f34664101eaca11ff24481ed4c378492fed2ff416cd9b06c399e90f321867d7e", [: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", "a042989ba1bc1cca7383ebb9e461398e3f89f868c92ce6671feb7ef132a252d1"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"postgrex": {:hex, :postgrex, "0.19.3", "a0bda6e3bc75ec07fca5b0a89bffd242ca209a4822a9533e7d3e84ee80707e19", [: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", "d31c28053655b78f47f948c85bb1cf86a9c1f8ead346ba1aa0d0df017fa05b61"},
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
}
48 changes: 13 additions & 35 deletions lib/ecto/association.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,6 @@ defmodule Ecto.Association do

alias Ecto.Query.Builder.OrderBy

@doc """
Helper to check if a queryable is compiled.
"""
def ensure_compiled(queryable, env) do
if not is_atom(queryable) or queryable in env.context_modules do
:skip
else
case Code.ensure_compiled(queryable) do
{:module, _} -> :compiled
{:error, :unavailable} -> :skip
{:error, _} -> :not_found
end
end
end

@doc """
Builds the association struct.

Expand Down Expand Up @@ -87,7 +72,7 @@ defmodule Ecto.Association do
Useful for checking if associated modules exist without running
into deadlocks.
"""
@callback after_compile_validation(t, Macro.Env.t()) :: :ok | {:error, String.t()}
@callback after_verify_validation(t) :: :ok | {:error, String.t()}

@doc """
Builds a struct for the given association.
Expand Down Expand Up @@ -771,14 +756,12 @@ defmodule Ecto.Association.Has do
]

@impl true
def after_compile_validation(%{queryable: queryable, related_key: related_key}, env) do
compiled = Ecto.Association.ensure_compiled(queryable, env)

def after_verify_validation(%{queryable: queryable, related_key: related_key}) do
cond do
compiled == :skip ->
not is_atom(queryable) ->
:ok

compiled == :not_found ->
not Code.ensure_loaded?(queryable) ->
{:error, "associated schema #{inspect(queryable)} does not exist"}

not function_exported?(queryable, :__schema__, 2) ->
Expand Down Expand Up @@ -1040,7 +1023,7 @@ defmodule Ecto.Association.HasThrough do
]

@impl true
def after_compile_validation(_, _) do
def after_verify_validation(_) do
:ok
end

Expand Down Expand Up @@ -1143,14 +1126,12 @@ defmodule Ecto.Association.BelongsTo do
]

@impl true
def after_compile_validation(%{queryable: queryable, related_key: related_key}, env) do
compiled = Ecto.Association.ensure_compiled(queryable, env)

def after_verify_validation(%{queryable: queryable, related_key: related_key}) do
cond do
compiled == :skip ->
not is_atom(queryable) ->
:ok

compiled == :not_found ->
not Code.ensure_loaded?(queryable) ->
{:error, "associated schema #{inspect(queryable)} does not exist"}

not function_exported?(queryable, :__schema__, 2) ->
Expand Down Expand Up @@ -1346,24 +1327,21 @@ defmodule Ecto.Association.ManyToMany do
]

@impl true
def after_compile_validation(%{queryable: queryable, join_through: join_through}, env) do
compiled = Ecto.Association.ensure_compiled(queryable, env)
join_compiled = Ecto.Association.ensure_compiled(join_through, env)

def after_verify_validation(%{queryable: queryable, join_through: join_through}) do
cond do
compiled == :skip ->
not is_atom(queryable) ->
:ok

compiled == :not_found ->
not Code.ensure_loaded?(queryable) ->
{:error, "associated schema #{inspect(queryable)} does not exist"}

not function_exported?(queryable, :__schema__, 2) ->
{:error, "associated module #{inspect(queryable)} is not an Ecto schema"}

join_compiled == :skip ->
not is_atom(join_through) ->
:ok

join_compiled == :not_found ->
not Code.ensure_loaded?(join_through) ->
{:error, ":join_through schema #{inspect(join_through)} does not exist"}

not function_exported?(join_through, :__schema__, 2) ->
Expand Down
Loading
Loading