activerecord-mysql2spatial-adapter 0.2.1 → 0.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.
- data/History.rdoc +7 -0
- data/README.rdoc +87 -45
- data/Version +1 -1
- data/lib/active_record/connection_adapters/mysql2spatial_adapter.rb +12 -162
- data/lib/active_record/connection_adapters/mysql2spatial_adapter/arel_tosql.rb +69 -0
- data/lib/active_record/connection_adapters/mysql2spatial_adapter/main_adapter.rb +136 -0
- data/lib/active_record/connection_adapters/mysql2spatial_adapter/spatial_column.rb +123 -0
- data/lib/active_record/connection_adapters/mysql2spatial_adapter/version.rb +62 -0
- data/test/tc_basic.rb +29 -20
- data/test/tc_spatial_queries.rb +125 -0
- metadata +14 -8
data/History.rdoc
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
=== 0.3.0 / 2011-01-26
|
2
|
+
|
3
|
+
* Reworked type and constraint handling, which should result in a large number of bug fixes, especially related to schema dumps.
|
4
|
+
* Experimental support for complex spatial queries. (Requires Arel 2.1, which is expected to be released with Rails 3.1.)
|
5
|
+
* The path to the Railtie is now different (see the README), though a compatibility wrapper has been left in the old location.
|
6
|
+
* Reorganized the code a bit for better clarity.
|
7
|
+
|
1
8
|
=== 0.2.1 / 2010-12-27
|
2
9
|
|
3
10
|
* Support for basic spatial equality queries. e.g. constructs such as:
|
data/README.rdoc
CHANGED
@@ -7,13 +7,9 @@ using the {RGeo}[http://github.com/dazuma/rgeo] library to represent
|
|
7
7
|
spatial data in Ruby. Like the standard mysql2 adapter, this adapter
|
8
8
|
requires the mysql2 gem.
|
9
9
|
|
10
|
-
|
10
|
+
== What This Adapter Provides
|
11
11
|
|
12
|
-
|
13
|
-
to your Gemfile, and then request the adapter name "mysql2spatial" in
|
14
|
-
your database connection configuration (which, for a Rails application,
|
15
|
-
is in the config/database.yml file). The other database connection
|
16
|
-
configuration parameters are the same as for the stock mysql2 adapter.
|
12
|
+
=== Spatial Migrations
|
17
13
|
|
18
14
|
First, this adapter extends the migration syntax to support creating
|
19
15
|
spatial columns and indexes. To create a spatial column, use the
|
@@ -25,24 +21,29 @@ column may need to be NOT NULL.
|
|
25
21
|
|
26
22
|
Examples:
|
27
23
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
create_table :my_spatial_table, :options => 'ENGINE=MyISAM' do |t|
|
25
|
+
t.column :latlon, :point, :null => false
|
26
|
+
t.line_string :path
|
27
|
+
t.geometry :shape
|
28
|
+
end
|
29
|
+
change_table :my_spatial_table do |t|
|
30
|
+
t.index :latlon, :spatial => true
|
31
|
+
end
|
32
|
+
|
33
|
+
=== Spatial Attributes
|
36
34
|
|
37
35
|
When this adapter is in use, spatial attributes in your \ActiveRecord
|
38
36
|
objects will have RGeo geometry values. You can set spatial attributes
|
39
37
|
either to RGeo geometry objects, or to strings in WKT (well-known text)
|
40
38
|
format, which the adapter will automatically convert to geometry objects.
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
Spatial objects in RGeo are tied to a factory that specifies the
|
41
|
+
coordinate system as well as other behaviors of the object. You must
|
42
|
+
therefore specify a factory for each spatial column (attribute) in your
|
43
|
+
ActiveRecord class. You can either set an explicit factory for a specific
|
44
|
+
column, or provide a factory generator that will yield the appropriate
|
45
|
+
factory for the table's spatial columns based on their types. For the
|
46
|
+
former, call the <tt>set_rgeo_factory_for_column</tt> class method on your
|
46
47
|
\ActiveRecord class. For the latter, set the rgeo_factory_generator class
|
47
48
|
attribute. This generator should understand at least the <tt>:srid</tt>
|
48
49
|
options, which will be provided based on the SRID embedded in the value
|
@@ -53,58 +54,98 @@ the "rgeo-activerecord" gem.
|
|
53
54
|
|
54
55
|
Examples, given the spatial table defined above:
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
class MySpatialTable < ActiveRecord::Base
|
58
|
+
|
59
|
+
# By default, use the GEOS implementation for spatial columns.
|
60
|
+
self.rgeo_factory_generator = RGeo::Geos.method(:factory)
|
61
|
+
|
62
|
+
# But use a geographic implementation for the :latlon column.
|
63
|
+
set_rgeo_factory_for_column(:latlon, RGeo::Geographic.spherical_factory)
|
64
|
+
|
65
|
+
end
|
65
66
|
|
66
67
|
Now you can interact with the data using the RGeo types:
|
67
68
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
69
|
+
rec = MySpatialTable.new
|
70
|
+
rec.latlon = 'POINT(-122 47)' # You can set by feature object or WKT.
|
71
|
+
loc = rec.latlon # Accessing always returns a feature object, in
|
72
|
+
# this case, a geographic that understands latitude.
|
73
|
+
loc.latitude # => 47
|
74
|
+
rec.shape = loc # the factory for the :shape column is GEOS, so the
|
75
|
+
# value will be cast from geographic to GEOS.
|
76
|
+
RGeo::Geos.is_geos?(rec.shape) # => true
|
77
|
+
|
78
|
+
=== Spatial Queries
|
76
79
|
|
77
80
|
You can create simple queries based on spatial equality in the same way
|
78
81
|
you would on a scalar column:
|
79
82
|
|
80
|
-
|
83
|
+
rec = MySpatialTable.where(:latlon => RGeo::Geos.factory.point(-122, 47)).first
|
81
84
|
|
82
85
|
You can also use WKT:
|
83
86
|
|
84
|
-
|
87
|
+
rec = MySpatialTable.where(:latlon => 'POINT(-122 47)').first
|
88
|
+
|
89
|
+
The adapter also provides experimental support for more complex queries
|
90
|
+
such as radius searches. However, these extensions require Arel 2.1
|
91
|
+
(which is scheduled for release with Rails 3.1). We do not have these
|
92
|
+
documented yet, and the syntax is subject to change. For now, you should
|
93
|
+
write more complex queries in SQL.
|
85
94
|
|
86
|
-
|
87
|
-
investigating writing a set of Arel extensions for constructing arbitrary
|
88
|
-
spatial queries.
|
95
|
+
== Installation And Configuration
|
89
96
|
|
90
|
-
===
|
97
|
+
=== Installing The Adapter Gem
|
91
98
|
|
92
99
|
This adapter has the following requirements:
|
93
100
|
|
94
101
|
* Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
|
95
102
|
* MySQL server 5.0 or later required for spatial extensions.
|
96
103
|
* \ActiveRecord 3.0.3 or later. Earlier versions will not work.
|
97
|
-
* rgeo gem 0.2.
|
98
|
-
* rgeo-activerecord gem 0.
|
104
|
+
* rgeo gem 0.2.4 or later.
|
105
|
+
* rgeo-activerecord gem 0.3.0 or later.
|
99
106
|
* mysql2 gem 0.2.6 or later.
|
100
107
|
|
101
108
|
Install this adapter as a gem:
|
102
109
|
|
103
|
-
|
110
|
+
gem install activerecord-mysql2spatial-adapter
|
104
111
|
|
105
112
|
See the README for the "rgeo" gem, a required dependency, for further
|
106
113
|
installation information.
|
107
114
|
|
115
|
+
=== Basic Setup
|
116
|
+
|
117
|
+
To use this adapter, add this gem, "activerecord-mysql2spatial-adapter",
|
118
|
+
to your Gemfile, and then request the adapter name "mysql2spatial" in
|
119
|
+
your database connection configuration (which, for a Rails application,
|
120
|
+
is in the config/database.yml file). The other database connection
|
121
|
+
configuration parameters are the same as for the stock mysql2 adapter,
|
122
|
+
so you can create a new Rails application using:
|
123
|
+
|
124
|
+
rails new my_app --database=mysql
|
125
|
+
|
126
|
+
...and then just change the adapter name to "mysql2spatial".
|
127
|
+
|
128
|
+
== Additional Information
|
129
|
+
|
130
|
+
=== Known bugs and limitations
|
131
|
+
|
132
|
+
This adapter is not yet well tested. There are probably some bugs and
|
133
|
+
holes in the functionality. We aren't using MySQL spatial extensions in
|
134
|
+
production at GeoPage, so we would appreciate testing help and feedback
|
135
|
+
from anyone who is.
|
136
|
+
|
137
|
+
One known issue is that if you want to use Rails's testing rake tasks and
|
138
|
+
you have spatial indexes in your schema, you should use the <tt>:sql</tt>
|
139
|
+
dump style. e.g. set <tt>config.active_record.schema_format = :sql</tt>.
|
140
|
+
The reason is that Rails's Ruby-format schema dumper does not preserve
|
141
|
+
the :options used to create the table, specifically setting the
|
142
|
+
Engine=MyISAM. Under MySQL Spatial, you may create spatial indexes only
|
143
|
+
on MyISAM tables; unfortunately, if you use the Ruby-format schema to
|
144
|
+
create your test databases, Rails does not transfer this information
|
145
|
+
properly, and your test tables are created as InnoDB. The workaround is
|
146
|
+
to use the <tt>:sql</tt> dump format. This has been reported as a bug in
|
147
|
+
Rails as of Rails 3.0.3, so we hope it will get rectified at some point.
|
148
|
+
|
108
149
|
=== Development and support
|
109
150
|
|
110
151
|
Documentation is available at http://virtuoso.rubyforge.org/activerecord-mysql2spatial-adapter/README_rdoc.html
|
@@ -119,7 +160,8 @@ Contact the author at dazuma at gmail dot com.
|
|
119
160
|
|
120
161
|
=== Acknowledgments
|
121
162
|
|
122
|
-
|
163
|
+
The Mysql2Spatial Adapter and its supporting libraries (including RGeo)
|
164
|
+
are written by Daniel Azuma (http://www.daniel-azuma.com).
|
123
165
|
|
124
166
|
Development of RGeo is sponsored by GeoPage, Inc. (http://www.geopage.com).
|
125
167
|
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
@@ -38,34 +38,6 @@ require 'rgeo/active_record'
|
|
38
38
|
require 'active_record/connection_adapters/mysql2_adapter'
|
39
39
|
|
40
40
|
|
41
|
-
# :stopdoc:
|
42
|
-
|
43
|
-
module Arel
|
44
|
-
module Visitors
|
45
|
-
|
46
|
-
class MySQL2Spatial < MySQL
|
47
|
-
|
48
|
-
FUNC_MAP = {
|
49
|
-
'ST_WKTToSQL' => 'GeomFromText',
|
50
|
-
'ST_Equals' => 'Equals',
|
51
|
-
}
|
52
|
-
|
53
|
-
include ::RGeo::ActiveRecord::SpatialToSql
|
54
|
-
|
55
|
-
def st_func(standard_name_)
|
56
|
-
FUNC_MAP[standard_name_] || standard_name_
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
VISITORS['mysql2spatial'] = ::Arel::Visitors::MySQL2Spatial
|
62
|
-
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
# :startdoc:
|
67
|
-
|
68
|
-
|
69
41
|
# The activerecord-mysql2spatial-adapter gem installs the *mysql2spatial*
|
70
42
|
# connection adapter into ActiveRecord.
|
71
43
|
|
@@ -87,153 +59,31 @@ module ActiveRecord
|
|
87
59
|
end
|
88
60
|
client_ = ::Mysql2::Client.new(config_.symbolize_keys)
|
89
61
|
options_ = [config_[:host], config_[:username], config_[:password], config_[:database], config_[:port], config_[:socket], 0]
|
90
|
-
ConnectionAdapters::Mysql2SpatialAdapter.new(client_, logger, options_, config_)
|
62
|
+
::ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::MainAdapter.new(client_, logger, options_, config_)
|
91
63
|
end
|
92
64
|
|
93
65
|
|
94
66
|
end
|
95
67
|
|
96
68
|
|
97
|
-
|
69
|
+
# All ActiveRecord adapters go in this namespace.
|
70
|
+
module ConnectionAdapters
|
98
71
|
|
99
|
-
|
100
|
-
|
72
|
+
# The Mysql2Spatial adapter
|
73
|
+
module Mysql2SpatialAdapter
|
101
74
|
|
75
|
+
# The name returned by the adapter_name method of this adapter.
|
102
76
|
ADAPTER_NAME = 'Mysql2Spatial'.freeze
|
103
77
|
|
104
|
-
NATIVE_DATABASE_TYPES = Mysql2Adapter::NATIVE_DATABASE_TYPES.merge(:geometry => {:name => "geometry"}, :point => {:name => "point"}, :line_string => {:name => "linestring"}, :polygon => {:name => "polygon"}, :geometry_collection => {:name => "geometrycollection"}, :multi_point => {:name => "multipoint"}, :multi_line_string => {:name => "multilinestring"}, :multi_polygon => {:name => "multipolygon"})
|
105
|
-
|
106
|
-
|
107
|
-
def native_database_types
|
108
|
-
NATIVE_DATABASE_TYPES
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
def adapter_name
|
113
|
-
ADAPTER_NAME
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
def quote(value_, column_=nil)
|
118
|
-
if ::RGeo::Feature::Geometry.check_type(value_)
|
119
|
-
"GeomFromWKB(0x#{::RGeo::WKRep::WKBGenerator.new(:hex_format => true).generate(value_)},#{value_.srid})"
|
120
|
-
else
|
121
|
-
super
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
def add_index(table_name_, column_name_, options_={})
|
127
|
-
if options_[:spatial]
|
128
|
-
index_name_ = index_name(table_name_, :column => Array(column_name_))
|
129
|
-
if ::Hash === options_
|
130
|
-
index_name_ = options_[:name] || index_name_
|
131
|
-
end
|
132
|
-
execute "CREATE SPATIAL INDEX #{index_name_} ON #{table_name_} (#{Array(column_name_).join(", ")})"
|
133
|
-
else
|
134
|
-
super
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
|
139
|
-
def columns(table_name_, name_=nil)
|
140
|
-
result_ = execute("SHOW FIELDS FROM #{quote_table_name(table_name_)}", :skip_logging)
|
141
|
-
columns_ = []
|
142
|
-
result_.each(:symbolize_keys => true, :as => :hash) do |field_|
|
143
|
-
columns_ << SpatialColumn.new(field_[:Field], field_[:Default], field_[:Type], field_[:Null] == "YES")
|
144
|
-
end
|
145
|
-
columns_
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
def indexes(table_name_, name_=nil)
|
150
|
-
indexes_ = []
|
151
|
-
current_index_ = nil
|
152
|
-
result_ = execute("SHOW KEYS FROM #{quote_table_name(table_name_)}", name_)
|
153
|
-
result_.each(:symbolize_keys => true, :as => :hash) do |row_|
|
154
|
-
if current_index_ != row_[:Key_name]
|
155
|
-
next if row_[:Key_name] == 'PRIMARY' # skip the primary key
|
156
|
-
current_index_ = row_[:Key_name]
|
157
|
-
indexes_ << ::RGeo::ActiveRecord::SpatialIndexDefinition.new(row_[:Table], row_[:Key_name], row_[:Non_unique] == 0, [], [], row_[:Index_type] == 'SPATIAL')
|
158
|
-
end
|
159
|
-
indexes_.last.columns << row_[:Column_name]
|
160
|
-
indexes_.last.lengths << row_[:Sub_part]
|
161
|
-
end
|
162
|
-
indexes_
|
163
|
-
end
|
164
|
-
|
165
|
-
|
166
|
-
class SpatialColumn < ConnectionAdapters::Mysql2Column # :nodoc:
|
167
|
-
|
168
|
-
|
169
|
-
def initialize(name_, default_, sql_type_=nil, null_=true)
|
170
|
-
super(name_, default_,sql_type_, null_)
|
171
|
-
@geometric_type = ::RGeo::ActiveRecord.geometric_type_from_name(sql_type_)
|
172
|
-
@ar_class = ::ActiveRecord::Base
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
def set_ar_class(val_)
|
177
|
-
@ar_class = val_
|
178
|
-
end
|
179
|
-
|
180
|
-
|
181
|
-
attr_reader :geometric_type
|
182
|
-
|
183
|
-
|
184
|
-
def spatial?
|
185
|
-
type == :geometry
|
186
|
-
end
|
187
|
-
|
188
|
-
|
189
|
-
def klass
|
190
|
-
type == :geometry ? ::RGeo::Feature::Geometry : super
|
191
|
-
end
|
192
|
-
|
193
|
-
|
194
|
-
def type_cast(value_)
|
195
|
-
type == :geometry ? SpatialColumn.convert_to_geometry(value_, @ar_class, name) : super
|
196
|
-
end
|
197
|
-
|
198
|
-
|
199
|
-
def type_cast_code(var_name_)
|
200
|
-
type == :geometry ? "::ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::SpatialColumn.convert_to_geometry(#{var_name_}, self.class, #{name.inspect})" : super
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
private
|
205
|
-
|
206
|
-
def simplified_type(sql_type_)
|
207
|
-
sql_type_ =~ /geometry|point|linestring|polygon/i ? :geometry : super
|
208
|
-
end
|
209
|
-
|
210
|
-
|
211
|
-
def self.convert_to_geometry(input_, ar_class_, column_)
|
212
|
-
case input_
|
213
|
-
when ::RGeo::Feature::Geometry
|
214
|
-
factory_ = ar_class_.rgeo_factory_for_column(column_, :srid => input_.srid)
|
215
|
-
::RGeo::Feature.cast(input_, factory_)
|
216
|
-
when ::String
|
217
|
-
marker_ = input_[4,1]
|
218
|
-
if marker_ == "\x00" || marker_ == "\x01"
|
219
|
-
factory_ = ar_class_.rgeo_factory_for_column(column_, :srid => input_[0,4].unpack(marker_ == "\x01" ? 'V' : 'N').first)
|
220
|
-
::RGeo::WKRep::WKBParser.new(factory_).parse(input_[4..-1])
|
221
|
-
else
|
222
|
-
factory_ = ar_class_.rgeo_factory_for_column(column_)
|
223
|
-
::RGeo::WKRep::WKTParser.new(factory_, :support_ewkt => true).parse(input_)
|
224
|
-
end
|
225
|
-
else
|
226
|
-
nil
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
|
231
|
-
end
|
232
|
-
|
233
|
-
|
234
78
|
end
|
235
79
|
|
236
80
|
end
|
237
81
|
|
238
82
|
|
239
83
|
end
|
84
|
+
|
85
|
+
|
86
|
+
require 'active_record/connection_adapters/mysql2spatial_adapter/version.rb'
|
87
|
+
require 'active_record/connection_adapters/mysql2spatial_adapter/main_adapter.rb'
|
88
|
+
require 'active_record/connection_adapters/mysql2spatial_adapter/spatial_column.rb'
|
89
|
+
require 'active_record/connection_adapters/mysql2spatial_adapter/arel_tosql.rb'
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Mysql2Spatial adapter for ActiveRecord
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
# :stopdoc:
|
38
|
+
|
39
|
+
module Arel
|
40
|
+
module Visitors
|
41
|
+
|
42
|
+
class MySQL2Spatial < MySQL
|
43
|
+
|
44
|
+
FUNC_MAP = {
|
45
|
+
'st_wkttosql' => 'GeomFromText',
|
46
|
+
'st_wkbtosql' => 'GeomFromWKB',
|
47
|
+
'st_length' => 'GLength',
|
48
|
+
}
|
49
|
+
|
50
|
+
include ::RGeo::ActiveRecord::SpatialToSql
|
51
|
+
|
52
|
+
def st_func(standard_name_)
|
53
|
+
if (name_ = FUNC_MAP[standard_name_.downcase])
|
54
|
+
name_
|
55
|
+
elsif standard_name_ =~ /^st_(\w+)$/i
|
56
|
+
$1
|
57
|
+
else
|
58
|
+
standard_name_
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
VISITORS['mysql2spatial'] = ::Arel::Visitors::MySQL2Spatial
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# :startdoc:
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Mysql2Spatial adapter for ActiveRecord
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
# :stopdoc:
|
38
|
+
|
39
|
+
module ActiveRecord
|
40
|
+
|
41
|
+
module ConnectionAdapters
|
42
|
+
|
43
|
+
module Mysql2SpatialAdapter
|
44
|
+
|
45
|
+
|
46
|
+
class MainAdapter < ConnectionAdapters::Mysql2Adapter
|
47
|
+
|
48
|
+
|
49
|
+
NATIVE_DATABASE_TYPES = Mysql2Adapter::NATIVE_DATABASE_TYPES.merge(:spatial => {:name => "geometry"})
|
50
|
+
|
51
|
+
|
52
|
+
def adapter_name
|
53
|
+
Mysql2SpatialAdapter::ADAPTER_NAME
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def spatial_column_constructor(name_)
|
58
|
+
::RGeo::ActiveRecord::DEFAULT_SPATIAL_COLUMN_CONSTRUCTORS[name_]
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def native_database_types
|
63
|
+
NATIVE_DATABASE_TYPES
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def quote(value_, column_=nil)
|
68
|
+
if ::RGeo::Feature::Geometry.check_type(value_)
|
69
|
+
"GeomFromWKB(0x#{::RGeo::WKRep::WKBGenerator.new(:hex_format => true).generate(value_)},#{value_.srid})"
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
def type_to_sql(type_, limit_=nil, precision_=nil, scale_=nil)
|
77
|
+
if (info_ = spatial_column_constructor(type_.to_sym))
|
78
|
+
type_ = limit_[:type] || type_ if limit_.is_a?(::Hash)
|
79
|
+
type_ = 'geometry' if type_.to_s == 'spatial'
|
80
|
+
type_ = type_.to_s.gsub('_', '').upcase
|
81
|
+
end
|
82
|
+
super(type_, limit_, precision_, scale_)
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
def add_index(table_name_, column_name_, options_={})
|
87
|
+
if options_[:spatial]
|
88
|
+
index_name_ = index_name(table_name_, :column => Array(column_name_))
|
89
|
+
if ::Hash === options_
|
90
|
+
index_name_ = options_[:name] || index_name_
|
91
|
+
end
|
92
|
+
execute "CREATE SPATIAL INDEX #{index_name_} ON #{table_name_} (#{Array(column_name_).join(", ")})"
|
93
|
+
else
|
94
|
+
super
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
|
99
|
+
def columns(table_name_, name_=nil)
|
100
|
+
result_ = execute("SHOW FIELDS FROM #{quote_table_name(table_name_)}", :skip_logging)
|
101
|
+
columns_ = []
|
102
|
+
result_.each(:symbolize_keys => true, :as => :hash) do |field_|
|
103
|
+
columns_ << SpatialColumn.new(field_[:Field], field_[:Default], field_[:Type], field_[:Null] == "YES")
|
104
|
+
end
|
105
|
+
columns_
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def indexes(table_name_, name_=nil)
|
110
|
+
indexes_ = []
|
111
|
+
current_index_ = nil
|
112
|
+
result_ = execute("SHOW KEYS FROM #{quote_table_name(table_name_)}", name_)
|
113
|
+
result_.each(:symbolize_keys => true, :as => :hash) do |row_|
|
114
|
+
if current_index_ != row_[:Key_name]
|
115
|
+
next if row_[:Key_name] == 'PRIMARY' # skip the primary key
|
116
|
+
current_index_ = row_[:Key_name]
|
117
|
+
indexes_ << ::RGeo::ActiveRecord::SpatialIndexDefinition.new(row_[:Table], row_[:Key_name], row_[:Non_unique] == 0, [], [], row_[:Index_type] == 'SPATIAL')
|
118
|
+
end
|
119
|
+
last_index_ = indexes_.last
|
120
|
+
last_index_.columns << row_[:Column_name]
|
121
|
+
last_index_.lengths << row_[:Sub_part] unless last_index_.spatial
|
122
|
+
end
|
123
|
+
indexes_
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
# :startdoc:
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Mysql2Spatial adapter for ActiveRecord
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
# :stopdoc:
|
38
|
+
|
39
|
+
module ActiveRecord
|
40
|
+
|
41
|
+
module ConnectionAdapters
|
42
|
+
|
43
|
+
module Mysql2SpatialAdapter
|
44
|
+
|
45
|
+
|
46
|
+
class SpatialColumn < ConnectionAdapters::Mysql2Column
|
47
|
+
|
48
|
+
|
49
|
+
def initialize(name_, default_, sql_type_=nil, null_=true)
|
50
|
+
super(name_, default_,sql_type_, null_)
|
51
|
+
@geometric_type = ::RGeo::ActiveRecord.geometric_type_from_name(sql_type_)
|
52
|
+
if type == :spatial
|
53
|
+
@limit = {:type => @geometric_type.type_name.underscore}
|
54
|
+
end
|
55
|
+
@ar_class = ::ActiveRecord::Base
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
def set_ar_class(val_)
|
60
|
+
@ar_class = val_
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
attr_reader :geometric_type
|
65
|
+
|
66
|
+
|
67
|
+
def spatial?
|
68
|
+
type == :spatial
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
def klass
|
73
|
+
type == :spatial ? ::RGeo::Feature::Geometry : super
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
def type_cast(value_)
|
78
|
+
type == :spatial ? SpatialColumn.convert_to_geometry(value_, @ar_class, name) : super
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def type_cast_code(var_name_)
|
83
|
+
type == :spatial ? "::ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::SpatialColumn.convert_to_geometry(#{var_name_}, self.class, #{name.inspect})" : super
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def simplified_type(sql_type_)
|
90
|
+
sql_type_ =~ /geometry|point|linestring|polygon/i ? :spatial : super
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def self.convert_to_geometry(input_, ar_class_, column_)
|
95
|
+
case input_
|
96
|
+
when ::RGeo::Feature::Geometry
|
97
|
+
factory_ = ar_class_.rgeo_factory_for_column(column_, :srid => input_.srid)
|
98
|
+
::RGeo::Feature.cast(input_, factory_)
|
99
|
+
when ::String
|
100
|
+
marker_ = input_[4,1]
|
101
|
+
if marker_ == "\x00" || marker_ == "\x01"
|
102
|
+
factory_ = ar_class_.rgeo_factory_for_column(column_, :srid => input_[0,4].unpack(marker_ == "\x01" ? 'V' : 'N').first)
|
103
|
+
::RGeo::WKRep::WKBParser.new(factory_).parse(input_[4..-1])
|
104
|
+
else
|
105
|
+
factory_ = ar_class_.rgeo_factory_for_column(column_)
|
106
|
+
::RGeo::WKRep::WKTParser.new(factory_, :support_ewkt => true).parse(input_)
|
107
|
+
end
|
108
|
+
else
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
# :startdoc:
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Mysql2Spatial adapter for ActiveRecord
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
begin
|
38
|
+
require 'versionomy'
|
39
|
+
rescue ::LoadError
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
module ActiveRecord
|
44
|
+
|
45
|
+
module ConnectionAdapters
|
46
|
+
|
47
|
+
module Mysql2SpatialAdapter
|
48
|
+
|
49
|
+
|
50
|
+
# Current version of Mysql2SpatialAdapter as a frozen string
|
51
|
+
VERSION_STRING = ::File.read(::File.dirname(__FILE__)+'/../../../../Version').strip.freeze
|
52
|
+
|
53
|
+
# Current version of Mysql2SpatialAdapter as a Versionomy object, if the
|
54
|
+
# Versionomy gem is available; otherwise equal to VERSION_STRING.
|
55
|
+
VERSION = defined?(::Versionomy) ? ::Versionomy.parse(VERSION_STRING) : VERSION_STRING
|
56
|
+
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/test/tc_basic.rb
CHANGED
@@ -62,6 +62,11 @@ module RGeo
|
|
62
62
|
end
|
63
63
|
|
64
64
|
|
65
|
+
def test_version
|
66
|
+
assert_not_nil(::ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::VERSION)
|
67
|
+
end
|
68
|
+
|
69
|
+
|
65
70
|
def test_create_simple_geometry
|
66
71
|
klass_ = create_ar_class
|
67
72
|
klass_.connection.create_table(:spatial_test) do |t_|
|
@@ -161,29 +166,33 @@ module RGeo
|
|
161
166
|
end
|
162
167
|
|
163
168
|
|
164
|
-
def
|
165
|
-
klass_ =
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
assert_equal(id_, obj2_.id)
|
172
|
-
obj3_ = klass_.where(:latlon => @factory.point(2, 2)).first
|
173
|
-
assert_nil(obj3_)
|
169
|
+
def test_create_simple_geometry_using_shortcut
|
170
|
+
klass_ = create_ar_class
|
171
|
+
klass_.connection.create_table(:spatial_test) do |t_|
|
172
|
+
t_.geometry 'latlon'
|
173
|
+
end
|
174
|
+
assert_equal(::RGeo::Feature::Geometry, klass_.columns.last.geometric_type)
|
175
|
+
assert(klass_.cached_attributes.include?('latlon'))
|
174
176
|
end
|
175
177
|
|
176
178
|
|
177
|
-
def
|
178
|
-
klass_ =
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
179
|
+
def test_create_point_geometry_using_shortcut
|
180
|
+
klass_ = create_ar_class
|
181
|
+
klass_.connection.create_table(:spatial_test) do |t_|
|
182
|
+
t_.point 'latlon'
|
183
|
+
end
|
184
|
+
assert_equal(::RGeo::Feature::Point, klass_.columns.last.geometric_type)
|
185
|
+
assert(klass_.cached_attributes.include?('latlon'))
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
def test_create_geometry_using_limit
|
190
|
+
klass_ = create_ar_class
|
191
|
+
klass_.connection.create_table(:spatial_test) do |t_|
|
192
|
+
t_.spatial 'geom', :limit => {:type => :line_string}
|
193
|
+
end
|
194
|
+
assert_equal(::RGeo::Feature::LineString, klass_.columns.last.geometric_type)
|
195
|
+
assert(klass_.cached_attributes.include?('geom'))
|
187
196
|
end
|
188
197
|
|
189
198
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Tests for the Mysql2Spatial ActiveRecord adapter
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
require 'test/unit'
|
37
|
+
require 'rgeo/active_record/adapter_test_helper'
|
38
|
+
|
39
|
+
|
40
|
+
module RGeo
|
41
|
+
module ActiveRecord # :nodoc:
|
42
|
+
module Mysql2SpatialAdapter # :nodoc:
|
43
|
+
module Tests # :nodoc:
|
44
|
+
|
45
|
+
class TestSpatialQueries < ::Test::Unit::TestCase # :nodoc:
|
46
|
+
|
47
|
+
DATABASE_CONFIG_PATH = ::File.dirname(__FILE__)+'/database.yml'
|
48
|
+
include AdapterTestHelper
|
49
|
+
|
50
|
+
define_test_methods do
|
51
|
+
|
52
|
+
|
53
|
+
def populate_ar_class(content_)
|
54
|
+
klass_ = create_ar_class
|
55
|
+
case content_
|
56
|
+
when :latlon_point
|
57
|
+
klass_.connection.create_table(:spatial_test) do |t_|
|
58
|
+
t_.column 'latlon', :point
|
59
|
+
end
|
60
|
+
when :path_linestring
|
61
|
+
klass_.connection.create_table(:spatial_test) do |t_|
|
62
|
+
t_.column 'path', :line_string
|
63
|
+
end
|
64
|
+
end
|
65
|
+
klass_
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def test_query_point
|
70
|
+
klass_ = populate_ar_class(:latlon_point)
|
71
|
+
obj_ = klass_.new
|
72
|
+
obj_.latlon = @factory.point(1, 2)
|
73
|
+
obj_.save!
|
74
|
+
id_ = obj_.id
|
75
|
+
obj2_ = klass_.where(:latlon => @factory.multi_point([@factory.point(1, 2)])).first
|
76
|
+
assert_equal(id_, obj2_.id)
|
77
|
+
obj3_ = klass_.where(:latlon => @factory.point(2, 2)).first
|
78
|
+
assert_nil(obj3_)
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def test_query_point_wkt
|
83
|
+
klass_ = populate_ar_class(:latlon_point)
|
84
|
+
obj_ = klass_.new
|
85
|
+
obj_.latlon = @factory.point(1, 2)
|
86
|
+
obj_.save!
|
87
|
+
id_ = obj_.id
|
88
|
+
obj2_ = klass_.where(:latlon => 'POINT(1 2)').first
|
89
|
+
assert_equal(id_, obj2_.id)
|
90
|
+
obj3_ = klass_.where(:latlon => 'POINT(2 2)').first
|
91
|
+
assert_nil(obj3_)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
if ::RGeo::ActiveRecord.spatial_expressions_supported?
|
96
|
+
|
97
|
+
|
98
|
+
def test_query_st_length
|
99
|
+
klass_ = populate_ar_class(:path_linestring)
|
100
|
+
obj_ = klass_.new
|
101
|
+
obj_.path = @factory.line(@factory.point(1, 2), @factory.point(3, 2))
|
102
|
+
obj_.save!
|
103
|
+
id_ = obj_.id
|
104
|
+
obj2_ = klass_.where(klass_.arel_table[:path].st_length.eq(2)).first
|
105
|
+
assert_equal(id_, obj2_.id)
|
106
|
+
obj3_ = klass_.where(klass_.arel_table[:path].st_length.gt(3)).first
|
107
|
+
assert_nil(obj3_)
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
else
|
112
|
+
|
113
|
+
puts "WARNING: The current Arel does not support named functions. Spatial expression tests skipped."
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Daniel Azuma
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date:
|
17
|
+
date: 2011-01-26 00:00:00 -08:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -23,13 +23,13 @@ dependencies:
|
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
segments:
|
29
29
|
- 0
|
30
|
-
-
|
31
|
-
-
|
32
|
-
version: 0.
|
30
|
+
- 3
|
31
|
+
- 0
|
32
|
+
version: 0.3.0
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
@@ -57,10 +57,15 @@ extra_rdoc_files:
|
|
57
57
|
- History.rdoc
|
58
58
|
- README.rdoc
|
59
59
|
files:
|
60
|
+
- lib/active_record/connection_adapters/mysql2spatial_adapter/arel_tosql.rb
|
61
|
+
- lib/active_record/connection_adapters/mysql2spatial_adapter/main_adapter.rb
|
62
|
+
- lib/active_record/connection_adapters/mysql2spatial_adapter/spatial_column.rb
|
63
|
+
- lib/active_record/connection_adapters/mysql2spatial_adapter/version.rb
|
60
64
|
- lib/active_record/connection_adapters/mysql2spatial_adapter.rb
|
61
65
|
- History.rdoc
|
62
66
|
- README.rdoc
|
63
67
|
- test/tc_basic.rb
|
68
|
+
- test/tc_spatial_queries.rb
|
64
69
|
- Version
|
65
70
|
has_rdoc: true
|
66
71
|
homepage: http://virtuoso.rubyforge.org/activerecord-mysql2spatial-adapter
|
@@ -98,3 +103,4 @@ specification_version: 3
|
|
98
103
|
summary: An ActiveRecord adapter for MySQL Spatial Extensions, based on RGeo and the mysql2 gem.
|
99
104
|
test_files:
|
100
105
|
- test/tc_basic.rb
|
106
|
+
- test/tc_spatial_queries.rb
|