MMDB2 Decoder v2.1.0 MMDB2Decoder View Source
MMDB2 file format decoder.
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(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
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::strings
is the default value:atoms
usesString.to_atom/1
:atoms!
usesString.to_existing_atom/1
:double_precision
defines the precision of decoded Double valuesnil
is the default for "unlimited" precision- any value from
Float.precision_range/0
to round the precision to
:float_precision
defines the precision of decoded Float valuesnil
is the default for "unlimited" precision- any value from
Float.precision_range/0
to round the precision to
Link to this section Summary
Functions
Fetches the pointer of an IP in the data if available.
Calls find_pointer/3
and raises if an error occurs.
Looks up the data associated with an IP tuple.
Calls lookup/4
and raises if an error occurs.
Fetches the data at a given pointer position.
Calls lookup_pointer/3
and unrolls the return tuple.
Parses a database binary and splits it into metadata, lookup tree and data.
Utility method to pipe parse_database/1
directly to lookup/4
.
Calls pipe_lookup/2
and raises if an error from parse_database/1
is given
or occurs during lookup/4
.
Link to this section Types
decode_option()
View Sourcedecode_option() :: {:double_precision, Float.precision_range()} | {:float_precision, Float.precision_range()} | {:map_keys, :atoms | :atoms! | :strings}
decode_options()
View Sourcedecode_options() :: decode_options_map() | [decode_option()]
decode_options_map()
View Sourcedecode_options_map() :: %{ optional(:double_precision) => nil | Float.precision_range(), optional(:float_precision) => nil | Float.precision_range(), optional(:map_keys) => nil | :atoms | :atoms! | :strings }
lookup_result()
View Sourcelookup_result() :: {:ok, lookup_value()} | {:error, term()}
parse_result()
View Sourceparse_result() :: {:ok, MMDB2Decoder.Metadata.t(), binary(), binary()} | {:error, term()}
tree_result()
View Sourcetree_result() :: {:ok, non_neg_integer()} | {:error, term()}
Link to this section Functions
find_pointer(ip, meta, tree)
View Sourcefind_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
iex> MMDB2Decoder.find_pointer({127, 0, 0, 1}, meta, tree)
123456
find_pointer!(ip, meta, tree)
View Sourcefind_pointer!(:inet.ip_address(), MMDB2Decoder.Metadata.t(), binary()) :: non_neg_integer() | no_return()
Calls find_pointer/3
and raises if an error occurs.
lookup(ip, meta, tree, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})
View Sourcelookup( :inet.ip_address(), MMDB2Decoder.Metadata.t(), binary(), binary(), decode_options() ) :: lookup_result()
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.ip_address/1
.
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
.
lookup!(ip, meta, tree, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})
View Sourcelookup!( :inet.ip_address(), MMDB2Decoder.Metadata.t(), binary(), binary(), decode_options() ) :: lookup_value() | no_return()
Calls lookup/4
and raises if an error occurs.
lookup_pointer(pointer, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})
View Sourcelookup_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
iex> MMDB2Decoder.lookup_pointer(123456, data)
{
:ok,
%{
"continent" => %{...},
"country" => %{...},
"registered_country" => %{...}
}
}
lookup_pointer!(pointer, data, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})
View Sourcelookup_pointer!(non_neg_integer(), binary(), decode_options()) :: lookup_value()
Calls lookup_pointer/3
and unrolls the return tuple.
parse_database(contents)
View Sourceparse_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
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}
pipe_lookup(parse_result, ip, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})
View Sourcepipe_lookup(parse_result(), :inet.ip_address(), decode_options()) :: lookup_result()
Utility method to pipe parse_database/1
directly to lookup/4
.
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, %{...}}
pipe_lookup!(parse_result, ip, options \\ %{double_precision: nil, float_precision: nil, map_keys: :strings})
View Sourcepipe_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
.