maxmind-geoip2 0.1.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/Gemfile +1 -5
  4. data/README.dev.md +1 -1
  5. data/README.md +82 -8
  6. data/lib/maxmind/geoip2.rb +1 -0
  7. data/lib/maxmind/geoip2/client.rb +333 -0
  8. data/lib/maxmind/geoip2/errors.rb +37 -3
  9. data/lib/maxmind/geoip2/model/abstract.rb +19 -15
  10. data/lib/maxmind/geoip2/model/anonymous_ip.rb +62 -50
  11. data/lib/maxmind/geoip2/model/asn.rb +33 -29
  12. data/lib/maxmind/geoip2/model/city.rb +59 -55
  13. data/lib/maxmind/geoip2/model/connection_type.rb +27 -23
  14. data/lib/maxmind/geoip2/model/country.rb +64 -53
  15. data/lib/maxmind/geoip2/model/domain.rb +27 -23
  16. data/lib/maxmind/geoip2/model/enterprise.rb +13 -9
  17. data/lib/maxmind/geoip2/model/insights.rb +18 -0
  18. data/lib/maxmind/geoip2/model/isp.rb +45 -41
  19. data/lib/maxmind/geoip2/reader.rb +260 -233
  20. data/lib/maxmind/geoip2/record/abstract.rb +17 -13
  21. data/lib/maxmind/geoip2/record/city.rb +33 -29
  22. data/lib/maxmind/geoip2/record/continent.rb +32 -28
  23. data/lib/maxmind/geoip2/record/country.rb +47 -43
  24. data/lib/maxmind/geoip2/record/location.rb +64 -60
  25. data/lib/maxmind/geoip2/record/maxmind.rb +21 -0
  26. data/lib/maxmind/geoip2/record/place.rb +22 -18
  27. data/lib/maxmind/geoip2/record/postal.rb +26 -22
  28. data/lib/maxmind/geoip2/record/represented_country.rb +20 -16
  29. data/lib/maxmind/geoip2/record/subdivision.rb +42 -38
  30. data/lib/maxmind/geoip2/record/traits.rb +204 -191
  31. data/maxmind-geoip2.gemspec +11 -3
  32. data/test/data/bad-data/maxminddb-python/bad-unicode-in-map-key.mmdb +0 -0
  33. data/test/data/source-data/GeoIP2-Anonymous-IP-Test.json +1 -0
  34. data/test/data/source-data/GeoIP2-ISP-Test.json +3 -1
  35. data/test/data/source-data/GeoIP2-Precision-Enterprise-Test.json +87 -0
  36. data/test/data/test-data/GeoIP2-Anonymous-IP-Test.mmdb +0 -0
  37. data/test/data/test-data/GeoIP2-City-Test-Broken-Double-Format.mmdb +0 -0
  38. data/test/data/test-data/GeoIP2-City-Test-Invalid-Node-Count.mmdb +0 -0
  39. data/test/data/test-data/GeoIP2-City-Test.mmdb +0 -0
  40. data/test/data/test-data/GeoIP2-Connection-Type-Test.mmdb +0 -0
  41. data/test/data/test-data/GeoIP2-Country-Test.mmdb +0 -0
  42. data/test/data/test-data/GeoIP2-DensityIncome-Test.mmdb +0 -0
  43. data/test/data/test-data/GeoIP2-Domain-Test.mmdb +0 -0
  44. data/test/data/test-data/GeoIP2-Enterprise-Test.mmdb +0 -0
  45. data/test/data/test-data/GeoIP2-ISP-Test.mmdb +0 -0
  46. data/test/data/test-data/GeoIP2-Precision-Enterprise-Test.mmdb +0 -0
  47. data/test/data/test-data/GeoIP2-Static-IP-Score-Test.mmdb +0 -0
  48. data/test/data/test-data/GeoIP2-User-Count-Test.mmdb +0 -0
  49. data/test/data/test-data/GeoLite2-ASN-Test.mmdb +0 -0
  50. data/test/data/test-data/MaxMind-DB-no-ipv4-search-tree.mmdb +0 -0
  51. data/test/data/test-data/MaxMind-DB-string-value-entries.mmdb +0 -0
  52. data/test/data/test-data/MaxMind-DB-test-broken-pointers-24.mmdb +0 -0
  53. data/test/data/test-data/MaxMind-DB-test-broken-search-tree-24.mmdb +0 -0
  54. data/test/data/test-data/MaxMind-DB-test-decoder.mmdb +0 -0
  55. data/test/data/test-data/MaxMind-DB-test-ipv4-24.mmdb +0 -0
  56. data/test/data/test-data/MaxMind-DB-test-ipv4-28.mmdb +0 -0
  57. data/test/data/test-data/MaxMind-DB-test-ipv4-32.mmdb +0 -0
  58. data/test/data/test-data/MaxMind-DB-test-ipv6-24.mmdb +0 -0
  59. data/test/data/test-data/MaxMind-DB-test-ipv6-28.mmdb +0 -0
  60. data/test/data/test-data/MaxMind-DB-test-ipv6-32.mmdb +0 -0
  61. data/test/data/test-data/MaxMind-DB-test-metadata-pointers.mmdb +0 -0
  62. data/test/data/test-data/MaxMind-DB-test-mixed-24.mmdb +0 -0
  63. data/test/data/test-data/MaxMind-DB-test-mixed-28.mmdb +0 -0
  64. data/test/data/test-data/MaxMind-DB-test-mixed-32.mmdb +0 -0
  65. data/test/data/test-data/MaxMind-DB-test-nested.mmdb +0 -0
  66. data/test/data/test-data/MaxMind-DB-test-pointer-decoder.mmdb +0 -0
  67. data/test/data/test-data/write-test-data.pl +68 -18
  68. data/test/test_client.rb +426 -0
  69. data/test/test_model_country.rb +16 -0
  70. data/test/test_reader.rb +59 -0
  71. metadata +113 -10
  72. data/Gemfile.lock +0 -38
