activerecord-mysql2rgeo-adapter 7.3.2 → 8.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 816dbf40bdc492a42c20ded6aef4f247a76dedbbdd73bc6d705a400f8b8cfdc7
4
- data.tar.gz: 4a04ba14c239948df20572c8b29a13f4c6296dfc11edb3beba35b1b76c26124f
3
+ metadata.gz: b8e687a3f8a5ccfc68ed65b3a4580741bc2b68aa33f18b11a0db6aa3eb5de58d
4
+ data.tar.gz: f86a9aa0893e135f478701e58bbfd23d99ddf3e5e2ae078dcbb4b5870baa69de
5
5
  SHA512:
6
- metadata.gz: 7dce6e73f2b2f93d1cdd543e6c30e305adf20135faec080f0361a00f1b7f95d34556ac51e4d98fdaa41c565674db4444353529b06b413ac708cf2b0c6750600e
7
- data.tar.gz: 2d697dc4767e38740316346fd727dcf352ab1bc41340b4a45ec4c15a3f73f0e1742ba3dc70c0af231aca6f5d091e5d87f9c17b2d6f96493625bc00a3c275ddbd
6
+ metadata.gz: 6fc4adc88222d567042ff0017179e86cab2a637ceb601b0406a1835aa7b850d0b7c13861f93d45bc5e83954ec4e956d731cb3d47a586c73048f177dd1b487bb2
7
+ data.tar.gz: b853618805dc918bb1c10ac1f5cf57ba582deabda7f5ae0dcca4cf8d4657d4c35bf41c22e1e89e3667feceae043d0f7f06ffe3df56781825a6dd723a51a9807d
@@ -9,10 +9,12 @@ module Arel # :nodoc:
9
9
  MySQL
10
10
  end
11
11
 
12
- class Mysql2Rgeo < MySQLSuperclass # :nodoc:
12
+ class Mysql2Rgeo < MySQLSuperclass # :nodoc:
13
13
  include RGeo::ActiveRecord::SpatialToSql
14
14
 
15
- include ::Arel::Visitors::BindVisitor if ::Arel::Visitors.const_defined?(:BindVisitor)
15
+ if ::Arel::Visitors.const_defined?(:BindVisitor)
16
+ include ::Arel::Visitors::BindVisitor
17
+ end
16
18
 
17
19
  FUNC_MAP = {
18
20
  "st_wkttosql" => "ST_GeomFromText",
@@ -50,12 +52,12 @@ module Arel # :nodoc:
50
52
  end
51
53
 
52
54
  def self.parse_node(node)
53
- if node.is_a?(RGeo::Feature::Instance)
55
+ if RGeo::Feature::Instance === node
54
56
  wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(node)
55
57
  return [wkt, node.srid]
56
58
  end
57
59
 
58
- if node.is_a?(RGeo::Cartesian::BoundingBox)
60
+ if RGeo::Cartesian::BoundingBox === node
59
61
  geometry = node.to_geometry
60
62
  wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(geometry)
61
63
  return [wkt, geometry.srid]
@@ -5,33 +5,34 @@ module ActiveRecord
5
5
  module Mysql2Rgeo
6
6
  class SchemaCreation < MySQL::SchemaCreation # :nodoc:
7
7
  private
8
+ def visit_IndexDefinition(o, create = false)
9
+ if o.using&.to_sym == :gist
10
+ sql = create ? ["CREATE SPATIAL INDEX"] : ["SPATIAL INDEX"]
11
+ sql << quote_column_name(o.name)
12
+ sql << "ON #{quote_table_name(o.table)}" if create
13
+ sql << "(#{quoted_columns(o)})"
14
+ return sql.join(" ")
15
+ end
8
16
 
9
- def visit_IndexDefinition(o, create = false)
10
- if o.using&.to_sym == :gist
11
- sql = create ? ["CREATE SPATIAL INDEX"] : ["SPATIAL INDEX"]
12
- sql << quote_column_name(o.name)
13
- sql << "ON #{quote_table_name(o.table)}" if create
14
- sql << "(#{quoted_columns(o)})"
15
- return sql.join(" ")
17
+ super
16
18
  end
17
19
 
18
- super
19
- end
20
+ def add_column_options!(sql, options)
21
+ if options[:srid]
22
+ sql << " /*!80003 SRID #{options[:srid]} */"
23
+ options = options.except(:srid)
24
+ end
20
25
 
21
- def add_column_options!(sql, options)
22
- if options[:srid]
23
- sql << " /*!80003 SRID #{options[:srid]} */"
24
- options = options.except(:srid)
25
- end
26
-
27
- options = options.except(:default) if options_include_default?(options) && spatial_column_definition?(options[:column])
26
+ if options_include_default?(options) && spatial_column_definition?(options[:column])
27
+ options = options.except(:default)
28
+ end
28
29
 
29
- super
30
- end
30
+ super
31
+ end
31
32
 
32
- def spatial_column_definition?(column)
33
- column.respond_to?(:type) && column.type && @conn.class.spatial_column_options(column.type.to_sym)
34
- end
33
+ def spatial_column_definition?(column)
34
+ column.respond_to?(:type) && column.type && @conn.class.spatial_column_options(column.type.to_sym)
35
+ end
35
36
  end
36
37
  end
37
38
  end
@@ -7,7 +7,7 @@ module ActiveRecord
7
7
  # super: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
8
8
 
9
9
  # override
10
- def indexes(table_name) # :nodoc:
10
+ def indexes(table_name) #:nodoc:
11
11
  indexes = super
12
12
  # HACK(aleks, 06/15/18): MySQL 5 does not support prefix lengths for spatial indexes
13
13
  # https://dev.mysql.com/doc/refman/5.6/en/create-index.html
@@ -33,7 +33,7 @@ module ActiveRecord
33
33
 
34
34
  column_options = column.limit.is_a?(Hash) ? column.limit.symbolize_keys.except(:type) : {}
35
35
  column_options[:comment] = column.comment if column.comment.present?
36
- change_column(table_name, name, column.limit[:type].to_sym, **column_options, null: false)
36
+ change_column(table_name, name, column.limit[:type].to_sym, **column_options.merge(null: false))
37
37
  end
38
38
  end
39
39
 
@@ -42,15 +42,21 @@ module ActiveRecord
42
42
 
43
43
  # override
44
44
  def type_to_sql(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **) # :nodoc:
45
- return "geometry(#{limit})" if type.to_sym == :geometry && limit.is_a?(String)
45
+ if type.to_sym == :geometry && limit.is_a?(String)
46
+ return "geometry(#{limit})"
47
+ end
46
48
 
47
- if RGeo::ActiveRecord.geometric_type_from_name(type.to_s.delete("_"))
49
+ if (info = RGeo::ActiveRecord.geometric_type_from_name(type.to_s.delete("_")))
48
50
  type = limit[:type] || type if limit.is_a?(::Hash)
49
51
  type = type.to_s.delete("_").upcase
50
52
  end
51
53
  super
52
54
  end
53
55
 
56
+ def update_table_definition(table_name, base)
57
+ Mysql2Rgeo::Table.new(table_name, base)
58
+ end
59
+
54
60
  private
55
61
 
56
62
  # override
@@ -63,10 +69,6 @@ module ActiveRecord
63
69
  Mysql2Rgeo::TableDefinition.new(self, *args, **options)
64
70
  end
65
71
 
66
- def update_table_definition(table_name, base)
67
- Mysql2Rgeo::Table.new(table_name, base)
68
- end
69
-
70
72
  # override
71
73
  def new_column_from_field(table_name, field, _definitions)
72
74
  type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
@@ -85,7 +87,7 @@ module ActiveRecord
85
87
  end
86
88
 
87
89
  if default&.match?(/\Ast_geomfromtext\(/i)
88
- default = "(#{default})" unless default.start_with?("(")
90
+ default = +"(#{default})" unless default.start_with?("(")
89
91
  default, default_function = nil, default
90
92
  end
91
93
  end
@@ -114,9 +116,9 @@ module ActiveRecord
114
116
  type: :geometry,
115
117
  limit: nil,
116
118
  precision: type_metadata.precision,
117
- scale: type_metadata.scale
119
+ scale: type_metadata.scale,
118
120
  ),
119
- extra: type_metadata.extra
121
+ extra: type_metadata.extra,
120
122
  )
