activerecord-mysql2rgeo-adapter 7.3.1 → 9.0.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.
- checksums.yaml +4 -4
- data/lib/active_record/connection_adapters/mysql2rgeo/arel_tosql.rb +8 -14
- data/lib/active_record/connection_adapters/mysql2rgeo/schema_creation.rb +21 -22
- data/lib/active_record/connection_adapters/mysql2rgeo/schema_statements.rb +47 -33
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_column.rb +55 -12
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_column_info.rb +5 -5
- data/lib/active_record/connection_adapters/mysql2rgeo/spatial_table_definition.rb +26 -14
- data/lib/active_record/connection_adapters/mysql2rgeo/version.rb +1 -1
- data/lib/active_record/connection_adapters/mysql2rgeo_adapter.rb +110 -88
- data/lib/active_record/type/spatial.rb +33 -26
- data/lib/activerecord-mysql2rgeo-adapter.rb +3 -0
- metadata +12 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3f886ffec9c1cc39dd75d324940ebb386a49b5a8b23d65f3e2016e9610dd0c23
|
|
4
|
+
data.tar.gz: ba5b9e5e18655b6a52f0e73a612679efd55f5a097e8eeaf6d13736631c9dcaf9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cd759c023b7736b538039efbb1ebe0e289f77532758df317b6c7273269cc22d5888a662365cc5dafcfb5eade82732f6e531cba88df7df652c15e085b9d839a9d
|
|
7
|
+
data.tar.gz: 6e6b9e64f3662ed48fd16a18fa9fcb4741d70748c306a2ad07abf8e72eddb8819c4f0a3c47f185c743c8b5a336aac8910d0affff618a94258c8eac23887d97a6
|
|
@@ -9,12 +9,10 @@ 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
|
-
if ::Arel::Visitors.const_defined?(:BindVisitor)
|
|
16
|
-
include ::Arel::Visitors::BindVisitor
|
|
17
|
-
end
|
|
15
|
+
include ::Arel::Visitors::BindVisitor if ::Arel::Visitors.const_defined?(:BindVisitor)
|
|
18
16
|
|
|
19
17
|
FUNC_MAP = {
|
|
20
18
|
"st_wkttosql" => "ST_GeomFromText",
|
|
@@ -26,16 +24,11 @@ module Arel # :nodoc:
|
|
|
26
24
|
FUNC_MAP[standard_name.downcase] || standard_name
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
def
|
|
27
|
+
def visit_RGeo_Feature_Instance(node, collector)
|
|
30
28
|
node, srid = Mysql2Rgeo.parse_node(node)
|
|
31
29
|
collector << spatial_constant_sql(node, srid)
|
|
32
30
|
end
|
|
33
|
-
alias visit_RGeo_Feature_Instance
|
|
34
|
-
alias visit_RGeo_Cartesian_BoundingBox visit_String
|
|
35
|
-
|
|
36
|
-
def visit_RGeo_ActiveRecord_SpatialNamedFunction(node, collector)
|
|
37
|
-
aggregate(st_func(node.name), node, collector)
|
|
38
|
-
end
|
|
31
|
+
alias visit_RGeo_Cartesian_BoundingBox visit_RGeo_Feature_Instance
|
|
39
32
|
|
|
40
33
|
def visit_in_spatial_context(node, collector)
|
|
41
34
|
case node
|
|
@@ -52,18 +45,19 @@ module Arel # :nodoc:
|
|
|
52
45
|
end
|
|
53
46
|
|
|
54
47
|
def self.parse_node(node)
|
|
55
|
-
if RGeo::Feature::Instance
|
|
48
|
+
if node.is_a?(RGeo::Feature::Instance)
|
|
56
49
|
wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(node)
|
|
57
50
|
return [wkt, node.srid]
|
|
58
51
|
end
|
|
59
52
|
|
|
60
|
-
if RGeo::Cartesian::BoundingBox
|
|
53
|
+
if node.is_a?(RGeo::Cartesian::BoundingBox)
|
|
61
54
|
geometry = node.to_geometry
|
|
62
55
|
wkt = RGeo::WKRep::WKTGenerator.new(tag_format: :wkt11, emit_ewkt_srid: false).generate(geometry)
|
|
63
56
|
return [wkt, geometry.srid]
|
|
64
57
|
end
|
|
65
58
|
|
|
66
|
-
value
|
|
59
|
+
value = nil
|
|
60
|
+
srid = 0
|
|
67
61
|
if node =~ /.*;.*$/i
|
|
68
62
|
params = Regexp.last_match(0).split(";")
|
|
69
63
|
if params.first =~ /(srid|SRID)=\d*/
|
|
@@ -5,34 +5,33 @@ 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
8
|
|
|
17
|
-
|
|
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(" ")
|
|
18
16
|
end
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
sql << " /*!80003 SRID #{options[:srid]} */"
|
|
23
|
-
options = options.except(:srid)
|
|
24
|
-
end
|
|
18
|
+
super
|
|
19
|
+
end
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
super
|
|
21
|
+
def add_column_options!(sql, options)
|
|
22
|
+
if options[:srid]
|
|
23
|
+
sql << " /*!80003 SRID #{options[:srid]} */"
|
|
24
|
+
options = options.except(:srid)
|
|
31
25
|
end
|
|
32
26
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
options = options.except(:default) if options_include_default?(options) && spatial_column_definition?(options[:column])
|
|
28
|
+
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def spatial_column_definition?(column)
|
|
33
|
+
column.respond_to?(:type) && column.type && @conn.class.spatial_column_options(column.type.to_sym)
|
|
34
|
+
end
|
|
36
35
|
end
|
|
37
36
|
end
|
|
38
37
|
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, null: false)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -42,17 +42,19 @@ module ActiveRecord
|
|
|
42
42
|
|
|
43
43
|
# override
|
|
44
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
|
|
45
|
+
return "geometry(#{limit})" if type.to_sym == :geometry && limit.is_a?(String)
|
|
48
46
|
|
|
49
|
-
if
|
|
47
|
+
if RGeo::ActiveRecord.geometric_type_from_name(type.to_s.delete("_"))
|
|
50
48
|
type = limit[:type] || type if limit.is_a?(::Hash)
|
|
51
49
|
type = type.to_s.delete("_").upcase
|
|
52
50
|
end
|
|
53
51
|
super
|
|
54
52
|
end
|
|
55
53
|
|
|
54
|
+
def update_table_definition(table_name, base)
|
|
55
|
+
Mysql2Rgeo::Table.new(table_name, base)
|
|
56
|
+
end
|
|
57
|
+
|
|
56
58
|
private
|
|
57
59
|
|
|
58
60
|
# override
|
|
@@ -61,43 +63,44 @@ module ActiveRecord
|
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
# override
|
|
64
|
-
def create_table_definition(
|
|
65
|
-
Mysql2Rgeo::TableDefinition.new(self,
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def update_table_definition(table_name, base)
|
|
69
|
-
Mysql2Rgeo::Table.new(table_name, base)
|
|
66
|
+
def create_table_definition(*, **)
|
|
67
|
+
Mysql2Rgeo::TableDefinition.new(self, *, **)
|
|
70
68
|
end
|
|
71
69
|
|
|
72
70
|
# override
|
|
73
71
|
def new_column_from_field(table_name, field, _definitions)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
field_name = field_value(field, "Field")
|
|
73
|
+
type_metadata = fetch_type_metadata(field_value(field, "Type"), field_value(field, "Extra"))
|
|
74
|
+
default = field_value(field, "Default")
|
|
75
|
+
default_function = nil
|
|
76
|
+
metadata_comment = field_value(field, "Comment")
|
|
77
|
+
metadata = Mysql2Rgeo::ColumnDefinitionUtils.extract_metadata(metadata_comment)
|
|
78
|
+
comment = Mysql2Rgeo::ColumnDefinitionUtils.strip_metadata_comment(metadata_comment)
|
|
78
79
|
default = metadata[:default_hex] if default.nil? && metadata[:default_hex].present?
|
|
79
80
|
|
|
80
81
|
if type_metadata.type == :datetime && /\ACURRENT_TIMESTAMP(?:\([0-6]?\))?\z/i.match?(default)
|
|
81
|
-
|
|
82
|
+
default_function = default
|
|
83
|
+
default = nil
|
|
82
84
|
elsif type_metadata.extra == "DEFAULT_GENERATED"
|
|
83
85
|
if default == "NULL" && metadata[:default_hex].present?
|
|
84
86
|
default = metadata[:default_hex]
|
|
85
87
|
elsif default == "NULL"
|
|
86
|
-
default = generated_default_for(table_name,
|
|
88
|
+
default = generated_default_for(table_name, field_name)
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
if default&.match?(/\Ast_geomfromtext\(/i)
|
|
90
|
-
default =
|
|
91
|
-
|
|
92
|
+
default = "(#{default})" unless default.start_with?("(")
|
|
93
|
+
default_function = default
|
|
94
|
+
default = nil
|
|
92
95
|
end
|
|
93
96
|
end
|
|
94
97
|
|
|
95
98
|
if type_metadata.extra.to_s.match?(/(?:VIRTUAL|STORED|PERSISTENT)\s+GENERATED/i)
|
|
96
|
-
default_function = generation_expression_for(table_name,
|
|
99
|
+
default_function = generation_expression_for(table_name, field_name)
|
|
97
100
|
end
|
|
98
101
|
|
|
99
102
|
# {:dimension=>2, :has_m=>false, :has_z=>false, :name=>"latlon", :srid=>0, :type=>"GEOMETRY"}
|
|
100
|
-
spatial = spatial_column_info(table_name).get(
|
|
103
|
+
spatial = spatial_column_info(table_name).get(field_name, type_metadata.sql_type)
|
|
101
104
|
if spatial
|
|
102
105
|
spatial[:has_z] ||= metadata[:has_z]
|
|
103
106
|
spatial[:has_m] ||= metadata[:has_m]
|
|
@@ -116,9 +119,9 @@ module ActiveRecord
|
|
|
116
119
|
type: :geometry,
|
|
117
120
|
limit: nil,
|
|
118
121
|
precision: type_metadata.precision,
|
|
119
|
-
scale: type_metadata.scale
|
|
122
|
+
scale: type_metadata.scale
|
|
120
123
|
),
|
|
121
|
-
extra: type_metadata.extra
|
|
124
|
+
extra: type_metadata.extra
|
|
122
125
|
)
|
|
123
126
|
|
|
124
127
|
if default_function&.match?(/\A\(?st_geomfromtext\(/i)
|
|
@@ -128,12 +131,13 @@ module ActiveRecord
|
|
|
128
131
|
end
|
|
129
132
|
|
|
130
133
|
SpatialColumn.new(
|
|
131
|
-
|
|
134
|
+
field_name,
|
|
135
|
+
lookup_cast_type(type_metadata.sql_type),
|
|
132
136
|
default,
|
|
133
137
|
type_metadata,
|
|
134
|
-
field
|
|
138
|
+
field_value(field, "Null") == "YES",
|
|
135
139
|
default_function,
|
|
136
|
-
collation: field
|
|
140
|
+
collation: field_value(field, "Collation"),
|
|
137
141
|
comment: comment,
|
|
138
142
|
spatial: spatial,
|
|
139
143
|
array: metadata[:array]
|
|
@@ -146,6 +150,10 @@ module ActiveRecord
|
|
|
146
150
|
@spatial_column_info[table_name.to_sym] = SpatialColumnInfo.new(self, table_name.to_s)
|
|
147
151
|
end
|
|
148
152
|
|
|
153
|
+
def field_value(field, key)
|
|
154
|
+
field[key] || field[key.to_sym]
|
|
155
|
+
end
|
|
156
|
+
|
|
149
157
|
def extract_spatial_default_hex(default_function, spatial)
|
|
150
158
|
default_sql = default_function.delete_prefix("(").delete_suffix(")").delete("\\")
|
|
151
159
|
match = default_sql.match(/\Ast_geomfromtext\(_utf8mb4'(.+?)',\s*(\d+)\)\z/i)
|
|
@@ -159,10 +167,11 @@ module ActiveRecord
|
|
|
159
167
|
srid: srid,
|
|
160
168
|
geographic: spatial[:geographic],
|
|
161
169
|
has_z: spatial[:has_z],
|
|
162
|
-
has_m: spatial[:has_m]
|
|
170
|
+
has_m: spatial[:has_m]
|
|
163
171
|
)
|
|
164
172
|
geometry = type.serialize(wkt)
|
|
165
173
|
return unless geometry
|
|
174
|
+
|
|
166
175
|
geometry = RGeo::Feature.cast(geometry, factory: type.send(:spatial_factory), project: true) if spatial[:geographic]
|
|
167
176
|
|
|
168
177
|
wkb = RGeo::WKRep::WKBGenerator.new(
|
|
@@ -171,10 +180,15 @@ module ActiveRecord
|
|
|
171
180
|
type_format: :wkb11,
|
|
172
181
|
emit_ewkb_srid: false
|
|
173
182
|
).generate(geometry)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
183
|
+
wkb = wkb.upcase
|
|
184
|
+
return wkb unless spatial[:geographic]
|
|
185
|
+
|
|
186
|
+
endian = wkb[0, 2]
|
|
187
|
+
type_hex = wkb[2, 8]
|
|
188
|
+
body = wkb[10..]
|
|
189
|
+
type = [type_hex].pack("H*").unpack1("V") | 0x20000000
|
|
190
|
+
srid_hex = [spatial[:srid].to_i].pack("V").unpack1("H*").upcase
|
|
191
|
+
"#{endian}#{[type].pack('V').unpack1('H*').upcase}#{srid_hex}#{body}"
|
|
178
192
|
end
|
|
179
193
|
|
|
180
194
|
def generation_expression_for(table_name, column_name)
|
|
@@ -185,7 +199,7 @@ module ActiveRecord
|
|
|
185
199
|
AND table_name = #{quote(table_name)}
|
|
186
200
|
AND column_name = #{quote(column_name)}
|
|
187
201
|
SQL
|
|
188
|
-
|
|
202
|
+
&.gsub(/st_buffer\(([^,]+),\s*(\d+)\)/i, 'st_buffer(\1, (\2)::double precision)')
|
|
189
203
|
end
|
|
190
204
|
|
|
191
205
|
def generated_default_for(table_name, column_name)
|
|
@@ -4,16 +4,32 @@ module ActiveRecord # :nodoc:
|
|
|
4
4
|
module ConnectionAdapters # :nodoc:
|
|
5
5
|
module Mysql2Rgeo # :nodoc:
|
|
6
6
|
class SpatialColumn < ConnectionAdapters::MySQL::Column # :nodoc:
|
|
7
|
-
|
|
7
|
+
# ActiveRecord 8.1 added cast_type as Column#initialize's second argument.
|
|
8
|
+
COLUMN_TAKES_CAST_TYPE = ActiveRecord.gem_version >= Gem::Version.new("8.1")
|
|
9
|
+
|
|
10
|
+
def initialize(name, cast_type, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil,
|
|
11
|
+
spatial: nil, array: false, **)
|
|
12
|
+
if default.respond_to?(:sql_type) && (sql_type_metadata.nil? || sql_type_metadata == true || sql_type_metadata == false)
|
|
13
|
+
null = sql_type_metadata unless sql_type_metadata.nil?
|
|
14
|
+
sql_type_metadata = default
|
|
15
|
+
default = cast_type
|
|
16
|
+
cast_type = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
8
19
|
@sql_type_metadata = sql_type_metadata
|
|
9
20
|
@array = array
|
|
21
|
+
@geographic = !!(sql_type_metadata&.sql_type =~ /geography\(/i)
|
|
10
22
|
if spatial
|
|
11
23
|
# This case comes from an entry in the geometry_columns table
|
|
12
24
|
set_geometric_type_from_name(spatial[:type])
|
|
13
25
|
@srid = spatial[:srid].to_i
|
|
14
|
-
@has_z = spatial[:has_z]
|
|
15
|
-
@has_m = spatial[:has_m]
|
|
16
|
-
@geographic = spatial[:geographic]
|
|
26
|
+
@has_z = !!spatial[:has_z]
|
|
27
|
+
@has_m = !!spatial[:has_m]
|
|
28
|
+
@geographic = !!spatial[:geographic] || @geographic
|
|
29
|
+
elsif @geographic
|
|
30
|
+
@srid = 4326
|
|
31
|
+
@has_z = @has_m = false
|
|
32
|
+
build_from_sql_type(sql_type_metadata.sql_type)
|
|
17
33
|
elsif sql_type =~ /geometry|point|linestring|polygon/i
|
|
18
34
|
build_from_sql_type(sql_type_metadata.sql_type)
|
|
19
35
|
elsif sql_type_metadata.sql_type =~ /geometry|point|linestring|polygon/i
|
|
@@ -21,15 +37,18 @@ module ActiveRecord # :nodoc:
|
|
|
21
37
|
# @geometric_type = geo_type_from_sql_type(sql_type)
|
|
22
38
|
build_from_sql_type(sql_type_metadata.sql_type)
|
|
23
39
|
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@limit[:geographic] = true if geographic?
|
|
29
|
-
@limit[:has_z] = true if has_z?
|
|
30
|
-
@limit[:has_m] = true if has_m?
|
|
31
|
-
end
|
|
40
|
+
if COLUMN_TAKES_CAST_TYPE
|
|
41
|
+
super(name, cast_type, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
|
|
42
|
+
else
|
|
43
|
+
super(name, default, sql_type_metadata, null, default_function, collation: collation, comment: comment)
|
|
32
44
|
end
|
|
45
|
+
return unless spatial?
|
|
46
|
+
return unless @srid
|
|
47
|
+
|
|
48
|
+
@limit = { type: limit_type_name, srid: @srid }
|
|
49
|
+
@limit[:geographic] = true if geographic?
|
|
50
|
+
@limit[:has_z] = true if has_z?
|
|
51
|
+
@limit[:has_m] = true if has_m?
|
|
33
52
|
end
|
|
34
53
|
|
|
35
54
|
attr_reader :geometric_type, :srid
|
|
@@ -67,6 +86,30 @@ module ActiveRecord # :nodoc:
|
|
|
67
86
|
%i[geometry geography].include?(@sql_type_metadata.type)
|
|
68
87
|
end
|
|
69
88
|
|
|
89
|
+
SPATIAL_ATTRIBUTES = %w[geographic geometric_type has_m has_z srid limit].freeze
|
|
90
|
+
|
|
91
|
+
def init_with(coder)
|
|
92
|
+
SPATIAL_ATTRIBUTES.each { |attr| instance_variable_set(:"@#{attr}", coder[attr]) }
|
|
93
|
+
super
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def encode_with(coder)
|
|
97
|
+
SPATIAL_ATTRIBUTES.each { |attr| coder[attr] = instance_variable_get(:"@#{attr}") }
|
|
98
|
+
super
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def ==(other)
|
|
102
|
+
other.is_a?(SpatialColumn) &&
|
|
103
|
+
super &&
|
|
104
|
+
array == other.array &&
|
|
105
|
+
SPATIAL_ATTRIBUTES.all? { |attr| public_send(attr) == other.public_send(attr) }
|
|
106
|
+
end
|
|
107
|
+
alias eql? ==
|
|
108
|
+
|
|
109
|
+
def hash
|
|
110
|
+
SPATIAL_ATTRIBUTES.reduce(SpatialColumn.hash ^ super.hash ^ array.hash) { |h, attr| h ^ public_send(attr).hash }
|
|
111
|
+
end
|
|
112
|
+
|
|
70
113
|
private
|
|
71
114
|
|
|
72
115
|
def set_geometric_type_from_name(name)
|
|
@@ -29,11 +29,11 @@ module ActiveRecord # :nodoc:
|
|
|
29
29
|
has_z = type.sub!(/z$/i, "").present?
|
|
30
30
|
has_m = type.sub!(/m$/i, "").present?
|
|
31
31
|
result[name] = {
|
|
32
|
-
name:
|
|
33
|
-
srid:
|
|
34
|
-
type:
|
|
35
|
-
has_z:
|
|
36
|
-
has_m:
|
|
32
|
+
name: name,
|
|
33
|
+
srid: row[1].to_i,
|
|
34
|
+
type: type,
|
|
35
|
+
has_z: has_z,
|
|
36
|
+
has_m: has_m,
|
|
37
37
|
geographic: column_comment.include?("mysql2rgeo:geographic"),
|
|
38
38
|
}
|
|
39
39
|
end
|
|
@@ -5,6 +5,7 @@ module ActiveRecord # :nodoc:
|
|
|
5
5
|
module Mysql2Rgeo # :nodoc:
|
|
6
6
|
class TableDefinition < MySQL::TableDefinition # :nodoc:
|
|
7
7
|
include ColumnMethods
|
|
8
|
+
|
|
8
9
|
# super: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
|
|
9
10
|
def new_column_definition(name, type, **options)
|
|
10
11
|
spatial_type = type.to_sym == :virtual ? options[:type]&.to_sym : type.to_sym
|
|
@@ -20,7 +21,9 @@ module ActiveRecord # :nodoc:
|
|
|
20
21
|
ColumnDefinitionUtils.geo_type(options[:type] || spatial_type || info[:type])
|
|
21
22
|
end
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
if type.to_sym == :virtual
|
|
25
|
+
options.delete(:srid)
|
|
26
|
+
else
|
|
24
27
|
options[:srid] ||= ColumnDefinitionUtils.default_srid(options)
|
|
25
28
|
options[:comment] = ColumnDefinitionUtils.add_metadata_comment(
|
|
26
29
|
options[:comment],
|
|
@@ -32,19 +35,20 @@ module ActiveRecord # :nodoc:
|
|
|
32
35
|
srid: options[:srid],
|
|
33
36
|
geo_type: geo_type
|
|
34
37
|
)
|
|
35
|
-
else
|
|
36
|
-
options.delete(:srid)
|
|
37
38
|
end
|
|
38
39
|
|
|
39
40
|
options[:spatial_type] = geo_type
|
|
40
|
-
if type.to_sym == :virtual
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
45
46
|
else
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
if options[:array]
|
|
48
|
+
options[:comment] =
|
|
49
|
+
ColumnDefinitionUtils.add_metadata_comment(options[:comment], array: options[:array])
|
|
50
|
+
end
|
|
51
|
+
column = super
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
column
|
|
@@ -77,14 +81,16 @@ module ActiveRecord # :nodoc:
|
|
|
77
81
|
options[:geographic] ? 4326 : Mysql2RgeoAdapter::DEFAULT_SRID
|
|
78
82
|
end
|
|
79
83
|
|
|
80
|
-
def add_metadata_comment(comment, geographic: false, has_m: false, has_z: false, array: false, default: nil, srid: nil,
|
|
84
|
+
def add_metadata_comment(comment, geographic: false, has_m: false, has_z: false, array: false, default: nil, srid: nil,
|
|
85
|
+
geo_type: nil)
|
|
81
86
|
values = [comment]
|
|
82
87
|
values << METADATA_TOKENS[:geographic] if geographic
|
|
83
88
|
values << METADATA_TOKENS[:has_m] if has_m
|
|
84
89
|
values << METADATA_TOKENS[:has_z] if has_z
|
|
85
90
|
values << METADATA_TOKENS[:array] if array
|
|
86
91
|
if default
|
|
87
|
-
values << "#{METADATA_TOKENS[:default_prefix]}#{encode_default(default, geographic: geographic, srid: srid,
|
|
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)}"
|
|
88
94
|
end
|
|
89
95
|
values.compact_blank.join(" ")
|
|
90
96
|
end
|
|
@@ -128,10 +134,16 @@ module ActiveRecord # :nodoc:
|
|
|
128
134
|
type_format: :wkb11,
|
|
129
135
|
emit_ewkb_srid: false
|
|
130
136
|
).generate(geometry).upcase
|
|
131
|
-
|
|
137
|
+
geographic ? with_ewkb_srid(wkb, srid) : wkb
|
|
138
|
+
end
|
|
132
139
|
|
|
140
|
+
def with_ewkb_srid(wkb, srid)
|
|
141
|
+
endian = wkb[0, 2]
|
|
142
|
+
type_hex = wkb[2, 8]
|
|
143
|
+
body = wkb[10..]
|
|
144
|
+
type = [type_hex].pack("H*").unpack1("V") | 0x20000000
|
|
133
145
|
srid_hex = [srid.to_i].pack("V").unpack1("H*").upcase
|
|
134
|
-
"#{srid_hex}#{
|
|
146
|
+
"#{endian}#{[type].pack('V').unpack1('H*').upcase}#{srid_hex}#{body}"
|
|
135
147
|
end
|
|
136
148
|
end
|
|
137
149
|
end
|
|
@@ -22,14 +22,21 @@ 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.
|
|
28
34
|
def mysql2rgeo_connection(config)
|
|
29
35
|
config = config.symbolize_keys
|
|
30
36
|
config[:flags] ||= 0
|
|
37
|
+
config[:database_timezone] ||= ConnectionAdapters::AbstractAdapter.validate_default_timezone(config[:default_timezone])
|
|
31
38
|
|
|
32
|
-
if config[:flags].
|
|
39
|
+
if config[:flags].is_a? Array
|
|
33
40
|
config[:flags].push "FOUND_ROWS"
|
|
34
41
|
else
|
|
35
42
|
config[:flags] |= Mysql2::Client::FOUND_ROWS
|
|
@@ -39,7 +46,7 @@ module ActiveRecord
|
|
|
39
46
|
ConnectionAdapters::Mysql2RgeoAdapter.new_client(config),
|
|
40
47
|
logger,
|
|
41
48
|
nil,
|
|
42
|
-
config
|
|
49
|
+
config
|
|
43
50
|
)
|
|
44
51
|
end
|
|
45
52
|
end
|
|
@@ -47,37 +54,34 @@ module ActiveRecord
|
|
|
47
54
|
module ConnectionAdapters
|
|
48
55
|
class Mysql2RgeoAdapter < Mysql2Adapter
|
|
49
56
|
ADAPTER_NAME = "Mysql2Rgeo"
|
|
50
|
-
MINIMUM_SUPPORTED_VERSION = "8.0.0"
|
|
51
57
|
|
|
52
58
|
include Mysql2Rgeo::SchemaStatements
|
|
53
59
|
|
|
54
60
|
SPATIAL_COLUMN_OPTIONS =
|
|
55
61
|
{
|
|
56
|
-
geography:
|
|
57
|
-
geometry:
|
|
58
|
-
geometrycollection:
|
|
62
|
+
geography: { type: "geometry", geographic: true },
|
|
63
|
+
geometry: {},
|
|
64
|
+
geometrycollection: {},
|
|
59
65
|
geometry_collection: { type: "geometrycollection" },
|
|
60
|
-
linestring:
|
|
61
|
-
line_string:
|
|
62
|
-
multilinestring:
|
|
63
|
-
multi_line_string:
|
|
64
|
-
multipoint:
|
|
65
|
-
multi_point:
|
|
66
|
-
multipolygon:
|
|
67
|
-
multi_polygon:
|
|
68
|
-
spatial:
|
|
69
|
-
point:
|
|
70
|
-
polygon:
|
|
71
|
-
st_point:
|
|
72
|
-
st_polygon:
|
|
66
|
+
linestring: {},
|
|
67
|
+
line_string: { type: "linestring" },
|
|
68
|
+
multilinestring: {},
|
|
69
|
+
multi_line_string: { type: "multilinestring" },
|
|
70
|
+
multipoint: {},
|
|
71
|
+
multi_point: { type: "multipoint" },
|
|
72
|
+
multipolygon: {},
|
|
73
|
+
multi_polygon: { type: "multipolygon" },
|
|
74
|
+
spatial: { type: "geometry" },
|
|
75
|
+
point: {},
|
|
76
|
+
polygon: {},
|
|
77
|
+
st_point: { type: "point" },
|
|
78
|
+
st_polygon: { type: "polygon" }
|
|
73
79
|
}.freeze
|
|
74
80
|
|
|
75
|
-
# MySQL uses SRID 0 when a spatial column does not declare one explicitly.
|
|
76
81
|
DEFAULT_SRID = 0
|
|
77
82
|
|
|
78
|
-
def initialize(
|
|
83
|
+
def initialize(...)
|
|
79
84
|
super
|
|
80
|
-
verify_supported_database_version!
|
|
81
85
|
|
|
82
86
|
@visitor = Arel::Visitors::Mysql2Rgeo.new(self)
|
|
83
87
|
end
|
|
@@ -93,86 +97,104 @@ module ActiveRecord
|
|
|
93
97
|
def native_database_types
|
|
94
98
|
# Add spatial types
|
|
95
99
|
# Reference: https://dev.mysql.com/doc/refman/5.6/en/spatial-type-overview.html
|
|
96
|
-
|
|
97
|
-
geometry: { name: "geometry" },
|
|
98
|
-
geometrycollection: { name: "geometrycollection" },
|
|
99
|
-
line_string: { name: "linestring" },
|
|
100
|
-
linestring: { name: "linestring" },
|
|
101
|
-
st_point: { name: "point" },
|
|
102
|
-
st_polygon: { name: "polygon" },
|
|
103
|
-
multi_line_string: { name: "multilinestring" },
|
|
104
|
-
multi_point: { name: "multipoint" },
|
|
105
|
-
multi_polygon: { name: "multipolygon" },
|
|
106
|
-
spatial: { name: "geometry" },
|
|
107
|
-
point: { name: "point" },
|
|
108
|
-
polygon: { name: "polygon" }
|
|
109
|
-
)
|
|
100
|
+
self.class.native_database_types
|
|
110
101
|
end
|
|
111
102
|
|
|
112
103
|
class << self
|
|
104
|
+
def native_database_types
|
|
105
|
+
# ActiveRecord < 8.1 only has the instance method, backed by NATIVE_DATABASE_TYPES.
|
|
106
|
+
(defined?(super) ? super : self::NATIVE_DATABASE_TYPES).merge(
|
|
107
|
+
geography: { name: "geometry" },
|
|
108
|
+
geometry: { name: "geometry" },
|
|
109
|
+
geometrycollection: { name: "geometrycollection" },
|
|
110
|
+
line_string: { name: "linestring" },
|
|
111
|
+
linestring: { name: "linestring" },
|
|
112
|
+
st_point: { name: "point" },
|
|
113
|
+
st_polygon: { name: "polygon" },
|
|
114
|
+
multi_line_string: { name: "multilinestring" },
|
|
115
|
+
multi_point: { name: "multipoint" },
|
|
116
|
+
multi_polygon: { name: "multipolygon" },
|
|
117
|
+
spatial: { name: "geometry" },
|
|
118
|
+
point: { name: "point" },
|
|
119
|
+
polygon: { name: "polygon" }
|
|
120
|
+
)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def extended_type_map(emulate_booleans:, default_timezone: nil)
|
|
124
|
+
Type::TypeMap.new(emulate_booleans ? TYPE_MAP_WITH_BOOLEAN : TYPE_MAP).tap do |m|
|
|
125
|
+
register_class_with_precision m, /\A[^(]*time/i, Type::Time, timezone: default_timezone
|
|
126
|
+
register_class_with_precision m, /\A[^(]*datetime/i, Type::DateTime, timezone: default_timezone
|
|
127
|
+
m.alias_type(/\A[^(]*timestamp/i, "datetime")
|
|
128
|
+
end
|
|
129
|
+
end
|
|
113
130
|
|
|
114
131
|
private
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
+
|
|
133
|
+
def initialize_type_map(m)
|
|
134
|
+
super
|
|
135
|
+
|
|
136
|
+
{
|
|
137
|
+
"geography" => "geometry",
|
|
138
|
+
"geometry" => "geometry",
|
|
139
|
+
"geometry_collection" => "geometrycollection",
|
|
140
|
+
"line_string" => "linestring",
|
|
141
|
+
"multi_line_string" => "multilinestring",
|
|
142
|
+
"multi_point" => "multipoint",
|
|
143
|
+
"multi_polygon" => "multipolygon",
|
|
144
|
+
"st_point" => "point",
|
|
145
|
+
"st_polygon" => "polygon",
|
|
146
|
+
}.each do |registered_type, geo_type|
|
|
147
|
+
m.register_type(registered_type) do |sql_type|
|
|
148
|
+
Type::Spatial.new(sql_type.to_s, geo_type: geo_type)
|
|
132
149
|
end
|
|
150
|
+
end
|
|
133
151
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
end
|
|
152
|
+
[
|
|
153
|
+
/\Ageometry(?:\(.*\))?\z/i,
|
|
154
|
+
/\Ageography(?:\(.*\))?\z/i,
|
|
155
|
+
/\Apoint(?:\s.*)?\z/i,
|
|
156
|
+
/\Alinestring(?:\s.*)?\z/i,
|
|
157
|
+
/\Apolygon(?:\s.*)?\z/i,
|
|
158
|
+
/\Amultipoint(?:\s.*)?\z/i,
|
|
159
|
+
/\Amultilinestring(?:\s.*)?\z/i,
|
|
160
|
+
/\Amultipolygon(?:\s.*)?\z/i,
|
|
161
|
+
/\Ageometrycollection(?:\s.*)?\z/i,
|
|
162
|
+
].each do |pattern|
|
|
163
|
+
m.register_type(pattern) do |sql_type|
|
|
164
|
+
Type::Spatial.new(sql_type.to_s)
|
|
148
165
|
end
|
|
166
|
+
end
|
|
149
167
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
end
|
|
168
|
+
{
|
|
169
|
+
st_point: "point",
|
|
170
|
+
st_polygon: "polygon",
|
|
171
|
+
line_string: "linestring",
|
|
172
|
+
multi_line_string: "multilinestring",
|
|
173
|
+
multi_point: "multipoint",
|
|
174
|
+
multi_polygon: "multipolygon",
|
|
175
|
+
}.each do |alias_type, geo_type|
|
|
176
|
+
ActiveRecord::Type.register(alias_type) do |_, **kwargs|
|
|
177
|
+
Type::Spatial.new(geo_type, geo_type: geo_type, **kwargs)
|
|
161
178
|
end
|
|
162
179
|
end
|
|
180
|
+
end
|
|
163
181
|
end
|
|
164
182
|
|
|
165
183
|
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
|
166
184
|
TYPE_MAP_WITH_BOOLEAN = Type::TypeMap.new(TYPE_MAP).tap do |m|
|
|
167
|
-
m.register_type
|
|
185
|
+
m.register_type(/^tinyint\(1\)/i, Type::Boolean.new)
|
|
168
186
|
end
|
|
169
187
|
|
|
170
188
|
def supports_spatial?
|
|
171
|
-
!mariadb? &&
|
|
189
|
+
!mariadb? && version >= "5.7.6"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def supports_partitioned_indexes?
|
|
193
|
+
false
|
|
172
194
|
end
|
|
173
195
|
|
|
174
196
|
def adapter_name
|
|
175
|
-
|
|
197
|
+
"Mysql2Rgeo"
|
|
176
198
|
end
|
|
177
199
|
|
|
178
200
|
def quote(value)
|
|
@@ -203,16 +225,16 @@ module ActiveRecord
|
|
|
203
225
|
end
|
|
204
226
|
|
|
205
227
|
private
|
|
206
|
-
def verify_supported_database_version!
|
|
207
|
-
return if database_version >= MINIMUM_SUPPORTED_VERSION
|
|
208
228
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
229
|
+
def type_map
|
|
230
|
+
if (key = extended_type_map_key)
|
|
231
|
+
self.class::EXTENDED_TYPE_MAPS.compute_if_absent(key) do
|
|
232
|
+
self.class.extended_type_map(**key)
|
|
233
|
+
end
|
|
234
|
+
else
|
|
214
235
|
emulate_booleans ? TYPE_MAP_WITH_BOOLEAN : TYPE_MAP
|
|
215
236
|
end
|
|
237
|
+
end
|
|
216
238
|
end
|
|
217
239
|
end
|
|
218
240
|
end
|
|
@@ -10,13 +10,14 @@ module ActiveRecord
|
|
|
10
10
|
# "geometry NOT NULL"
|
|
11
11
|
# "geometry"
|
|
12
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
|
|
13
|
+
@sql_type = -(geographic ? "geography" : sql_type.to_s)
|
|
14
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)
|
|
15
|
+
@geo_type = -self.class.normalize_geo_type(geo_type || parsed_geo_type).to_s
|
|
16
16
|
@srid = srid || parsed_srid
|
|
17
17
|
@has_z = has_z || parsed_has_z
|
|
18
18
|
@has_m = has_m || parsed_has_m
|
|
19
19
|
@geographic = geographic || parsed_geographic
|
|
20
|
+
freeze
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
# sql_type: geometry, geometry(Point), geometry(Point,4326), ...
|
|
@@ -41,9 +42,7 @@ module ActiveRecord
|
|
|
41
42
|
has_z = Regexp.last_match(2).casecmp("z").zero?
|
|
42
43
|
has_m = Regexp.last_match(3).casecmp("m").zero?
|
|
43
44
|
end
|
|
44
|
-
if params.last =~ /(\d+)/
|
|
45
|
-
srid = Regexp.last_match(1).to_i
|
|
46
|
-
end
|
|
45
|
+
srid = Regexp.last_match(1).to_i if params.last =~ /(\d+)/
|
|
47
46
|
elsif sql_type =~ /\A(geography|geometry)\z/i
|
|
48
47
|
geographic = Regexp.last_match(1).casecmp("geography").zero?
|
|
49
48
|
geo_type = Regexp.last_match(1)
|
|
@@ -72,16 +71,16 @@ module ActiveRecord
|
|
|
72
71
|
end
|
|
73
72
|
end
|
|
74
73
|
|
|
75
|
-
def spatial_factory
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
74
|
+
def spatial_factory(srid = @srid)
|
|
75
|
+
# Don't use instance variable caching since Type objects are frozen in Rails 8.1+
|
|
76
|
+
# The SpatialFactoryStore already caches factories internally
|
|
77
|
+
# Use provided srid or fall back to instance srid
|
|
78
|
+
RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(
|
|
79
|
+
geo_type: @geo_type,
|
|
80
|
+
has_m: @has_m,
|
|
81
|
+
has_z: @has_z,
|
|
82
|
+
sql_type: @geographic ? "geography" : "geometry",
|
|
83
|
+
srid: srid
|
|
85
84
|
)
|
|
86
85
|
end
|
|
87
86
|
|
|
@@ -118,37 +117,35 @@ module ActiveRecord
|
|
|
118
117
|
def cast_value(value)
|
|
119
118
|
return if value.nil?
|
|
120
119
|
|
|
121
|
-
::String
|
|
120
|
+
value.is_a?(::String) ? parse_wkt(value) : value
|
|
122
121
|
end
|
|
123
122
|
|
|
124
123
|
# convert WKT string into RGeo object
|
|
125
124
|
def parse_wkt(string)
|
|
126
125
|
marker = string[4, 1]
|
|
127
126
|
if ["\x00", "\x01"].include?(marker)
|
|
128
|
-
|
|
129
|
-
RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid:
|
|
127
|
+
srid = string[0, 4].unpack1(marker == "\x01" ? "V" : "N")
|
|
128
|
+
RGeo::WKRep::WKBParser.new(spatial_factory(srid), support_ewkb: true, default_srid: srid).parse(string[4..])
|
|
130
129
|
elsif string.match?(/\A[0-9a-fA-F]+\z/)
|
|
131
|
-
original_srid = @srid
|
|
132
130
|
parser = RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid: @srid)
|
|
133
131
|
|
|
134
132
|
begin
|
|
135
133
|
return parser.parse([string].pack("H*"))
|
|
136
134
|
rescue RGeo::Error::ParseError, RGeo::Error::InvalidGeometry
|
|
137
|
-
@srid = original_srid
|
|
138
135
|
end
|
|
139
136
|
|
|
140
137
|
if string[0, 10] =~ /[0-9a-fA-F]{8}0[01]/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
parser = RGeo::WKRep::WKBParser.new(spatial_factory, support_ewkb: true, default_srid:
|
|
144
|
-
return parser.parse([string[8
|
|
138
|
+
srid = string[0, 8].to_i(16)
|
|
139
|
+
srid = [srid].pack("V").unpack1("N") if string[9, 1] == "1"
|
|
140
|
+
parser = RGeo::WKRep::WKBParser.new(spatial_factory(srid), support_ewkb: true, default_srid: srid)
|
|
141
|
+
return parser.parse([string[8..]].pack("H*"))
|
|
145
142
|
end
|
|
146
143
|
|
|
147
144
|
parser.parse([string].pack("H*"))
|
|
148
145
|
else
|
|
149
146
|
string, srid = Arel::Visitors::Mysql2Rgeo.parse_node(string)
|
|
150
|
-
|
|
151
|
-
RGeo::WKRep::WKTParser.new(spatial_factory, support_ewkt: true, default_srid:
|
|
147
|
+
srid = @srid if srid.zero?
|
|
148
|
+
RGeo::WKRep::WKTParser.new(spatial_factory(srid), support_ewkt: true, default_srid: srid).parse(string)
|
|
152
149
|
end
|
|
153
150
|
rescue RGeo::Error::ParseError, RGeo::Error::InvalidGeometry
|
|
154
151
|
nil
|
|
@@ -156,3 +153,13 @@ module ActiveRecord
|
|
|
156
153
|
end
|
|
157
154
|
end
|
|
158
155
|
end
|
|
156
|
+
|
|
157
|
+
module ActiveRecord
|
|
158
|
+
module ConnectionAdapters
|
|
159
|
+
module Mysql2Rgeo
|
|
160
|
+
module OID
|
|
161
|
+
Spatial = ActiveRecord::Type::Spatial
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-mysql2rgeo-adapter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 9.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yongdae Hwang
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -16,28 +15,28 @@ dependencies:
|
|
|
16
15
|
requirements:
|
|
17
16
|
- - "~>"
|
|
18
17
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
18
|
+
version: 8.0.0
|
|
20
19
|
type: :runtime
|
|
21
20
|
prerelease: false
|
|
22
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
22
|
requirements:
|
|
24
23
|
- - "~>"
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
25
|
+
version: 8.0.0
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
27
|
name: rgeo-activerecord
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - "~>"
|
|
32
31
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
32
|
+
version: 8.0.0
|
|
34
33
|
type: :runtime
|
|
35
34
|
prerelease: false
|
|
36
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
36
|
requirements:
|
|
38
37
|
- - "~>"
|
|
39
38
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
39
|
+
version: 8.0.0
|
|
41
40
|
- !ruby/object:Gem::Dependency
|
|
42
41
|
name: rake
|
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -67,19 +66,19 @@ dependencies:
|
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
67
|
version: '5.4'
|
|
69
68
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
69
|
+
name: minitest-excludes
|
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
|
72
71
|
requirements:
|
|
73
72
|
- - "~>"
|
|
74
73
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
74
|
+
version: '2.0'
|
|
76
75
|
type: :development
|
|
77
76
|
prerelease: false
|
|
78
77
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
78
|
requirements:
|
|
80
79
|
- - "~>"
|
|
81
80
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
81
|
+
version: '2.0'
|
|
83
82
|
- !ruby/object:Gem::Dependency
|
|
84
83
|
name: benchmark-ips
|
|
85
84
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -134,10 +133,10 @@ homepage: http://github.com/stadia/activerecord-mysql2rgeo-adapter
|
|
|
134
133
|
licenses:
|
|
135
134
|
- BSD-3-Clause
|
|
136
135
|
metadata:
|
|
136
|
+
funding_uri: https://opencollective.com/rgeo
|
|
137
137
|
source_code_uri: https://github.com/stadia/activerecord-mysql2rgeo-adapter
|
|
138
138
|
documentation_uri: https://github.com/stadia/activerecord-mysql2rgeo-adapter/blob/main/README.md
|
|
139
139
|
rubygems_mfa_required: 'true'
|
|
140
|
-
post_install_message:
|
|
141
140
|
rdoc_options: []
|
|
142
141
|
require_paths:
|
|
143
142
|
- lib
|
|
@@ -145,15 +144,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
145
144
|
requirements:
|
|
146
145
|
- - ">="
|
|
147
146
|
- !ruby/object:Gem::Version
|
|
148
|
-
version: 3.
|
|
147
|
+
version: 3.2.0
|
|
149
148
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
149
|
requirements:
|
|
151
150
|
- - ">="
|
|
152
151
|
- !ruby/object:Gem::Version
|
|
153
152
|
version: '0'
|
|
154
153
|
requirements: []
|
|
155
|
-
rubygems_version:
|
|
156
|
-
signing_key:
|
|
154
|
+
rubygems_version: 4.0.20
|
|
157
155
|
specification_version: 4
|
|
158
156
|
summary: ActiveRecord adapter for MySQL, based on RGeo.
|
|
159
157
|
test_files: []
|