From 18fc2397da655e50e7755e98a3d4d889886fd900 Mon Sep 17 00:00:00 2001 From: Mathias Polligkeit Date: Sun, 16 Jul 2023 19:36:22 +0900 Subject: [PATCH] add get_field function to adapter --- lib/flop/adapter.ex | 2 ++ lib/flop/adapter/ecto.ex | 20 ++++++++++++++++ lib/flop/schema.ex | 49 ++++++++-------------------------------- 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/lib/flop/adapter.ex b/lib/flop/adapter.ex index 9ab4ef5..c8fc14f 100644 --- a/lib/flop/adapter.ex +++ b/lib/flop/adapter.ex @@ -37,4 +37,6 @@ defmodule Flop.Adapter do @callback count(queryable, opts) :: non_neg_integer @callback list(queryable, opts) :: [any] + + @callback get_field(any, atom, Flop.FieldInfo.t()) :: any end diff --git a/lib/flop/adapter/ecto.ex b/lib/flop/adapter/ecto.ex index 48a4fc2..eb3d760 100644 --- a/lib/flop/adapter/ecto.ex +++ b/lib/flop/adapter/ecto.ex @@ -211,6 +211,26 @@ defmodule Flop.Adapter.Ecto do end) end + @impl Flop.Adapter + def get_field(%{} = item, _field, %FieldInfo{ + extra: %{type: :compound, fields: fields} + }) do + Enum.map_join(fields, " ", &get_field(item, &1, %FieldInfo{})) + end + + def get_field(%{} = item, _field, %FieldInfo{ + extra: %{type: :join, path: path} + }) do + Enum.reduce(path, item, fn + field, %{} = acc -> Map.get(acc, field) + _, _ -> nil + end) + end + + def get_field(%{} = item, field, %FieldInfo{}) do + Map.get(item, field) + end + @impl Flop.Adapter def apply_filter( query, diff --git a/lib/flop/schema.ex b/lib/flop/schema.ex index a40be50..6104130 100644 --- a/lib/flop/schema.ex +++ b/lib/flop/schema.ex @@ -895,7 +895,7 @@ defimpl Flop.Schema, for: Any do order_by_func = build_order_by_func(compound_fields, join_fields, alias_fields) - get_field_func = build_get_field_func(compound_fields, join_fields) + get_field_func = build_get_field_func(struct, adapter, adapter_opts) cursor_dynamic_func_compound = build_cursor_dynamic_func_compound(compound_fields) @@ -1354,46 +1354,17 @@ defimpl Flop.Schema, for: Any do end end - def build_get_field_func(compound_fields, join_fields) do - compound_field_funcs = - for {name, fields} <- compound_fields do - quote do - def get_field(struct, unquote(name)) do - Enum.map_join( - unquote(fields), - " ", - &Flop.Schema.get_field(struct, &1) - ) - end - end - end - - join_field_funcs = - for {name, %{path: path}} <- join_fields do - quote do - def get_field(struct, unquote(name)) do - Enum.reduce(unquote(path), struct, fn field, acc -> - case acc do - %{} -> Map.get(acc, field) - _ -> nil - end - end) - - # assoc = Map.get(struct, unquote(assoc_field)) || %{} - # Map.get(assoc, unquote(field)) - end - end - end - - fallback_func = + def build_get_field_func(struct, adapter, adapter_opts) do + for {field, field_info} <- adapter.fields(struct, adapter_opts) do quote do - def get_field(struct, field), do: Map.get(struct, field) + def get_field(struct, unquote(field)) do + unquote(adapter).get_field( + struct, + unquote(field), + unquote(Macro.escape(field_info)) + ) + end end - - quote do - unquote(compound_field_funcs) - unquote(join_field_funcs) - unquote(fallback_func) end end