121
123
 
122
124
  if default_function&.match?(/\A\(?st_geomfromtext\(/i)
@@ -157,11 +159,10 @@ module ActiveRecord
157
159
  srid: srid,
158
160
  geographic: spatial[:geographic],
159
161
  has_z: spatial[:has_z],
160
- has_m: spatial[:has_m]
162
+ has_m: spatial[:has_m],
161
163
  )
162
164
  geometry = type.serialize(wkt)
163
165
  return unless geometry
164
-
165
166
  geometry = RGeo::Feature.cast(geometry, factory: type.send(:spatial_factory), project: true) if spatial[:geographic]
166
167
 
167
168
  wkb = RGeo::WKRep::WKBGenerator.new(
@@ -170,10 +171,15 @@ module ActiveRecord
170
171
  type_format: :wkb11,
171
172
  emit_ewkb_srid: false
172
173
  ).generate(geometry)
173
- return wkb.upcase unless spatial[:geographic]
174
-
175
- srid_hex = [spatial[:srid].to_i].pack("V").unpack1("H*")
176
- "#{srid_hex}#{wkb}".upcase
174
+ wkb = wkb.upcase
175
+ return wkb unless spatial[:geographic]
176
+
177
+ endian = wkb[0, 2]
178
+ type_hex = wkb[2, 8]
179
+ body = wkb[10..]
180
+ type = [type_hex].pack("H*").unpack1("V") | 0x20000000
181
+ srid_hex = [spatial[:srid].to_i].pack("V").unpack1("H*").upcase
182
+ "#{endian}#{[type].pack('V').unpack1('H*').upcase}#{srid_hex}#{body}"
177
183
  end
178
184
 
179
185
  def generation_expression_for(table_name, column_name)
@@ -184,7 +190,7 @@ module ActiveRecord
184
190
  AND table_name = #{quote(table_name)}
185
191
  AND column_name = #{quote(column_name)}
186
192
  SQL
187
- &.gsub(/st_buffer\(([^,]+),\s*(\d+)\)/i, 'st_buffer(\1, (\2)::double precision)')
193
+ &.gsub(/st_buffer\(([^,]+),\s*(\d+)\)/i, 'st_buffer(\1, (\2)::double precision)')
188
194
  end
189
195
 
190
196
  def generated_default_for(table_name, column_name)
@@ -4,17 +4,21 @@ module ActiveRecord # :nodoc:
4
4
  module ConnectionAdapters # :nodoc:
5
5
  module Mysql2Rgeo # :nodoc:
6
6
  class SpatialColumn < ConnectionAdapters::MySQL::Column # :nodoc:
7
- def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil,
8
- spatial: nil, array: false, **)
7
+ def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, spatial: nil, array: false, **)
9
8
  @sql_type_metadata = sql_type_metadata
10
9
  @array = array
10
+ @geographic = !!(sql_type_metadata&.sql_type =~ /geography\(/i)
11
11
  if spatial
12
12
  # This case comes from an entry in the geometry_columns table
13
13
  set_geometric_type_from_name(spatial[:type])
14
14
  @srid = spatial[:srid].to_i
15
- @has_z = spatial[:has_z]
16
- @has_m = spatial[:has_m]
17
- @geographic = spatial[:geographic]
15
+ @has_z = !!spatial[:has_z]
16
+ @has_m = !!spatial[:has_m]
17
+ @geographic = !!spatial[:geographic] || @geographic
18
+ elsif @geographic
19
+ @srid = 4326
20
+ @has_z = @has_m = false
21
+ build_from_sql_type(sql_type_metadata.sql_type)
18
22
  elsif sql_type =~ /geometry|point|linestring|polygon/i
19
23
  build_from_sql_type(sql_type_metadata.sql_type)
20
24
  elsif sql_type_metadata.sql_type =~ /geometry|point|linestring|polygon/i
@@ -23,13 +27,14 @@ spatial: nil, array: false, **)
23
27
  build_from_sql_type(sql_type_metadata.sql_type)
24
28
  end
25
29
  super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
26
- return unless spatial?
27
- return unless @srid
28
-
29
- @limit = { type: limit_type_name, srid: @srid }
30
- @limit[:geographic] = true if geographic?
31
- @limit[:has_z] = true if has_z?
32
- @limit[:has_m] = true if has_m?
30
+ if spatial?
31
+ if @srid
32
+ @limit = { type: limit_type_name, srid: @srid }
33
+ @limit[:geographic] = true if geographic?
34
+ @limit[:has_z] = true if has_z?
35
+ @limit[:has_m] = true if has_m?
36
+ end
37
+ end
33
38
  end
34
39
 
35
40
  attr_reader :geometric_type, :srid
@@ -67,6 +72,30 @@ spatial: nil, array: false, **)
67
72
  %i[geometry geography].include?(@sql_type_metadata.type)
68
73
  end
69
74
 
75
+ SPATIAL_ATTRIBUTES = %w[geographic geometric_type has_m has_z srid limit].freeze
76
+
77
+ def init_with(coder)
78
+ SPATIAL_ATTRIBUTES.each { |attr| instance_variable_set(:"@#{attr}", coder[attr]) }
79
+ super
80
+ end
81
+
82
+ def encode_with(coder)
83
+ SPATIAL_ATTRIBUTES.each { |attr| coder[attr] = instance_variable_get(:"@#{attr}") }
84
+ super
85
+ end
86
+
87
+ def ==(other)
88
+ other.is_a?(SpatialColumn) &&
89
+ super &&
90
+ array == other.array &&
91
+ SPATIAL_ATTRIBUTES.all? { |attr| public_send(attr) == other.public_send(attr) }
92
+ end
93
+ alias eql? ==
94
+
95
+ def hash
96
+ SPATIAL_ATTRIBUTES.reduce(SpatialColumn.hash ^ super.hash ^ array.hash) { |h, attr| h ^ public_send(attr).hash }
97
+ end
98
+
70
99
  private
71
100
 
72
101
  def set_geometric_type_from_name(name)
@@ -5,7 +5,6 @@ module ActiveRecord # :nodoc:
5
5
  module Mysql2Rgeo # :nodoc:
6
6
  class TableDefinition < MySQL::TableDefinition # :nodoc:
7
7
  include ColumnMethods
8
-
9
8
  # super: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
10
9
  def new_column_definition(name, type, **options)
11
10
  spatial_type = type.to_sym == :virtual ? options[:type]&.to_sym : type.to_sym
@@ -21,9 +20,7 @@ module ActiveRecord # :nodoc:
21
20
  ColumnDefinitionUtils.geo_type(options[:type] || spatial_type || info[:type])
22
21
  end
23
22
 
24
- if type.to_sym == :virtual
25
- options.delete(:srid)
26
- else
23
+ unless type.to_sym == :virtual
27
24
  options[:srid] ||= ColumnDefinitionUtils.default_srid(options)
28
25
  options[:comment] = ColumnDefinitionUtils.add_metadata_comment(
29
26
  options[:comment],
@@ -35,20 +32,19 @@ module ActiveRecord # :nodoc:
35
32
  srid: options[:srid],
36
33
  geo_type: geo_type
37
34
  )
35
+ else
36
+ options.delete(:srid)
38
37
  end
39
38
 
40
39
  options[:spatial_type] = geo_type
41
- column = if type.to_sym == :virtual
42
- super(name, type, **options.merge(type: geo_type.downcase.to_sym))
43
- else
44
- super(name, geo_type.downcase.to_sym, **options)
45
- end
46
- else
47
- if options[:array]
48
- options[:comment] =
49
- ColumnDefinitionUtils.add_metadata_comment(options[:comment], array: options[:array])
40
+ if type.to_sym == :virtual
41
+ column = super(name, type, **options.merge(type: geo_type.downcase.to_sym))
42
+ else
43
+ column = super(name, geo_type.downcase.to_sym, **options)
50
44
  end
51
- column = super
45
+ else
46
+ options[:comment] = ColumnDefinitionUtils.add_metadata_comment(options[:comment], array: options[:array]) if options[:array]
47
+ column = super(name, type, **options)
52
48
  end
53
49
 
54
50
  column
@@ -81,16 +77,14 @@ module ActiveRecord # :nodoc:
81
77
  options[:geographic] ? 4326 : Mysql2RgeoAdapter::DEFAULT_SRID
82
78
  end
83
79
 
84
- def add_metadata_comment(comment, geographic: false, has_m: false, has_z: false, array: false, default: nil, srid: nil,
85
- geo_type: nil)
80
+ def add_metadata_comment(comment, geographic: false, has_m: false, has_z: false, array: false, default: nil, srid: nil, geo_type: nil)
86
81
  values = [comment]
87
82
  values << METADATA_TOKENS[:geographic] if geographic
88
83
  values << METADATA_TOKENS[:has_m] if has_m
89
84
  values << METADATA_TOKENS[:has_z] if has_z
90
85
  values << METADATA_TOKENS[:array] if array
91
86
  if default
92
- values << "#{METADATA_TOKENS[:default_prefix]}#{encode_default(default, geographic: geographic, srid: srid,
93
- geo_type: geo_type, has_m: has_m, has_z: has_z)}"
87
+ values << "#{METADATA_TOKENS[:default_prefix]}#{encode_default(default, geographic: geographic, srid: srid, geo_type: geo_type, has_m: has_m, has_z: has_z)}"
94
88
  end
95
89
  values.compact_blank.join(" ")
96
90
  end
@@ -134,10 +128,16 @@ geo_type: nil)
134
128
  type_format: :wkb11,
135
129
  emit_ewkb_srid: false
136
130
  ).generate(geometry).upcase
137
- return wkb unless geographic
131
+ geographic ? with_ewkb_srid(wkb, srid) : wkb
132
+ end
138
133
 
134
+ def with_ewkb_srid(wkb, srid)
135
+ endian = wkb[0, 2]
136
+ type_hex = wkb[2, 8]
137
+ body = wkb[10..]
138
+ type = [type_hex].pack("H*").unpack1("V") | 0x20000000
139
139
  srid_hex = [srid.to_i].pack("V").unpack1("H*").upcase
140
- "#{srid_hex}#{wkb}"
140
+ "#{endian}#{[type].pack('V').unpack1('H*').upcase}#{srid_hex}#{body}"
141
141
  end
142
142
  end
143
143
  end
@@ -3,7 +3,7 @@
3
3
  module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module Mysql2Rgeo
6
- VERSION = "7.3.2"
6
+ VERSION = "8.0.4"
7
7
  end
8
8
  end
9
9
  end
@@ -22,6 +22,12 @@ require "active_record/type/spatial"
22
22
 
23
23
  # :startdoc:
24
24
 
25
+ ActiveRecord::ConnectionAdapters.register(
26
+ "mysql2rgeo",
27
+ "ActiveRecord::ConnectionAdapters::Mysql2RgeoAdapter",
28
+ "active_record/connection_adapters/mysql2rgeo_adapter"
29
+ )
30
+
25
31
  module ActiveRecord
26
32
  module ConnectionHandling # :nodoc:
27
33
  # Establishes a connection to the database that's used by all Active Record objects.
@@ -29,7 +35,7 @@ module ActiveRecord
29
35
  config = config.symbolize_keys
30
36
  config[:flags] ||= 0
31
37
 
32
- if config[:flags].is_a? Array
38
+ if config[:flags].kind_of? Array
33
39
  config[:flags].push "FOUND_ROWS"
34
40
  else
35
41
  config[:flags] |= Mysql2::Client::FOUND_ROWS