@@ -2,62 +2,73 @@
2
2
 
3
3
  require 'maxmind/geoip2/record/continent'
4
4
  require 'maxmind/geoip2/record/country'
5
+ require 'maxmind/geoip2/record/maxmind'
5
6
  require 'maxmind/geoip2/record/represented_country'
6
7
  require 'maxmind/geoip2/record/traits'
7
8
 
8
- module MaxMind::GeoIP2::Model
9
- # Model class for the data returned by the GeoIP2 Country web service and
10
- # database. It is also used for GeoLite2 Country lookups.
11
- class Country
12
- # Continent data for the IP address.
13
- #
14
- # @return [MaxMind::GeoIP2::Record::Continent]
15
- attr_reader :continent
16
-
17
- # Country data for the IP address. This object represents the country where
18
- # MaxMind believes the end user is located.
19
- #
20
- # @return [MaxMind::GeoIP2::Record::Country]
21
- attr_reader :country
22
-
23
- # Registered country data for the IP address. This record represents the
24
- # country where the ISP has registered a given IP block and may differ from
25
- # the user's country.
26
- #
27
- # @return [MaxMind::GeoIP2::Record::Country]
28
- attr_reader :registered_country
29
-
30
- # Represented country data for the IP address. The represented country is
31
- # used for things like military bases. It is only present when the
32
- # represented country differs from the country.
33
- #
34
- # @return [MaxMind::GeoIP2::Record::RepresentedCountry]
35
- attr_reader :represented_country
36
-
37
- # Data for the traits of the IP address.
38
- #
39
- # @return [MaxMind::GeoIP2::Record::Traits]
40
- attr_reader :traits
41
-
42
- # @!visibility private
43
- def initialize(record, locales)
44
- @continent = MaxMind::GeoIP2::Record::Continent.new(
45
- record['continent'],
46
- locales,
47
- )
48
- @country = MaxMind::GeoIP2::Record::Country.new(
49
- record['country'],
50
- locales,
51
- )
52
- @registered_country = MaxMind::GeoIP2::Record::Country.new(
53
- record['registered_country'],
54
- locales,
55
- )
56
- @represented_country = MaxMind::GeoIP2::Record::RepresentedCountry.new(
57
- record['represented_country'],
58
- locales,
59
- )
60
- @traits = MaxMind::GeoIP2::Record::Traits.new(record['traits'])
9
+ module MaxMind
10
+ module GeoIP2
11
+ module Model
12
+ # Model class for the data returned by the GeoIP2 Country web service and
13
+ # database. It is also used for GeoLite2 Country lookups.
14
+ class Country
15
+ # Continent data for the IP address.
16
+ #
17
+ # @return [MaxMind::GeoIP2::Record::Continent]
18
+ attr_reader :continent
19
+
20
+ # Country data for the IP address. This object represents the country where
21
+ # MaxMind believes the end user is located.
22
+ #
23
+ # @return [MaxMind::GeoIP2::Record::Country]
24
+ attr_reader :country
25
+
26
+ # Data related to your MaxMind account.
27
+ #
28
+ # @return [MaxMind::GeoIP2::Record::MaxMind]
29
+ attr_reader :maxmind
30
+
31
+ # Registered country data for the IP address. This record represents the
32
+ # country where the ISP has registered a given IP block and may differ from
33
+ # the user's country.
34
+ #
35
+ # @return [MaxMind::GeoIP2::Record::Country]
36
+ attr_reader :registered_country
37
+
38
+ # Represented country data for the IP address. The represented country is
39
+ # used for things like military bases. It is only present when the
40
+ # represented country differs from the country.
41
+ #
42
+ # @return [MaxMind::GeoIP2::Record::RepresentedCountry]
43
+ attr_reader :represented_country
44
+
45
+ # Data for the traits of the IP address.
46
+ #
47
+ # @return [MaxMind::GeoIP2::Record::Traits]
48
+ attr_reader :traits
49
+
50
+ # @!visibility private
51
+ def initialize(record, locales)
52
+ @continent = MaxMind::GeoIP2::Record::Continent.new(
53
+ record['continent'],
54
+ locales,
55
+ )
56
+ @country = MaxMind::GeoIP2::Record::Country.new(
57
+ record['country'],
58
+ locales,
59
+ )
60
+ @maxmind = MaxMind::GeoIP2::Record::MaxMind.new(record['maxmind'])
61
+ @registered_country = MaxMind::GeoIP2::Record::Country.new(
62
+ record['registered_country'],
63
+ locales,
64
+ )
65
+ @represented_country = MaxMind::GeoIP2::Record::RepresentedCountry.new(
66
+ record['represented_country'],
67
+ locales,
68
+ )
69
+ @traits = MaxMind::GeoIP2::Record::Traits.new(record['traits'])
70
+ end
71
+ end
61
72
  end
