Current section

Files

Jump to
ex_dgraph lib exdgraph mutation.ex
Raw

lib/exdgraph/mutation.ex

defmodule ExDgraph.Mutation do
@moduledoc """
Provides the functions for the callbacks from the DBConnection behaviour.
"""
alias ExDgraph.{Exception, MutationStatement, QueryStatement, Transform}
@doc false
def mutation!(conn, statement) do
case mutation_commit(conn, statement) do
{:error, f} ->
raise Exception, code: f.code, message: f.message
r ->
r
end
end
@doc false
def mutation(conn, statement) do
case mutation_commit(conn, statement) do
{:error, f} -> {:error, code: f.code, message: f.message}
r -> {:ok, r}
end
end
@doc false
def set_map(conn, map) do
map_with_tmp_uids = insert_tmp_uids(map)
json = Poison.encode!(map_with_tmp_uids)
case set_map_commit(conn, json, map_with_tmp_uids) do
{:error, f} -> {:error, code: f.code, message: f.message}
r -> {:ok, r}
end
end
@doc false
def set_map!(conn, map) do
map_with_tmp_uids = insert_tmp_uids(map)
json = Poison.encode!(map_with_tmp_uids)
case set_map_commit(conn, json, map_with_tmp_uids) do
{:error, f} ->
raise Exception, code: f.code, message: f.message
r ->
r
end
end
defp mutation_commit(conn, statement) do
exec = fn conn ->
q = %MutationStatement{statement: statement}
case DBConnection.execute(conn, q, %{}) do
{:ok, resp} -> Transform.transform_mutation(resp)
other -> other
end
end
# Response.transform(DBConnection.run(conn, exec, run_opts()))
DBConnection.run(conn, exec, run_opts())
end
defp set_map_commit(conn, json, map_with_tmp_uids) do
exec = fn conn ->
q = %MutationStatement{set_json: json}
case DBConnection.execute(conn, q, %{}) do
{:ok, resp} ->
parsed_response = Transform.transform_mutation(resp)
# Now exchange the tmp ids for the ones returned from the db
result_with_uids = replace_tmp_uids(map_with_tmp_uids, parsed_response.uids)
Map.put(parsed_response, :result, result_with_uids)
other ->
other
end
end
# Response.transform(DBConnection.run(conn, exec, run_opts()))
DBConnection.run(conn, exec, run_opts())
end
defp insert_tmp_uids(map) when is_list(map), do: Enum.map(map, &insert_tmp_uids/1)
defp insert_tmp_uids(map) when is_map(map) do
map
|> Map.update(:uid, "_:#{UUID.uuid4()}", fn existing_uuid -> existing_uuid end)
|> Enum.reduce(%{}, fn
{key, a_map = %{}}, a -> Map.merge(a, %{key => insert_tmp_uids(a_map)})
{key, not_a_map}, a -> Map.merge(a, %{key => insert_tmp_uids(not_a_map)})
end)
end
defp insert_tmp_uids(value), do: value
defp replace_tmp_uids(map, uids) when is_list(map),
do: Enum.map(map, &replace_tmp_uids(&1, uids))
defp replace_tmp_uids(map, uids) when is_map(map) do
map
|> Map.update(:uid, map[:uid], fn existing_uuid ->
case String.slice(existing_uuid, 0, 2) == "_:" do
true -> uids[String.replace_leading(existing_uuid, "_:", "")]
false -> existing_uuid
end
end)
|> Enum.reduce(%{}, fn
{key, a_map = %{}}, a -> Map.merge(a, %{key => replace_tmp_uids(a_map, uids)})
{key, not_a_map}, a -> Map.merge(a, %{key => replace_tmp_uids(not_a_map, uids)})
end)
end
defp replace_tmp_uids(value, uids), do: value
defp get_real_uid(tmp_value, uids) do
end
defp run_opts do
[pool: ExDgraph.config(:pool)]
end
end