@@ -39,7 +45,7 @@ module ActiveRecord
39
45
  ConnectionAdapters::Mysql2RgeoAdapter.new_client(config),
40
46
  logger,
41
47
  nil,
42
- config
48
+ config,
43
49
  )
44
50
  end
45
51
  end
@@ -47,7 +53,6 @@ module ActiveRecord
47
53
  module ConnectionAdapters
48
54
  class Mysql2RgeoAdapter < Mysql2Adapter
49
55
  ADAPTER_NAME = "Mysql2Rgeo"
50
- MINIMUM_SUPPORTED_VERSION = "8.0.0"
51
56
 
52
57
  include Mysql2Rgeo::SchemaStatements
53
58
 
@@ -72,12 +77,10 @@ module ActiveRecord
72
77
  st_polygon: { type: "polygon" }
73
78
  }.freeze
74
79
 
75
- # MySQL uses SRID 0 when a spatial column does not declare one explicitly.
76
80
  DEFAULT_SRID = 0
77
81
 
78
- def initialize(connection, logger, connection_options, config)
82
+ def initialize(...)
79
83
  super
80
- verify_supported_database_version!
81
84
 
82
85
  @visitor = Arel::Visitors::Mysql2Rgeo.new(self)
83
86
  end
@@ -110,69 +113,74 @@ module ActiveRecord
110
113
  end
111
114
 
112
115
  class << self
113
- private
114
116
 
115
- def initialize_type_map(m)
116
- super
117
-
118
- {
119
- "geography" => "geometry",
120
- "geometry" => "geometry",
121
- "geometry_collection" => "geometrycollection",
122
- "line_string" => "linestring",
123
- "multi_line_string" => "multilinestring",
124
- "multi_point" => "multipoint",
125
- "multi_polygon" => "multipolygon",
126
- "st_point" => "point",
127
- "st_polygon" => "polygon",
128
- }.each do |registered_type, geo_type|
129
- m.register_type(registered_type) do |sql_type|
130
- Type::Spatial.new(sql_type.to_s, geo_type: geo_type)
117
+ private
118
+ def initialize_type_map(m)
119
+ super
120
+
121
+ {
122
+ "geography" => "geometry",
123
+ "geometry" => "geometry",
124
+ "geometry_collection" => "geometrycollection",
125
+ "line_string" => "linestring",
126
+ "multi_line_string" => "multilinestring",
127
+ "multi_point" => "multipoint",
128
+ "multi_polygon" => "multipolygon",
129
+ "st_point" => "point",
130
+ "st_polygon" => "polygon",
131
+ }.each do |registered_type, geo_type|
132
+ m.register_type(registered_type) do |sql_type|
133
+ Type::Spatial.new(sql_type.to_s, geo_type: geo_type)
134
+ end
131
135
  end
132
- end
133
136
 
134
- [
135
- /\Ageometry(?:\(.*\))?\z/i,
136
- /\Ageography(?:\(.*\))?\z/i,
137
- /\Apoint(?:\s.*)?\z/i,
138
- /\Alinestring(?:\s.*)?\z/i,
139
- /\Apolygon(?:\s.*)?\z/i,
140
- /\Amultipoint(?:\s.*)?\z/i,
141
- /\Amultilinestring(?:\s.*)?\z/i,
142
- /\Amultipolygon(?:\s.*)?\z/i,
143
- /\Ageometrycollection(?:\s.*)?\z/i,
144
- ].each do |pattern|
145
- m.register_type(pattern) do |sql_type|
146
- Type::Spatial.new(sql_type.to_s)
137
+ [
138
+ /\Ageometry(?:\(.*\))?\z/i,
139
+ /\Ageography(?:\(.*\))?\z/i,
140
+ /\Apoint(?:\s.*)?\z/i,
141
+ /\Alinestring(?:\s.*)?\z/i,
142
+ /\Apolygon(?:\s.*)?\z/i,
143
+ /\Amultipoint(?:\s.*)?\z/i,
144
+ /\Amultilinestring(?:\s.*)?\z/i,
145
+ /\Amultipolygon(?:\s.*)?\z/i,
146
+ /\Ageometrycollection(?:\s.*)?\z/i,
147
+ ].each do |pattern|
148
+ m.register_type(pattern) do |sql_type|
149
+ Type::Spatial.new(sql_type.to_s)
150
+ end
147
151
  end