62
73
  end
63
74
  end
@@ -2,31 +2,35 @@
2
2
 
3
3
  require 'maxmind/geoip2/model/abstract'
4
4
 
5
- module MaxMind::GeoIP2::Model
6
- # Model class for the GeoIP2 Domain database.
7
- class Domain < Abstract
8
- # The second level domain associated with the IP address. This will be
9
- # something like "example.com" or "example.co.uk", not "foo.example.com".
10
- #
11
- # @return [String, nil]
12
- def domain
13
- get('domain')
14
- end
5
+ module MaxMind
6
+ module GeoIP2
7
+ module Model
8
+ # Model class for the GeoIP2 Domain database.
9
+ class Domain < Abstract
10
+ # The second level domain associated with the IP address. This will be
11
+ # something like "example.com" or "example.co.uk", not "foo.example.com".
12
+ #
13
+ # @return [String, nil]
14
+ def domain
15
+ get('domain')
16
+ end
15
17
 
16
- # The IP address that the data in the model is for.
17
- #
18
- # @return [String]
19
- def ip_address
20
- get('ip_address')
21
- end
18
+ # The IP address that the data in the model is for.
19
+ #
20
+ # @return [String]
21
+ def ip_address
22
+ get('ip_address')
23
+ end
22
24
 
23
- # The network in CIDR notation associated with the record. In particular,
24
- # this is the largest network where all of the fields besides ip_address
25
- # have the same value.
26
- #
27
- # @return [String]
28
- def network
29
- get('network')
25
+ # The network in CIDR notation associated with the record. In particular,
26
+ # this is the largest network where all of the fields besides ip_address
27
+ # have the same value.
28
+ #
29
+ # @return [String]
30
+ def network
31
+ get('network')
32
+ end
33
+ end
30
34
  end
31
35
  end
32
36
  end
@@ -2,14 +2,18 @@
2
2
 
3
3
  require 'maxmind/geoip2/model/city'
4
4
 
5
- module MaxMind::GeoIP2::Model
6
- # Model class for the data returned by GeoIP2 Enterprise database lookups.
7
- #
8
- # The only difference between the City and Insights model classes is which
9
- # fields in each record may be populated. See
10
- # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
11
- #
12
- # See {MaxMind::GeoIP2::Model::City} for inherited methods.
13
- class Enterprise < City
5
+ module MaxMind
6
+ module GeoIP2
7
+ module Model
8
+ # Model class for the data returned by GeoIP2 Enterprise database lookups.
9
+ #
10
+ # The only difference between the City and Insights model classes is which
11
+ # fields in each record may be populated. See
12
+ # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
13
+ #
14
+ # See {MaxMind::GeoIP2::Model::City} for inherited methods.
15
+ class Enterprise < City
16
+ end
17
+ end
14
18
  end
15
19
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/model/city'
4
+
5
+ module MaxMind
6
+ module GeoIP2
7
+ module Model
8
+ # Model class for the data returned by the GeoIP2 Precision Insights web
9
+ # service.
10
+ #
11
+ # The only difference between the City and Insights model classes is which
12
+ # fields in each record may be populated. See
13
+ # https://dev.maxmind.com/geoip/geoip2/web-services for more details.
14
+ class Insights < City
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,52 +2,56 @@
2
2
 
3
3
  require 'maxmind/geoip2/model/abstract'
4
4
 
5
- module MaxMind::GeoIP2::Model
6
- # Model class for the GeoIP2 ISP database.
7
- class ISP < Abstract
8
- # The autonomous system number associated with the IP address.
9
- #
10
- # @return [Integer, nil]
11
- def autonomous_system_number
12
- get('autonomous_system_number')
13
- end
5
+ module MaxMind
6
+ module GeoIP2
7
+ module Model
8
+ # Model class for the GeoIP2 ISP database.
9
+ class ISP < Abstract
10
+ # The autonomous system number associated with the IP address.
11
+ #
12
+ # @return [Integer, nil]
13
+ def autonomous_system_number
14
+ get('autonomous_system_number')
15
+ end
14
16
 
15
- # The organization associated with the registered autonomous system number
16
- # for the IP address.
17
- #
18
- # @return [String, nil]
19
- def autonomous_system_organization
20
- get('autonomous_system_organization')
21
- end
17
+ # The organization associated with the registered autonomous system number
18
+ # for the IP address.
19
+ #
20
+ # @return [String, nil]
21
+ def autonomous_system_organization
22
+ get('autonomous_system_organization')
23
+ end
22
24
 
23
- # The IP address that the data in the model is for.
24
- #
25
- # @return [String]
26
- def ip_address
27
- get('ip_address')
28
- end
25
+ # The IP address that the data in the model is for.
26
+ #
27
+ # @return [String]
28
+ def ip_address
29
+ get('ip_address')
30
+ end
29
31
 
30
- # The name of the ISP associated with the IP address.
31
- #
32
- # @return [String, nil]
33
- def isp
34
- get('isp')
35
- end
32
+ # The name of the ISP associated with the IP address.
33
+ #
34
+ # @return [String, nil]
35
+ def isp
36
+ get('isp')
37
+ end
36
38
 
37
- # The network in CIDR notation associated with the record. In particular,
38
- # this is the largest network where all of the fields besides ip_address
39
- # have the same value.
40
- #
41
- # @return [String]
42
- def network
43
- get('network')
44
- end
39
+ # The network in CIDR notation associated with the record. In particular,
40
+ # this is the largest network where all of the fields besides ip_address
41
+ # have the same value.
42
+ #
43
+ # @return [String]
44
+ def network
45
+ get('network')
46
+ end
45
47
 
46
- # The name of the organization associated with the IP address.
47
- #
48
- # @return [String, nil]
49
- def organization
50
- get('organization')
48
+ # The name of the organization associated with the IP address.
49
+ #
50
+ # @return [String, nil]
51
+ def organization
52
+ get('organization')
53
+ end
54
+ end
51
55
  end
52
56
  end
53
57
  end
@@ -11,267 +11,294 @@ require 'maxmind/geoip2/model/domain'
11
11
  require 'maxmind/geoip2/model/enterprise'
12
12
  require 'maxmind/geoip2/model/isp'
13
13
 
14
- module MaxMind::GeoIP2
15
- # Reader is a reader for the GeoIP2/GeoLite2 database format. IP addresses
16
- # can be looked up using the database specific methods.
17
- #
18
- # == Example
19
- #
20
- # require 'maxmind/geoip2'
21
- #
22
- # reader = MaxMind::GeoIP2::Reader.new('GeoIP2-Country.mmdb')
23
- #
24
- # record = reader.country('1.2.3.4')
25
- # puts record.country.iso_code
26
- #
27
- # reader.close
28
- class Reader
29
- # Create a Reader for looking up IP addresses in a GeoIP2/GeoLite2 database
30
- # file.
14
+ module MaxMind
15
+ module GeoIP2
16
+ # Reader is a reader for the GeoIP2/GeoLite2 database format. IP addresses
17
+ # can be looked up using the database specific methods.
31
18
  #
32
- # If you're performing multiple lookups, it's most efficient to create one
33
- # Reader and reuse it.
19
+ # == Example
34
20
  #
35
- # Once created, the Reader is safe to use for lookups from multiple
36
- # threads. It is safe to use after forking only if you use
37
- # MaxMind::DB::MODE_MEMORY or if your version of Ruby supports IO#pread.
21
+ # require 'maxmind/geoip2'
38
22
  #
39
- # @param database [String] a path to a GeoIP2/GeoLite2 database file.
23
+ # reader = MaxMind::GeoIP2::Reader.new(database: 'GeoIP2-Country.mmdb')
40
24
  #
41
- # @param locales [Array<String>] a list of locale codes to use in the name
42
- # property from most preferred to least preferred.
25
+ # record = reader.country('1.2.3.4')
26
+ # puts record.country.iso_code
43
27
  #
