activerecord-mysql2rgeo-adapter 7.1.1 → 7.3.0
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.
Potentially problematic release.
This version of activerecord-mysql2rgeo-adapter might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/active_record/connection_adapters/mysql2rgeo/arel_tosql.rb +29 -12
- data/lib/active_record/connection_adapters/mysql2rgeo/column_methods.rb +6 -0
- data/lib/active_record/connection_adapters/mysql2rgeo/schema_creation.rb +20 -0
- data/lib/active_record/connection_adapters/mysql2rgeo/schema_statements.rb +132 -5
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_column.rb +37 -6
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_column_info.rb +8 -3
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_table_definition.rb +101 -5
- data/lib/active_record/connection_adapters/mysql2rgeo/version.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2rgeo_adapter.rb +80 -13
- data/lib/active_record/type/spatial.rb +64 -11
- metadata +26 -36
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1c82a0cb0dbcc28e78febc6535b3aced42be547987218719e93343517942dd16
|
|
4
|
+
data.tar.gz: 2fa96c0d9224d4db1a6cf853f5dbbbf625414134481b361cbc0d28d121ff3c1b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8d09ca66bf3116806b61d0ff633c7decdbba69bb4a870de87810ba275770deac6e34c0c5065c45a4f1f1f8c0fd920db88c5affed40adec6e23a60d7d88667b92
|
|
7
|
+
data.tar.gz: b7af75ce324fde5f6e5a51e2aa603a7ddf2f15c84ce47c7940f42f098ae5b2222e7eaad00249af892523f39fdcec22bca413840ef2317a8b49cc45f2705bc753
|
|
@@ -28,12 +28,10 @@ module Arel # :nodoc:
|
|
|
28
28
|
|
|
29
29
|
def visit_String(node, collector)
|
|
30
30
|
node, srid = Mysql2Rgeo.parse_node(node)
|
|
31
|
-
collector <<
|
|
32
|
-
"#{st_func('ST_WKTToSQL')}(#{quote(node)})"
|
|
33
|
-
else
|
|
34
|
-
"#{st_func('ST_WKTToSQL')}(#{quote(node)}, #{srid})"
|
|
35
|
-
end
|
|
31
|
+
collector << spatial_constant_sql(node, srid)
|
|
36
32
|
end
|
|
33
|
+
alias visit_RGeo_Feature_Instance visit_String
|
|
34
|
+
alias visit_RGeo_Cartesian_BoundingBox visit_String
|
|
37
35
|
|
|
38
36
|
def visit_RGeo_ActiveRecord_SpatialNamedFunction(node, collector)
|
|
39
37
|
aggregate(st_func(node.name), node, collector)
|
|
@@ -43,21 +41,28 @@ module Arel # :nodoc:
|
|
|
43
41
|
case node
|
|
44
42
|
when String
|
|
45
43
|
node, srid = Mysql2Rgeo.parse_node(node)
|
|
46
|
-
collector <<
|
|
47
|
-
"#{st_func('ST_WKTToSQL')}(#{quote(node)})"
|
|
48
|
-
else
|
|
49
|
-
"#{st_func('ST_WKTToSQL')}(#{quote(node)}, #{srid})"
|
|
50
|
-
end
|
|
44
|
+
collector << spatial_constant_sql(node, srid)
|
|
51
45
|
when RGeo::Feature::Instance
|
|
52
|
-
|
|
46
|
+
visit_RGeo_Feature_Instance(node, collector)
|
|
53
47
|
when RGeo::Cartesian::BoundingBox
|
|
54
|
-
|
|
48
|
+
visit_RGeo_Cartesian_BoundingBox(node, collector)
|
|
55
49
|
else
|
|
56
50
|
visit(node, collector)
|
|
57
51
|
end
|
|
58
52
|
end
|
|
59
53
|
|
|
60
54
|
def self.parse_node(node)
|
|
55
|
+
if RGeo::Feature::Instance === node
|
|
56
|
+
wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(node)
|
|
57
|
+
return [wkt, node.srid]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
if RGeo::Cartesian::BoundingBox === node
|
|
61
|
+
geometry = node.to_geometry
|
|
62
|
+
wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(geometry)
|
|
63
|
+
return [wkt, geometry.srid]
|
|
64
|
+
end
|
|
65
|
+
|
|
61
66
|
value, srid = nil, 0
|
|
62
67
|
if node =~ /.*;.*$/i
|
|
63
68
|
params = Regexp.last_match(0).split(";")
|
|
@@ -76,6 +81,18 @@ module Arel # :nodoc:
|
|
|
76
81
|
end
|
|
77
82
|
[value, srid]
|
|
78
83
|
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def spatial_constant_sql(node, srid)
|
|
88
|
+
if srid == 0
|
|
89
|
+
"#{st_func('ST_WKTToSQL')}(#{quote(node)})"
|
|
90
|
+
elsif srid == 4326
|
|
91
|
+
"#{st_func('ST_WKTToSQL')}(#{quote(node)}, #{srid}, 'axis-order=long-lat')"
|
|
92
|
+
else
|
|
93
|
+
"#{st_func('ST_WKTToSQL')}(#{quote(node)}, #{srid})"
|
|
94
|
+
end
|
|
95
|
+
end
|
|
79
96
|
end
|
|
80
97
|
end
|
|
81
98
|
end
|
|
@@ -14,6 +14,10 @@ module ActiveRecord
|
|
|
14
14
|
column(name, :geometry, **options)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
def geography(name, options = {})
|
|
18
|
+
column(name, :geometry, geographic: true, **options)
|
|
19
|
+
end
|
|
20
|
+
|
|
17
21
|
def geometry_collection(name, options = {})
|
|
18
22
|
column(name, :geometrycollection, **options)
|
|
19
23
|
end
|
|
@@ -42,10 +46,12 @@ module ActiveRecord
|
|
|
42
46
|
def point(name, options = {})
|
|
43
47
|
column(name, :point, **options)
|
|
44
48
|
end
|
|
49
|
+
alias st_point point
|
|
45
50
|
|
|
46
51
|
def polygon(name, options = {})
|
|
47
52
|
column(name, :polygon, **options)
|
|
48
53
|
end
|
|
54
|
+
alias st_polygon polygon
|
|
49
55
|
end
|
|
50
56
|
end
|
|
51
57
|
|
|
@@ -5,14 +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
|
|
16
|
+
|
|
17
|
+
super
|
|
18
|
+
end
|
|
8
19
|
|
|
9
20
|
def add_column_options!(sql, options)
|
|
10
21
|
if options[:srid]
|
|
11
22
|
sql << " /*!80003 SRID #{options[:srid]} */"
|
|
23
|
+
options = options.except(:srid)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if options_include_default?(options) && spatial_column_definition?(options[:column])
|
|
27
|
+
options = options.except(:default)
|
|
12
28
|
end
|
|
13
29
|
|
|
14
30
|
super
|
|
15
31
|
end
|
|
32
|
+
|
|
33
|
+
def spatial_column_definition?(column)
|
|
34
|
+
column.respond_to?(:type) && column.type && @conn.class.spatial_column_options(column.type.to_sym)
|
|
35
|
+
end
|
|
16
36
|
end
|
|
17
37
|
end
|
|
18
38
|
end
|
|
@@ -13,12 +13,39 @@ module ActiveRecord
|
|
|
13
13
|
# https://dev.mysql.com/doc/refman/5.6/en/create-index.html
|
|
14
14
|
indexes.select do |idx|
|
|
15
15
|
idx.type == :spatial
|
|
16
|
-
end.each
|
|
16
|
+
end.each do |idx|
|
|
17
|
+
if idx.is_a?(Struct)
|
|
18
|
+
idx.lengths = {}
|
|
19
|
+
idx.using = :gist if idx.members.include?(:using)
|
|
20
|
+
else
|
|
21
|
+
idx.instance_variable_set(:@lengths, {})
|
|
22
|
+
idx.instance_variable_set(:@using, :gist)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
17
25
|
indexes
|
|
18
26
|
end
|
|
19
27
|
|
|
28
|
+
def add_index(table_name, column_name, **options) # :nodoc:
|
|
29
|
+
if options[:using]&.to_sym == :gist
|
|
30
|
+
Array(column_name).each do |name|
|
|
31
|
+
column = columns(table_name).find { |col| col.name == name.to_s }
|
|
32
|
+
next unless column&.spatial? && column.null
|
|
33
|
+
|
|
34
|
+
column_options = column.limit.is_a?(Hash) ? column.limit.symbolize_keys.except(:type) : {}
|
|
35
|
+
column_options[:comment] = column.comment if column.comment.present?
|
|
36
|
+
change_column(table_name, name, column.limit[:type].to_sym, **column_options.merge(null: false))
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
super
|
|
41
|
+
end
|
|
42
|
+
|
|
20
43
|
# override
|
|
21
44
|
def type_to_sql(type, limit: nil, precision: nil, scale: nil, unsigned: nil, **) # :nodoc:
|
|
45
|
+
if type.to_sym == :geometry && limit.is_a?(String)
|
|
46
|
+
return "geometry(#{limit})"
|
|
47
|
+
end
|
|
48
|
+
|
|
22
49
|
if (info = RGeo::ActiveRecord.geometric_type_from_name(type.to_s.delete("_")))
|
|
23
50
|
type = limit[:type] || type if limit.is_a?(::Hash)
|
|
24
51
|
type = type.to_s.delete("_").upcase
|
|
@@ -38,20 +65,67 @@ module ActiveRecord
|
|
|
38
65
|
Mysql2Rgeo::TableDefinition.new(self, *args, **options)
|
|
39
66
|
end
|
|
40
67
|
|
|
68
|
+
def update_table_definition(table_name, base)
|
|
69
|
+
Mysql2Rgeo::Table.new(table_name, base)
|
|
70
|
+
end
|
|
71
|
+
|
|
41
72
|
# override
|
|
42
73
|
def new_column_from_field(table_name, field, _definitions)
|
|
43
74
|
type_metadata = fetch_type_metadata(field[:Type], field[:Extra])
|
|
44
75
|
default, default_function = field[:Default], nil
|
|
76
|
+
metadata = Mysql2Rgeo::ColumnDefinitionUtils.extract_metadata(field[:Comment])
|
|
77
|
+
comment = Mysql2Rgeo::ColumnDefinitionUtils.strip_metadata_comment(field[:Comment])
|
|
78
|
+
default = metadata[:default_hex] if default.nil? && metadata[:default_hex].present?
|
|
45
79
|
|
|
46
80
|
if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
|
|
47
81
|
default, default_function = nil, default
|
|
48
82
|
elsif type_metadata.extra == "DEFAULT_GENERATED"
|
|
49
|
-
default
|
|
50
|
-
|
|
83
|
+
if default == "NULL" && metadata[:default_hex].present?
|
|
84
|
+
default = metadata[:default_hex]
|
|
85
|
+
elsif default == "NULL"
|
|
86
|
+
default = generated_default_for(table_name, field[:Field])
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
if default&.match?(/\Ast_geomfromtext\(/i)
|
|
90
|
+
default = +"(#{default})" unless default.start_with?("(")
|
|
91
|
+
default, default_function = nil, default
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if type_metadata.extra.to_s.match?(/(?:VIRTUAL|STORED|PERSISTENT)\s+GENERATED/i)
|
|
96
|
+
default_function = generation_expression_for(table_name, field[:Field])
|
|
51
97
|
end
|
|
52
98
|
|
|
53
99
|
# {:dimension=>2, :has_m=>false, :has_z=>false, :name=>"latlon", :srid=>0, :type=>"GEOMETRY"}
|
|
54
100
|
spatial = spatial_column_info(table_name).get(field[:Field], type_metadata.sql_type)
|
|
101
|
+
if spatial
|
|
102
|
+
spatial[:has_z] ||= metadata[:has_z]
|
|
103
|
+
spatial[:has_m] ||= metadata[:has_m]
|
|
104
|
+
spatial[:geographic] ||= metadata[:geographic]
|
|
105
|
+
geo_type = spatial[:type].camelize
|
|
106
|
+
geo_type = "#{geo_type}Z" if spatial[:has_z]
|
|
107
|
+
geo_type = "#{geo_type}M" if spatial[:has_m]
|
|
108
|
+
sql_type = if spatial[:geographic]
|
|
109
|
+
"geography(#{geo_type},#{spatial[:srid]})"
|
|
110
|
+
else
|
|
111
|
+
"geometry(#{geo_type},#{spatial[:srid]})"
|
|
112
|
+
end
|
|
113
|
+
type_metadata = MySQL::TypeMetadata.new(
|
|
114
|
+
ConnectionAdapters::SqlTypeMetadata.new(
|
|
115
|
+
sql_type: sql_type,
|
|
116
|
+
type: :geometry,
|
|
117
|
+
limit: nil,
|
|
118
|
+
precision: type_metadata.precision,
|
|
119
|
+
scale: type_metadata.scale,
|
|
120
|
+
),
|
|
121
|
+
extra: type_metadata.extra,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if default_function&.match?(/\A\(?st_geomfromtext\(/i)
|
|
125
|
+
default = extract_spatial_default_hex(default_function, spatial)
|
|
126
|
+
default_function = nil
|
|
127
|
+
end
|
|
128
|
+
end
|
|
55
129
|
|
|
56
130
|
SpatialColumn.new(
|
|
57
131
|
field[:Field],
|
|
@@ -60,8 +134,9 @@ module ActiveRecord
|
|
|
60
134
|
field[:Null] == "YES",
|
|
61
135
|
default_function,
|
|
62
136
|
collation: field[:Collation],
|
|
63
|
-
comment:
|
|
64
|
-
spatial: spatial
|
|
137
|
+
comment: comment,
|
|
138
|
+
spatial: spatial,
|
|
139
|
+
array: metadata[:array]
|
|
65
140
|
)
|
|
66
141
|
end
|
|
67
142
|
|
|
@@ -70,6 +145,58 @@ module ActiveRecord
|
|
|
70
145
|
@spatial_column_info ||= {}
|
|
71
146
|
@spatial_column_info[table_name.to_sym] = SpatialColumnInfo.new(self, table_name.to_s)
|
|
72
147
|
end
|
|
148
|
+
|
|
149
|
+
def extract_spatial_default_hex(default_function, spatial)
|
|
150
|
+
default_sql = default_function.delete_prefix("(").delete_suffix(")").delete("\\")
|
|
151
|
+
match = default_sql.match(/\Ast_geomfromtext\(_utf8mb4'(.+?)',\s*(\d+)\)\z/i)
|
|
152
|
+
return unless match
|
|
153
|
+
|
|
154
|
+
wkt = match[1]
|
|
155
|
+
srid = match[2].to_i
|
|
156
|
+
type = ActiveRecord::Type::Spatial.new(
|
|
157
|
+
spatial[:geographic] ? "geography" : "geometry",
|
|
158
|
+
geo_type: ActiveRecord::Type::Spatial.normalize_geo_type(spatial[:type]),
|
|
159
|
+
srid: srid,
|
|
160
|
+
geographic: spatial[:geographic],
|
|
161
|
+
has_z: spatial[:has_z],
|
|
162
|
+
has_m: spatial[:has_m],
|
|
163
|
+
)
|
|
164
|
+
geometry = type.serialize(wkt)
|
|
165
|
+
return unless geometry
|
|
166
|
+
geometry = RGeo::Feature.cast(geometry, factory: type.send(:spatial_factory), project: true) if spatial[:geographic]
|
|
167
|
+
|
|
168
|
+
wkb = RGeo::WKRep::WKBGenerator.new(
|
|
169
|
+
hex_format: true,
|
|
170
|
+
little_endian: true,
|
|
171
|
+
type_format: :wkb11,
|
|
172
|
+
emit_ewkb_srid: false
|
|
173
|
+
).generate(geometry)
|
|
174
|
+
return wkb.upcase unless spatial[:geographic]
|
|
175
|
+
|
|
176
|
+
srid_hex = [spatial[:srid].to_i].pack("V").unpack1("H*")
|
|
177
|
+
"#{srid_hex}#{wkb}".upcase
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def generation_expression_for(table_name, column_name)
|
|
181
|
+
query_value(<<~SQL)&.gsub("`", "")
|
|
182
|
+
SELECT generation_expression
|
|
183
|
+
FROM information_schema.columns
|
|
184
|
+
WHERE table_schema = DATABASE()
|
|
185
|
+
AND table_name = #{quote(table_name)}
|
|
186
|
+
AND column_name = #{quote(column_name)}
|
|
187
|
+
SQL
|
|
188
|
+
&.gsub(/st_buffer\(([^,]+),\s*(\d+)\)/i, 'st_buffer(\1, (\2)::double precision)')
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def generated_default_for(table_name, column_name)
|
|
192
|
+
query_value(<<~SQL)
|
|
193
|
+
SELECT column_default
|
|
194
|
+
FROM information_schema.columns
|
|
195
|
+
WHERE table_schema = DATABASE()
|
|
196
|
+
AND table_name = #{quote(table_name)}
|
|
197
|
+
AND column_name = #{quote(column_name)}
|
|
198
|
+
SQL
|
|
199
|
+
end
|
|
73
200
|
end
|
|
74
201
|
end
|
|
75
202
|
end
|
|
@@ -4,12 +4,16 @@ 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, spatial: nil, **)
|
|
7
|
+
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, spatial: nil, array: false, **)
|
|
8
8
|
@sql_type_metadata = sql_type_metadata
|
|
9
|
+
@array = array
|
|
9
10
|
if spatial
|
|
10
11
|
# This case comes from an entry in the geometry_columns table
|
|
11
12
|
set_geometric_type_from_name(spatial[:type])
|
|
12
13
|
@srid = spatial[:srid].to_i
|
|
14
|
+
@has_z = spatial[:has_z]
|
|
15
|
+
@has_m = spatial[:has_m]
|
|
16
|
+
@geographic = spatial[:geographic]
|
|
13
17
|
elsif sql_type =~ /geometry|point|linestring|polygon/i
|
|
14
18
|
build_from_sql_type(sql_type_metadata.sql_type)
|
|
15
19
|
elsif sql_type_metadata.sql_type =~ /geometry|point|linestring|polygon/i
|
|
@@ -20,23 +24,31 @@ module ActiveRecord # :nodoc:
|
|
|
20
24
|
super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
|
|
21
25
|
if spatial?
|
|
22
26
|
if @srid
|
|
23
|
-
@limit = { type:
|
|
27
|
+
@limit = { type: limit_type_name, srid: @srid }
|
|
28
|
+
@limit[:geographic] = true if geographic?
|
|
29
|
+
@limit[:has_z] = true if has_z?
|
|
30
|
+
@limit[:has_m] = true if has_m?
|
|
24
31
|
end
|
|
25
32
|
end
|
|
26
33
|
end
|
|
27
34
|
|
|
28
35
|
attr_reader :geometric_type, :srid
|
|
29
36
|
|
|
37
|
+
def array
|
|
38
|
+
@array || false
|
|
39
|
+
end
|
|
40
|
+
alias array? array
|
|
41
|
+
|
|
30
42
|
def has_z
|
|
31
|
-
false
|
|
43
|
+
spatial? ? (@has_z || false) : nil
|
|
32
44
|
end
|
|
33
45
|
|
|
34
46
|
def has_m
|
|
35
|
-
false
|
|
47
|
+
spatial? ? (@has_m || false) : nil
|
|
36
48
|
end
|
|
37
49
|
|
|
38
50
|
def geographic
|
|
39
|
-
false
|
|
51
|
+
spatial? ? (@geographic || false) : nil
|
|
40
52
|
end
|
|
41
53
|
|
|
42
54
|
alias geographic? geographic
|
|
@@ -59,12 +71,31 @@ module ActiveRecord # :nodoc:
|
|
|
59
71
|
|
|
60
72
|
def set_geometric_type_from_name(name)
|
|
61
73
|
@geometric_type = RGeo::ActiveRecord.geometric_type_from_name(name) || RGeo::Feature::Geometry
|
|
74
|
+
@geo_type_name = ActiveRecord::Type::Spatial.normalize_geo_type(name)
|
|
62
75
|
end
|
|
63
76
|
|
|
64
77
|
def build_from_sql_type(sql_type)
|
|
65
|
-
geo_type, @srid = Type::Spatial.parse_sql_type(sql_type)
|
|
78
|
+
geo_type, @srid, @has_z, @has_m, @geographic = Type::Spatial.parse_sql_type(sql_type)
|
|
66
79
|
set_geometric_type_from_name(geo_type)
|
|
67
80
|
end
|
|
81
|
+
|
|
82
|
+
def limit_type_name
|
|
83
|
+
type_name = @geo_type_name || geometric_type.type_name.underscore
|
|
84
|
+
case type_name
|
|
85
|
+
when "point", "polygon"
|
|
86
|
+
"st_#{type_name}"
|
|
87
|
+
when "linestring"
|
|
88
|
+
"line_string"
|
|
89
|
+
when "multilinestring"
|
|
90
|
+
"multi_line_string"
|
|
91
|
+
when "multipoint"
|
|
92
|
+
"multi_point"
|
|
93
|
+
when "multipolygon"
|
|
94
|
+
"multi_polygon"
|
|
95
|
+
else
|
|
96
|
+
type_name
|
|
97
|
+
end
|
|
98
|
+
end
|
|
68
99
|
end
|
|
69
100
|
end
|
|
70
101
|
end
|
|
@@ -13,11 +13,11 @@ module ActiveRecord # :nodoc:
|
|
|
13
13
|
def all
|
|
14
14
|
info = if @adapter.supports_expression_index?
|
|
15
15
|
@adapter.query(
|
|
16
|
-
"SELECT column_name, srs_id, column_type FROM INFORMATION_SCHEMA.Columns WHERE table_name='#{@table_name}'"
|
|
16
|
+
"SELECT column_name, srs_id, column_type, column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_schema = DATABASE() AND table_name='#{@table_name}'"
|
|
17
17
|
)
|
|
18
18
|
else
|
|
19
19
|
@adapter.query(
|
|
20
|
-
"SELECT column_name, 0, column_type FROM INFORMATION_SCHEMA.Columns WHERE table_name='#{@table_name}'"
|
|
20
|
+
"SELECT column_name, 0, column_type, column_comment FROM INFORMATION_SCHEMA.Columns WHERE table_schema = DATABASE() AND table_name='#{@table_name}'"
|
|
21
21
|
)
|
|
22
22
|
end
|
|
23
23
|
|
|
@@ -25,11 +25,16 @@ module ActiveRecord # :nodoc:
|
|
|
25
25
|
info.each do |row|
|
|
26
26
|
name = row[0]
|
|
27
27
|
type = row[2]
|
|
28
|
-
|
|
28
|
+
column_comment = row[3].to_s
|
|
29
|
+
has_z = type.sub!(/z$/i, "").present?
|
|
30
|
+
has_m = type.sub!(/m$/i, "").present?
|
|
29
31
|
result[name] = {
|
|
30
32
|
name: name,
|
|
31
33
|
srid: row[1].to_i,
|
|
32
34
|
type: type,
|
|
35
|
+
has_z: has_z,
|
|
36
|
+
has_m: has_m,
|
|
37
|
+
geographic: column_comment.include?("mysql2rgeo:geographic"),
|
|
33
38
|
}
|
|
34
39
|
end
|
|
35
40
|
result
|
|
@@ -7,16 +7,43 @@ module ActiveRecord # :nodoc:
|
|
|
7
7
|
include ColumnMethods
|
|
8
8
|
# super: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
|
|
9
9
|
def new_column_definition(name, type, **options)
|
|
10
|
-
|
|
10
|
+
spatial_type = type.to_sym == :virtual ? options[:type]&.to_sym : type.to_sym
|
|
11
|
+
|
|
12
|
+
if spatial_type && (info = Mysql2RgeoAdapter.spatial_column_options(spatial_type))
|
|
11
13
|
if (limit = options.delete(:limit)) && limit.is_a?(::Hash)
|
|
12
14
|
options.merge!(limit)
|
|
13
15
|
end
|
|
14
16
|
|
|
15
|
-
geo_type =
|
|
17
|
+
geo_type = if type.to_sym == :virtual
|
|
18
|
+
"GEOMETRY"
|
|
19
|
+
else
|
|
20
|
+
ColumnDefinitionUtils.geo_type(options[:type] || spatial_type || info[:type])
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
unless type.to_sym == :virtual
|
|
24
|
+
options[:srid] ||= ColumnDefinitionUtils.default_srid(options)
|
|
25
|
+
options[:comment] = ColumnDefinitionUtils.add_metadata_comment(
|
|
26
|
+
options[:comment],
|
|
27
|
+
geographic: options[:geographic],
|
|
28
|
+
has_m: options[:has_m],
|
|
29
|
+
has_z: options[:has_z],
|
|
30
|
+
array: options[:array],
|
|
31
|
+
default: options[:default],
|
|
32
|
+
srid: options[:srid],
|
|
33
|
+
geo_type: geo_type
|
|
34
|
+
)
|
|
35
|
+
else
|
|
36
|
+
options.delete(:srid)
|
|
37
|
+
end
|
|
16
38
|
|
|
17
39
|
options[:spatial_type] = geo_type
|
|
18
|
-
|
|
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)
|
|
44
|
+
end
|
|
19
45
|
else
|
|
46
|
+
options[:comment] = ColumnDefinitionUtils.add_metadata_comment(options[:comment], array: options[:array]) if options[:array]
|
|
20
47
|
column = super(name, type, **options)
|
|
21
48
|
end
|
|
22
49
|
|
|
@@ -24,19 +51,88 @@ module ActiveRecord # :nodoc:
|
|
|
24
51
|
end
|
|
25
52
|
|
|
26
53
|
def valid_column_definition_options
|
|
27
|
-
super + %i[geographic has_m spatial_type srid]
|
|
54
|
+
super + %i[array geographic has_m has_z spatial_type srid]
|
|
28
55
|
end
|
|
29
56
|
end
|
|
30
57
|
|
|
58
|
+
class Table < MySQL::Table # :nodoc:
|
|
59
|
+
include ColumnMethods
|
|
60
|
+
end
|
|
61
|
+
|
|
31
62
|
module ColumnDefinitionUtils
|
|
63
|
+
METADATA_TOKENS = {
|
|
64
|
+
geographic: "mysql2rgeo:geographic",
|
|
65
|
+
has_m: "mysql2rgeo:has_m",
|
|
66
|
+
has_z: "mysql2rgeo:has_z",
|
|
67
|
+
array: "mysql2rgeo:array",
|
|
68
|
+
default_prefix: "mysql2rgeo:default:"
|
|
69
|
+
}.freeze
|
|
70
|
+
|
|
32
71
|
class << self
|
|
33
72
|
def geo_type(type = "GEOMETRY")
|
|
34
|
-
type.to_s.delete("_").upcase
|
|
73
|
+
type.to_s.sub(/\Ast_/, "").delete("_").upcase
|
|
35
74
|
end
|
|
36
75
|
|
|
37
76
|
def default_srid(options)
|
|
38
77
|
options[:geographic] ? 4326 : Mysql2RgeoAdapter::DEFAULT_SRID
|
|
39
78
|
end
|
|
79
|
+
|
|
80
|
+
def add_metadata_comment(comment, geographic: false, has_m: false, has_z: false, array: false, default: nil, srid: nil, geo_type: nil)
|
|
81
|
+
values = [comment]
|
|
82
|
+
values << METADATA_TOKENS[:geographic] if geographic
|
|
83
|
+
values << METADATA_TOKENS[:has_m] if has_m
|
|
84
|
+
values << METADATA_TOKENS[:has_z] if has_z
|
|
85
|
+
values << METADATA_TOKENS[:array] if array
|
|
86
|
+
if default
|
|
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)}"
|
|
88
|
+
end
|
|
89
|
+
values.compact_blank.join(" ")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def extract_metadata(comment)
|
|
93
|
+
text = comment.to_s
|
|
94
|
+
default_hex = text[/#{Regexp.escape(METADATA_TOKENS[:default_prefix])}([0-9A-F]+)/i, 1]
|
|
95
|
+
{
|
|
96
|
+
geographic: text.include?(METADATA_TOKENS[:geographic]),
|
|
97
|
+
has_m: text.include?(METADATA_TOKENS[:has_m]),
|
|
98
|
+
has_z: text.include?(METADATA_TOKENS[:has_z]),
|
|
99
|
+
array: text.include?(METADATA_TOKENS[:array]),
|
|
100
|
+
default_hex: default_hex,
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def strip_metadata_comment(comment)
|
|
105
|
+
text = comment.to_s
|
|
106
|
+
METADATA_TOKENS.each_value do |token|
|
|
107
|
+
text = text.gsub(token, "")
|
|
108
|
+
end
|
|
109
|
+
text = text.gsub(/mysql2rgeo:default:[0-9A-F]+/i, "")
|
|
110
|
+
text.squeeze(" ").strip.presence
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def encode_default(default, geographic:, srid:, geo_type:, has_m:, has_z:)
|
|
114
|
+
type = ActiveRecord::Type::Spatial.new(
|
|
115
|
+
geographic ? "geography" : "geometry",
|
|
116
|
+
geo_type: ActiveRecord::Type::Spatial.normalize_geo_type(geo_type),
|
|
117
|
+
srid: srid,
|
|
118
|
+
geographic: geographic,
|
|
119
|
+
has_z: has_z,
|
|
120
|
+
has_m: has_m
|
|
121
|
+
)
|
|
122
|
+
geometry = type.serialize(default)
|
|
123
|
+
geometry = RGeo::Feature.cast(geometry, factory: type.send(:spatial_factory), project: true) if geographic
|
|
124
|
+
|
|
125
|
+
wkb = RGeo::WKRep::WKBGenerator.new(
|
|
126
|
+
hex_format: true,
|
|
127
|
+
little_endian: true,
|
|
128
|
+
type_format: :wkb11,
|
|
129
|
+
emit_ewkb_srid: false
|
|
130
|
+
).generate(geometry).upcase
|
|
131
|
+
return wkb unless geographic
|
|
132
|
+
|
|
133
|
+
srid_hex = [srid.to_i].pack("V").unpack1("H*").upcase
|
|
134
|
+
"#{srid_hex}#{wkb}"
|
|
135
|
+
end
|
|
40
136
|
end
|
|
41
137
|
end
|
|
42
138
|
end
|
|
@@ -52,15 +52,23 @@ module ActiveRecord
|
|
|
52
52
|
|
|
53
53
|
SPATIAL_COLUMN_OPTIONS =
|
|
54
54
|
{
|
|
55
|
+
geography: { type: "geometry", geographic: true },
|
|
55
56
|
geometry: {},
|
|
56
57
|
geometrycollection: {},
|
|
58
|
+
geometry_collection: { type: "geometrycollection" },
|
|
57
59
|
linestring: {},
|
|
60
|
+
line_string: { type: "linestring" },
|
|
58
61
|
multilinestring: {},
|
|
62
|
+
multi_line_string: { type: "multilinestring" },
|
|
59
63
|
multipoint: {},
|
|
64
|
+
multi_point: { type: "multipoint" },
|
|
60
65
|
multipolygon: {},
|
|
66
|
+
multi_polygon: { type: "multipolygon" },
|
|
61
67
|
spatial: { type: "geometry" },
|
|
62
68
|
point: {},
|
|
63
|
-
polygon: {}
|
|
69
|
+
polygon: {},
|
|
70
|
+
st_point: { type: "point" },
|
|
71
|
+
st_polygon: { type: "polygon" }
|
|
64
72
|
}.freeze
|
|
65
73
|
|
|
66
74
|
# http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
|
|
@@ -86,7 +94,10 @@ module ActiveRecord
|
|
|
86
94
|
super.merge(
|
|
87
95
|
geometry: { name: "geometry" },
|
|
88
96
|
geometrycollection: { name: "geometrycollection" },
|
|
97
|
+
line_string: { name: "linestring" },
|
|
89
98
|
linestring: { name: "linestring" },
|
|
99
|
+
st_point: { name: "point" },
|
|
100
|
+
st_polygon: { name: "polygon" },
|
|
90
101
|
multi_line_string: { name: "multilinestring" },
|
|
91
102
|
multi_point: { name: "multipoint" },
|
|
92
103
|
multi_polygon: { name: "multipolygon" },
|
|
@@ -102,20 +113,50 @@ module ActiveRecord
|
|
|
102
113
|
def initialize_type_map(m)
|
|
103
114
|
super
|
|
104
115
|
|
|
105
|
-
|
|
106
|
-
geometry
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
linestring
|
|
110
|
-
|
|
111
|
-
multipoint
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
{
|
|
117
|
+
"geography" => "geometry",
|
|
118
|
+
"geometry" => "geometry",
|
|
119
|
+
"geometry_collection" => "geometrycollection",
|
|
120
|
+
"line_string" => "linestring",
|
|
121
|
+
"multi_line_string" => "multilinestring",
|
|
122
|
+
"multi_point" => "multipoint",
|
|
123
|
+
"multi_polygon" => "multipolygon",
|
|
124
|
+
"st_point" => "point",
|
|
125
|
+
"st_polygon" => "polygon",
|
|
126
|
+
}.each do |registered_type, geo_type|
|
|
127
|
+
m.register_type(registered_type) do |sql_type|
|
|
128
|
+
Type::Spatial.new(sql_type.to_s, geo_type: geo_type)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
[
|
|
133
|
+
/\Ageometry(?:\(.*\))?\z/i,
|
|
134
|
+
/\Ageography(?:\(.*\))?\z/i,
|
|
135
|
+
/\Apoint(?:\s.*)?\z/i,
|
|
136
|
+
/\Alinestring(?:\s.*)?\z/i,
|
|
137
|
+
/\Apolygon(?:\s.*)?\z/i,
|
|
138
|
+
/\Amultipoint(?:\s.*)?\z/i,
|
|
139
|
+
/\Amultilinestring(?:\s.*)?\z/i,
|
|
140
|
+
/\Amultipolygon(?:\s.*)?\z/i,
|
|
141
|
+
/\Ageometrycollection(?:\s.*)?\z/i,
|
|
142
|
+
].each do |pattern|
|
|
143
|
+
m.register_type(pattern) do |sql_type|
|
|
116
144
|
Type::Spatial.new(sql_type.to_s)
|
|
117
145
|
end
|
|
118
146
|
end
|
|
147
|
+
|
|
148
|
+
{
|
|
149
|
+
st_point: "point",
|
|
150
|
+
st_polygon: "polygon",
|
|
151
|
+
line_string: "linestring",
|
|
152
|
+
multi_line_string: "multilinestring",
|
|
153
|
+
multi_point: "multipoint",
|
|
154
|
+
multi_polygon: "multipolygon",
|
|
155
|
+
}.each do |alias_type, geo_type|
|
|
156
|
+
ActiveRecord::Type.register(alias_type) do |_, **kwargs|
|
|
157
|
+
Type::Spatial.new(geo_type, geo_type: geo_type, **kwargs)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
119
160
|
end
|
|
120
161
|
end
|
|
121
162
|
|
|
@@ -128,15 +169,41 @@ module ActiveRecord
|
|
|
128
169
|
!mariadb? && version >= "5.7.6"
|
|
129
170
|
end
|
|
130
171
|
|
|
172
|
+
def postgis_lib_version
|
|
173
|
+
"3.0.mysql2rgeo"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def adapter_name
|
|
177
|
+
"PostGIS"
|
|
178
|
+
end
|
|
179
|
+
|
|
131
180
|
def quote(value)
|
|
132
181
|
dbval = value.try(:value_for_database) || value
|
|
133
182
|
if RGeo::Feature::Geometry.check_type(dbval)
|
|
134
|
-
|
|
183
|
+
wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(dbval)
|
|
184
|
+
if dbval.srid == 4326
|
|
185
|
+
"ST_GeomFromText(#{super(wkt)}, #{dbval.srid}, 'axis-order=long-lat')"
|
|
186
|
+
else
|
|
187
|
+
"ST_GeomFromText(#{super(wkt)}, #{dbval.srid})"
|
|
188
|
+
end
|
|
135
189
|
else
|
|
136
190
|
super
|
|
137
191
|
end
|
|
138
192
|
end
|
|
139
193
|
|
|
194
|
+
def quote_default_expression(value, column) # :nodoc:
|
|
195
|
+
return super unless column.respond_to?(:spatial?) && column.spatial?
|
|
196
|
+
|
|
197
|
+
value = lookup_cast_type(column.sql_type).serialize(value)
|
|
198
|
+
hex = RGeo::WKRep::WKBGenerator.new(
|
|
199
|
+
hex_format: true,
|
|
200
|
+
little_endian: true,
|
|
201
|
+
type_format: :wkb11,
|
|
202
|
+
emit_ewkb_srid: false
|
|
203
|
+
).generate(value).upcase
|
|
204
|
+
"(ST_GeomFromWKB(x'#{hex}', #{value.srid}))"
|
|
205
|
+
end
|
|
206
|
+
|
|
140
207
|
private
|
|
141
208
|
def type_map
|
|
142
209
|
emulate_booleans ? TYPE_MAP_WITH_BOOLEAN : TYPE_MAP
|
|
@@ -9,9 +9,14 @@ module ActiveRecord
|
|
|
9
9
|
# "geography"
|
|
10
10
|
# "geometry NOT NULL"
|
|
11
11
|
# "geometry"
|
|
12
|
-
def initialize(sql_type = "geometry")
|
|
13
|
-
@sql_type = sql_type
|
|
14
|
-
|
|
12
|
+
def initialize(sql_type = "geometry", geo_type: nil, srid: nil, geographic: false, has_z: false, has_m: false, **_options)
|
|
13
|
+
@sql_type = geographic ? "geography" : sql_type
|
|
14
|
+
parsed_geo_type, parsed_srid, parsed_has_z, parsed_has_m, parsed_geographic = self.class.parse_sql_type(@sql_type)
|
|
15
|
+
@geo_type = self.class.normalize_geo_type(geo_type || parsed_geo_type)
|
|
16
|
+
@srid = srid || parsed_srid
|
|
17
|
+
@has_z = has_z || parsed_has_z
|
|
18
|
+
@has_m = has_m || parsed_has_m
|
|
19
|
+
@geographic = geographic || parsed_geographic
|
|
15
20
|
end
|
|
16
21
|
|
|
17
22
|
# sql_type: geometry, geometry(Point), geometry(Point,4326), ...
|
|
@@ -20,23 +25,51 @@ module ActiveRecord
|
|
|
20
25
|
# geo_type: geography, geometry, point, line_string, polygon, ...
|
|
21
26
|
# srid: 1234
|
|
22
27
|
def self.parse_sql_type(sql_type)
|
|
23
|
-
geo_type
|
|
28
|
+
geo_type = nil
|
|
29
|
+
srid = 0
|
|
30
|
+
has_z = false
|
|
31
|
+
has_m = false
|
|
32
|
+
geographic = false
|
|
33
|
+
|
|
24
34
|
if sql_type =~ /(geography|geometry)\((.*)\)$/i
|
|
25
35
|
# geometry(Point)
|
|
26
36
|
# geometry(Point,4326)
|
|
37
|
+
geographic = Regexp.last_match(1).casecmp("geography").zero?
|
|
27
38
|
params = Regexp.last_match(2).split(",")
|
|
28
39
|
if params.first =~ /([a-z]+[^zm])(z?)(m?)/i
|
|
29
40
|
geo_type = Regexp.last_match(1)
|
|
41
|
+
has_z = Regexp.last_match(2).casecmp("z").zero?
|
|
42
|
+
has_m = Regexp.last_match(3).casecmp("m").zero?
|
|
30
43
|
end
|
|
31
44
|
if params.last =~ /(\d+)/
|
|
32
45
|
srid = Regexp.last_match(1).to_i
|
|
33
46
|
end
|
|
47
|
+
elsif sql_type =~ /\A(geography|geometry)\z/i
|
|
48
|
+
geographic = Regexp.last_match(1).casecmp("geography").zero?
|
|
49
|
+
geo_type = Regexp.last_match(1)
|
|
34
50
|
else
|
|
35
51
|
# geometry
|
|
36
52
|
# otherType(a,b)
|
|
37
53
|
geo_type = sql_type
|
|
38
54
|
end
|
|
39
|
-
[geo_type, srid]
|
|
55
|
+
[geo_type, srid, has_z, has_m, geographic]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.normalize_geo_type(geo_type)
|
|
59
|
+
case geo_type.to_s.underscore.delete("_")
|
|
60
|
+
when "geometrycollection"
|
|
61
|
+
"geometry_collection"
|
|
62
|
+
when "linestring"
|
|
63
|
+
"line_string"
|
|
64
|
+
when "multilinestring"
|
|
65
|
+
"multi_line_string"
|
|
66
|
+
when "multipoint"
|
|
67
|
+
"multi_point"
|
|
68
|
+
when "multipolygon"
|
|
69
|
+
"multi_polygon"
|
|
70
|
+
else
|
|
71
|
+
geo_type.to_s.underscore.presence
|
|
72
|
+
end
|
|
40
73
|
end
|
|
41
74
|
|
|
42
75
|
def spatial_factory
|
|
@@ -45,7 +78,9 @@ module ActiveRecord
|
|
|
45
78
|
@spatial_factories[@srid] ||=
|
|
46
79
|
RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(
|
|
47
80
|
geo_type: @geo_type,
|
|
48
|
-
|
|
81
|
+
has_m: @has_m,
|
|
82
|
+
has_z: @has_z,
|
|
83
|
+
sql_type: @geographic ? "geography" : "geometry",
|
|
49
84
|
srid: @srid
|
|
50
85
|
)
|
|
51
86
|
end
|
|
@@ -67,6 +102,9 @@ module ActiveRecord
|
|
|
67
102
|
return if value.nil?
|
|
68
103
|
|
|
69
104
|
geo_value = cast_value(value)
|
|
105
|
+
if geo_value && !@geographic && @srid.to_i.zero? && geo_value.srid != @srid
|
|
106
|
+
geo_value = RGeo::Feature.cast(geo_value, factory: spatial_factory, project: true)
|
|
107
|
+
end
|
|
70
108
|
|
|
71
109
|
# TODO: - only valid types should be allowed
|
|
72
110
|
# e.g. linestring is not valid for point column
|
|
@@ -89,12 +127,27 @@ module ActiveRecord
|
|
|
89
127
|
if ["\x00", "\x01"].include?(marker)
|
|
90
128
|
@srid = string[0, 4].unpack1(marker == "\x01" ? "V" : "N")
|
|
91
129
|
RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid).parse(string[4..-1])
|
|
92
|
-
elsif string[0
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
130
|
+
elsif string.match?(/\A[0-9a-fA-F]+\z/)
|
|
131
|
+
original_srid = @srid
|
|
132
|
+
parser = RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid)
|
|
133
|
+
|
|
134
|
+
begin
|
|
135
|
+
return parser.parse([string].pack("H*"))
|
|
136
|
+
rescue RGeo::Error::ParseError, RGeo::Error::InvalidGeometry
|
|
137
|
+
@srid = original_srid
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
if string[0, 10] =~ /[0-9a-fA-F]{8}0[01]/
|
|
141
|
+
@srid = string[0, 8].to_i(16)
|
|
142
|
+
@srid = [@srid].pack("V").unpack("N").first if string[9, 1] == "1"
|
|
143
|
+
parser = RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid)
|
|
144
|
+
return parser.parse([string[8..-1]].pack("H*"))
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
parser.parse([string].pack("H*"))
|
|
96
148
|
else
|
|
97
|
-
string,
|
|
149
|
+
string, srid = Arel::Visitors::Mysql2Rgeo.parse_node(string)
|
|
150
|
+
@srid = srid.zero? ? @srid : srid
|
|
98
151
|
RGeo::WKRep::WKTParser.new(spatial_factory, support_ewkt: true, default_srid: @srid).parse(string)
|
|
99
152
|
end
|
|
100
153
|
rescue RGeo::Error::ParseError, RGeo::Error::InvalidGeometry
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-mysql2rgeo-adapter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.
|
|
4
|
+
version: 7.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yongdae Hwang
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-03-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -39,92 +39,79 @@ dependencies:
|
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 7.0.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - "~>"
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: '3.0'
|
|
48
|
-
type: :runtime
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - "~>"
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: '3.0'
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: securerandom
|
|
42
|
+
name: rake
|
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
|
58
44
|
requirements:
|
|
59
45
|
- - "~>"
|
|
60
46
|
- !ruby/object:Gem::Version
|
|
61
|
-
version:
|
|
62
|
-
type: :
|
|
47
|
+
version: '13.0'
|
|
48
|
+
type: :development
|
|
63
49
|
prerelease: false
|
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
51
|
requirements:
|
|
66
52
|
- - "~>"
|
|
67
53
|
- !ruby/object:Gem::Version
|
|
68
|
-
version:
|
|
54
|
+
version: '13.0'
|
|
69
55
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
56
|
+
name: minitest
|
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
|
72
58
|
requirements:
|
|
73
59
|
- - "~>"
|
|
74
60
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
61
|
+
version: '5.4'
|
|
76
62
|
type: :development
|
|
77
63
|
prerelease: false
|
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
65
|
requirements:
|
|
80
66
|
- - "~>"
|
|
81
67
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
68
|
+
version: '5.4'
|
|
83
69
|
- !ruby/object:Gem::Dependency
|
|
84
|
-
name:
|
|
70
|
+
name: mocha
|
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
|
86
72
|
requirements:
|
|
87
73
|
- - "~>"
|
|
88
74
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
75
|
+
version: '1.1'
|
|
90
76
|
type: :development
|
|
91
77
|
prerelease: false
|
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
79
|
requirements:
|
|
94
80
|
- - "~>"
|
|
95
81
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
82
|
+
version: '1.1'
|
|
97
83
|
- !ruby/object:Gem::Dependency
|
|
98
|
-
name:
|
|
84
|
+
name: benchmark-ips
|
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
|
100
86
|
requirements:
|
|
101
87
|
- - "~>"
|
|
102
88
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '2.
|
|
89
|
+
version: '2.12'
|
|
104
90
|
type: :development
|
|
105
91
|
prerelease: false
|
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
93
|
requirements:
|
|
108
94
|
- - "~>"
|
|
109
95
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '2.
|
|
96
|
+
version: '2.12'
|
|
111
97
|
- !ruby/object:Gem::Dependency
|
|
112
|
-
name:
|
|
98
|
+
name: rubocop
|
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
|
114
100
|
requirements:
|
|
115
101
|
- - "~>"
|
|
116
102
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: '
|
|
103
|
+
version: '1.50'
|
|
118
104
|
type: :development
|
|
119
105
|
prerelease: false
|
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
107
|
requirements:
|
|
122
108
|
- - "~>"
|
|
123
109
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: '
|
|
110
|
+
version: '1.50'
|
|
125
111
|
description: ActiveRecord connection adapter for MySQL. It is based on the stock MySQL
|
|
126
112
|
adapter, and adds built-in support for the spatial extensions provided by MySQL.
|
|
127
|
-
It uses the RGeo library to represent spatial data in Ruby.
|
|
113
|
+
It uses the RGeo library to represent spatial data in Ruby. This gem is maintained
|
|
114
|
+
for MySQL 8.0 and 8.4.
|
|
128
115
|
email: stadia@gmail.com
|
|
129
116
|
executables: []
|
|
130
117
|
extensions: []
|
|
@@ -146,7 +133,10 @@ files:
|
|
|
146
133
|
homepage: http://github.com/stadia/activerecord-mysql2rgeo-adapter
|
|
147
134
|
licenses:
|
|
148
135
|
- BSD-3-Clause
|
|
149
|
-
metadata:
|
|
136
|
+
metadata:
|
|
137
|
+
source_code_uri: https://github.com/stadia/activerecord-mysql2rgeo-adapter
|
|
138
|
+
documentation_uri: https://github.com/stadia/activerecord-mysql2rgeo-adapter/blob/main/README.md
|
|
139
|
+
rubygems_mfa_required: 'true'
|
|
150
140
|
post_install_message:
|
|
151
141
|
rdoc_options: []
|
|
152
142
|
require_paths:
|
|
@@ -155,14 +145,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
155
145
|
requirements:
|
|
156
146
|
- - ">="
|
|
157
147
|
- !ruby/object:Gem::Version
|
|
158
|
-
version:
|
|
148
|
+
version: 3.0.0
|
|
159
149
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
160
150
|
requirements:
|
|
161
151
|
- - ">="
|
|
162
152
|
- !ruby/object:Gem::Version
|
|
163
153
|
version: '0'
|
|
164
154
|
requirements: []
|
|
165
|
-
rubygems_version: 3.
|
|
155
|
+
rubygems_version: 3.3.27
|
|
166
156
|
signing_key:
|
|
167
157
|
specification_version: 4
|
|
168
158
|
summary: ActiveRecord adapter for MySQL, based on RGeo.
|