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