Skip to content
Snippets Groups Projects
Commit d35b9d7b authored by Alex Reisner's avatar Alex Reisner
Browse files

Merge pull request #376 from nicolasdespres/more_control_over_select_clause

More control over select clause
parents a33bbebe 81ae5d4e
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
require 'geocoder/sql'
require 'geocoder/stores/base'
......@@ -93,13 +94,19 @@ module Geocoder::Store
# between the given point and each found nearby point;
# set to false for no bearing calculation. Use
# Geocoder.configure[:distances] to configure default calculation method.
# * +:select+ - string with the SELECT SQL fragment (e.g. “id, name”)
# * +:order+ - column(s) for ORDER BY SQL clause; default is distance;
# set to false or nil to omit the ORDER BY clause
# * +:exclude+ - an object to exclude (used by the +nearbys+ method)
# * +:select+ - string with the SELECT SQL fragment (e.g. “id, name”)
# * +:select_distance+ - whether to include the distance alias in the
# SELECT SQL fragment (e.g. <formula> AS distance)
# * +:select_bearing+ - like +:select_distance+ but for bearing.
# * +:order+ - column(s) for ORDER BY SQL clause; default is distance;
# set to false or nil to omit the ORDER BY clause
# * +:exclude+ - an object to exclude (used by the +nearbys+ method)
#
def near_scope_options(latitude, longitude, radius = 20, options = {})
options[:units] ||= (geocoder_options[:units] || Geocoder.config.units)
select_distance = options.fetch(:select_distance, true)
options[:order] = "" if !select_distance && !options.include?(:order)
select_bearing = options.fetch(:select_bearing, true)
bearing = bearing_sql(latitude, longitude, options)
distance = distance_sql(latitude, longitude, options)
......@@ -116,7 +123,9 @@ module Geocoder::Store
conditions = [bounding_box_conditions + " AND #{distance} <= ?", radius]
end
{
:select => select_clause(options[:select], distance, bearing),
:select => select_clause(options[:select],
select_distance ? distance : nil,
select_bearing ? bearing : nil),
:conditions => add_exclude_condition(conditions, options[:exclude]),
:order => options.include?(:order) ? options[:order] : "distance ASC"
}
......@@ -166,10 +175,17 @@ module Geocoder::Store
elsif columns == :geo_only
clause = ""
else
clause = (columns || full_column_name("*")) + ", "
clause = (columns || full_column_name("*"))
end
clause + "#{distance} AS distance" +
(bearing ? ", #{bearing} AS bearing" : "")
if distance
clause += ", " unless clause.empty?
clause += "#{distance} AS distance"
end
if bearing
clause += ", " unless clause.empty?
clause += "#{bearing} AS bearing"
end
clause
end
##
......@@ -241,4 +257,3 @@ module Geocoder::Store
alias_method :fetch_address, :reverse_geocode
end
end
......@@ -8,4 +8,36 @@ class NearTest < Test::Unit::TestCase
assert_match /test_table_name.latitude BETWEEN 0.9276\d* AND 1.0723\d* AND test_table_name.longitude BETWEEN 1.9276\d* AND 2.0723\d* AND /,
result[:conditions][0]
end
def test_near_scope_options_with_defaults
result = Event.send(:near_scope_options, 1.0, 2.0, 5)
assert_match /AS distance/, result[:select]
assert_match /AS bearing/, result[:select]
assert_no_consecutive_comma(result[:select])
end
def test_near_scope_options_with_no_distance
result = Event.send(:near_scope_options, 1.0, 2.0, 5, :select_distance => false)
assert_no_match /AS distance/, result[:select]
assert_match /AS bearing/, result[:select]
assert_no_match /distance/, result[:condition]
assert_no_match /distance/, result[:order]
assert_no_consecutive_comma(result[:select])
end
def test_near_scope_options_with_no_bearing
result = Event.send(:near_scope_options, 1.0, 2.0, 5, :select_bearing => false)
assert_match /AS distance/, result[:select]
assert_no_match /AS bearing/, result[:select]
assert_no_consecutive_comma(result[:select])
end
private
def assert_no_consecutive_comma(string)
assert_no_match /, *,/, string, "two consecutive commas"
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment