diff --git a/.travis.yml b/.travis.yml index a285f44f3ebaec1559f784c7c8742ff60acd035c..3540d2e7f0ff9a8f419d97aa1588bb980f46fa25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ env: matrix: - DB= - DB=sqlite + - DB=sqlite USE_SQLITE_EXT=1 - DB=postgres - DB=mysql rvm: @@ -45,3 +46,5 @@ matrix: gemfile: gemfiles/Gemfile.ruby1.9.3 - rvm: 2.3.0 gemfile: gemfiles/Gemfile.ruby1.9.3 + - env: DB=sqlite USE_SQLITE_EXT=1 + rvm: jruby-19mode diff --git a/Gemfile b/Gemfile index 288a90caf46c6207edf968939c14a44f54ca50bd..128b94fda783a6366b719f50a4d2160261a117d4 100644 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,11 @@ group :development, :test do end group :test do - gem 'sqlite3', :platform => [:ruby, :mswin, :mingw] + platforms :ruby, :mswin, :mingw do + gem 'sqlite3' + gem 'sqlite_ext', '~> 1.5.0' + end + gem 'webmock' platforms :ruby do diff --git a/gemfiles/Gemfile.rails3.2 b/gemfiles/Gemfile.rails3.2 index 08d6223fbd41fc8101b2031f11699ca76d6e4f71..da838d6ab85e9806611fbffc366a79015f50ca88 100644 --- a/gemfiles/Gemfile.rails3.2 +++ b/gemfiles/Gemfile.rails3.2 @@ -23,7 +23,11 @@ group :development, :test do end group :test do - gem 'sqlite3', :platform => [:ruby, :mswin, :mingw] + platforms :ruby do + gem 'sqlite3' + gem 'sqlite_ext', '~> 1.5.0' + end + gem 'webmock' platforms :ruby do diff --git a/gemfiles/Gemfile.rails4.1 b/gemfiles/Gemfile.rails4.1 index 681c02cae153f351fdc0e44b03e01424c58e81b1..34f96168bed207f6e0bcf84aef0a083739aa855f 100644 --- a/gemfiles/Gemfile.rails4.1 +++ b/gemfiles/Gemfile.rails4.1 @@ -23,7 +23,11 @@ group :development, :test do end group :test do - gem 'sqlite3', :platform => [:ruby, :mswin, :mingw] + platforms :ruby, :mswin, :mingw do + gem 'sqlite3' + gem 'sqlite_ext', '~> 1.5.0' + end + gem 'webmock' platforms :ruby do diff --git a/gemfiles/Gemfile.ruby1.9.3 b/gemfiles/Gemfile.ruby1.9.3 index 64383a62c3e551a0e6b8d63d2085cd2dfbc7208b..2be48dc3115601ac1b58a27ea452cd95dd8eec50 100644 --- a/gemfiles/Gemfile.ruby1.9.3 +++ b/gemfiles/Gemfile.ruby1.9.3 @@ -8,6 +8,7 @@ group :development, :test do gem 'rubyzip' gem 'rails' gem 'sqlite3' + gem 'sqlite_ext', '~> 1.5.0' gem 'pg' gem 'mysql2', '~> 0.3.11' diff --git a/lib/geocoder/stores/active_record.rb b/lib/geocoder/stores/active_record.rb index 771d5f89aa963a8ca38bda40289ed1f2232d7a14..7c99e055344794a29b0a0e737e6da05a9068243d 100644 --- a/lib/geocoder/stores/active_record.rb +++ b/lib/geocoder/stores/active_record.rb @@ -138,7 +138,7 @@ module Geocoder::Store ] bounding_box_conditions = Geocoder::Sql.within_bounding_box(*args) - if using_sqlite? + if using_unextended_sqlite? conditions = bounding_box_conditions else min_radius = options.fetch(:min_radius, 0).to_f @@ -160,7 +160,7 @@ module Geocoder::Store # capabilities (trig functions?). # def distance_sql(latitude, longitude, options = {}) - method_prefix = using_sqlite? ? "approx" : "full" + method_prefix = using_unextended_sqlite? ? "approx" : "full" Geocoder::Sql.send( method_prefix + "_distance", latitude, longitude, @@ -179,7 +179,7 @@ module Geocoder::Store options[:bearing] = Geocoder.config.distances end if options[:bearing] - method_prefix = using_sqlite? ? "approx" : "full" + method_prefix = using_unextended_sqlite? ? "approx" : "full" Geocoder::Sql.send( method_prefix + "_bearing", latitude, longitude, @@ -225,8 +225,20 @@ module Geocoder::Store conditions end + def using_unextended_sqlite? + using_sqlite? && !using_sqlite_with_extensions? + end + def using_sqlite? - connection.adapter_name.match(/sqlite/i) + !!connection.adapter_name.match(/sqlite/i) + end + + def using_sqlite_with_extensions? + connection.adapter_name.match(/sqlite/i) && + defined?(::SqliteExt) && + %W(MOD POWER SQRT PI SIN COS ASIN ATAN2).all?{ |fn_name| + connection.raw_connection.function_created?(fn_name) + } end def using_postgres? @@ -244,7 +256,7 @@ module Geocoder::Store # Value which can be passed to where() to produce no results. # def false_condition - using_sqlite? ? 0 : "false" + using_unextended_sqlite? ? 0 : "false" end ## diff --git a/test/test_helper.rb b/test/test_helper.rb index 89aa2bef97f4884b047a70375bc5441efe77833b..dda4330bb1204138f3a9e193d18df38a72fe1d6a 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -15,6 +15,11 @@ if configs.keys.include? ENV['DB'] ActiveRecord::Base.configurations = configs db_name = ENV['DB'] + if db_name == 'sqlite' && ENV['USE_SQLITE_EXT'] == '1' then + gem 'sqlite_ext' + require 'sqlite_ext' + SqliteExt.register_ruby_math + end ActiveRecord::Base.establish_connection(db_name) ActiveRecord::Base.default_timezone = :utc diff --git a/test/unit/near_test.rb b/test/unit/near_test.rb index 3cd9ae365e8401cdbaf4e5da0d76ae2d40f4b1e5..53401f4b0e50f133d66db189bd0b76e42c8320df 100644 --- a/test/unit/near_test.rb +++ b/test/unit/near_test.rb @@ -3,23 +3,23 @@ require 'test_helper' class NearTest < GeocoderTestCase - def test_near_scope_options_without_sqlite_includes_bounding_box_condition - omit("Not applicable to SQLite") if ENV['DB'] == 'sqlite' + def test_near_scope_options_includes_bounding_box_condition + omit("Not applicable to unextended SQLite") if using_unextended_sqlite? result = PlaceWithCustomResultsHandling.send(:near_scope_options, 1.0, 2.0, 5) table_name = PlaceWithCustomResultsHandling.table_name assert_match(/#{table_name}.latitude BETWEEN 0.9276\d* AND 1.0723\d* AND #{table_name}.longitude BETWEEN 1.9276\d* AND 2.0723\d* AND /, result[:conditions][0]) end - def test_near_scope_options_without_sqlite_includes_radius_condition - omit("Not applicable to SQLite") if ENV['DB'] == 'sqlite' + def test_near_scope_options_includes_radius_condition + omit("Not applicable to unextended SQLite") if using_unextended_sqlite? result = Place.send(:near_scope_options, 1.0, 2.0, 5) assert_match(/BETWEEN \? AND \?$/, result[:conditions][0]) end - def test_near_scope_options_without_sqlite_includes_radius_default_min_radius - omit("Not applicable to SQLite") if ENV['DB'] == 'sqlite' + def test_near_scope_options_includes_radius_default_min_radius + omit("Not applicable to unextended SQLite") if using_unextended_sqlite? result = Place.send(:near_scope_options, 1.0, 2.0, 5) @@ -27,8 +27,8 @@ class NearTest < GeocoderTestCase assert_equal(5, result[:conditions][2]) end - def test_near_scope_options_without_sqlite_includes_radius_custom_min_radius - omit("Not applicable to SQLite") if ENV['DB'] == 'sqlite' + def test_near_scope_options_includes_radius_custom_min_radius + omit("Not applicable to unextended SQLite") if using_unextended_sqlite? result = Place.send(:near_scope_options, 1.0, 2.0, 5, :min_radius => 3) @@ -36,8 +36,8 @@ class NearTest < GeocoderTestCase assert_equal(5, result[:conditions][2]) end - def test_near_scope_options_without_sqlite_includes_radius_bogus_min_radius - omit("Not applicable to SQLite") if ENV['DB'] == 'sqlite' + def test_near_scope_options_includes_radius_bogus_min_radius + omit("Not applicable to unextended SQLite") if using_unextended_sqlite? result = Place.send(:near_scope_options, 1.0, 2.0, 5, :min_radius => 'bogus') @@ -94,4 +94,8 @@ class NearTest < GeocoderTestCase def assert_no_consecutive_comma(string) assert_no_match(/, *,/, string, "two consecutive commas") end + + def using_unextended_sqlite? + ENV['DB'] == 'sqlite' && ENV['USE_SQLITE_EXT'] != '1' + end end