44
- # @param options [Hash<Symbol, Symbol>] options controlling the behavior of
45
- # the Reader.
46
- #
47
- # @option options [Symbol] :mode Defines how to open the database. It may
48
- # be one of MaxMind::DB::MODE_AUTO, MaxMind::DB::MODE_FILE, or
49
- # MaxMind::DB::MODE_MEMORY. If you don't provide one, the Reader uses
50
- # MaxMind::DB::MODE_AUTO. Refer to the definition of those constants in
51
- # MaxMind::DB for an explanation of their meaning.
52
- #
53
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database is corrupt or
54
- # invalid.
55
- #
56
- # @raise [ArgumentError] if the mode is invalid.
57
- def initialize(database, locales = ['en'], options = {})
58
- @reader = MaxMind::DB.new(database, options)
59
- @type = @reader.metadata.database_type
60
- locales = ['en'] if locales.empty?
61
- @locales = locales
62
- end
28
+ # reader.close
29
+ class Reader
30
+ # rubocop:disable Metrics/CyclomaticComplexity
31
+ # rubocop:disable Metrics/PerceivedComplexity
63
32
 
64
- # Look up the IP address in the database.
65
- #
66
- # @param ip_address [String] a string in the standard notation. It may be
67
- # IPv4 or IPv6.
68
- #
69
- # @return [MaxMind::GeoIP2::Model::AnonymousIP]
70
- #
71
- # @raise [ArgumentError] if used against a non-Anonymous IP database or if
72
- # you attempt to look up an IPv6 address in an IPv4 only database.
73
- #
74
- # @raise [AddressNotFoundError] if the IP address is not found in the
75
- # database.
76
- #
77
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
78
- # corrupt.
79
- def anonymous_ip(ip_address)
80
- flat_model_for(
81
- Model::AnonymousIP,
82
- 'anonymous_ip',
83
- 'GeoIP2-Anonymous-IP',
84
- ip_address,
85
- )
86
- end
33
+ # Create a Reader for looking up IP addresses in a GeoIP2/GeoLite2 database
34
+ # file.
35
+ #
36
+ # If you're performing multiple lookups, it's most efficient to create one
37
+ # Reader and reuse it.
38
+ #
39
+ # Once created, the Reader is safe to use for lookups from multiple
40
+ # threads. It is safe to use after forking only if you use
41
+ # MaxMind::DB::MODE_MEMORY or if your version of Ruby supports IO#pread.
42
+ #
43
+ # @overload initialize(database:, locales: ['en'], mode: MaxMind::DB::MODE_AUTO)
44
+ # @param database [String] a path to a GeoIP2/GeoLite2 database file.
45
+ # @param locales [Array<String>] a list of locale codes to use in the name
46
+ # property from most preferred to least preferred.
47
+ # @param mode [Symbol] Defines how to open the database. It may be one of
48
+ # MaxMind::DB::MODE_AUTO, MaxMind::DB::MODE_FILE, or
49
+ # MaxMind::DB::MODE_MEMORY. If you don't provide one, the Reader uses
50
+ # MaxMind::DB::MODE_AUTO. Refer to the definition of those constants in
51
+ # MaxMind::DB for an explanation of their meaning.
52
+ #
53
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database is corrupt
54
+ # or invalid.
55
+ #
56
+ # @raise [ArgumentError] if the mode is invalid.
57
+ def initialize(*args)
58
+ # This if statement is to let us support calling as though we are using
59
+ # Ruby 2.0 keyword arguments. We can't use keyword argument syntax as
60
+ # we want to be backwards compatible with the old way we accepted
61
+ # parameters, which looked like:
62
+ # def initialize(database, locales = ['en'], options = {})
63
+ if args.length == 1 && args[0].instance_of?(Hash)
64
+ database = args[0][:database]
65
+ locales = args[0][:locales]
66
+ mode = args[0][:mode]
67
+ else
68
+ database = args[0]
69
+ locales = args[1]
70
+ mode = args[2].instance_of?(Hash) ? args[2][:mode] : nil
71
+ end
87
72
 
88
- # Look up the IP address in an ASN database.
89
- #
90
- # @param ip_address [String] a string in the standard notation. It may be
91
- # IPv4 or IPv6.
92
- #
93
- # @return [MaxMind::GeoIP2::Model::ASN]
94
- #
95
- # @raise [ArgumentError] if used against a non-ASN database or if you
96
- # attempt to look up an IPv6 address in an IPv4 only database.
97
- #
98
- # @raise [AddressNotFoundError] if the IP address is not found in the
99
- # database.
100
- #
101
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
102
- # corrupt.
103
- def asn(ip_address)
104
- flat_model_for(Model::ASN, 'asn', 'GeoLite2-ASN', ip_address)
105
- end
73
+ if !database.instance_of?(String)
74
+ raise ArgumentError, 'Invalid database parameter'
75
+ end
106
76
 
