From 98d77847256b8a62b358449dbb0b0e361dd3a855 Mon Sep 17 00:00:00 2001 From: Alan Vardy Date: Tue, 18 Jun 2024 08:45:35 -0700 Subject: [PATCH] Add query modifier --- README.md | 10 ++++++++++ config/test.exs | 2 +- docker-compose.yml | 2 -- lib/exzeitable/database.ex | 21 ++++++++++++++++++++- lib/exzeitable/params.ex | 1 + test/exzeitable/database_test.exs | 3 ++- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d36bca3d..6c1af5c0 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,16 @@ Note that if you are navigating to the live table using [Phoenix LiveView live_s - `pagination: [:top, :bottom]` Whether to show the pagination above and below - `text: Exzeitable.Text.Default` The translation that appears on the table, defaults to English. - `assigns: %{}` Passes additional assigns to socket.assigns. Keep your payload small! +- `query_modifier: {MyModule, :my_function}` Passes the query to MyModule.my_function/2, where query can then be dynamically altered before being returned. Arguments are the query, and the `Exzeitable.Params` struct, which is how Exzeitable stores state. Return value is the query. + +```elixir +defmodule MyApp.MyModule do + def my_function(query, _state) do + # Make your modifications and return the new query + query + end +end +``` ### Field options diff --git a/config/test.exs b/config/test.exs index e6e6b88a..84a0ba4a 100644 --- a/config/test.exs +++ b/config/test.exs @@ -28,7 +28,7 @@ config :exzeitable, Exzeitable.Mailer, adapter: Swoosh.Adapters.Test config :stream_data, max_runs: 100 # Print only warnings and errors during test -config :logger, level: :warn +config :logger, level: :warning # Initialize plugs at runtime for faster test compilation config :phoenix, :plug_init_mode, :runtime diff --git a/docker-compose.yml b/docker-compose.yml index 7a979b77..378c9ec6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ - -version: '3' services: dbserver: image: postgres:14.2 diff --git a/lib/exzeitable/database.ex b/lib/exzeitable/database.ex index 6084bde1..0256466b 100644 --- a/lib/exzeitable/database.ex +++ b/lib/exzeitable/database.ex @@ -1,14 +1,16 @@ defmodule Exzeitable.Database do @moduledoc "Database interactions" import Ecto.Query + alias Exzeitable.Params @doc "Get the data using query" @spec get_records(map) :: [map] - def get_records(%{query: query} = params) do + def get_records(%Params{query: query} = params) do query |> order_query(params) |> search_query(params) |> paginate_query(params) + |> modify_query(params) |> get_query(params) end @@ -50,6 +52,23 @@ defmodule Exzeitable.Database do from(q in query, select: count(q.id)) end + defp modify_query(query, %Params{query_modifier: nil}) do + query + end + + defp modify_query(query, %Params{query_modifier: {mod, fun}} = params) when is_atom(mod) and is_atom(fun) do + apply(mod, fun, [query, params]) + end + + defp modify_query(_query, %Params{query_modifier: invalid}) do + raise """ + Invalid option given for :query_modifier + + Expected: {Module, :function} + Got: #{inspect(invalid)} + """ + end + # Repo.all @spec get_query(Ecto.Query.t(), map) :: [map] defp get_query(query, %{repo: repo}), do: repo.all(query) diff --git a/lib/exzeitable/params.ex b/lib/exzeitable/params.ex index a9e96e01..aec33787 100644 --- a/lib/exzeitable/params.ex +++ b/lib/exzeitable/params.ex @@ -51,6 +51,7 @@ defmodule Exzeitable.Params do :module, :csrf_token, # optional + :query_modifier, :order, :parent, :belongs_to, diff --git a/test/exzeitable/database_test.exs b/test/exzeitable/database_test.exs index dceebfac..dbcf6a9b 100644 --- a/test/exzeitable/database_test.exs +++ b/test/exzeitable/database_test.exs @@ -4,9 +4,10 @@ defmodule Exzeitable.DatabaseTest do alias Exzeitable.Database alias TestWeb.User - @assigns %{ + @assigns %Exzeitable.Params{ query: from(u in User), parent: nil, + csrf_token: "234", routes: TestWeb.Router.Helpers, repo: TestWeb.Repo, path: :user_path,