Created
September 5, 2023 13:51
-
-
Save lessless/557ff48af24394d2b049ffebb79df82f to your computer and use it in GitHub Desktop.
Revisions
-
lessless created this gist
Sep 5, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,46 @@ # courtesy @mrdotb defmodule T do import Ecto.Query alias Your.Repo @doc """ Use runtime data as an adhoc db table to join to data. `types` need to be a compile time string literal. `values` can be runtime supplied. ## Example data = [%{id: 1, text: "hey"}, %{id: 2, text: "ho"}] from a in Table, join: b in jsonb_recordset("id uuid, text text", data), on: a.id == b.id """ defmacro jsonb_recordset(types, values) do quote do fragment( unquote("(SELECT * FROM json_to_recordset(?) as t(#{types}))"), ^unquote(values) ) end end def find_non_existing_set(set_list) do pairs = Enum.map(set_list, fn {id, another_id} -> %{id: id, another_id: another_id} end) "pairs" |> with_cte("pairs", as: jsonb_recordset("id int, another_id int", pairs)) |> join(:left, [pair], item in "items", on: item.id == pair.id and item.another_id == pair.another_id) |> where([_pair, item], is_nil(item)) |> select([pair, _item], {pair.id, pair.another_id}) |> Repo.all() end def tests do find_non_existing_set([{1, 2}, {3, 4}, {1337, 1337}]) # [{1337, 1337}] end end