107
- # Look up the IP address in a City database.
108
- #
109
- # @param ip_address [String] a string in the standard notation. It may be
110
- # IPv4 or IPv6.
111
- #
112
- # @return [MaxMind::GeoIP2::Model::City]
113
- #
114
- # @raise [ArgumentError] if used against a non-City database or if you
115
- # attempt to look up an IPv6 address in an IPv4 only database.
116
- #
117
- # @raise [AddressNotFoundError] if the IP address is not found in the
118
- # database.
119
- #
120
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
121
- # corrupt.
122
- def city(ip_address)
123
- model_for(Model::City, 'city', 'City', ip_address)
124
- end
77
+ locales = ['en'] if locales.nil? || locales.empty?
125
78
 
126
- # Look up the IP address in a Connection Type database.
127
- #
128
- # @param ip_address [String] a string in the standard notation. It may be
129
- # IPv4 or IPv6.
130
- #
131
- # @return [MaxMind::GeoIP2::Model::ConnectionType]
132
- #
133
- # @raise [ArgumentError] if used against a non-Connection Type database or if
134
- # you attempt to look up an IPv6 address in an IPv4 only database.
135
- #
136
- # @raise [AddressNotFoundError] if the IP address is not found in the
137
- # database.
138
- #
139
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
140
- # corrupt.
141
- def connection_type(ip_address)
142
- flat_model_for(
143
- Model::ConnectionType,
144
- 'connection_type',
145
- 'GeoIP2-Connection-Type',
146
- ip_address,
147
- )
148
- end
79
+ options = {}
80
+ options[:mode] = mode if !mode.nil?
81
+ @reader = MaxMind::DB.new(database, options)
149
82
 
150
- # Look up the IP address in a Country database.
151
- #
152
- # @param ip_address [String] a string in the standard notation. It may be
153
- # IPv4 or IPv6.
154
- #
155
- # @return [MaxMind::GeoIP2::Model::Country]
156
- #
157
- # @raise [ArgumentError] if used against a non-Country database or if you
158
- # attempt to look up an IPv6 address in an IPv4 only database.
159
- #
160
- # @raise [AddressNotFoundError] if the IP address is not found in the
161
- # database.
162
- #
163
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
164
- # corrupt.
165
- def country(ip_address)
166
- model_for(Model::Country, 'country', 'Country', ip_address)
167
- end
83
+ @type = @reader.metadata.database_type
168
84
 
169
- # Look up the IP address in a Domain database.
170
- #
171
- # @param ip_address [String] a string in the standard notation. It may be
172
- # IPv4 or IPv6.
173
- #
174
- # @return [MaxMind::GeoIP2::Model::Domain]
175
- #
176
- # @raise [ArgumentError] if used against a non-Domain database or if you
177
- # attempt to look up an IPv6 address in an IPv4 only database.
178
- #
179
- # @raise [AddressNotFoundError] if the IP address is not found in the
180
- # database.
181
- #
182
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
183
- # corrupt.
184
- def domain(ip_address)
185
- flat_model_for(Model::Domain, 'domain', 'GeoIP2-Domain', ip_address)
186
- end
85
+ @locales = locales
86
+ end
87
+ # rubocop:enable Metrics/CyclomaticComplexity
88
+ # rubocop:enable Metrics/PerceivedComplexity
187
89
 
188
- # Look up the IP address in an Enterprise database.
189
- #
190
- # @param ip_address [String] a string in the standard notation. It may be
191
- # IPv4 or IPv6.
192
- #
193
- # @return [MaxMind::GeoIP2::Model::Enterprise]
194
- #
195
- # @raise [ArgumentError] if used against a non-Enterprise database or if
196
- # you attempt to look up an IPv6 address in an IPv4 only database.
197
- #
198
- # @raise [AddressNotFoundError] if the IP address is not found in the
199
- # database.
200
- #
201
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
202
- # corrupt.
203
- def enterprise(ip_address)
204
- model_for(Model::Enterprise, 'enterprise', 'Enterprise', ip_address)
205
- end
90
+ # Look up the IP address in the database.
91
+ #
92
+ # @param ip_address [String] a string in the standard notation. It may be
93
+ # IPv4 or IPv6.
94
+ #
95
+ # @return [MaxMind::GeoIP2::Model::AnonymousIP]
96
+ #
97
+ # @raise [ArgumentError] if used against a non-Anonymous IP database or if
98
+ # you attempt to look up an IPv6 address in an IPv4 only database.
99
+ #
100
+ # @raise [AddressNotFoundError] if the IP address is not found in the
101
+ # database.
102
+ #
103
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
104
+ # corrupt.
105
+ def anonymous_ip(ip_address)
106
+ flat_model_for(
107
+ Model::AnonymousIP,
108
+ 'anonymous_ip',
109
+ 'GeoIP2-Anonymous-IP',
110
+ ip_address,
111
+ )
112
+ end
206
113
 
