scisco v0.1.0 Scisco.Query behaviour View Source

Easy pagination/sorting/filtering.

Use this module to provide the default Scisco query interface:

defmodule MyQuery do
  use Scisco.Query

  def base_queryable(), do: MySchema
  def repo(), do: MyRepo
end

and then call it from outside:

MyQuery.list(%{page: %{number: 3, size: 10}, filter: %{"foo" => "bar"}, sort: "-baz"})

Pagination

The query module supports by default two pagination strategies: the "classic paginator" style (with :size and :number keys - :number defaulting to 1) and the "raw paginator" style (with :limit and :offset keys - :offset defaulting to 0).

Sorting

By default any string in the sort key will enforce sorting the queryable by the corresponding field of the queryable - descending if the string starts with "-", ascending otherwise.

One can implement additional clauses that respect the sort_callback typespec. The clauses will always receive :asc or :desc depending on whether the original sort param starts with "-".

defmodule MyQuery do
  use Scisco.Query

  def base_queryable(), do: MySchema
  def repo(), do: MyRepo

  def sort(queryable, {:some_key, :asc})
  def sort(queryable, {:some_key, :desc})
end

Filtering

By default any key in the filter map will be converted into an exact match of the corresponding field of the queryable.

One can implement additional clauses that respect the filter_callback typespec.

defmodule MyQuery do
  use Scisco.Query

  def base_queryable(), do: MySchema
  def repo(), do: MyRepo

  def filter(queryable, {:some_key, value})
end

Link to this section Summary

Functions

Performs an actual filtering.

Performs an actual pagination.

Performs an actual sorting.

Callbacks

Needs to be implemented by the module, returning an initial queryable for pagination etc.

Implements specific filtering behavior. Falls back to match the term with the field

Needs to be implemented by the module, returning the Ecto Repo with which to actually execute the queries.

Implements specific sorting behavior. Falls back to sorting by the given field

Link to this section Types

Link to this type

filter_callback()

View Source
filter_callback() ::
  (Ecto.Queryable.t(), {atom(), term()} -> Ecto.Queryable.t())
Link to this type

filter_param()

View Source
filter_param() :: nil | %{optional(String.t()) => term()}
Link to this type

page_param()

View Source
page_param() ::
  nil
  | %{:size => pos_integer(), optional(:number) => pos_integer()}
  | %{:limit => pos_integer(), optional(:offset) => non_neg_integer()}
Link to this type

params()

View Source
params() :: %{
  optional(:page) => page_param(),
  optional(:sort) => sort_param(),
  optional(:filter) => filter_param()
}

The map representing the query params.

Link to this type

sort_callback()

View Source
sort_callback() ::
  (Ecto.Queryable.t(), {atom(), :asc | :desc} -> Ecto.Queryable.t())
Link to this type

sort_param()

View Source
sort_param() :: nil | String.t()

Link to this section Functions

Link to this function

filter(queryable, filters, cb)

View Source
filter(
  queryable :: Ecto.Queryable.t(),
  params :: filter_param(),
  cb :: filter_callback()
) :: Ecto.Queryable.t()

Performs an actual filtering.

Link to this function

paginate(queryable, param)

View Source
paginate(queryable :: any(), params :: nil | page_param()) :: any()

Performs an actual pagination.

Link to this function

sort(queryable, key, cb)

View Source
sort(
  queryable :: Ecto.Queryable.t(),
  params :: sort_param(),
  cb :: sort_callback()
) :: Ecto.Queryable.t()

Performs an actual sorting.

Link to this section Callbacks

Link to this callback

base_queryable()

View Source
base_queryable() :: Ecto.Queryable.t()

Needs to be implemented by the module, returning an initial queryable for pagination etc.

Link to this callback

filter(queryable, {})

View Source
filter(queryable :: Ecto.Queryable.t(), {field :: atom(), value :: term()}) ::
  Ecto.Queryable.t()

Implements specific filtering behavior. Falls back to match the term with the field

Needs to be implemented by the module, returning the Ecto Repo with which to actually execute the queries.

Link to this callback

sort(queryable, {})

View Source
sort(
  queryable :: Ecto.Queryable.t(),
  {field :: atom(), direction :: :asc | :desc}
) :: Ecto.Queryable.t()

Implements specific sorting behavior. Falls back to sorting by the given field