From 20bb694d4cc891619e312c2441a8995b7dbe215f Mon Sep 17 00:00:00 2001 From: Brennan Dunn Date: Tue, 29 Sep 2009 15:09:54 -0400 Subject: [PATCH] Added SQL Server support --- lib/geokit-rails/acts_as_mappable.rb | 4 ++- lib/geokit-rails/adapters/abstract.rb | 2 ++ lib/geokit-rails/adapters/sqlserver.rb | 43 ++++++++++++++++++++++++++ test/database.yml | 10 ++++-- 4 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 lib/geokit-rails/adapters/sqlserver.rb diff --git a/lib/geokit-rails/acts_as_mappable.rb b/lib/geokit-rails/acts_as_mappable.rb index 9a73b88..e80dcb5 100644 --- a/lib/geokit-rails/acts_as_mappable.rb +++ b/lib/geokit-rails/acts_as_mappable.rb @@ -135,7 +135,9 @@ module SingletonMethods #:nodoc: def adapter @adapter ||= begin require File.join(File.dirname(__FILE__), 'adapters', connection.adapter_name.downcase) - Adapters.const_get(connection.adapter_name.camelcase).new(self) + klass = Adapters.const_get(connection.adapter_name.camelcase) + klass.load(self) unless klass.loaded + klass.new(self) rescue LoadError raise UnsupportedAdapter, "`#{connection.adapter_name.downcase}` is not a supported adapter." end diff --git a/lib/geokit-rails/adapters/abstract.rb b/lib/geokit-rails/adapters/abstract.rb index f7df2ee..7d98816 100644 --- a/lib/geokit-rails/adapters/abstract.rb +++ b/lib/geokit-rails/adapters/abstract.rb @@ -3,6 +3,8 @@ module Adapters class Abstract class NotImplementedError < StandardError ; end + cattr_accessor :loaded + def initialize(klass) @owner = klass end diff --git a/lib/geokit-rails/adapters/sqlserver.rb b/lib/geokit-rails/adapters/sqlserver.rb new file mode 100644 index 0000000..b1aea20 --- /dev/null +++ b/lib/geokit-rails/adapters/sqlserver.rb @@ -0,0 +1,43 @@ +module Geokit + module Adapters + class SQLServer < Abstract + + class << self + + def load(klass) + klass.connection.execute <<-EOS + if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[geokit_least]') and xtype in (N'FN', N'IF', N'TF')) + drop function [dbo].[geokit_least] + EOS + + klass.connection.execute <<-EOS + CREATE FUNCTION [dbo].geokit_least (@value1 float,@value2 float) RETURNS float AS BEGIN + return (SELECT CASE WHEN @value1 < @value2 THEN @value1 ELSE @value2 END) END + EOS + self.loaded = true + end + + end + + def initialize(*args) + super(*args) + end + + def sphere_distance_sql(lat, lng, multiplier) + %| + (ACOS([dbo].geokit_least(1,COS(#{lat})*COS(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*COS(RADIANS(#{qualified_lng_column_name}))+ + COS(#{lat})*SIN(#{lng})*COS(RADIANS(#{qualified_lat_column_name}))*SIN(RADIANS(#{qualified_lng_column_name}))+ + SIN(#{lat})*SIN(RADIANS(#{qualified_lat_column_name}))))*#{multiplier}) + | + end + + def flat_distance_sql(origin, lat_degree_units, lng_degree_units) + %| + SQRT(POWER(#{lat_degree_units}*(#{origin.lat}-#{qualified_lat_column_name}),2)+ + POWER(#{lng_degree_units}*(#{origin.lng}-#{qualified_lng_column_name}),2)) + | + end + + end + end +end \ No newline at end of file diff --git a/test/database.yml b/test/database.yml index d1af3ae..6851d14 100644 --- a/test/database.yml +++ b/test/database.yml @@ -2,7 +2,7 @@ baes: &base host: localhost username: root password: - + mysql: adapter: mysql database: geokit_plugin_test @@ -11,4 +11,10 @@ mysql: postgresql: adapter: postgresql database: geokit_plugin_test - <<: *base \ No newline at end of file + <<: *base + +sqlserver: + adapter: sqlserver + mode: ODBC + dsn: geokit_tests + username: ruby