View Source MMDB2Decoder (MMDB2 Decoder v3.0.1)

MMDB2 file format decoder.

usage

Usage

To prepare lookups in a given database you need to parse it and hold the result available for later usage:

iex(1)> database = File.read!("/path/to/database.mmdb")
iex(2)> {:ok, meta, tree, data} = MMDB2Decoder.parse_database(database)

Using the returned database contents you can start looking up individual entries:

iex(3)> {:ok, ip} = :inet.parse_address(String.to_charlist("127.0.0.1"))
iex(4)> MMDB2Decoder.lookup(ip, meta, tree, data)
{:ok, %{...}}

For more details on the lookup methods (and a function suitable for direct piping) please see the individual function documentations.

lookup-options

Lookup Options

The behaviour of the decoder can be adjusted by passing an option map as the last argument to the lookup functions:

iex> MMDB2Decoder.lookup(ip, meta, tree, data, %{map_keys: :atoms!})

The following options are available:

  • :map_keys defines the type of the keys in a decoded map:
  • :double_precision defines the precision of decoded Double values
  • :float_precision defines the precision of decoded Float values

Link to this section Summary

Link to this section Types

@type decode_options() :: %{
  optional(:double_precision) => nil | Float.precision_range(),
  optional(:float_precision) => nil | Float.precision_range(),
  optional(:map_keys) => nil | :atoms | :atoms! | :strings
}
@type decoded_value() ::
  :cache_container
  | :end_marker
  | binary()
  | boolean()
  | list()
  | map()
  | number()
@type lookup_result() :: {:ok, lookup_value()} | {:error, term()}
@type lookup_value() :: decoded_value() | nil
@type parse_result() ::
  {:ok, MMDB2Decoder.Metadata.t(), binary(), binary()} | {:error, term()}
@type tree_result() :: {:ok, non_neg_integer()} | {:error, term()}

Link to this section Functions

Link to this function

find_pointer!(ip, meta, tree)

View Source

Calls find_pointer/3 and raises if an error occurs.

Link to this function

find_pointer(ip, meta, tree)

View Source
@spec find_pointer(:inet.ip_address(), MMDB2Decoder.Metadata.t(), binary()) ::
  tree_result()

Fetches the pointer of an IP in the data if available.

The pointer will be calculated to be relative to the start of the binary data.

usage

Usage

iex> MMDB2Decoder.find_pointer({127, 0, 0, 1}, meta, tree)
123456
Link to this function

lookup!(ip, meta, tree, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})

View Source

Calls lookup/4 and raises if an error occurs.

Link to this function

lookup(ip, meta, tree, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})

View Source

Looks up the data associated with an IP tuple.

This is probably the main function you will use. The ip address is expected to be a 4- or 8-element tuple describing an IPv4 or IPv6 address. To obtain this tuple from a string you can use :inet.parse_address/1.

usage

Usage

iex> MMDB2Decoder.lookup({127, 0, 0, 1}, meta, tree, data)
{
  :ok,
  %{
    "continent" => %{...},
    "country" => %{...},
    "registered_country" => %{...}
  }
}

The values for meta, tree and data can be obtained by parsing the file contents of a database using parse_database/1.

Link to this function

lookup_pointer!(pointer, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})

View Source
@spec lookup_pointer!(non_neg_integer(), binary(), decode_options()) :: lookup_value()

Calls lookup_pointer/3 and unrolls the return tuple.

Link to this function

lookup_pointer(pointer, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})

View Source
@spec lookup_pointer(non_neg_integer(), binary(), decode_options()) ::
  {:ok, lookup_value()}

Fetches the data at a given pointer position.

The pointer is expected to be relative to the start of the binary data.

usage

Usage

iex> MMDB2Decoder.lookup_pointer(123456, data)
{
  :ok,
  %{
    "continent" => %{...},
    "country" => %{...},
    "registered_country" => %{...}
  }
}
Link to this function

parse_database(contents)

View Source
@spec parse_database(binary()) :: parse_result()

Parses a database binary and splits it into metadata, lookup tree and data.

It is expected that you pass the real contents of the file, not the name of the database or the path to it.

usage

Usage

iex> MMDB2Decoder.parse_database(File.read!("/path/to/database.mmdb"))
{
  :ok,
  %MMDB2Decoder.Metadata{...},
  <<...>>,
  <<...>>
}

If parsing the database fails you will receive an appropriate error tuple:

iex> MMDB2Decoder.parse_database("invalid-database-contents")
{:error, :no_metadata}
Link to this function

pipe_lookup!(parse_result, ip, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})

View Source
@spec pipe_lookup!(parse_result(), :inet.ip_address(), decode_options()) ::
  lookup_value() | no_return()

Calls pipe_lookup/2 and raises if an error from parse_database/1 is given or occurs during lookup/4.

Link to this function

pipe_lookup(parse_result, ip, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})

View Source
@spec pipe_lookup(parse_result(), :inet.ip_address(), decode_options()) ::
  lookup_result()

Utility method to pipe parse_database/1 directly to lookup/4.

usage

Usage

Depending on how you handle the parsed database contents you may want to pass the results directly to the lookup.

iex> "/path/to/database.mmdb"
...> |> File.read!()
...> |> MMDB2Decoder.parse_database()
...> |> MMDB2Decoder.pipe_lookup({127, 0, 0, 1})
{:ok, %{...}}