Packages

A forked ETS adapter for Ecto

Current section

Files

Jump to
logflare_etso lib etso ets objects_sorter.ex
Raw

lib/etso/ets/objects_sorter.ex

defmodule Etso.ETS.ObjectsSorter do
@moduledoc """
The ETS Objects Sorter module is responsible for sorting results returned from ETS according to
the sort predicates provided in the query.
"""
def sort(ets_objects, %Ecto.Query{order_bys: []}) do
ets_objects
end
def sort(ets_objects, %Ecto.Query{} = query) do
sort_predicates = build_sort_predicates(query)
Enum.sort_by(ets_objects, & &1, &compare(&1, &2, sort_predicates))
end
defp build_sort_predicates(%Ecto.Query{} = query) do
Enum.flat_map(query.order_bys, fn %Ecto.Query.QueryExpr{expr: list} ->
Enum.map(list, fn {direction, field} ->
{direction, Enum.find_index(query.select.fields, &(&1 == field))}
end)
end)
end
defp compare(lhs, rhs, [{direction, index} | predicates]) do
case {direction, Enum.at(lhs, index), Enum.at(rhs, index)} do
{_, lhs, rhs} when lhs == rhs -> compare(lhs, rhs, predicates)
{:asc, lhs, rhs} -> lhs < rhs
{:desc, lhs, rhs} -> lhs > rhs
end
end
defp compare(_lhs, _rhs, []) do
true
end
end