Skip to content
Open
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: 6 additions & 4 deletions .github/workflows/fat_ecto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

services:
postgres:
image: postgres:16
image: postgres:17
ports:
- "5432:5432"
env:
Expand All @@ -34,13 +34,15 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
elixir-version: 1.18.2
otp-version: 27.2
# Single source of truth — keep CI in lockstep with .tool-versions
# (elixir 1.20.1 / erlang 29.0.2).
version-file: .tool-versions
version-type: strict

- name: Install dependencies
run: |
Expand Down
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
elixir 1.18.1
erlang 27.2
elixir 1.20.1
erlang 29.0.2
1 change: 0 additions & 1 deletion lib/fat_ecto/pagination/helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ defmodule FatEcto.Pagination.Helper do
"""

alias FatEcto.SharedHelper
require Ecto.Query

@min_limit 0
@min_skip 0
Expand Down
40 changes: 26 additions & 14 deletions lib/fat_ecto/sort/sortable.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,29 @@ defmodule FatEcto.Sort.Sortable do

defmacro __using__(options \\ []) do
sortable = options[:sortable] || []
overrideable = options[:overrideable] || []

# Only emit the override-callback processing when overrideable fields are
# configured. With `overrideable: []`, `override_sortable/2` is just the
# default clause (returns nil), so Elixir 1.18+'s type checker proves the
# `order when not is_nil(order)` guard is unreachable and warns
# "this clause will never match". Skipping the block when there is nothing
# to override removes the dead code (and the warning) entirely.
override_orders_ast =
if overrideable == [] do
quote do: []
else
quote do
sort_params
|> Map.take(@overrideable_fields)
|> Enum.flat_map(fn {field, operator} ->
case override_sortable(field, operator) do
order when not is_nil(order) -> [order]
_ -> []
end
end)
end
end

{_direct_sortable, join_sorts} = FatEcto.SharedHelper.separate_filterables(sortable)
sort_join_filters_map = FatEcto.SharedHelper.build_join_filters_map(join_sorts)
Expand Down Expand Up @@ -83,23 +106,12 @@ defmodule FatEcto.Sort.Sortable do
"""
@spec build(map()) :: [Sorter.order_expr()]
def build(sort_params) when is_map(sort_params) do
# Filter standard sortable fields first
standard_params = Helper.filter_sortable_fields(sort_params, @sortable_fields)

# Filter overrideable fields (only those explicitly listed)
override_params = Map.take(sort_params, @overrideable_fields)

# Process standard fields (with alias resolution and join binding support)
standard_params = Helper.filter_sortable_fields(sort_params, @sortable_fields)
standard_orders = Sorter.build_order_by(standard_params, @sort_aliases, @sort_join_filters_map)

# Process override fields with callback
override_orders =
Enum.flat_map(override_params, fn {field, operator} ->
case override_sortable(field, operator) do
order when not is_nil(order) -> [order]
_ -> []
end
end)
# Process override fields with callback (only when overrideable fields exist)
override_orders = unquote(override_orders_ast)

standard_orders ++ override_orders
end
Expand Down
32 changes: 19 additions & 13 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule FatEcto.MixProject do
def project do
[
app: :fat_ecto,
version: "1.4.0",
version: "1.4.1",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
build_embedded: Mix.env() == :prod,
Expand All @@ -23,13 +23,6 @@ defmodule FatEcto.MixProject do
],
source_url: "https://github.com/tanweerdev/fat_ecto",
test_coverage: [tool: ExCoveralls],
preferred_cli_env: [
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.github": :test
],
coveralls: [
minimum_coverage: 60
],
Expand All @@ -39,6 +32,19 @@ defmodule FatEcto.MixProject do
]
end

# CLI task environments (Elixir 1.19+: moved out of `project/0`).
def cli do
[
preferred_envs: [
coveralls: :test,
"coveralls.detail": :test,
"coveralls.post": :test,
"coveralls.html": :test,
"coveralls.github": :test
]
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
Expand All @@ -53,11 +59,11 @@ defmodule FatEcto.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:ecto, "~> 3.2 or ~> 3.5 or ~> 3.8 or ~> 3.10 or ~> 3.12"},
{:ecto_sql, "~> 3.2 or ~> 3.5 or ~> 3.8 or ~> 3.10 or ~> 3.12"},
{:postgrex, "~> 0.15 or ~> 0.16 or ~> 0.17 or ~> 0.19 or ~> 0.20"},
{:earmark, "~> 1.4", only: [:dev, :test], optional: true},
{:ex_doc, "~> 0.19 or ~> 0.28 or ~> 0.30 or ~> 0.31 or ~> 0.32 or ~> 0.36 or ~> 0.37",
{:ecto, "~> 3.2 or ~> 3.5 or ~> 3.8 or ~> 3.10 or ~> 3.12 or ~> 3.14"},
{:ecto_sql, "~> 3.2 or ~> 3.5 or ~> 3.8 or ~> 3.10 or ~> 3.12 or ~> 3.14"},
{:postgrex, "~> 0.15 or ~> 0.16 or ~> 0.17 or ~> 0.19 or ~> 0.20 or ~> 0.21 or ~> 0.22 "},
{:ex_doc,
"~> 0.19 or ~> 0.28 or ~> 0.30 or ~> 0.31 or ~> 0.32 or ~> 0.36 or ~> 0.37 or ~> 0.38 or ~> 0.39 or ~> 0.40",
only: [:dev, :test], runtime: false, optional: true},
{:ex_machina, "~> 2.3 or ~> 2.7 or ~> 2.8", only: [:dev, :test], optional: true},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false, optional: true},
Expand Down
Loading