From 6ad9fde623adf027c088b11da315b0e453d23920 Mon Sep 17 00:00:00 2001 From: Alex Reisner <alex@alexreisner.com> Date: Sun, 23 Feb 2014 01:07:26 -0500 Subject: [PATCH] Add local DB support for :maxmind_local lookup. --- lib/geocoder/lookups/maxmind_local.rb | 34 ++++++++++++++++----------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/geocoder/lookups/maxmind_local.rb b/lib/geocoder/lookups/maxmind_local.rb index ccca8774..94867e67 100644 --- a/lib/geocoder/lookups/maxmind_local.rb +++ b/lib/geocoder/lookups/maxmind_local.rb @@ -1,3 +1,4 @@ +require 'ipaddr' require 'geocoder/lookups/base' require 'geocoder/results/maxmind_local' @@ -5,11 +6,13 @@ module Geocoder::Lookup class MaxmindLocal < Base def initialize - begin - gem = RUBY_PLATFORM == 'java' ? 'jgeoip' : 'geoip' - require gem - rescue LoadError - raise "Could not load geoip dependency. To use MaxMind Local lookup you must add the #{gem} gem to your Gemfile or have it installed in your system." + if !configuration[:file].nil? + begin + gem = RUBY_PLATFORM == 'java' ? 'jgeoip' : 'geoip' + require gem + rescue LoadError + raise "Could not load geoip dependency. To use MaxMind Local lookup you must add the #{gem} gem to your Gemfile or have it installed in your system." + end end super end @@ -25,16 +28,19 @@ module Geocoder::Lookup private def results(query) - if configuration[:database].nil? - raise( - Geocoder::ConfigurationError, - "When using MaxMind Database you MUST specify the path: " + - "Geocoder.configure(:maxmind_local => {:database => ...}), " - ) + if !configuration[:file].nil? + geoip_class = RUBY_PLATFORM == "java" ? JGeoIP : GeoIP + result = geoip_class.new(configuration[:file]).city(query.to_s) + result.nil? ? [] : [result.to_hash] + else + addr = IPAddr.new(query.text).to_i + q = "SELECT l.country, l.region, l.city + FROM maxmind_location l JOIN maxmind_blocks b USING (locId) + WHERE b.startIpNum <= #{addr} AND #{addr} <= b.endIpNum AND b.endIpNum" + if r = ActiveRecord::Base.connection.execute(q).first + [Hash[*[:country_name, :region_name, :city_name].zip(r).flatten]] + end end - geoip_class = RUBY_PLATFORM == "java" ? JGeoIP : GeoIP - result = geoip_class.new(configuration[:database]).city(query.to_s) - result.nil? ? [] : [result.to_hash] end end end -- GitLab