mirror of
https://github.com/ash-project/ash_postgres.git
synced 2024-09-20 05:23:18 +12:00
WIP
This commit is contained in:
parent
9c2c11bb56
commit
00c8ae8941
3 changed files with 226 additions and 37 deletions
|
@ -1,5 +1,5 @@
|
||||||
# Used by "mix format"
|
# Used by "mix format"
|
||||||
[
|
[
|
||||||
locals_without_parens: []
|
locals_without_parens: [],
|
||||||
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||||
]
|
]
|
||||||
|
|
|
@ -94,10 +94,11 @@ defmodule AshPostgres do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def create(resource, changeset) do
|
def create(resource, changeset) do
|
||||||
changeset = Map.update!(changeset, :action, fn
|
changeset =
|
||||||
:create -> :insert
|
Map.update!(changeset, :action, fn
|
||||||
action -> action
|
:create -> :insert
|
||||||
end)
|
action -> action
|
||||||
|
end)
|
||||||
|
|
||||||
repo(resource).insert(changeset)
|
repo(resource).insert(changeset)
|
||||||
rescue
|
rescue
|
||||||
|
@ -128,25 +129,212 @@ defmodule AshPostgres do
|
||||||
# make queries perform well. For now, I'm just choosing the most naive approach
|
# make queries perform well. For now, I'm just choosing the most naive approach
|
||||||
# possible: left join to relationships that appear in `or` conditions, inner
|
# possible: left join to relationships that appear in `or` conditions, inner
|
||||||
# join to conditions in the mainline query.
|
# join to conditions in the mainline query.
|
||||||
def filter(query, filter, resource) do
|
|
||||||
IO.inspect(filter)
|
|
||||||
{:ok, query}
|
|
||||||
# filter
|
|
||||||
# |> join_relationships()
|
|
||||||
# |> Enum.flat_map(fn {key, filter} ->
|
|
||||||
# Enum.map(filter, fn {filter_type, value} ->
|
|
||||||
# {key, filter_type, value}
|
|
||||||
# end)
|
|
||||||
# end)
|
|
||||||
# |> Enum.reduce({:ok, query}, fn
|
|
||||||
# _, {:error, error} ->
|
|
||||||
# {:error, error}
|
|
||||||
|
|
||||||
# {key, filter_type, value}, {:ok, query} ->
|
def filter(query, filter, resource) do
|
||||||
# do_filter(query, key, filter_type, value)
|
new_query =
|
||||||
# end)
|
query
|
||||||
|
|> Map.put(:bindings, %{})
|
||||||
|
|> join_all_relationships(filter)
|
||||||
|
|> add_filter_expression(filter)
|
||||||
|
|
||||||
|
{:ok, new_query}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp join_all_relationships(query, filter, path \\ [])
|
||||||
|
|
||||||
|
defp join_all_relationships(query, %{relationships: relationships}, _path)
|
||||||
|
when relationships == %{} do
|
||||||
|
query
|
||||||
|
end
|
||||||
|
|
||||||
|
defp join_all_relationships(query, filter, path) do
|
||||||
|
query =
|
||||||
|
Map.put_new(query, :__ash_bindings__, %{current: Enum.count(query.joins) + 1, bindings: %{}})
|
||||||
|
|
||||||
|
Enum.reduce(filter.relationships, query, fn {name, relationship_filter}, query ->
|
||||||
|
# TODO: This can be smarter. If the same relationship exists in all `ors`,
|
||||||
|
# we can inner join it, (unless the filter is only for fields being null)
|
||||||
|
join_type =
|
||||||
|
if Enum.empty?(filter.ors) && filter.not == nil do
|
||||||
|
:inner
|
||||||
|
else
|
||||||
|
:left
|
||||||
|
end
|
||||||
|
|
||||||
|
current_path = [Ash.relationship(filter.resource, name) | path]
|
||||||
|
|
||||||
|
joined_query = join_relationship(query, current_path, join_type)
|
||||||
|
|
||||||
|
join_all_relationships(joined_query, relationship_filter, current_path)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp join_relationship(query, path, join_type) do
|
||||||
|
path_names = Enum.map(path, & &1.name)
|
||||||
|
|
||||||
|
case Map.get(query.__ash_bindings__.bindings, path_names) do
|
||||||
|
%{type: existing_join_type} when join_type != existing_join_type ->
|
||||||
|
raise "unreachable?"
|
||||||
|
|
||||||
|
nil ->
|
||||||
|
do_join_relationship(query, path, join_type)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
query
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_join_relationship(query, [%{type: :many_to_many} = relationship], :inner) do
|
||||||
|
new_query =
|
||||||
|
from(row in query,
|
||||||
|
join: through in ^relationship.through,
|
||||||
|
on:
|
||||||
|
field(row, ^relationship.source_field) ==
|
||||||
|
field(through, ^relationship.source_field_on_join_table),
|
||||||
|
join: destination in ^relationship.destination,
|
||||||
|
on:
|
||||||
|
field(destination, ^relationship.destination_field) ==
|
||||||
|
field(through, ^relationship.destination_field_on_join_table)
|
||||||
|
)
|
||||||
|
|
||||||
|
join_path = [String.to_existing_atom(to_string(relationship.name) <> "_join_assoc")]
|
||||||
|
full_path = [relationship.name]
|
||||||
|
|
||||||
|
new_query
|
||||||
|
|> add_binding(join_path, :inner)
|
||||||
|
|> add_binding(full_path, :inner)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_join_relationship(query, [relationship], :inner) do
|
||||||
|
new_query =
|
||||||
|
from(row in query,
|
||||||
|
join: destination in ^relationship.destination,
|
||||||
|
on: field(row, ^relationship.source_field) == field(row, ^relationship.destination_field)
|
||||||
|
)
|
||||||
|
|
||||||
|
add_binding(new_query, [relationship.name], :inner)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp add_filter_expression(query, filter) do
|
||||||
|
{params, not_expr} =
|
||||||
|
case filter.not do
|
||||||
|
nil ->
|
||||||
|
{[], nil}
|
||||||
|
|
||||||
|
not_filter ->
|
||||||
|
filter_to_expr(not_filter)
|
||||||
|
end
|
||||||
|
|
||||||
|
{params, expr} = filter_to_expr(filter, query.__ash_bindings__.bindings, params)
|
||||||
|
|
||||||
|
expr = join_exprs(not_expr, expr, :and)
|
||||||
|
|
||||||
|
{params, expr} =
|
||||||
|
Enum.reduce(filter.ors, {params, expr}, fn or_filter, {params, existing_expr} ->
|
||||||
|
{params, expr} = filter_to_expr(or_filter, params)
|
||||||
|
|
||||||
|
{params, join_exprs(existing_expr, expr, :or)}
|
||||||
|
end)
|
||||||
|
|
||||||
|
if expr do
|
||||||
|
query
|
||||||
|
else
|
||||||
|
boolean_expr = %Ecto.Query.BooleanExpr{
|
||||||
|
expr: expr,
|
||||||
|
op: :and,
|
||||||
|
params: params
|
||||||
|
}
|
||||||
|
|
||||||
|
%{query | wheres: [boolean_expr | query.wheres]}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp join_exprs(nil, nil, _op), do: nil
|
||||||
|
defp join_exprs(expr, nil, _op), do: expr
|
||||||
|
defp join_exprs(nil, expr, _op), do: expr
|
||||||
|
defp join_exprs(expr, expr, op), do: {op, expr, expr}
|
||||||
|
|
||||||
|
defp filter_to_expr(filter, bindings, current_binding \\ 0, params \\ [], path \\ []) do
|
||||||
|
param_count = Enum.count(params)
|
||||||
|
|
||||||
|
{params, existing_expr, _param_count} =
|
||||||
|
Enum.reduce(filter.attributes, {params, nil, param_count}, fn {attribute, filter},
|
||||||
|
{params, existing_expr,
|
||||||
|
param_count} ->
|
||||||
|
case filter_value_to_expr(attribute, filter, current_binding) do
|
||||||
|
{param, expr} ->
|
||||||
|
{params ++ [param], join_exprs(existing_expr, expr, :and), param_count + 1}
|
||||||
|
|
||||||
|
expr ->
|
||||||
|
{params, join_exprs(existing_expr, expr, :and), param_count}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
Enum.reduce(filter.relationships, {params, existing_expr}, fn {relationship,
|
||||||
|
relationship_filter},
|
||||||
|
{params, existing_expr} ->
|
||||||
|
full_path = path ++ [relationship]
|
||||||
|
|
||||||
|
binding = Map.get(bindings, full_path) || raise "unbound relationship referenced!"
|
||||||
|
|
||||||
|
{params, expr} = filter_to_expr(relationship_filter, bindings, binding, params, full_path)
|
||||||
|
|
||||||
|
{params, join_exprs(expr, existing_expr)}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp add_binding(query, path, type) do
|
||||||
|
current = query.__ash_bindings__.current
|
||||||
|
bindings = query.__ash_bindings__.bindings
|
||||||
|
|
||||||
|
new_ash_bindings = %{
|
||||||
|
query.__ash_bindings__
|
||||||
|
| bindings: do_add_binding(bindings, path, current, type),
|
||||||
|
current: current + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
%{query | __ash_bindings__: new_ash_bindings}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp do_add_binding(bindings, path, current, type) do
|
||||||
|
Map.put(bindings, path, %{binding: current, type: type})
|
||||||
|
end
|
||||||
|
|
||||||
|
# defp join_all_relationships(query, filter, kind \\ :inner) do
|
||||||
|
# case filter.ors do
|
||||||
|
# [] ->
|
||||||
|
# Enum.reduce(filter.relationships, query, fn {relationship_name, filter}, query ->
|
||||||
|
# relationship = Ash.relationship(filter.resource, relationship_name)
|
||||||
|
# join_relationship(query, relationship, filter, kind)
|
||||||
|
# end)
|
||||||
|
|
||||||
|
# ors ->
|
||||||
|
# Enum.reduce([filter | ors], query, fn filter, query ->
|
||||||
|
# join_all_relationships(query, Map.put(filter, :ors, []), :left)
|
||||||
|
# end)
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
|
||||||
|
# defp join_relationships(_query, _relationship, _filter, :left), do: raise "unimplemented"
|
||||||
|
# defp join_relationship(query, %{type: :many_to_many} = relationship, filter, _type) do
|
||||||
|
# filtered_destination = filter(Ecto.Queryable.to_query(relationship.destination), filter, relationship.destination)
|
||||||
|
|
||||||
|
# from row in query,
|
||||||
|
# left_join: through in ^relationship.through,
|
||||||
|
# on: field(row, ^relationship.source_field) == field(through, ^relationship.source_field_on_join_table),
|
||||||
|
# left_join: destination in ^filtered_destination,
|
||||||
|
# on: field(destination, ^relationship.destination_field) == field(through, ^relationship.destination_field_on_join_table)
|
||||||
|
# end
|
||||||
|
|
||||||
|
# defp join_relationship(query, relationship, filter, join_kind) do
|
||||||
|
# filtered_destination = filter(Ecto.Queryable.to_query(relationship.destination), filter, relationship.destination)
|
||||||
|
|
||||||
|
# from row in query,
|
||||||
|
# join: destination in ^filtered_destination,
|
||||||
|
# on: field(row, ^relationship.source_field) == field(destination, ^relationship.destination_field)
|
||||||
|
# query
|
||||||
|
# end
|
||||||
|
|
||||||
defp do_filter(query, key, :equals, value) do
|
defp do_filter(query, key, :equals, value) do
|
||||||
from(row in query,
|
from(row in query,
|
||||||
where: field(row, ^key) == ^value
|
where: field(row, ^key) == ^value
|
||||||
|
|
33
mix.lock
33
mix.lock
|
@ -1,24 +1,25 @@
|
||||||
%{
|
%{
|
||||||
"ash": {:hex, :ash, "0.1.1", "2db9c647db445e57e9f789c7c0b2fe0ab45bed51d8004a5069baea974f4cc7f4", [:mix], [{:ashton, "~> 0.4.1", [hex: :ashton, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}], "hexpm"},
|
"ash": {:hex, :ash, "0.1.1", "2db9c647db445e57e9f789c7c0b2fe0ab45bed51d8004a5069baea974f4cc7f4", [:mix], [{:ashton, "~> 0.4.1", [hex: :ashton, repo: "hexpm", optional: false]}, {:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8.0", [hex: :ets, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
"ashton": {:hex, :ashton, "0.4.1", "d0f7782ac44fa22da7ce544028ee3d2078592a834d8adf3e5b4b6aeb94413a55", [:mix], [], "hexpm"},
|
"ashton": {:hex, :ashton, "0.4.1", "d0f7782ac44fa22da7ce544028ee3d2078592a834d8adf3e5b4b6aeb94413a55", [:mix], [], "hexpm", "24db667932517fdbc3f2dae777f28b8d87629271387d4490bc4ae8d9c46ff3d3"},
|
||||||
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"},
|
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm", "4a0850c9be22a43af9920a71ab17c051f5f7d45c209e40269a1938832510e4d9"},
|
||||||
"dataloader": {:hex, :dataloader, "1.0.6", "fb724d6d3fb6acb87d27e3b32dea3a307936ad2d245faf9cf5221d1323d6a4ba", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
"dataloader": {:hex, :dataloader, "1.0.6", "fb724d6d3fb6acb87d27e3b32dea3a307936ad2d245faf9cf5221d1323d6a4ba", [:mix], [{:ecto, ">= 0.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"db_connection": {:hex, :db_connection, "2.1.1", "a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm"},
|
"db_connection": {:hex, :db_connection, "2.1.1", "a51e8a2ee54ef2ae6ec41a668c85787ed40cb8944928c191280fe34c15b76ae5", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "5a0e8c1c722dbcd31c0cbd1906b1d1074c863d335c295e4b994849b65a1fbe47"},
|
||||||
"decimal": {:hex, :decimal, "1.8.0", "ca462e0d885f09a1c5a342dbd7c1dcf27ea63548c65a65e67334f4b61803822e", [:mix], [], "hexpm"},
|
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
|
||||||
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm"},
|
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
|
||||||
"ecto": {:hex, :ecto, "3.2.5", "76c864b77948a479e18e69cc1d0f0f4ee7cced1148ffe6a093ff91eba644f0b5", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
"ecto": {:hex, :ecto, "3.2.5", "76c864b77948a479e18e69cc1d0f0f4ee7cced1148ffe6a093ff91eba644f0b5", [:mix], [{:decimal, "~> 1.6", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "01251d9b28081b7e0af02a1875f9b809b057f064754ca3b274949d5216ea6f5f"},
|
||||||
"ecto_sql": {:hex, :ecto_sql, "3.2.0", "751cea597e8deb616084894dd75cbabfdbe7255ff01e8c058ca13f0353a3921b", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm"},
|
"ecto_sql": {:hex, :ecto_sql, "3.2.0", "751cea597e8deb616084894dd75cbabfdbe7255ff01e8c058ca13f0353a3921b", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.2.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.2.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a2e23cf761668126252418cae07eff7967ad0152fbc5e2d0dc3de487a5ec774c"},
|
||||||
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm"},
|
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
|
||||||
"ets": {:hex, :ets, "0.8.0", "90153faafd289bb0801a537d5b05661f46d5e70b2bb55cccf5ab7f0d41d07832", [:mix], [], "hexpm"},
|
"ets": {:hex, :ets, "0.8.0", "90153faafd289bb0801a537d5b05661f46d5e70b2bb55cccf5ab7f0d41d07832", [:mix], [], "hexpm", "bda4e05b16eada36798cfda16db551dc5243c0adc9a6dfe655b1bc1279b99cb8"},
|
||||||
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
|
"ex_doc": {:hex, :ex_doc, "0.21.2", "caca5bc28ed7b3bdc0b662f8afe2bee1eedb5c3cf7b322feeeb7c6ebbde089d6", [:mix], [{:earmark, "~> 1.3.3 or ~> 1.4", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f1155337ae17ff7a1255217b4c1ceefcd1860b7ceb1a1874031e7a861b052e39"},
|
||||||
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
|
"machinery": {:hex, :machinery, "1.0.0", "df6968d84c651b9971a33871c78c10157b6e13e4f3390b0bee5b0e8bdea8c781", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}], "hexpm", "4f6eb4185a48e7245360bedf653af4acc6fa6ae8ff4690619395543fa1a8395f"},
|
||||||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"},
|
"makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "a10c6eb62cca416019663129699769f0c2ccf39428b3bb3c0cb38c718a0c186d"},
|
||||||
|
"makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "d4b316c7222a85bbaa2fd7c6e90e37e953257ad196dc229505137c5e505e9eff"},
|
||||||
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
|
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
|
||||||
"nimble_parsec": {:hex, :nimble_parsec, "0.5.2", "1d71150d5293d703a9c38d4329da57d3935faed2031d64bc19e77b654ef2d177", [:mix], [], "hexpm"},
|
"nimble_parsec": {:hex, :nimble_parsec, "0.5.2", "1d71150d5293d703a9c38d4329da57d3935faed2031d64bc19e77b654ef2d177", [:mix], [], "hexpm", "51aa192e0941313c394956718bdb1e59325874f88f45871cff90345b97f60bba"},
|
||||||
"picosat_elixir": {:hex, :picosat_elixir, "0.1.1", "5d7dc32f4a896d588d73a9bd987a291e4217d6f687b2091bf4115cf3ea1cbac9", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm"},
|
"picosat_elixir": {:hex, :picosat_elixir, "0.1.1", "5d7dc32f4a896d588d73a9bd987a291e4217d6f687b2091bf4115cf3ea1cbac9", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "099ef22e9b86dcba88cd3ca5f3c40c8026005ba93a129429234e275a56f54043"},
|
||||||
"plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
|
"plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
|
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
|
||||||
"postgrex": {:hex, :postgrex, "0.15.1", "23ce3417de70f4c0e9e7419ad85bdabcc6860a6925fe2c6f3b1b5b1e8e47bf2f", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
"postgrex": {:hex, :postgrex, "0.15.1", "23ce3417de70f4c0e9e7419ad85bdabcc6860a6925fe2c6f3b1b5b1e8e47bf2f", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "12cd418e207b8ed787dfe0f520fccd6c001f58d9108233feae7df36462593d1f"},
|
||||||
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm"},
|
"telemetry": {:hex, :telemetry, "0.4.0", "8339bee3fa8b91cb84d14c2935f8ecf399ccd87301ad6da6b71c09553834b2ab", [:rebar3], [], "hexpm", "e9e3cacfd37c1531c0ca70ca7c0c30ce2dbb02998a4f7719de180fe63f8d41e4"},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue