Skip to content

Commit

Permalink
referenced this page
Browse files Browse the repository at this point in the history
  • Loading branch information
jeff(황용대) committed Feb 6, 2017
1 parent 520a9d1 commit 906da6a
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 78 deletions.
38 changes: 19 additions & 19 deletions lib/active_record/connection_adapters/mysql2rgeo/column_methods.rb
Expand Up @@ -7,41 +7,41 @@ def spatial(name, options = {})
column(name, options[:limit][:type], options)
end

def geography(name, options = {})
type = options.dig(:limit, :type)
column(name, type.nil? ? :geometry : type, options)
def geography(*args, **options)
args.each { |name| column(name, :geometry, options) }
end

def geometry(name, options = {})
column(name, :geometry, options)
def geometry(*args, multi: false, **options)
multi ? multi_geometry(*args, **options) : args.each { |name| column(name, :geometry, options) }
end

def geometry_collection(name, options = {})
column(name, :geometry_collection, options)
def multi_geometry(*args, **options)
args.each { |name| column(name, :geometrycollection, options) }
end

def line_string(name, options = {})
column(name, :line_string, options)
def point(*args, multi: false, **options)
multi ? multi_point(*args, **options) : args.each { |name| column(name, :point, options) }
end

def multi_line_string(name, options = {})
column(name, :multi_line_string, options)
def multi_point(*args, **options)
args.each { |name| column(name, :multipoint, options) }
end

def multi_point(name, options = {})
column(name, :multi_point, options)
def linestring(*args, multi: false, **options)
multi ? multi_linestring(*args, **options) : args.each { |name| column(name, :linestring, options) }
end

def multi_polygon(name, options = {})
column(name, :multi_polygon, options)
def multi_linestring(*args, **options)
args.each { |name| column(name, :multilinestring, options) }
end

def point(name, options = {})
column(name, :point, options)
def polygon(*args, multi: false, **options)
type = multi ? :multipolygon : :polygon
args.each { |name| column(name, type, options) }
end

def polygon(name, options = {})
column(name, :polygon, options)
def multi_polygon(*args, **options)
polygon(args, true, options)
end
end

Expand Down
Expand Up @@ -24,16 +24,15 @@ def spatial_column_constructor(name)
def native_database_types
# Add spatial types
super.merge(
geography: { name: "geography" },
geometry: { name: "geometry" },
geometry_collection: { name: "geometry_collection" },
line_string: { name: "line_string" },
multi_line_string: { name: "multi_line_string" },
multi_point: { name: "multi_point" },
multi_polygon: { name: "multi_polygon" },
spatial: { name: "geometry", limit: { type: :point } },
point: { name: "point" },
polygon: { name: "polygon" }
linestring: { name: "linestring" },
polygon: { name: "polygon" },
multi_geometry: { name: "geometrycollection" },
multi_point: { name: "multipoint" },
multi_linestring: { name: "multilinestring" },
multi_polygon: { name: "multipolygon" },
spatial: { name: "geometry", limit: { type: :point } }
)
end

Expand All @@ -50,10 +49,18 @@ def type_cast(value, column = nil)

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'
%w(
geometry
point
linestring
polygon
geometrycollection
multipoint
multilinestring
multipolygon
).each do |geo_type|
m.register_type(geo_type, Type::Spatial.new(geo_type))
end
end
end
end
Expand Down
Expand Up @@ -2,12 +2,6 @@ module ActiveRecord # :nodoc:
module ConnectionAdapters # :nodoc:
module Mysql2Rgeo # :nodoc:
class SpatialColumn < ConnectionAdapters::MySQL::Column # :nodoc:
# sql_type examples:
# "Geometry"
# "Geography"
# cast_type example classes:
# OID::Spatial
# OID::Integer
def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, default_function = nil, collation = nil, comment: nil)
@geometric_type = nil
if sql_type =~ /geometry|point|linestring|polygon/i
Expand Down Expand Up @@ -61,6 +55,10 @@ def spatial?
!@geometric_type.nil?
end

def multi?
/^(geometrycollection|multi)/i.match?(sql_type)
end

private
def set_geometric_type_from_name(name)
@geometric_type = RGeo::ActiveRecord.geometric_type_from_name(name) || RGeo::Feature::Geometry
Expand Down
Expand Up @@ -40,21 +40,6 @@ def create_column_definition(name, type)
class ColumnDefinition < MySQL::ColumnDefinition
# needs to accept the spatial type? or figure out from limit ?

def self.options_to_limit(type, options = {})
spatial_type = geo_type(type)
spatial_type << ",#{options[:srid] || 4326}"
spatial_type
end

