activerecord-mysqlspatial-adapter 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.rdoc ADDED
@@ -0,0 +1,6 @@
1
+ === 0.2.0 / 2010-12-07
2
+
3
+ * Initial public alpha release. Spun activerecord-mysqlspatial-adapter off from the core rgeo gem.
4
+ * You can now set the factory for a specific column by name.
5
+
6
+ For earlier history, see the History file for the rgeo gem.
data/README.rdoc ADDED
@@ -0,0 +1,146 @@
1
+ == MySQL Spatial \ActiveRecord Adapter
2
+
3
+ The MySQL Spatial \ActiveRecord Adapter is an \ActiveRecord connection
4
+ adapter based on the standard mysql adapter. It extends the standard
5
+ adapter to provide support for spatial columns and indexes in MySQL,
6
+ using the {RGeo}[http://github.com/dazuma/rgeo] library to represent
7
+ spatial data in Ruby. Like the standard mysql adapter, this adapter
8
+ requires the mysql gem.
9
+
10
+ === Usage
11
+
12
+ To use this adapter, add this gem, "activerecord-mysqlspatial-adapter",
13
+ to your Gemfile, and then request the adapter name "mysqlspatial" 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 mysql adapter.
17
+
18
+ First, this adapter extends the migration syntax to support creating
19
+ spatial columns and indexes. To create a spatial column, use the
20
+ <tt>:geometry</tt> type, or any of the OGC spatial types such as
21
+ <tt>:point</tt> or <tt>:line_string</tt>. To create a spatial index, set
22
+ the <tt>:spatial</tt> option to true. Remember that, on some versions of
23
+ MySQL, only the MyISAM engine supports spatial indexes, and the indexed
24
+ column may need to be NOT NULL.
25
+
26
+ Examples:
27
+
28
+ create_table :spatial_table, :options => 'ENGINE=MyISAM' do |t|
29
+ t.column :latlon, :point, :null => false
30
+ t.line_string :path
31
+ t.geometry :shape
32
+ end
33
+ change_table :spatial_table do |t|
34
+ t.index :latlon, :spatial => true
35
+ end
36
+
37
+ When this adapter is in use, spatial attributes in your \ActiveRecord
38
+ objects will have RGeo geometry values. You can set spatial attributes
39
+ either to RGeo geometry objects, or to strings in WKT (well-known text)
40
+ format, which the adapter will automatically convert to geometry objects.
41
+
42
+ To specify the RGeo geometry factory, you can either set an explicit
43
+ factory for a column, or provide a factory generator that will yield the
44
+ appropriate factory for the table's spatial columns based on the value.
45
+ For the former, call the set_rgeo_factory_for_column class method on your
46
+ \ActiveRecord class. For the latter, set the rgeo_factory_generator class
47
+ attribute. This generator should understand at least the <tt>:srid</tt>
48
+ options, which will be provided based on the SRID embedded in the value
49
+ itself, since MySQL does not support SRID or dimension constraints on
50
+ spatial columns themselves. The set_rgeo_factory_for_column and
51
+ rgeo_factory_generator methods are actually implemented and documented in
52
+ the "rgeo-activerecord" gem.
53
+
54
+ Examples, given the spatial table defined above:
55
+
56
+ class SpatialTable < ActiveRecord::Base
57
+
58
+ # By default, use the GEOS implementation for spatial columns.
59
+ self.rgeo_factory_generator = RGeo::Geos.method(:factory)
60
+
61
+ # But use a geographic implementation for the :latlon column.
62
+ set_rgeo_factory_for_column(:latlon, RGeo::Geographic.spherical_factory)
63
+
64
+ end
65
+
66
+ Now you can interact with the data using the RGeo types:
67
+
68
+ rec = SpatialTable.new
69
+ rec.latlon = 'POINT(-122 47)' # You can set by feature object or WKT.
70
+ loc = rec.latlon # Accessing always returns a feature object, in
71
+ # this case, a geographic that understands latitude.
72
+ loc.latitude # => 47
73
+ rec.shape = loc # the factory for the :shape column is GEOS, so the
74
+ # value will be cast from geographic to GEOS.
75
+ RGeo::Geos.is_geos?(rec.shape) # => true
76
+
77
+ === Installation
78
+
79
+ This adapter has the following requirements:
80
+
81
+ * Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
82
+ * MySQL server 5.0 or later required for spatial extensions.
83
+ * \ActiveRecord 3.0.3 or later. Earlier versions will not work.
84
+ * rgeo gem 0.2.0 or later.
85
+ * rgeo-activerecord gem 0.2.0 or later.
86
+ * mysql gem 2.8 or later.
87
+
88
+ Install this adapter as a gem:
89
+
90
+ gem install activerecord-mysqlspatial-adapter
91
+
92
+ See the README for the "rgeo" gem, a required dependency, for further
93
+ installation information.
94
+
95
+ === Development and support
96
+
97
+ Documentation is available at http://virtuoso.rubyforge.org/activerecord-mysqlspatial-adapter/README_rdoc.html
98
+
99
+ Source code is hosted on Github at http://github.com/dazuma/activerecord-mysqlspatial-adapter
100
+
101
+ Contributions are welcome. Fork the project on Github.
102
+
103
+ Report bugs on Github issues at http://github.org/dazuma/activerecord-mysqlspatial-adapter/issues
104
+
105
+ Contact the author at dazuma at gmail dot com.
106
+
107
+ === Acknowledgments
108
+
109
+ RGeo is written by Daniel Azuma (http://www.daniel-azuma.com).
110
+
111
+ Development of RGeo is sponsored by GeoPage, Inc. (http://www.geopage.com).
112
+
113
+ This adapter implementation owes some debt to the spatial_adapter plugin
114
+ (http://github.com/fragility/spatial_adapter). Although we made a few
115
+ different design decisions for this adapter, studying the spatial_adapter
116
+ source gave us a head start on the implementation.
117
+
118
+ === License
119
+
120
+ Copyright 2010 Daniel Azuma
121
+
122
+ All rights reserved.
123
+
124
+ Redistribution and use in source and binary forms, with or without
125
+ modification, are permitted provided that the following conditions are met:
126
+
127
+ * Redistributions of source code must retain the above copyright notice,
128
+ this list of conditions and the following disclaimer.
129
+ * Redistributions in binary form must reproduce the above copyright notice,
130
+ this list of conditions and the following disclaimer in the documentation
131
+ and/or other materials provided with the distribution.
132
+ * Neither the name of the copyright holder, nor the names of any other
133
+ contributors to this software, may be used to endorse or promote products
134
+ derived from this software without specific prior written permission.
135
+
136
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
137
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
138
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
139
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
140
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
141
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
142
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
143
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
144
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
145
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
146
+ POSSIBILITY OF SUCH DAMAGE.
data/Version ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,234 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # MysqlSpatial 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
+ require 'rgeo/active_record'
38
+ require 'active_record/connection_adapters/mysql_adapter'
39
+
40
+
41
+ # :stopdoc:
42
+
43
+ module Arel
44
+ module Visitors
45
+ VISITORS['mysqlspatial'] = ::Arel::Visitors::MySQL
46
+ end
47
+ end
48
+
49
+ # :startdoc:
50
+
51
+
52
+ # The activerecord-mysqlspatial-adapter gem installs the *mysqlspatial*
53
+ # connection adapter into ActiveRecord.
54
+
55
+ module ActiveRecord
56
+
57
+
58
+ # ActiveRecord looks for the mysqlspatial_connection factory method in
59
+ # this class.
60
+
61
+ class Base
62
+
63
+
64
+ # Create a mysqlspatial connection adapter.
65
+
66
+ def self.mysqlspatial_connection(config_)
67
+ unless defined?(::Mysql)
68
+ begin
69
+ require 'mysql'
70
+ rescue ::LoadError
71
+ raise "!!! Missing the mysql gem. Add it to your Gemfile: gem 'mysql'"
72
+ end
73
+ unless defined?(::Mysql::Result) && ::Mysql::Result.method_defined?(:each_hash)
74
+ raise "!!! Outdated mysql gem. Upgrade to 2.8.1 or later. In your Gemfile: gem 'mysql', '2.8.1'. Or use gem 'mysql2'"
75
+ end
76
+ end
77
+ config_ = config_.symbolize_keys
78
+ mysql_ = ::Mysql.init
79
+ mysql_.ssl_set(config_[:sslkey], config_[:sslcert], config_[:sslca], config_[:sslcapath], config_[:sslcipher]) if config_[:sslca] || config_[:sslkey]
80
+ default_flags_ = ::Mysql.const_defined?(:CLIENT_MULTI_RESULTS) ? ::Mysql::CLIENT_MULTI_RESULTS : 0
81
+ default_flags_ |= ::Mysql::CLIENT_FOUND_ROWS if ::Mysql.const_defined?(:CLIENT_FOUND_ROWS)
82
+ options_ = [config_[:host], config_[:username] ? config_[:username].to_s : 'root', config_[:password].to_s, config_[:database], config_[:port], config_[:socket], default_flags_]
83
+ ConnectionAdapters::MysqlSpatialAdapter.new(mysql_, logger, options_, config_)
84
+ end
85
+
86
+
87
+ end
88
+
89
+
90
+ module ConnectionAdapters # :nodoc:
91
+
92
+ class MysqlSpatialAdapter < MysqlAdapter # :nodoc:
93
+
94
+
95
+ ADAPTER_NAME = 'MysqlSpatial'.freeze
96
+
97
+ NATIVE_DATABASE_TYPES = MysqlAdapter::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"})
98
+
99
+
100
+ def native_database_types
101
+ NATIVE_DATABASE_TYPES
102
+ end
103
+
104
+
105
+ def adapter_name
106
+ ADAPTER_NAME
107
+ end
108
+
109
+
110
+ def quote(value_, column_=nil)
111
+ if ::RGeo::Feature::Geometry.check_type(value_)
112
+ "GeomFromWKB(0x#{::RGeo::WKRep::WKBGenerator.new(:hex_format => true).generate(value_)},#{value_.srid})"
113
+ else
114
+ super
115
+ end
116
+ end
117
+
118
+
119
+ def add_index(table_name_, column_name_, options_={})
120
+ if options_[:spatial]
121
+ index_name_ = index_name(table_name_, :column => Array(column_name_))
122
+ if ::Hash === options_
123
+ index_name_ = options_[:name] || index_name_
124
+ end
125
+ execute "CREATE SPATIAL INDEX #{index_name_} ON #{table_name_} (#{Array(column_name_).join(", ")})"
126
+ else
127
+ super
128
+ end
129
+ end
130
+
131
+
132
+ def columns(table_name_, name_=nil)
133
+ result_ = execute("SHOW FIELDS FROM #{quote_table_name(table_name_)}", :skip_logging)
134
+ columns_ = []
135
+ result_.each do |field_|
136
+ columns_ << SpatialColumn.new(field_[0], field_[4], field_[1], field_[2] == "YES")
137
+ end
138
+ result_.free
139
+ columns_
140
+ end
141
+
142
+
143
+ def indexes(table_name_, name_=nil)
144
+ indexes_ = []
145
+ current_index_ = nil
146
+ result_ = execute("SHOW KEYS FROM #{quote_table_name(table_name_)}", name_)
147
+ result_.each do |row_|
148
+ if current_index_ != row_[2]
149
+ next if row_[2] == "PRIMARY" # skip the primary key
150
+ current_index_ = row_[2]
151
+ indexes_ << ::RGeo::ActiveRecord::SpatialIndexDefinition.new(row_[0], row_[2], row_[1] == "0", [], [], row_[10] == 'SPATIAL')
152
+ end
153
+ indexes_.last.columns << row_[4]
154
+ indexes_.last.lengths << row_[7]
155
+ end
156
+ result_.free
157
+ indexes_
158
+ end
159
+
160
+
161
+ class SpatialColumn < ConnectionAdapters::MysqlColumn # :nodoc:
162
+
163
+
164
+ def initialize(name_, default_, sql_type_=nil, null_=true)
165
+ super(name_, default_,sql_type_, null_)
166
+ @geometric_type = ::RGeo::ActiveRecord.geometric_type_from_name(sql_type_)
167
+ @ar_class = ::ActiveRecord::Base
168
+ end
169
+
170
+
171
+ def set_ar_class(val_)
172
+ @ar_class = val_
173
+ end
174
+
175
+
176
+ attr_reader :geometric_type
177
+
178
+
179
+ def spatial?
180
+ type == :geometry
181
+ end
182
+
183
+
184
+ def klass
185
+ type == :geometry ? ::RGeo::Feature::Geometry : super
186
+ end
187
+
188
+
189
+ def type_cast(value_)
190
+ type == :geometry ? SpatialColumn.convert_to_geometry(value_, @ar_class, name) : super
191
+ end
192
+
193
+
194
+ def type_cast_code(var_name_)
195
+ type == :geometry ? "::ActiveRecord::ConnectionAdapters::MysqlSpatialAdapter::SpatialColumn.convert_to_geometry(#{var_name_}, self.class, #{name.inspect})" : super
196
+ end
197
+
198
+
199
+ private
200
+
201
+ def simplified_type(sql_type_)
202
+ sql_type_ =~ /geometry|point|linestring|polygon/i ? :geometry : super
203
+ end
204
+
205
+
206
+ def self.convert_to_geometry(input_, ar_class_, column_)
207
+ case input_
208
+ when ::RGeo::Feature::Geometry
209
+ factory_ = ar_class_.rgeo_factory_for_column(column_, :srid => input_.srid)
210
+ ::RGeo::Feature.cast(input_, factory_)
211
+ when ::String
212
+ marker_ = input_[4,1]
213
+ if marker_ == "\x00" || marker_ == "\x01"
214
+ factory_ = ar_class_.rgeo_factory_for_column(column_, :srid => input_[0,4].unpack(marker_ == "\x01" ? 'V' : 'N').first)
215
+ ::RGeo::WKRep::WKBParser.new(factory_).parse(input_[4..-1])
216
+ else
217
+ factory_ = ar_class_.rgeo_factory_for_column(column_)
218
+ ::RGeo::WKRep::WKTParser.new(factory_, :support_ewkt => true).parse(input_)
219
+ end
220
+ else
221
+ nil
222
+ end
223
+ end
224
+
225
+
226
+ end
227
+
228
+
229
+ end
230
+
231
+ end
232
+
233
+
234
+ end
data/test/tc_basic.rb ADDED
@@ -0,0 +1,171 @@
1
+ # -----------------------------------------------------------------------------
2
+ #
3
+ # Tests for the MysqlSpatial 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 MysqlSpatialAdapter # :nodoc:
43
+ module Tests # :nodoc:
44
+
45
+ class TestBasic < ::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
+ end
61
+ klass_
62
+ end
63
+
64
+
65
+ def test_create_simple_geometry
66
+ klass_ = create_ar_class
67
+ klass_.connection.create_table(:spatial_test) do |t_|
68
+ t_.column 'latlon', :geometry
69
+ end
70
+ assert_equal(::RGeo::Feature::Geometry, klass_.columns.last.geometric_type)
71
+ assert(klass_.cached_attributes.include?('latlon'))
72
+ end
73
+
74
+
75
+ def test_create_point_geometry
76
+ klass_ = create_ar_class
77
+ klass_.connection.create_table(:spatial_test) do |t_|
78
+ t_.column 'latlon', :point
79
+ end
80
+ assert_equal(::RGeo::Feature::Point, klass_.columns.last.geometric_type)
81
+ assert(klass_.cached_attributes.include?('latlon'))
82
+ end
83
+
84
+
85
+ def test_create_geometry_with_index
86
+ klass_ = create_ar_class
87
+ klass_.connection.create_table(:spatial_test, :options => 'ENGINE=MyISAM') do |t_|
88
+ t_.column 'latlon', :geometry, :null => false
89
+ end
90
+ klass_.connection.change_table(:spatial_test) do |t_|
91
+ t_.index([:latlon], :spatial => true)
92
+ end
93
+ assert(klass_.connection.indexes(:spatial_test).last.spatial)
94
+ end
95
+
96
+
97
+ def test_set_and_get_point
98
+ klass_ = populate_ar_class(:latlon_point)
99
+ obj_ = klass_.new
100
+ assert_nil(obj_.latlon)
101
+ obj_.latlon = @factory.point(1, 2)
102
+ assert_equal(@factory.point(1, 2), obj_.latlon)
103
+ assert_equal(4326, obj_.latlon.srid)
104
+ end
105
+
106
+
107
+ def test_set_and_get_point_from_wkt
108
+ klass_ = populate_ar_class(:latlon_point)
109
+ obj_ = klass_.new
110
+ assert_nil(obj_.latlon)
111
+ obj_.latlon = 'SRID=1000;POINT(1 2)'
112
+ assert_equal(@factory.point(1, 2), obj_.latlon)
113
+ assert_equal(1000, obj_.latlon.srid)
114
+ end
115
+
116
+
117
+ def test_save_and_load_point
118
+ klass_ = populate_ar_class(:latlon_point)
119
+ obj_ = klass_.new
120
+ obj_.latlon = @factory.point(1, 2)
121
+ obj_.save!
122
+ id_ = obj_.id
123
+ obj2_ = klass_.find(id_)
124
+ assert_equal(@factory.point(1, 2), obj2_.latlon)
125
+ assert_equal(4326, obj2_.latlon.srid)
126
+ end
127
+
128
+
129
+ def test_save_and_load_point_from_wkt
130
+ klass_ = populate_ar_class(:latlon_point)
131
+ obj_ = klass_.new
132
+ obj_.latlon = 'SRID=1000;POINT(1 2)'
133
+ obj_.save!
134
+ id_ = obj_.id
135
+ obj2_ = klass_.find(id_)
136
+ assert_equal(@factory.point(1, 2), obj2_.latlon)
137
+ assert_equal(1000, obj2_.latlon.srid)
138
+ end
139
+
140
+
141
+ def test_readme_example
142
+ klass_ = create_ar_class
143
+ klass_.connection.create_table(:spatial_test, :options => 'ENGINE=MyISAM') do |t_|
144
+ t_.column(:latlon, :point, :null => false)
145
+ t_.line_string(:path)
146
+ t_.geometry(:shape)
147
+ end
148
+ klass_.connection.change_table(:spatial_test) do |t_|
149
+ t_.index(:latlon, :spatial => true)
150
+ end
151
+ klass_.class_eval do
152
+ self.rgeo_factory_generator = ::RGeo::Geos.method(:factory)
153
+ set_rgeo_factory_for_column(:latlon, ::RGeo::Geographic.spherical_factory)
154
+ end
155
+ rec_ = klass_.new
156
+ rec_.latlon = 'POINT(-122 47)'
157
+ loc_ = rec_.latlon
158
+ assert_equal(47, loc_.latitude)
159
+ rec_.shape = loc_
160
+ assert_equal(true, ::RGeo::Geos.is_geos?(rec_.shape))
161
+ end
162
+
163
+
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+ end
170
+ end
171
+ end
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-mysqlspatial-adapter
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Daniel Azuma
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-12-07 00:00:00 -08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rgeo-activerecord
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 2
31
+ - 0
32
+ version: 0.2.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: mysql
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 2
45
+ - 8
46
+ - 1
47
+ version: 2.8.1
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ description: This is an ActiveRecord connection adapter for MySQL Spatial Extensions. It is based on the stock MySQL adapter, but provides built-in support for spatial columns. It uses the RGeo library to represent spatial data in Ruby.
51
+ email: dazuma@gmail.com
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files:
57
+ - History.rdoc
58
+ - README.rdoc
59
+ files:
60
+ - lib/active_record/connection_adapters/mysqlspatial_adapter.rb
61
+ - History.rdoc
62
+ - README.rdoc
63
+ - test/tc_basic.rb
64
+ - Version
65
+ has_rdoc: true
66
+ homepage: http://virtuoso.rubyforge.org/activerecord-mysqlspatial-adapter
67
+ licenses: []
68
+
69
+ post_install_message:
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 1
81
+ - 8
82
+ - 7
83
+ version: 1.8.7
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ segments:
90
+ - 0
91
+ version: "0"
92
+ requirements: []
93
+
94
+ rubyforge_project: virtuoso
95
+ rubygems_version: 1.3.7
96
+ signing_key:
97
+ specification_version: 3
98
+ summary: An ActiveRecord adapter for MySQL Spatial Extensions, based on RGeo.
99
+ test_files:
100
+ - test/tc_basic.rb