Current section
Files
Jump to
Current section
Files
lib/mmdb2/database.ex
defmodule Geolix.Adapter.MMDB2.Database do
@moduledoc false
alias Geolix.Adapter.MMDB2
alias Geolix.Adapter.MMDB2.Result
alias Geolix.Adapter.MMDB2.Storage
alias MMDB2Decoder.Metadata
@mmdb2_opts %{double_precision: 8, float_precision: 4, map_keys: :atoms}
@doc """
Performs a lookup in a loaded database.
"""
@spec lookup(:inet.ip_address(), Keyword.t(), MMDB2.database()) :: map | nil
def lookup(ip, opts, %{id: id} = database) do
with {%Metadata{} = meta, tree, data} when is_binary(tree) and is_binary(data) <-
Storage.get(id),
mmdb2_opts <- mmdb2_opts(opts, database),
{:ok, result} when is_map(result) <-
MMDB2Decoder.lookup(ip, meta, tree, data, mmdb2_opts),
result_as <- result_as(opts, database),
result_ip_key <- result_ip_key(mmdb2_opts) do
result
|> Map.put(result_ip_key, ip)
|> maybe_to_struct(result_as, meta, opts)
else
_ -> nil
end
end
@doc """
Returns the metadata for a loaded database.
"""
@spec metadata(MMDB2.database()) :: Metadata.t() | nil
def metadata(%{id: id}) do
case Storage.get(id) do
{%Metadata{} = meta, _, _} -> meta
_ -> nil
end
end
defp maybe_to_struct(result, :raw, _, _), do: result
defp maybe_to_struct(result, :struct, %{database_type: type}, opts) do
locale = Keyword.get(opts, :locale, :en)
Result.to_struct(type, result, locale)
end
defp mmdb2_opts(opts, database) do
opts[:mmdb2_decoder_options] || database[:mmdb2_decoder_options] || @mmdb2_opts
end
defp result_as(opts, database) do
opts[:as] || database[:result_as] || :struct
end
defp result_ip_key(%{map_keys: :atoms}), do: :ip_address
defp result_ip_key(%{map_keys: :atoms!}), do: :ip_address
defp result_ip_key(_), do: "ip_address"
end