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 +4 -4
- data/lib/active_record/connection_adapters/mysql2rgeo/arel_tosql.rb +6 -4
- data/lib/active_record/connection_adapters/mysql2rgeo/schema_creation.rb +22 -21
- data/lib/active_record/connection_adapters/mysql2rgeo/schema_statements.rb +24 -18
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_column.rb +41 -12
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_table_definition.rb +20 -20
- data/lib/active_record/connection_adapters/mysql2rgeo/version.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2rgeo_adapter.rb +63 -63
- data/lib/active_record/type/spatial.rb +7 -5
- metadata +26 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8e687a3f8a5ccfc68ed65b3a4580741bc2b68aa33f18b11a0db6aa3eb5de58d
|
|
4
|
+
data.tar.gz: f86a9aa0893e135f478701e58bbfd23d99ddf3e5e2ae078dcbb4b5870baa69de
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
12
|
+
class Mysql2Rgeo < MySQLSuperclass # :nodoc:
|
|
13
13
|
include RGeo::ActiveRecord::SpatialToSql
|
|
14
14
|
|
|
15
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
30
|
-
|
|
30
|
+
super
|
|
31
|
+
end
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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)
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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}#{
|
|
140
|
+
"#{endian}#{[type].pack('V').unpack1('H*').upcase}#{srid_hex}#{body}"
|
|
141
141
|
end
|
|
142
142
|
end
|
|
143
143
|
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].
|
|
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(
|
|
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
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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(
|
|
171
|
+
m.register_type %r(^tinyint\(1\))i, Type::Boolean.new
|
|
168
172
|
end
|
|
169
173
|
|
|
170
174
|
def supports_spatial?
|
|
171
|
-
!mariadb? &&
|
|
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
|
-
|
|
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
|
-
|
|
208
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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.
|
|
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.
|
|
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:
|
|
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:
|
|
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.
|
|
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:
|
|
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: []
|