Skip to content

Commit b1bd163

Browse files
committedJan 18, 2019
Fix finding values for limit and offset with where arrays, close #170
1 parent b897537 commit b1bd163

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed
 

‎lib/mongo_ecto/normalized_query.ex

+26-4
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,22 @@ defmodule Mongo.Ecto.NormalizedQuery do
345345

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

348+
defp offset_limit(
349+
%Query.QueryExpr{expr: {:^, l, [idx]} = expr},
350+
params,
351+
pk,
352+
%Query{wheres: wheres} = query,
353+
where
354+
) do
355+
param_offset =
356+
Enum.reduce(wheres, 0, fn %Query.BooleanExpr{expr: expr}, acc ->
357+
_from..to = pair_params_range(expr)
358+
acc + to
359+
end)
360+
361+
value({:^, l, [idx + param_offset]}, params, pk, query, where)
362+
end
363+
348364
defp offset_limit(%Query.QueryExpr{expr: expr}, params, pk, query, where),
349365
do: value(expr, params, pk, query, where)
350366

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

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

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

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

@@ -545,4 +563,8 @@ defmodule Mongo.Ecto.NormalizedQuery do
545563
defp error(place) do
546564
raise ArgumentError, "Invalid expression for MongoDB adapter in #{place}"
547565
end
566+
567+
defp pair_params_range({:in, _, [_, {:^, _, [ix, len]}]}), do: ix..(ix + len - 1)
568+
defp pair_params_range({:not, _, [{:in, _, [_, {:^, _, [ix, len]}]}]}), do: ix..(ix + len - 1)
569+
defp pair_params_range(expr), do: 0..0
548570
end

‎test/mongo_ecto_test.exs

+12
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@ defmodule Mongo.EctoTest do
9191
assert 10 == TestRepo.one(query)
9292
end
9393

94+
test "where in ids + dynamic limit + dynamic offset" do
95+
post1 = TestRepo.insert!(%Post{})
96+
post2 = TestRepo.insert!(%Post{})
97+
post3 = TestRepo.insert!(%Post{})
98+
ids = [post1.id, post2.id, post3.id]
99+
limit = 1
100+
offset = 1
101+
102+
query = from p in Post, where: p.id in ^ids, limit: ^limit, offset: ^offset
103+
assert TestRepo.all(query) == [post2]
104+
end
105+
94106
# test "partial update in map" do
95107
# post = TestRepo.insert!(%Post{meta: %{author: %{name: "michal"}, other: "value"}})
96108
# TestRepo.update_all(Post, set: [meta: change_map("author.name", "michal")])

0 commit comments

Comments
 (0)