207
- # Look up the IP address in an ISP database.
208
- #
209
- # @param ip_address [String] a string in the standard notation. It may be
210
- # IPv4 or IPv6.
211
- #
212
- # @return [MaxMind::GeoIP2::Model::ISP]
213
- #
214
- # @raise [ArgumentError] if used against a non-ISP database or if you
215
- # attempt to look up an IPv6 address in an IPv4 only database.
216
- #
217
- # @raise [AddressNotFoundError] if the IP address is not found in the
218
- # database.
219
- #
220
- # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
221
- # corrupt.
222
- def isp(ip_address)
223
- flat_model_for(Model::ISP, 'isp', 'GeoIP2-ISP', ip_address)
224
- end
114
+ # Look up the IP address in an ASN database.
115
+ #
116
+ # @param ip_address [String] a string in the standard notation. It may be
117
+ # IPv4 or IPv6.
118
+ #
119
+ # @return [MaxMind::GeoIP2::Model::ASN]
120
+ #
121
+ # @raise [ArgumentError] if used against a non-ASN database or if you
122
+ # attempt to look up an IPv6 address in an IPv4 only database.
123
+ #
124
+ # @raise [AddressNotFoundError] if the IP address is not found in the
125
+ # database.
126
+ #
127
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
128
+ # corrupt.
129
+ def asn(ip_address)
130
+ flat_model_for(Model::ASN, 'asn', 'GeoLite2-ASN', ip_address)
131
+ end
225
132
 
226
- # Return the metadata associated with the database.
227
- #
228
- # @return [MaxMind::DB::Metadata]
229
- def metadata
230
- @reader.metadata
231
- end
133
+ # Look up the IP address in a City database.
134
+ #
135
+ # @param ip_address [String] a string in the standard notation. It may be
136
+ # IPv4 or IPv6.
137
+ #
138
+ # @return [MaxMind::GeoIP2::Model::City]
139
+ #
140
+ # @raise [ArgumentError] if used against a non-City database or if you
141
+ # attempt to look up an IPv6 address in an IPv4 only database.
142
+ #
143
+ # @raise [AddressNotFoundError] if the IP address is not found in the
144
+ # database.
145
+ #
146
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
147
+ # corrupt.
148
+ def city(ip_address)
149
+ model_for(Model::City, 'city', 'City', ip_address)
150
+ end
232
151
 
233
- # Close the Reader and return resources to the system.
234
- #
235
- # @return [void]
236
- def close
237
- @reader.close
238
- end
152
+ # Look up the IP address in a Connection Type database.
153
+ #
154
+ # @param ip_address [String] a string in the standard notation. It may be
155
+ # IPv4 or IPv6.
156
+ #
157
+ # @return [MaxMind::GeoIP2::Model::ConnectionType]
158
+ #
159
+ # @raise [ArgumentError] if used against a non-Connection Type database or if
160
+ # you attempt to look up an IPv6 address in an IPv4 only database.
161
+ #
162
+ # @raise [AddressNotFoundError] if the IP address is not found in the
163
+ # database.
164
+ #
165
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
166
+ # corrupt.
167
+ def connection_type(ip_address)
168
+ flat_model_for(
169
+ Model::ConnectionType,
170
+ 'connection_type',
171
+ 'GeoIP2-Connection-Type',
172
+ ip_address,
173
+ )
174
+ end
239
175
 
240
- private
176
+ # Look up the IP address in a Country database.
177
+ #
178
+ # @param ip_address [String] a string in the standard notation. It may be
179
+ # IPv4 or IPv6.
180
+ #
181
+ # @return [MaxMind::GeoIP2::Model::Country]
182
+ #
183
+ # @raise [ArgumentError] if used against a non-Country database or if you
184
+ # attempt to look up an IPv6 address in an IPv4 only database.
185
+ #
186
+ # @raise [AddressNotFoundError] if the IP address is not found in the
187
+ # database.
188
+ #
189
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
190
+ # corrupt.
191
+ def country(ip_address)
192
+ model_for(Model::Country, 'country', 'Country', ip_address)
193
+ end
241
194
 
