Skip to content

Commit

Permalink
Upgrate Active Record dependency to 4.2.
Browse files Browse the repository at this point in the history
This commit reapplies fjl82 and agoln's commits from
fjl82/activerecord-mysql2spatial-adapter to current master.
Not all tests pass yet.
  • Loading branch information
dschweisguth committed Jul 21, 2017
1 parent b0ab983 commit f14b07f
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 85 deletions.
4 changes: 2 additions & 2 deletions activerecord-mysql2spatial-adapter.gemspec
Expand Up @@ -44,8 +44,8 @@
['Version']
s_.extra_rdoc_files = ::Dir.glob("*.rdoc")
s_.platform = ::Gem::Platform::RUBY
s_.add_dependency('activerecord', '>= 4.0', '< 4.2')
s_.add_dependency('rgeo-activerecord', '~> 1.3')
s_.add_dependency('activerecord', '~> 4.2.9')
s_.add_dependency('rgeo-activerecord', '~> 2.1.1')
s_.add_dependency('mysql2', '>= 0.2.13', '< 0.4.0')
s_.add_development_dependency('rake', '>= 0.9.2')
s_.add_development_dependency('rdoc', '>= 3.12')
Expand Down
Expand Up @@ -75,3 +75,4 @@ module Mysql2SpatialAdapter
require 'active_record/connection_adapters/mysql2spatial_adapter/main_adapter.rb'
require 'active_record/connection_adapters/mysql2spatial_adapter/spatial_column.rb'
require 'active_record/connection_adapters/mysql2spatial_adapter/arel_tosql.rb'
require 'active_record/type/spatial.rb'
Expand Up @@ -93,11 +93,11 @@ def add_index(table_name_, column_name_, options_={})
end

def columns(table_name_, name_=nil)
result_ = execute("SHOW FIELDS FROM #{quote_table_name(table_name_)}", :skip_logging)
result_ = @connection.query "SHOW FULL FIELDS FROM #{quote_table_name(table_name_)}"
columns_ = []
result_.each(symbolize_keys: true, as: :hash) do |field_|
columns_ << SpatialColumn.new(@rgeo_factory_settings, table_name_.to_s,
field_[:Field], field_[:Default], field_[:Type], field_[:Null] == "YES")
field_[:Field], field_[:Default], lookup_cast_type(field_[:Type]), field_[:Type], field_[:Null] == "YES", field_[:Collation], field_[:Extra])
end
columns_
end
Expand Down Expand Up @@ -128,6 +128,17 @@ def indexes(table_name_, name_=nil)
end
indexes_
end

protected

def initialize_type_map(m)
super
register_class_with_limit m, %r(geometry)i, Type::Spatial
m.alias_type %r(point)i, 'geometry'
m.alias_type %r(linestring)i, 'geometry'
m.alias_type %r(polygon)i, 'geometry'
end

end
end
end
Expand Down
Expand Up @@ -35,97 +35,20 @@
module ActiveRecord
module ConnectionAdapters
module Mysql2SpatialAdapter

# ActiveRecord 3.2 uses ConnectionAdapters::Mysql2Adapter::Column
# whereas 3.0 and 3.1 use ConnectionAdapters::Mysql2Column
column_base_class_ = defined?(ConnectionAdapters::Mysql2Adapter::Column) ?
ConnectionAdapters::Mysql2Adapter::Column : ConnectionAdapters::Mysql2Column

class SpatialColumn < column_base_class_

class SpatialColumn < ConnectionAdapters::Mysql2Adapter::Column
FACTORY_SETTINGS_CACHE = {}

def initialize(factory_settings_, table_name_, name_, default_, sql_type_=nil, null_=true)
@factory_settings = factory_settings_
@table_name = table_name_
super(name_, default_,sql_type_, null_)
@geometric_type = ::RGeo::ActiveRecord.geometric_type_from_name(sql_type_)
def initialize(factory_settings_, table_name_, name_, default_, cast_type_ = nil, sql_type_ = nil, null_ = true, collation_ = nil, extra_ = "")
super(name_, default_, cast_type_, sql_type_, null_, collation_, false, extra_)
if type == :spatial
@limit = { type: @geometric_type.type_name.underscore }
cast_type.set_geo_params(factory_settings_, table_name_, ::RGeo::ActiveRecord.geometric_type_from_name(sql_type_))
end
FACTORY_SETTINGS_CACHE[factory_settings_.object_id] = factory_settings_
end

