Skip to content

Commit

Permalink
Add order_by option to Query.changes/2 (#114)
Browse files Browse the repository at this point in the history
Co-authored-by: Malte Rohde <maltoe@posteo.de>
  • Loading branch information
wkirschbaum and maltoe authored Aug 20, 2024
1 parent 75bd637 commit 144946d
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Unreleased

### Added

* Add `:order_by` option to `Carbonite.Query.changes/2` to either disable default ordering or specify the order.

## [0.14.0] - 2024-07-25

**New migration patches:** 10
Expand Down
17 changes: 15 additions & 2 deletions lib/carbonite/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ defmodule Carbonite.Query do

@type prefix_option :: {:carbonite_prefix, prefix()}
@type preload_option :: {:preload, boolean()}
@type order_by_option :: {:order_by, false | nil | term()}

@type transactions_option :: prefix_option() | preload_option()

Expand Down Expand Up @@ -181,7 +182,8 @@ defmodule Carbonite.Query do

@default_table_prefix "public"

@type changes_option :: prefix_option() | preload_option() | {:table_prefix, prefix()}
@type changes_option ::
prefix_option() | preload_option() | order_by_option() | {:table_prefix, prefix()}

@doc """
Returns an `t:Ecto.Query.t/0` that can be used to select changes for a single record.
Expand All @@ -201,6 +203,7 @@ defmodule Carbonite.Query do
* `carbonite_prefix` defines the audit trail's schema, defaults to `"carbonite_default"`
* `table_prefix` allows to override the table prefix, defaults to schema prefix of the record
* `preload` can be used to preload the transaction
* `order_by` allows to override the ordering, defaults to `{:asc, :id}`
"""
@doc since: "0.2.0"
@spec changes(record :: Ecto.Schema.t()) :: Ecto.Query.t()
Expand All @@ -223,7 +226,7 @@ defmodule Carbonite.Query do
|> where([c], c.table_name == ^table_name)
|> where([c], c.table_pk == ^table_pk)
|> maybe_preload(opts, :transaction, from_with_prefix(Transaction, opts))
|> order_by({:asc, :id})
|> maybe_order_by(opts)
end

defp maybe_apply(queryable, opts, key, default, fun) do
Expand All @@ -234,6 +237,16 @@ defmodule Carbonite.Query do
end
end

defp maybe_order_by(queryable, opts) do
case Keyword.get(opts, :order_by, {:asc, :id}) do
order_by when order_by in [false, nil] ->
queryable

value ->
order_by(queryable, ^value)
end
end

defp maybe_preload(queryable, opts, association, preload_query) do
case Keyword.get(opts, :preload, false) do
preload when preload in [false, nil] ->
Expand Down
14 changes: 14 additions & 0 deletions test/carbonite/query_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,20 @@ defmodule Carbonite.QueryTest do
assert [%Change{data: %{"name" => "Jack"}}] = changes(rabbit)
end

test "can disable ordering", %{rabbit: rabbit} do
assert Map.get(Query.changes(rabbit, order_by: false), :order_bys) == []
end

test "can set custom ordering", %{rabbit: rabbit} do
rabbit
|> Rabbit.rename_changeset("Gerda")
|> TestRepo.update!()

[_, _] = descending_ids = changes(rabbit, order_by: {:desc, :id})

assert Enum.reverse(descending_ids) == changes(rabbit)
end

test "can preload the transaction", %{rabbit: rabbit} do
assert [%Change{transaction: %Transaction{}}] = changes(rabbit, preload: true)
end
Expand Down

0 comments on commit 144946d

Please sign in to comment.