242
- def model_for(model_class, method, type, ip_address)
243
- record, prefix_length = get_record(method, type, ip_address)
195
+ # Look up the IP address in a Domain database.
196
+ #
197
+ # @param ip_address [String] a string in the standard notation. It may be
198
+ # IPv4 or IPv6.
199
+ #
200
+ # @return [MaxMind::GeoIP2::Model::Domain]
201
+ #
202
+ # @raise [ArgumentError] if used against a non-Domain database or if you
203
+ # attempt to look up an IPv6 address in an IPv4 only database.
204
+ #
205
+ # @raise [AddressNotFoundError] if the IP address is not found in the
206
+ # database.
207
+ #
208
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
209
+ # corrupt.
210
+ def domain(ip_address)
211
+ flat_model_for(Model::Domain, 'domain', 'GeoIP2-Domain', ip_address)
212
+ end
244
213
 
245
- record['traits'] = {} if !record.key?('traits')
246
- record['traits']['ip_address'] = ip_address
247
- record['traits']['prefix_length'] = prefix_length
214
+ # Look up the IP address in an Enterprise database.
215
+ #
216
+ # @param ip_address [String] a string in the standard notation. It may be
217
+ # IPv4 or IPv6.
218
+ #
219
+ # @return [MaxMind::GeoIP2::Model::Enterprise]
220
+ #
221
+ # @raise [ArgumentError] if used against a non-Enterprise database or if
222
+ # you attempt to look up an IPv6 address in an IPv4 only database.
223
+ #
224
+ # @raise [AddressNotFoundError] if the IP address is not found in the
225
+ # database.
226
+ #
227
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
228
+ # corrupt.
229
+ def enterprise(ip_address)
230
+ model_for(Model::Enterprise, 'enterprise', 'Enterprise', ip_address)
231
+ end
248
232
 
249
- model_class.new(record, @locales)
250
- end
233
+ # Look up the IP address in an ISP database.
234
+ #
235
+ # @param ip_address [String] a string in the standard notation. It may be
236
+ # IPv4 or IPv6.
237
+ #
238
+ # @return [MaxMind::GeoIP2::Model::ISP]
239
+ #
240
+ # @raise [ArgumentError] if used against a non-ISP database or if you
241
+ # attempt to look up an IPv6 address in an IPv4 only database.
242
+ #
243
+ # @raise [AddressNotFoundError] if the IP address is not found in the
244
+ # database.
245
+ #
246
+ # @raise [MaxMind::DB::InvalidDatabaseError] if the database appears
247
+ # corrupt.
248
+ def isp(ip_address)
249
+ flat_model_for(Model::ISP, 'isp', 'GeoIP2-ISP', ip_address)
250
+ end
251
251
 
252
- def get_record(method, type, ip_address)
253
- if !@type.include?(type)
254
- raise ArgumentError,
255
- "The #{method} method cannot be used with the #{@type} database."
252
+ # Return the metadata associated with the database.
253
+ #
254
+ # @return [MaxMind::DB::Metadata]
255
+ def metadata
256
+ @reader.metadata
256
257
  end
257
258
 
258
- record, prefix_length = @reader.get_with_prefix_length(ip_address)
259
+ # Close the Reader and return resources to the system.
260
+ #
261
+ # @return [void]
262
+ def close
263
+ @reader.close
264
+ end
259
265
 
260
- if record.nil?
261
- raise AddressNotFoundError,
262
- "The address #{ip_address} is not in the database."
266
+ private
267
+
268
+ def model_for(model_class, method, type, ip_address)
269
+ record, prefix_length = get_record(method, type, ip_address)
270
+
271
+ record['traits'] = {} if !record.key?('traits')
272
+ record['traits']['ip_address'] = ip_address
273
+ record['traits']['prefix_length'] = prefix_length
274
+
275
+ model_class.new(record, @locales)
263
276
  end
264
277
 
265
- [record, prefix_length]
266
- end
278
+ def get_record(method, type, ip_address)
279
+ if !@type.include?(type)
280
+ raise ArgumentError,
281
+ "The #{method} method cannot be used with the #{@type} database."
282
+ end
267
283
 
268
- def flat_model_for(model_class, method, type, ip_address)
269
- record, prefix_length = get_record(method, type, ip_address)
284
+ record, prefix_length = @reader.get_with_prefix_length(ip_address)
270
285
 
271
- record['ip_address'] = ip_address
272
- record['prefix_length'] = prefix_length
286
+ if record.nil?
287
+ raise AddressNotFoundError,
288
+ "The address #{ip_address} is not in the database."
289
+ end
273
290
 
274
- model_class.new(record)
291
+ [record, prefix_length]
292
+ end
293
+
294
+ def flat_model_for(model_class, method, type, ip_address)
295
+ record, prefix_length = get_record(method, type, ip_address)
296
+
297
+ record['ip_address'] = ip_address
298
+ record['prefix_length'] = prefix_length
299
+
300
+ model_class.new(record)
301
+ end
275
302
  end
276
303
  end
277
304
  end