diff --git a/lib/nebulex/adapters/local.ex b/lib/nebulex/adapters/local.ex index eb0cf3ff..409fd145 100644 --- a/lib/nebulex/adapters/local.ex +++ b/lib/nebulex/adapters/local.ex @@ -862,8 +862,8 @@ defmodule Nebulex.Adapters.Local do end defp do_delete_all(backend, tab, [k1, k2 | keys], batch_size, deleted) do - k1 = if is_tuple(k1), do: {k1}, else: k1 - k2 = if is_tuple(k2), do: {k2}, else: k2 + k1 = if is_tuple(k1), do: tuple_to_match_spec(k1), else: k1 + k2 = if is_tuple(k2), do: tuple_to_match_spec(k2), else: k2 do_delete_all( backend, @@ -888,7 +888,7 @@ defmodule Nebulex.Adapters.Local do end defp do_delete_all(backend, tab, [k | keys], batch_size, deleted, count, acc) do - k = if is_tuple(k), do: {k}, else: k + k = if is_tuple(k), do: tuple_to_match_spec(k), else: k do_delete_all( backend, @@ -901,6 +901,22 @@ defmodule Nebulex.Adapters.Local do ) end + defp tuple_to_match_spec(data) do + data + |> :erlang.tuple_to_list() + |> tuple_to_match_spec([]) + end + + defp tuple_to_match_spec([], acc) do + {acc |> Enum.reverse() |> :erlang.list_to_tuple()} + end + + defp tuple_to_match_spec([e | tail], acc) do + e = if is_tuple(e), do: tuple_to_match_spec(e), else: e + + tuple_to_match_spec(tail, [e | acc]) + end + defp return(entry_or_entries, field \\ nil) defp return(nil, _field), do: nil diff --git a/test/shared/local_test.exs b/test/shared/local_test.exs index fb4fb9e5..768679a0 100644 --- a/test/shared/local_test.exs +++ b/test/shared/local_test.exs @@ -191,7 +191,7 @@ defmodule Nebulex.LocalTest do assert cache.all() |> Enum.sort() == Enum.sort(rem) end - test "delete all entries given by a list of keys", %{cache: cache} do + test "delete all entries with special query {:in, keys}", %{cache: cache} do entries = for x <- 1..10, into: %{}, do: {x, x} :ok = cache.put_all(entries) @@ -203,6 +203,24 @@ defmodule Nebulex.LocalTest do assert cache.count_all() == 5 assert cache.all() |> Enum.sort() == [1, 3, 5, 7, 9] end + + test "delete all entries with special query {:in, keys} (nested tuples)", %{cache: cache} do + [ + {1, {:foo, "bar"}}, + {2, {nil, nil}}, + {3, {nil, {nil, nil}}}, + {4, {nil, {nil, nil, {nil, nil}}}}, + {5, {:a, {:b, {:c, {:d, {:e, "f"}}}}}}, + {6, {:a, :b, {:c, :d, {:e, :f, {:g, :h, {:i, :j, "k"}}}}}} + ] + |> Enum.each(fn {k, v} -> + :ok = cache.put(k, v) + + assert cache.count_all() == 1 + assert cache.delete_all({:in, [k]}) == 1 + assert cache.count_all() == 0 + end) + end end describe "older generation hitted on" do