148
- end
149
152
 
150
- {
151
- st_point: "point",
152
- st_polygon: "polygon",
153
- line_string: "linestring",
154
- multi_line_string: "multilinestring",
155
- multi_point: "multipoint",
156
- multi_polygon: "multipolygon",
157
- }.each do |alias_type, geo_type|
158
- ActiveRecord::Type.register(alias_type) do |_, **kwargs|
159
- Type::Spatial.new(geo_type, geo_type: geo_type, **kwargs)
153
+ {
154
+ st_point: "point",
155
+ st_polygon: "polygon",
156
+ line_string: "linestring",
157
+ multi_line_string: "multilinestring",
158
+ multi_point: "multipoint",
159
+ multi_polygon: "multipolygon",
160
+ }.each do |alias_type, geo_type|
161
+ ActiveRecord::Type.register(alias_type) do |_, **kwargs|
162
+ Type::Spatial.new(geo_type, geo_type: geo_type, **kwargs)
163
+ end
160
164
  end
165
+
161
166
  end
162
- end
163
167
  end
164
168
 
165
169
  TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
166
170
  TYPE_MAP_WITH_BOOLEAN = Type::TypeMap.new(TYPE_MAP).tap do |m|
167
- m.register_type(/^tinyint\(1\)/i, Type::Boolean.new)
171
+ m.register_type %r(^tinyint\(1\))i, Type::Boolean.new
168
172
  end
169
173
 
170
174
  def supports_spatial?
171
- !mariadb? && database_version >= MINIMUM_SUPPORTED_VERSION
175
+ !mariadb? && version >= "5.7.6"
176
+ end
177
+
178
+ def supports_partitioned_indexes?
179
+ false
172
180
  end
173
181
 
174
182
  def adapter_name
175
- ADAPTER_NAME
183
+ "Mysql2Rgeo"
176
184
  end
177
185
 
178
186
  def quote(value)
@@ -203,17 +211,9 @@ module ActiveRecord
203
211
  end
204
212
 
205
213
  private
206
-
207
- def verify_supported_database_version!
208
- return if database_version >= MINIMUM_SUPPORTED_VERSION
209
-
210
- raise ActiveRecord::ConnectionNotEstablished,
211
- "#{ADAPTER_NAME} supports MySQL #{MINIMUM_SUPPORTED_VERSION}+ only (detected #{database_version})"
212
- end
213
-
214
- def type_map
215
- emulate_booleans ? TYPE_MAP_WITH_BOOLEAN : TYPE_MAP
216
- end
214
+ def type_map
215
+ emulate_booleans ? TYPE_MAP_WITH_BOOLEAN : TYPE_MAP
216
+ end
217
217
  end
218
218
  end
219
219
  end
@@ -41,7 +41,9 @@ module ActiveRecord
41
41
  has_z = Regexp.last_match(2).casecmp("z").zero?
42
42
  has_m = Regexp.last_match(3).casecmp("m").zero?
43
43
  end
44
- srid = Regexp.last_match(1).to_i if params.last =~ /(\d+)/
44
+ if params.last =~ /(\d+)/
45
+ srid = Regexp.last_match(1).to_i
46
+ end
45
47
  elsif sql_type =~ /\A(geography|geometry)\z/i
46
48
  geographic = Regexp.last_match(1).casecmp("geography").zero?
47
49
  geo_type = Regexp.last_match(1)
@@ -80,7 +82,7 @@ module ActiveRecord
80
82
  has_z: @has_z,
81
83
  sql_type: @geographic ? "geography" : "geometry",
82
84
  srid: @srid
83
- )
85
+ )
84
86
  end
85
87
 
86
88
  def klass
@@ -116,7 +118,7 @@ module ActiveRecord
116
118
  def cast_value(value)