attr_reader :geometric_type

def spatial?
type == :spatial
end

def klass
type == :spatial ? ::RGeo::Feature::Geometry : super
end

def type_cast(value_)
if type == :spatial
SpatialColumn.convert_to_geometry(value_, @factory_settings, @table_name, name)
else
super
end
end

def type_cast_code(var_name_)
if type == :spatial
"::ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::SpatialColumn.convert_to_geometry("+
"#{var_name_}, ::ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::SpatialColumn::"+
"FACTORY_SETTINGS_CACHE[#{@factory_settings.object_id}], #{@table_name.inspect}, #{name.inspect})"
else
super
end
end

private

def simplified_type(sql_type_)
sql_type_ =~ /geometry|point|linestring|polygon/i ? :spatial : super
end


def self.convert_to_geometry(input_, factory_settings_, table_name_, column_)
case input_
when ::RGeo::Feature::Geometry
factory_ = factory_settings_.get_column_factory(table_name_, column_, srid: input_.srid)
::RGeo::Feature.cast(input_, factory_) rescue nil
when ::String
marker_ = input_[4,1]
if marker_ == "\x00" || marker_ == "\x01"
factory_ = factory_settings_.get_column_factory(table_name_, column_,
srid: input_[0, 4].unpack(marker_ == "\x01" ? 'V' : 'N').first)
::RGeo::WKRep::WKBParser.new(factory_).parse(input_[4..-1]) rescue nil
elsif input_[0,10] =~ /[0-9a-fA-F]{8}0[01]/
srid_ = input_[0,8].to_i(16)
if input[9,1] == '1'
srid_ = [srid_].pack('V').unpack('N').first
end
factory_ = factory_settings_.get_column_factory(table_name_, column_, srid: srid_)
::RGeo::WKRep::WKBParser.new(factory_).parse(input_[8..-1]) rescue nil
else
factory_ = factory_settings_.get_column_factory(table_name_, column_)
::RGeo::WKRep::WKTParser.new(factory_, support_ewkt: true).parse(input_) rescue nil
end
else
nil
end
end


end


end

end

end

# :startdoc:
53 changes: 53 additions & 0 deletions lib/active_record/type/spatial.rb
@@ -0,0 +1,53 @@
module ActiveRecord
module Type
class Spatial < Value # :nodoc:
def type
:spatial
end

def spatial?
type == :spatial
end

def klass
type == :spatial ? ::RGeo::Feature::Geometry : super
end

def set_geo_params(factory_settings, table_name, geometric_type)
@factory_settings = factory_settings
@table_name = table_name
@geometric_type = geometric_type
end

private

def cast_value(value)
case value
when ::RGeo::Feature::Geometry
factory = @factory_settings.get_column_factory(@table_name, @column, :srid => value.srid)
::RGeo::Feature.cast(value, factory) rescue nil
when ::String
marker = value[4,1]
if marker == "\x00" || marker == "\x01"
factory = @factory_settings.get_column_factory(@table_name, @column,
:srid => value[0,4].unpack(marker == "\x01" ? 'V' : 'N').first)
::RGeo::WKRep::WKBParser.new(factory).parse(value[4..-1]) rescue nil
elsif value[0,10] =~ /[0-9a-fA-F]{8}0[01]/
srid = value[0,8].to_i(16)
if value[9,1] == '1'
srid = [srid].pack('V').unpack('N').first
end
factory = @factory_settings.get_column_factory(@table_name, @column, :srid => srid)
::RGeo::WKRep::WKBParser.new(factory).parse(value[8..-1]) rescue nil
else
factory = @factory_settings.get_column_factory(@table_name, @column)
::RGeo::WKRep::WKTParser.new(factory, support_ewkt: true).parse(value) rescue nil
end
else
nil
end
end

end
end
end

0 comments on commit f14b07f

Please sign in to comment.