Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
require 'rubygems'
require 'spec/rake/spectask'
require 'rspec/core/rake_task'

[:mysql, :mysql2, :postgresql].each do |adapter|
desc "Run specs for #{adapter} adapter"
Spec::Rake::SpecTask.new("spec:#{adapter.to_s}") do |t|
t.spec_files = FileList["spec/#{adapter}/*_spec.rb"]
RSpec::Core::RakeTask.new("spec:#{adapter.to_s}") do |spec|
spec.pattern = "spec/#{adapter}/*_spec.rb"
spec.rspec_opts = ['--backtrace']
end
end

Expand Down
8 changes: 3 additions & 5 deletions lib/spatial_adapter/mysql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,9 @@ class SpatialMysqlColumn < MysqlColumn
#MySql-specific geometry string parsing. By default, MySql returns geometries in strict wkb format with "0" characters in the first 4 positions.
def self.string_to_geometry(string)
return string unless string.is_a?(String)
begin
GeoRuby::SimpleFeatures::Geometry.from_ewkb(string[4..-1])
rescue Exception => exception
nil
end
GeoRuby::SimpleFeatures::Geometry.from_ewkb(string[4..-1])
rescue Exception
nil
end
end
end
Expand Down
8 changes: 3 additions & 5 deletions lib/spatial_adapter/mysql2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,9 @@ class SpatialMysql2Column < Mysql2Column
#MySql-specific geometry string parsing. By default, MySql returns geometries in strict wkb format with "0" characters in the first 4 positions.
def self.string_to_geometry(string)
return string unless string.is_a?(String)
begin
GeoRuby::SimpleFeatures::Geometry.from_ewkb(string[4..-1])
rescue Exception => exception
nil
end
GeoRuby::SimpleFeatures::Geometry.from_ewkb(string[4..-1])
rescue Exception
nil
end
end
end
Expand Down
61 changes: 31 additions & 30 deletions lib/spatial_adapter/postgresql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
include SpatialAdapter

def postgis_version
begin
select_value("SELECT postgis_full_version()").scan(/POSTGIS="([\d\.]*)"/)[0][0]
rescue ActiveRecord::StatementInvalid
nil
end
select_value("SELECT postgis_full_version()").scan(/POSTGIS="([\d\.]*)"/)[0][0]
rescue ActiveRecord::StatementInvalid
nil
end

def postgis_major_version
Expand All @@ -35,6 +33,15 @@ def native_database_types
original_native_database_types.merge!(geometry_data_types)
end

alias :original_type_cast :type_cast
def type_cast(value, column)
if value.kind_of?(GeoRuby::SimpleFeatures::Geometry)
value.as_hex_ewkb
else
original_type_cast(value, column)
end
end

alias :original_quote :quote
#Redefines the quote method to add behaviour for when a Geometry is encountered
def quote(value, column = nil)
Expand Down Expand Up @@ -155,21 +162,18 @@ def indexes(table_name, name = nil)
# Changed from upstread: link to pg_am to grab the index type (e.g. "gist")
result = query(<<-SQL, name)
SELECT distinct i.relname, d.indisunique, d.indkey, t.oid, am.amname
FROM pg_class t, pg_class i, pg_index d, pg_attribute a, pg_am am
FROM pg_class t
INNER JOIN pg_index d ON t.oid = d.indrelid
INNER JOIN pg_class i ON d.indexrelid = i.oid
INNER JOIN pg_attribute a ON a.attrelid = t.oid
INNER JOIN pg_am am ON i.relam = am.oid
WHERE i.relkind = 'i'
AND d.indexrelid = i.oid
AND d.indisprimary = 'f'
AND t.oid = d.indrelid
AND t.relname = '#{table_name}'
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) )
AND i.relam = am.oid
AND a.attrelid = t.oid
ORDER BY i.relname
SQL


indexes = []

indexes = result.map do |row|
index_name = row[0]
unique = row[1] == 't'
Expand All @@ -180,29 +184,27 @@ def indexes(table_name, name = nil)
# Changed from upstream: need to get the column types to test for spatial indexes
columns = query(<<-SQL, "Columns for index #{row[0]} on #{table_name}").inject({}) {|attlist, r| attlist[r[1]] = [r[0], r[2]]; attlist}
SELECT a.attname, a.attnum, t.typname
FROM pg_attribute a, pg_type t
FROM pg_attribute a
INNER JOIN pg_type t ON a.atttypid = t.oid
WHERE a.attrelid = #{oid}
AND a.attnum IN (#{indkey.join(",")})
AND a.atttypid = t.oid
SQL

# Only GiST indexes on spatial columns denote a spatial index
spatial = indtype == 'gist' && columns.size == 1 && (columns.values.first[1] == 'geometry' || columns.values.first[1] == 'geography')

column_names = indkey.map {|attnum| columns[attnum] ? columns[attnum][0] : nil }
column_names = indkey.map {|attnum| columns[attnum] ? columns[attnum][0] : nil }.compact
ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, spatial)
end