117
119
  return if value.nil?
118
120
 
119
- value.is_a?(::String) ? parse_wkt(value) : value
121
+ ::String === value ? parse_wkt(value) : value
120
122
  end
121
123
 
122
124
  # convert WKT string into RGeo object
@@ -124,7 +126,7 @@ module ActiveRecord
124
126
  marker = string[4, 1]
125
127
  if ["\x00", "\x01"].include?(marker)
126
128
  @srid = string[0, 4].unpack1(marker == "\x01" ? "V" : "N")
127
- RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid).parse(string[4..])
129
+ RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid).parse(string[4..-1])
128
130
  elsif string.match?(/\A[0-9a-fA-F]+\z/)
129
131
  original_srid = @srid
130
132
  parser = RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid)
@@ -139,7 +141,7 @@ module ActiveRecord
139
141
  @srid = string[0, 8].to_i(16)
140
142
  @srid = [@srid].pack("V").unpack("N").first if string[9, 1] == "1"
141
143
  parser = RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid)
142
- return parser.parse([string[8..]].pack("H*"))
144
+ return parser.parse([string[8..-1]].pack("H*"))
143
145
  end
144
146
 
145
147
  parser.parse([string].pack("H*"))
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-mysql2rgeo-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.3.2
4
+ version: 8.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yongdae Hwang
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-03-31 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: activerecord
@@ -15,28 +16,28 @@ dependencies:
15
16
  requirements:
16
17
  - - "~>"
17
18
  - !ruby/object:Gem::Version
18
- version: 7.1.0
19
+ version: 7.2.0
19
20
  type: :runtime
20
21
  prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
24
  - - "~>"
24
25
  - !ruby/object:Gem::Version
25
- version: 7.1.0
26
+ version: 7.2.0
26
27
  - !ruby/object:Gem::Dependency
27
28
  name: rgeo-activerecord
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: 7.0.0
33
+ version: 8.0.0
33
34
  type: :runtime
34
35
  prerelease: false
35
36
  version_requirements: !ruby/object:Gem::Requirement
36
37
  requirements:
37
38
  - - "~>"
38
39
  - !ruby/object:Gem::Version
39
- version: 7.0.0
40
+ version: 8.0.0
40
41
  - !ruby/object:Gem::Dependency
41
42
  name: rake
42
43
  requirement: !ruby/object:Gem::Requirement
@@ -65,6 +66,20 @@ dependencies:
65
66
  - - "~>"
66
67
  - !ruby/object:Gem::Version
67
68
  version: '5.4'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-excludes
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
68
83
  - !ruby/object:Gem::Dependency
69
84
  name: mocha
70
85
  requirement: !ruby/object:Gem::Requirement
@@ -133,9 +148,11 @@ homepage: http://github.com/stadia/activerecord-mysql2rgeo-adapter
133
148
  licenses:
134
149
  - BSD-3-Clause
135
150
  metadata:
151
+ funding_uri: https://opencollective.com/rgeo
136
152
  source_code_uri: https://github.com/stadia/activerecord-mysql2rgeo-adapter
137
153
  documentation_uri: https://github.com/stadia/activerecord-mysql2rgeo-adapter/blob/main/README.md
138
154
  rubygems_mfa_required: 'true'
155
+ post_install_message:
139
156
  rdoc_options: []
140
157
  require_paths:
141
158
  - lib
@@ -143,14 +160,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
143
160
  requirements:
144
161
  - - ">="
145
162
  - !ruby/object:Gem::Version
146
- version: 3.0.0
163
+ version: 3.1.0
147
164
  required_rubygems_version: !ruby/object:Gem::Requirement
148
165
  requirements:
149
166
  - - ">="
150
167
  - !ruby/object:Gem::Version
151
168
  version: '0'
152
169
  requirements: []
153
- rubygems_version: 4.0.20
170
+ rubygems_version: 3.3.27
171
+ signing_key:
154
172
  specification_version: 4
155
173
  summary: ActiveRecord adapter for MySQL, based on RGeo.
156
174
  test_files: []