Skip to content

Commit

Permalink
Fix finding values for limit and offset with where arrays, close #170
Browse files Browse the repository at this point in the history
  • Loading branch information
exAspArk committed Jan 18, 2019
1 parent b897537 commit b1bd163
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
30 changes: 26 additions & 4 deletions lib/mongo_ecto/normalized_query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,22 @@ defmodule Mongo.Ecto.NormalizedQuery do

defp offset_limit(nil, _params, _pk, _query, _where), do: nil

defp offset_limit(
%Query.QueryExpr{expr: {:^, l, [idx]} = expr},
params,
pk,
%Query{wheres: wheres} = query,
where
) do
param_offset =
Enum.reduce(wheres, 0, fn %Query.BooleanExpr{expr: expr}, acc ->
_from..to = pair_params_range(expr)
acc + to
end)

value({:^, l, [idx + param_offset]}, params, pk, query, where)
end

defp offset_limit(%Query.QueryExpr{expr: expr}, params, pk, query, where),
do: value(expr, params, pk, query, where)

Expand Down Expand Up @@ -466,9 +482,10 @@ defmodule Mongo.Ecto.NormalizedQuery do
{field(left, pk, query, place), ["$in": []]}
end

defp pair({:in, _, [left, {:^, _, [ix, len]}]}, params, pk, query, place) do
defp pair({:in, _, [left, _]} = expr, params, pk, query, place) do
args =
ix..(ix + len - 1)
expr
|> pair_params_range()
|> Enum.map(&elem(params, &1))
|> Enum.map(&value(&1, params, pk, query, place))

Expand All @@ -483,9 +500,10 @@ defmodule Mongo.Ecto.NormalizedQuery do
{field(left, pk, query, place), [{binary_op(op), value(right, params, pk, query, place)}]}
end

defp pair({:not, _, [{:in, _, [left, {:^, _, [ix, len]}]}]}, params, pk, query, place) do
defp pair({:not, _, [{:in, _, [left, _]}]} = expr, params, pk, query, place) do
args =
ix..(ix + len - 1)
expr
|> pair_params_range()
|> Enum.map(&elem(params, &1))
|> Enum.map(&value(&1, params, pk, query, place))

Expand Down Expand Up @@ -545,4 +563,8 @@ defmodule Mongo.Ecto.NormalizedQuery do
defp error(place) do
raise ArgumentError, "Invalid expression for MongoDB adapter in #{place}"
end

defp pair_params_range({:in, _, [_, {:^, _, [ix, len]}]}), do: ix..(ix + len - 1)
defp pair_params_range({:not, _, [{:in, _, [_, {:^, _, [ix, len]}]}]}), do: ix..(ix + len - 1)
defp pair_params_range(expr), do: 0..0
end
12 changes: 12 additions & 0 deletions test/mongo_ecto_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ defmodule Mongo.EctoTest do
assert 10 == TestRepo.one(query)
end

test "where in ids + dynamic limit + dynamic offset" do
post1 = TestRepo.insert!(%Post{})
post2 = TestRepo.insert!(%Post{})
post3 = TestRepo.insert!(%Post{})
ids = [post1.id, post2.id, post3.id]
limit = 1
offset = 1

query = from p in Post, where: p.id in ^ids, limit: ^limit, offset: ^offset
assert TestRepo.all(query) == [post2]
end

# test "partial update in map" do
# post = TestRepo.insert!(%Post{meta: %{author: %{name: "michal"}, other: "value"}})
# TestRepo.update_all(Post, set: [meta: change_map("author.name", "michal")])
Expand Down

0 comments on commit b1bd163

Please sign in to comment.