indexes
end

def disable_referential_integrity(&block) #:nodoc:
if supports_disable_referential_integrity?() then
if supports_disable_referential_integrity?
execute(tables_without_postgis.collect { |name| "ALTER TABLE #{quote_table_name(name)} DISABLE TRIGGER ALL" }.join(";"))
end
yield
ensure
if supports_disable_referential_integrity?() then
if supports_disable_referential_integrity?
execute(tables_without_postgis.collect { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(";"))
end
end
Expand Down Expand Up @@ -237,7 +239,6 @@ def column_spatial_info(table_name)
end

raw_geom_infos

end
end

Expand Down Expand Up @@ -272,8 +273,7 @@ def column(name, type, options = {})
end

class PostgreSQLColumnDefinition < ColumnDefinition
attr_accessor :table_name
attr_accessor :srid, :with_z, :with_m, :geographic
attr_accessor :table_name, :srid, :with_z, :with_m, :geographic
attr_reader :spatial

def initialize(base = nil, name = nil, type=nil, limit=nil, default=nil, null=nil, srid=-1, with_z=false, with_m=false, geographic=false)
Expand Down Expand Up @@ -304,13 +304,14 @@ def to_sql
if spatial && !geographic
type_sql = base.geometry_data_types[type.to_sym][:name]
type_sql += "M" if with_m and !with_z
if with_m and with_z
dimension = 4
elsif with_m or with_z
dimension = 3
else
dimension = 2
end
dimension =
if with_m and with_z
4
elsif with_m or with_z
3
else
2
end

column_sql = "SELECT AddGeometryColumn('#{table_name}','#{name}',#{srid},'#{type_sql}',#{dimension})"
column_sql += ";ALTER TABLE #{table_name} ALTER #{name} SET NOT NULL" if null == false
Expand Down
13 changes: 7 additions & 6 deletions lib/spatial_adapter/railtie.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
module SpatialAdapter
class Railtie < Rails::Railtie
initializer "spatial_adapter.load_current_database_adapter" do
adapter = ActiveRecord::Base.configurations[Rails.env]['adapter']
begin
require "spatial_adapter/#{adapter}"
rescue LoadError
raise SpatialAdapter::NotCompatibleError.new("spatial_adapter does not currently support the #{adapter} database.")
ActiveSupport.on_load :active_record do
adapter = ActiveRecord::Base.configurations[Rails.env]['adapter']
begin
require "spatial_adapter/#{adapter}"
rescue LoadError
raise SpatialAdapter::NotCompatibleError.new("spatial_adapter does not currently support the #{adapter} database.")
end
end
end
end
end

25 changes: 17 additions & 8 deletions spec/postgresql/connection_adapter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@
postgis_connection
@connection = ActiveRecord::Base.connection
end


describe '#native_database_types' do
it 'should include the geometry types' do
@connection.native_database_types.should include(@connection.geometry_data_types)
end

it 'should include the basic types' do
@connection.native_database_types.should include(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES)
end
end

describe '#postgis_version' do
it 'should report a version number if PostGIS is installed' do
@connection.should_receive(:select_value).with('SELECT postgis_full_version()').and_return('POSTGIS="1.5.0" GEOS="3.2.0-CAPI-1.6.0" PROJ="Rel. 4.7.1, 23 September 2009" LIBXML="2.7.6" USE_STATS')
Expand Down Expand Up @@ -209,19 +219,18 @@
end

describe "#add_index" do
after :each do
@connection.should_receive(:execute).with(any_args())
@connection.remove_index('geometry_models', 'geom')
end

it "should create a spatial index given :spatial => true" do
@connection.should_receive(:execute).with(/using gist/i)
@connection.add_index('geometry_models', 'geom', :spatial => true)
@connection.indexes('geometry_models').first.spatial.should be_true
@connection.indexes('geometry_models').first.columns.should == ['geom']
@connection.remove_index('geometry_models', 'geom')
end

it "should not create a spatial index unless specified" do
@connection.should_not_receive(:execute).with(/using gist/i)
@connection.add_index('geometry_models', 'extra')
@connection.indexes('geometry_models').first.spatial.should be_false
@connection.indexes('geometry_models').first.columns.should == ['extra']
@connection.remove_index('geometry_models', 'extra')
end
end
end
4 changes: 2 additions & 2 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'rubygems'
require 'spec'
require 'rspec'
require 'geo_ruby'
gem 'activerecord', '=3.0.3'
gem 'activerecord', '>=3.0.3'
require 'active_record'

$:.unshift((File.join(File.dirname(__FILE__), '..', 'lib')))
Expand Down