Skip to content

Commit

Permalink
Update the all callback in ResourceFunctions to support limit and offset
Browse files Browse the repository at this point in the history
Add additional option support for limits and offsets. Also refactored
to use a reduce as it makes it easier to only apply query changes
for options that are present.
  • Loading branch information
jakeprem authored and joseph-lozano committed Nov 18, 2024
1 parent 8a9f447 commit 6f8081f
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 8 deletions.
18 changes: 10 additions & 8 deletions lib/resource_functions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,16 @@ defmodule EctoResource.ResourceFunctions do
@spec all(Ecto.Repo.t(), module, term()) :: list(Ecto.Schema.t())

def all(repo, schema, options \\ []) do
preloads = Keyword.get(options, :preloads, [])
order_by = Keyword.get(options, :order_by, [])
where = Keyword.get(options, :where, [])

schema
|> preload(^preloads)
|> order_by(^order_by)
|> where(^where)
options
|> Keyword.take([:preloads, :order_by, :where, :limit, :offset])
|> Enum.reduce(schema, fn
{:preloads, preloads}, query -> preload(query, ^preloads)
{:order_by, order_by}, query -> order_by(query, ^order_by)
{:where, where}, query -> where(query, ^where)
{:limit, limit}, query -> limit(query, ^limit)
{:offset, offset}, query -> offset(query, ^offset)
_, query -> query
end)
|> repo.all([])
end

Expand Down
73 changes: 73 additions & 0 deletions test/ecto_resource/resource_functions_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
defmodule EctoResource.ResourceFunctionsTestContext.People do
use EctoResource

alias EctoResource.TestRepo
alias EctoResource.TestSchema.Person

using_repo TestRepo do
resource(Person)
end
end

defmodule EctoResource.ResourceFunctionsTest do
use EctoResource.RepoCase

alias EctoResource.TestSchema.Person
alias EctoResource.ResourceFunctionsTestContext.People

defp create_person(opts) do
opts = Keyword.merge([first_name: "Test", last_name: "Person", age: 42], opts)

Person |> struct(opts) |> Repo.insert!()
end

describe "all/2" do
setup do
michael = create_person(first_name: "Michael", age: 50)
dwight = create_person(first_name: "Dwight", age: 33)

%{michael: michael, dwight: dwight}
end

test "returns all records", %{
michael: michael,
dwight: dwight
} do
people = People.all_people()

assert michael in people
assert dwight in people
end

test "returns all records with a where clause", %{
michael: michael,
dwight: dwight
} do
assert People.all_people(where: [age: 50]) == [michael]
assert People.all_people(where: [age: 33]) == [dwight]
end

test "returns all records up to limit", %{
michael: michael,
dwight: dwight
} do
assert People.all_people(limit: 1) == [michael]
assert People.all_people(limit: 2) == [michael, dwight]
end

test "returns records in order of order_by", %{
michael: michael,
dwight: dwight
} do
assert People.all_people(order_by: :age) == [dwight, michael]
assert People.all_people(order_by: [desc: :age]) == [michael, dwight]
end

test "returns records with offset", %{
dwight: dwight
} do
assert People.all_people(offset: 1) == [dwight]
assert People.all_people(offset: 2) == []
end
end
end

0 comments on commit 6f8081f

Please sign in to comment.