Class: MaxMind::DB

Inherits:
Object
  • Object
show all
Defined in:
lib/maxmind/db.rb,
lib/maxmind/db/errors.rb,
lib/maxmind/db/decoder.rb,
lib/maxmind/db/metadata.rb,
lib/maxmind/db/file_reader.rb,
lib/maxmind/db/memory_reader.rb

Overview

DB provides a way to read MaxMind DB files.

MaxMind DB is a binary file format that stores data indexed by IP address subnets (IPv4 or IPv6).

This class is a pure Ruby implementation of a reader for the format.

Example

require 'maxmind/db'

reader = MaxMind::DB.new('GeoIP2-City.mmdb', mode: MaxMind::DB::MODE_MEMORY)

record = reader.get('1.1.1.1')
if record.nil?
  puts '1.1.1.1 was not found in the database'
else
  puts record['country']['iso_code']
  puts record['country']['names']['en']
end

reader.close

Exceptions

DB raises an InvalidDatabaseError if the database is corrupt or invalid. It can raise other exceptions, such as ArgumentError, if other errors occur.

Defined Under Namespace

Classes: Decoder, FileReader, InvalidDatabaseError, MemoryReader, Metadata

Constant Summary collapse

MODE_AUTO =

Choose the default method to open the database. Currently the default is MODE_FILE.

:MODE_AUTO
MODE_FILE =

Open the database as a regular file and read on demand.

:MODE_FILE
MODE_MEMORY =

Read the database into memory. This is faster than MODE_FILE but causes increased memory use.

:MODE_MEMORY
MODE_PARAM_IS_BUFFER =

Treat the database parameter as containing a database already read into memory. It must be a binary string. This primarily exists for testing.

:MODE_PARAM_IS_BUFFER

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(database, options = {}) ⇒ DB

Create a DB. A DB provides a way to read MaxMind DB files. If you’re performing multiple lookups, it’s most efficient to create one DB and reuse it.

Once created, the DB is safe to use for lookups from multiple threads. It is safe to use after forking only if you use MODE_MEMORY or if your version of Ruby supports IO#pread.

Creating the DB may raise an exception if initialization fails.

database is a path to a MaxMind DB.

options is an option hash where each key is a symbol. The options control the behaviour of the DB.

The available options are:

:mode

defines how to open the database. It may be one of MODE_AUTO, MODE_FILE, or MODE_MEMORY. If you don’t provide one, DB uses MODE_AUTO. Refer to the definition of those constants for an explanation of their meaning.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/maxmind/db.rb', line 87

def initialize(database, options = {})
  options[:mode] = MODE_AUTO unless options.key?(:mode)

  case options[:mode]
  when MODE_AUTO, MODE_FILE
    @io = FileReader.new(database)
  when MODE_MEMORY
    @io = MemoryReader.new(database)
  when MODE_PARAM_IS_BUFFER
    @io = MemoryReader.new(database, is_buffer: true)
  else
    raise ArgumentError, 'Invalid mode'
  end

  begin
    @size = @io.size

     = 
     = Decoder.new(@io, )
    , = .decode()
     = .new()
    @decoder = Decoder.new(@io, .search_tree_size +
                           DATA_SECTION_SEPARATOR_SIZE)

    # Store copies as instance variables to reduce method calls.
    @ip_version       = .ip_version
    @node_count       = .node_count
    @node_byte_size   = .node_byte_size
    @record_size      = .record_size
    @search_tree_size = .search_tree_size

    @ipv4_start = nil
    # Find @ipv4_start up front. If we don't, we either have a race to
    # get/set it or have to synchronize access.
    start_node(0)
  rescue StandardError => e
    @io.close
    raise e
  end
end

Instance Attribute Details

#metadataObject (readonly)

Return the metadata associated with the MaxMind DB as a Metadata object.



63
64
65
# File 'lib/maxmind/db.rb', line 63

def 
  
end

Instance Method Details

#closeObject

Close the DB and return resources to the system.

There is no useful return value. #close raises an exception if there is an error.



295
296
297
# File 'lib/maxmind/db.rb', line 295

def close
  @io.close
end

#get(ip_address) ⇒ Object

Return the record for the ip_address in the MaxMind DB. The record can be one of several types and depends on the contents of the database.

If no record is found for ip_address, get returns nil.

get raises an exception if there is an error performing the lookup.

ip_address is a string in the standard notation. It may be IPv4 or IPv6.



138
139
140
141
142
# File 'lib/maxmind/db.rb', line 138

def get(ip_address)
  record, = get_with_prefix_length(ip_address)

  record
end

#get_with_prefix_length(ip_address) ⇒ Object

Return an array containing the record for the ip_address in the MaxMind DB and its associated network prefix length. The record can be one of several types and depends on the contents of the database.

If no record is found for ip_address, the record will be nil and the prefix length will be the value for the missing network.

get_with_prefix_length raises an exception if there is an error performing the lookup.

ip_address is a string in the standard notation. It may be IPv4 or IPv6.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/maxmind/db.rb', line 157

def get_with_prefix_length(ip_address)
  ip = IPAddr.new(ip_address)
  # We could check the IP has the correct prefix (32 or 128) but I do not
  # for performance reasons.

  ip_version = ip.ipv6? ? 6 : 4
  if ip_version == 6 && @ip_version == 4
    raise ArgumentError,
          "Error looking up #{ip}. You attempted to look up an IPv6 address in an IPv4-only database."
  end

  pointer, depth = find_address_in_tree(ip, ip_version)
  return nil, depth if pointer == 0

  [resolve_data_pointer(pointer), depth]
end