# limit is how column options are passed to #type_to_sql
# returns: "Point,4326"
def limit
"".tap do |value|
value << self.class.geo_type(spatial_type)
value << ",#{srid}"
end
end

def self.geo_type(type = "GEOMETRY")
g_type = type.to_s.delete("_").upcase
return "POINT" if g_type == "POINT"
Expand Down
33 changes: 14 additions & 19 deletions lib/active_record/connection_adapters/mysql2rgeo_adapter.rb
Expand Up @@ -26,22 +26,17 @@ class Mysql2RgeoAdapter < Mysql2Adapter
include Mysql2Rgeo::SchemaStatements

SPATIAL_COLUMN_OPTIONS =
{
geometry: {},
geometry_collection: {},
geometrycollection: {},
line_string: {},
linestring: {},
multi_line_string: {},
multilinestring: {},
multi_point: {},
multipoint: {},
multi_polygon: {},
multipolygon: {},
spatial: {},
point: {},
polygon: {},
}.freeze
{
geometry: {},
geometrycollection: {},
linestring: {},
spatial: { type: "geometry" }.freeze,
point: {},
polygon: {},
multilinestring: {},
multipoint: {},
multipolygon: {},
}.freeze

# http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
DEFAULT_SRID = 0
Expand Down Expand Up @@ -79,18 +74,18 @@ def indexes(table_name, name = nil) #:nodoc:
current_index = row[:Key_name]

mysql_index_type = row[:Index_type].downcase.to_sym
index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil
index_type = INDEX_TYPES.include?(mysql_index_type) ? mysql_index_type : nil
index_using = INDEX_USINGS.include?(mysql_index_type) ? mysql_index_type : nil
indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], {}, nil, nil, index_type, index_using, row[:Index_comment].presence)
if row[:Index_type] != 'SPATIAL'
if mysql_index_type != :spatial
indexes << IndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique].to_i == 0, [], [], nil, nil, index_type, index_using, row[:Index_comment].presence)
else
indexes << RGeo::ActiveRecord::SpatialIndexDefinition.new(row[:Table], row[:Key_name], row[:Non_unique] == 0, [], [], row[:Index_type] == 'SPATIAL')
end
end

indexes.last.columns << row[:Column_name]
indexes.last.lengths << row[:Sub_part] unless indexes.last.try(:spatial)
indexes.last.lengths.merge!(row[:Column_name] => row[:Sub_part].to_i) if row[:Sub_part] && mysql_index_type != :spatial
end
end

Expand Down
4 changes: 4 additions & 0 deletions lib/active_record/type/spatial.rb
Expand Up @@ -53,6 +53,10 @@ def type
:spatial
end

def self.type
:spatial
end

def spatial?
type == :spatial
end
Expand Down
2 changes: 1 addition & 1 deletion test/basic_test.rb
Expand Up @@ -107,7 +107,7 @@ def test_readme_example
klass = SpatialModel
klass.connection.create_table(:spatial_models, force: true) do |t|
t.column(:shape, :geometry)
t.line_string(:path, srid: 3785)
t.linestring(:path, srid: 3785)
t.point(:latlon, null: false, geographic: true)
end
klass.reset_column_information
Expand Down
2 changes: 1 addition & 1 deletion test/database.yml
@@ -1,4 +1,4 @@
adapter: mysql2rgeo
database: mysql2rgeo_adapter_test
username: travis
username: root
encoding: utf8
25 changes: 20 additions & 5 deletions test/ddl_test.rb
Expand Up @@ -4,11 +4,11 @@ class DDLTest < ActiveSupport::TestCase # :nodoc:
def test_spatial_column_options
[
:geometry,
:geometry_collection,
:line_string,
:multi_line_string,
:multi_point,
:multi_polygon,
:geometrycollection,
:linestring,
:multilinestring,
:multipoint,
:multipolygon,
:point,
:polygon,
].each do |type|
Expand Down Expand Up @@ -270,6 +270,21 @@ def test_non_spatial_column_limits
assert_equal 123, col.limit
end

def test_includes_spatial_types
klass.connection.create_table("spatial_types", force: true, options: "ENGINE=MyISAM") do |t|
t.geometry :geometry_field
t.polygon :polygon_field, null: false, index: { type: :spatial }
t.point :point_field
t.linestring :linestring_field

t.geometry :geometry_multi, multi: true
t.polygon :polygon_multi, multi: true
t.point :point_multi, multi: true
t.linestring :linestring_multi, multi: true
end
klass.reset_column_information
end

private

def klass
Expand Down

0 comments on commit 906da6a

Please sign in to comment.