rgeo-activerecord 0.3.4 → 0.4.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 +6 -0
- data/README.rdoc +4 -1
- data/Version +1 -1
- data/lib/rgeo/active_record/adapter_test_helper.rb +10 -1
- data/lib/rgeo/active_record/ar_factory_settings.rb +143 -33
- data/lib/rgeo/active_record/arel_spatial_queries.rb +82 -122
- data/lib/rgeo/active_record/common_adapter_elements.rb +58 -123
- metadata +4 -4
data/History.rdoc
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
=== 0.4.0 / 2011-08-15
|
2
|
+
|
3
|
+
* Several compatibility fixes for Rails 3.1.
|
4
|
+
* Revamped factory setter mechanism with a system that should be more robust.
|
5
|
+
* Some general code cleanup.
|
6
|
+
|
1
7
|
=== 0.3.4 / 2011-05-23
|
2
8
|
|
3
9
|
* Uses the mixin feature of RGeo 0.3 to add an as_json method to all geometry objects. This should allow ActiveRecord's JSON serialization to function for models with geometry fields. (Reported by thenetduck and tonyc on github.)
|
data/README.rdoc
CHANGED
@@ -23,8 +23,9 @@ need to interact directly with this library.
|
|
23
23
|
RGeo::ActiveRecord has the following requirements:
|
24
24
|
|
25
25
|
* Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
|
26
|
-
* \RGeo 0.3.
|
26
|
+
* \RGeo 0.3.2 or later.
|
27
27
|
* \ActiveRecord 3.0.3 or later. Earlier versions will not work.
|
28
|
+
Appears to be compatible with Rails 3.1rc5.
|
28
29
|
* \Arel 2.0.6 or later. Earlier versions will not work.
|
29
30
|
|
30
31
|
Generally, \ActiveRecord adapters which depend on this module should be
|
@@ -58,6 +59,8 @@ Contributions are welcome. Fork the project on Github.
|
|
58
59
|
|
59
60
|
Report bugs on Github issues at http://github.org/dazuma/rgeo-activerecord/issues
|
60
61
|
|
62
|
+
Support available on the rgeo-users google group at http://groups.google.com/group/rgeo-users
|
63
|
+
|
61
64
|
Contact the author at dazuma at gmail dot com.
|
62
65
|
|
63
66
|
=== Acknowledgments
|
data/Version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -106,7 +106,7 @@ module RGeo
|
|
106
106
|
# cartesian factory) and @geographic_factory (a spherical factory)
|
107
107
|
|
108
108
|
def setup
|
109
|
-
@factory = ::RGeo::Cartesian.preferred_factory(:srid =>
|
109
|
+
@factory = ::RGeo::Cartesian.preferred_factory(:srid => 3785)
|
110
110
|
@geographic_factory = ::RGeo::Geographic.spherical_factory(:srid => 4326)
|
111
111
|
cleanup_tables
|
112
112
|
end
|
@@ -129,6 +129,15 @@ module RGeo
|
|
129
129
|
if klass_.connection.tables.include?('spatial_test')
|
130
130
|
klass_.connection.drop_table(:spatial_test)
|
131
131
|
end
|
132
|
+
# Clear any RGeo factory settings.
|
133
|
+
klass_.connection_pool.rgeo_factory_settings.clear!
|
134
|
+
# Rails 3.1 does more aggressive caching than 3.0 did; need to
|
135
|
+
# clear those because the next test might assume different data.
|
136
|
+
if klass_.connection_pool.respond_to?(:clear_cache!)
|
137
|
+
klass_.connection_pool.clear_cache!
|
138
|
+
klass_.connection.clear_query_cache
|
139
|
+
klass_.connection.clear_cache!
|
140
|
+
end
|
132
141
|
end
|
133
142
|
|
134
143
|
|
@@ -37,41 +37,128 @@
|
|
37
37
|
require 'active_record'
|
38
38
|
|
39
39
|
|
40
|
-
module
|
40
|
+
module RGeo
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
# attributes. These attributes are inherited by subclasses, and can
|
45
|
-
# be overridden in subclasses.
|
46
|
-
#
|
47
|
-
# === ActiveRecord::Base::rgeo_factory_generator
|
48
|
-
#
|
49
|
-
# The value of this attribute is a RGeo::Feature::FactoryGenerator
|
50
|
-
# that is used to generate the proper factory when loading geometry
|
51
|
-
# objects from the database. For example, if the data being loaded
|
52
|
-
# has M but not Z coordinates, and an embedded SRID, then this
|
53
|
-
# FactoryGenerator is called with the appropriate configuration to
|
54
|
-
# obtain a factory with those properties. This factory is the one
|
55
|
-
# associated with the actual geometry properties of the ActiveRecord
|
56
|
-
# object. The result of this generator can be overridden by setting
|
57
|
-
# an explicit factory for a given class and column using the
|
58
|
-
# column_rgeo_factory method.
|
59
|
-
|
60
|
-
class Base
|
42
|
+
module ActiveRecord
|
43
|
+
|
61
44
|
|
45
|
+
# The default factory generator for ActiveRecord::Base.
|
62
46
|
|
63
|
-
|
64
|
-
|
47
|
+
DEFAULT_FACTORY_GENERATOR = ::Proc.new do |config_|
|
48
|
+
if config_.delete(:geographic)
|
49
|
+
::RGeo::Geographic.spherical_factory(config_)
|
50
|
+
else
|
51
|
+
::RGeo::Cartesian.preferred_factory(config_)
|
52
|
+
end
|
53
|
+
end
|
65
54
|
|
66
55
|
|
67
|
-
|
56
|
+
# An object that manages the RGeo factories for a ConnectionPool.
|
57
|
+
|
58
|
+
class RGeoFactorySettings
|
59
|
+
|
60
|
+
def initialize # :nodoc:
|
61
|
+
@factory_generators = {}
|
62
|
+
@column_factories = {}
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# Get the default factory generator for the given table
|
67
|
+
|
68
|
+
def get_factory_generator(table_name_)
|
69
|
+
@factory_generators[table_name_.to_s] || ::RGeo::ActiveRecord::DEFAULT_FACTORY_GENERATOR
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Set the default factory generator for the given table
|
74
|
+
|
75
|
+
def set_factory_generator(table_name_, gen_)
|
76
|
+
@factory_generators[table_name_.to_s] = gen_
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# Get the factory or factory generator for the given table name
|
81
|
+
# and column name.
|
82
|
+
|
83
|
+
def get_column_factory(table_name_, column_name_, params_=nil)
|
84
|
+
table_name_ = table_name_.to_s
|
85
|
+
column_name_ = column_name_.to_s
|
86
|
+
result_ = (@column_factories[table_name_] ||= {})[column_name_] ||
|
87
|
+
@factory_generators[table_name_] || ::RGeo::ActiveRecord::DEFAULT_FACTORY_GENERATOR
|
88
|
+
if params_ && !result_.kind_of?(::RGeo::Feature::Factory::Instance)
|
89
|
+
result_ = result_.call(params_)
|
90
|
+
end
|
91
|
+
result_
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# Set the factory or factory generator for the given table name
|
96
|
+
# and column name.
|
97
|
+
|
98
|
+
def set_column_factory(table_name_, column_name_, factory_)
|
99
|
+
(@column_factories[table_name_.to_s] ||= {})[column_name_.to_s] = factory_
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# Clear settings for the given table name, or for all tables
|
104
|
+
|
105
|
+
def clear!(table_name_=nil)
|
106
|
+
if table_name_
|
107
|
+
table_name_ = table_name_.to_s
|
108
|
+
@factory_generators.delete(table_name_)
|
109
|
+
@column_factories.delete(table_name_)
|
110
|
+
else
|
111
|
+
@factory_generators.clear
|
112
|
+
@column_factories.clear
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Additional class methods on ::ActiveRecord::Base that provide
|
121
|
+
# a way to control the RGeo factory used for ActiveRecord objects.
|
122
|
+
|
123
|
+
module ActiveRecordBaseFactorySettings
|
124
|
+
|
125
|
+
|
126
|
+
# Return the RGeoFactorySettings object associated with this
|
127
|
+
# class's connection.
|
128
|
+
|
129
|
+
def rgeo_factory_settings
|
130
|
+
connection_pool.rgeo_factory_settings
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
# The value of this attribute is a RGeo::Feature::FactoryGenerator
|
135
|
+
# that is used to generate the proper factory when loading geometry
|
136
|
+
# objects from the database. For example, if the data being loaded
|
137
|
+
# has M but not Z coordinates, and an embedded SRID, then this
|
138
|
+
# FactoryGenerator is called with the appropriate configuration to
|
139
|
+
# obtain a factory with those properties. This factory is the one
|
140
|
+
# associated with the actual geometry properties of the ActiveRecord
|
141
|
+
# object. The result of this generator can be overridden by setting
|
142
|
+
# an explicit factory for a given class and column using the
|
143
|
+
# column_rgeo_factory method.
|
144
|
+
|
145
|
+
def rgeo_factory_generator
|
146
|
+
rgeo_factory_settings.get_factory_generator(table_name)
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
# Set the rgeo_factory_generator attribute
|
151
|
+
|
152
|
+
def rgeo_factory_generator=(gen_)
|
153
|
+
rgeo_factory_settings.set_factory_generator(table_name, gen_)
|
154
|
+
end
|
68
155
|
|
69
156
|
|
70
157
|
# This is a convenient way to set the rgeo_factory_generator by
|
71
158
|
# passing a block.
|
72
159
|
|
73
160
|
def to_generate_rgeo_factory(&block_)
|
74
|
-
|
161
|
+
rgeo_factory_settings.set_factory_generator(table_name, block_)
|
75
162
|
end
|
76
163
|
|
77
164
|
|
@@ -79,9 +166,8 @@ module ActiveRecord
|
|
79
166
|
# column name. This setting, if present, overrides the result of the
|
80
167
|
# rgeo_factory_generator.
|
81
168
|
|
82
|
-
def set_rgeo_factory_for_column(
|
83
|
-
|
84
|
-
@rgeo_factory_for_column[column_.to_sym] = factory_
|
169
|
+
def set_rgeo_factory_for_column(column_name_, factory_)
|
170
|
+
rgeo_factory_settings.set_column_factory(table_name, column_name_, factory_)
|
85
171
|
end
|
86
172
|
|
87
173
|
|
@@ -94,18 +180,42 @@ module ActiveRecord
|
|
94
180
|
# rgeo_factory_generator for this class.
|
95
181
|
|
96
182
|
def rgeo_factory_for_column(column_, params_=nil)
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
183
|
+
rgeo_factory_settings.get_column_factory(table_name, column_name_, params_)
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
end
|
188
|
+
|
189
|
+
::ActiveRecord::Base.extend(ActiveRecordBaseFactorySettings)
|
190
|
+
|
191
|
+
|
192
|
+
# :stopdoc:
|
193
|
+
|
194
|
+
|
195
|
+
# Patch for connection pool to track geo factories per table name
|
196
|
+
|
197
|
+
::ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
|
198
|
+
|
199
|
+
def rgeo_factory_settings
|
200
|
+
@_rgeo_factory_settings ||= RGeoFactorySettings.new
|
201
|
+
end
|
202
|
+
|
203
|
+
private
|
204
|
+
alias_method :new_connection_without_rgeo_modification, :new_connection
|
205
|
+
def new_connection
|
206
|
+
result_ = new_connection_without_rgeo_modification
|
207
|
+
if result_.respond_to?(:set_rgeo_factory_settings)
|
208
|
+
result_.set_rgeo_factory_settings(rgeo_factory_settings)
|
101
209
|
end
|
102
210
|
result_
|
103
211
|
end
|
104
212
|
|
105
|
-
|
106
213
|
end
|
107
214
|
|
215
|
+
|
216
|
+
# :startdoc:
|
217
|
+
|
218
|
+
|
108
219
|
end
|
109
220
|
|
110
|
-
|
111
221
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# -----------------------------------------------------------------------------
|
2
2
|
#
|
3
|
-
#
|
3
|
+
# Various Arel hacks to support spatial queries
|
4
4
|
#
|
5
5
|
# -----------------------------------------------------------------------------
|
6
6
|
# Copyright 2010 Daniel Azuma
|
@@ -72,30 +72,6 @@ module RGeo
|
|
72
72
|
end
|
73
73
|
|
74
74
|
|
75
|
-
# Returns a true value if the given node is of spatial type-- that
|
76
|
-
# is, if it is a spatial literal or a reference to a spatial
|
77
|
-
# attribute.
|
78
|
-
|
79
|
-
def node_has_spatial_type?(node_)
|
80
|
-
case node_
|
81
|
-
when ::Arel::Attribute
|
82
|
-
@connection.instance_variable_set(:@_getting_columns, true)
|
83
|
-
begin
|
84
|
-
col_ = node_.column
|
85
|
-
col_ && col_.respond_to?(:spatial?) && col_.spatial? ? true : false
|
86
|
-
ensure
|
87
|
-
@connection.instance_variable_set(:@_getting_columns, false)
|
88
|
-
end
|
89
|
-
when ::RGeo::ActiveRecord::SpatialNamedFunction
|
90
|
-
node_.spatial_result?
|
91
|
-
when ::RGeo::ActiveRecord::SpatialConstantNode, ::RGeo::Feature::Instance
|
92
|
-
true
|
93
|
-
else
|
94
|
-
false
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
75
|
# Generates SQL for a spatial node.
|
100
76
|
# The node must be a string (in which case it is treated as WKT),
|
101
77
|
# an RGeo feature, or a spatial attribute.
|
@@ -112,71 +88,52 @@ module RGeo
|
|
112
88
|
end
|
113
89
|
|
114
90
|
|
115
|
-
def _check_equality_for_rgeo(node_, negate_) # :nodoc:
|
116
|
-
left_ = node_.left
|
117
|
-
right_ = node_.right
|
118
|
-
if !@connection.instance_variable_get(:@_getting_columns) && !right_.nil? && (node_has_spatial_type?(left_) || node_has_spatial_type?(right_))
|
119
|
-
"#{negate_ ? 'NOT ' : ''}#{st_func('ST_Equals')}(#{visit_in_spatial_context(left_)}, #{visit_in_spatial_context(right_)})"
|
120
|
-
else
|
121
|
-
false
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
# Override equality nodes to use the ST_Equals function if at least
|
127
|
-
# one of the operands is a spatial node.
|
128
|
-
|
129
|
-
def visit_Arel_Nodes_Equality(node_)
|
130
|
-
_check_equality_for_rgeo(node_, false) || super
|
131
|
-
end
|
132
|
-
|
133
|
-
|
134
|
-
# Override equality nodes to use the ST_Equals function if at least
|
135
|
-
# one of the operands is a spatial node.
|
136
|
-
|
137
|
-
def visit_Arel_Nodes_NotEqual(node_)
|
138
|
-
_check_equality_for_rgeo(node_, true) || super
|
139
|
-
end
|
140
|
-
|
141
91
|
end
|
142
92
|
|
143
93
|
|
144
|
-
|
145
|
-
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
# :stopdoc:
|
150
|
-
|
151
|
-
|
152
|
-
# This node wraps an RGeo feature and gives it spatial expression
|
153
|
-
# constructors.
|
154
|
-
|
155
|
-
module RGeo
|
156
|
-
module ActiveRecord
|
94
|
+
# This node wraps an RGeo feature and gives it spatial expression
|
95
|
+
# constructors.
|
157
96
|
|
158
97
|
class SpatialConstantNode
|
159
98
|
|
160
99
|
include ::RGeo::ActiveRecord::SpatialExpressions
|
161
100
|
|
101
|
+
|
102
|
+
# The delegate should be the RGeo feature.
|
103
|
+
|
162
104
|
def initialize(delegate_)
|
163
105
|
@delegate = delegate_
|
164
106
|
end
|
165
107
|
|
108
|
+
|
109
|
+
# Return the RGeo feature
|
110
|
+
|
166
111
|
attr_reader :delegate
|
167
112
|
|
113
|
+
|
168
114
|
end
|
169
115
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
#
|
175
|
-
#
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
116
|
+
|
117
|
+
# :stopdoc:
|
118
|
+
|
119
|
+
|
120
|
+
# Hack Arel Attributes dispatcher to recognize geometry columns.
|
121
|
+
# This is deprecated but necessary to support legacy Arel versions.
|
122
|
+
|
123
|
+
if ::Arel::Attributes.method_defined?(:for)
|
124
|
+
module ArelAttributesLegacyClassMethods
|
125
|
+
def for(column_)
|
126
|
+
column_.type == :spatial ? Attribute : super
|
127
|
+
end
|
128
|
+
end
|
129
|
+
::Arel::Attributes.extend(ArelAttributesLegacyClassMethods)
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# Make sure the standard Arel visitors can handle RGeo feature objects
|
134
|
+
# by default.
|
135
|
+
|
136
|
+
::Arel::Visitors::Visitor.class_eval do
|
180
137
|
def visit_RGeo_ActiveRecord_SpatialConstantNode(node_)
|
181
138
|
if respond_to?(:visit_in_spatial_context)
|
182
139
|
visit_in_spatial_context(node_.delegate)
|
@@ -185,66 +142,69 @@ module Arel
|
|
185
142
|
end
|
186
143
|
end
|
187
144
|
end
|
188
|
-
|
145
|
+
::Arel::Visitors::Dot.class_eval do
|
189
146
|
alias :visit_RGeo_Feature_Instance :visit_String
|
190
147
|
end
|
191
|
-
|
148
|
+
::Arel::Visitors::DepthFirst.class_eval do
|
192
149
|
alias :visit_RGeo_Feature_Instance :terminal
|
193
150
|
end
|
194
|
-
|
151
|
+
::Arel::Visitors::ToSql.class_eval do
|
195
152
|
alias :visit_RGeo_Feature_Instance :visit_String
|
196
153
|
end
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
|
201
|
-
# Add tools to build spatial structures in the AST.
|
202
|
-
# This stuff requires Arel 2.1 or later.
|
203
|
-
|
204
|
-
if defined?(::Arel::Nodes::NamedFunction)
|
205
|
-
|
206
|
-
# Allow chaining of predications from named functions
|
207
|
-
# (Hack because Arel doesn't do this but should.)
|
208
|
-
::Arel::Nodes::NamedFunction.class_eval do
|
209
|
-
include ::Arel::Predications unless include?(::Arel::Predications)
|
210
|
-
end
|
211
|
-
|
212
|
-
# Allow chaining of spatial expressions from attributes
|
213
|
-
::Arel::Attribute.class_eval do
|
214
|
-
include ::RGeo::ActiveRecord::SpatialExpressions
|
215
|
-
end
|
216
|
-
|
217
|
-
|
218
|
-
# A NamedFunction subclass that keeps track of the spatial-ness of
|
219
|
-
# the arguments and return values, so that it can provide context to
|
220
|
-
# visitors that want to interpret syntax differently when dealing with
|
221
|
-
# spatial elements.
|
222
|
-
|
223
|
-
class ::RGeo::ActiveRecord::SpatialNamedFunction < ::Arel::Nodes::NamedFunction
|
224
154
|
|
225
|
-
include ::RGeo::ActiveRecord::SpatialExpressions
|
226
155
|
|
227
|
-
|
228
|
-
|
229
|
-
@spatial_flags = spatial_flags_
|
230
|
-
end
|
156
|
+
# Add tools to build spatial structures in the AST.
|
157
|
+
# This stuff requires Arel 2.1 or later.
|
231
158
|
|
232
|
-
|
233
|
-
|
159
|
+
if defined?(::Arel::Nodes::NamedFunction)
|
160
|
+
|
161
|
+
# Allow chaining of predications from named functions
|
162
|
+
# (Some older versions of Arel didn't do this.)
|
163
|
+
::Arel::Nodes::NamedFunction.class_eval do
|
164
|
+
include ::Arel::Predications unless include?(::Arel::Predications)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Allow chaining of spatial expressions from attributes
|
168
|
+
::Arel::Attribute.class_eval do
|
169
|
+
include ::RGeo::ActiveRecord::SpatialExpressions
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
# A NamedFunction subclass that keeps track of the spatial-ness of
|
174
|
+
# the arguments and return values, so that it can provide context to
|
175
|
+
# visitors that want to interpret syntax differently when dealing with
|
176
|
+
# spatial elements.
|
177
|
+
|
178
|
+
class SpatialNamedFunction < ::Arel::Nodes::NamedFunction
|
179
|
+
|
180
|
+
include ::RGeo::ActiveRecord::SpatialExpressions
|
181
|
+
|
182
|
+
def initialize(name_, expr_, spatial_flags_=[], aliaz_=nil)
|
183
|
+
super(name_, expr_, aliaz_)
|
184
|
+
@spatial_flags = spatial_flags_
|
185
|
+
end
|
186
|
+
|
187
|
+
def spatial_result?
|
188
|
+
@spatial_flags.first
|
189
|
+
end
|
190
|
+
|
191
|
+
def spatial_argument?(index_)
|
192
|
+
@spatial_flags[index_+1]
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
else
|
198
|
+
|
199
|
+
# A dummy SpatialNamedFunction for pre-2.1 versions of Arel.
|
200
|
+
class SpatialNamedFunction; end
|
201
|
+
|
234
202
|
end
|
235
203
|
|
236
|
-
|
237
|
-
|
238
|
-
|
204
|
+
|
205
|
+
# :startdoc:
|
206
|
+
|
239
207
|
|
240
208
|
end
|
241
209
|
|
242
|
-
else
|
243
|
-
|
244
|
-
# A dummy SpatialNamedFunction for pre-2.1 versions of Arel.
|
245
|
-
class ::RGeo::ActiveRecord::SpatialNamedFunction; end
|
246
|
-
|
247
210
|
end
|
248
|
-
|
249
|
-
|
250
|
-
# :startdoc:
|
@@ -34,6 +34,11 @@
|
|
34
34
|
;
|
35
35
|
|
36
36
|
|
37
|
+
require 'active_record'
|
38
|
+
|
39
|
+
::ActiveRecord::ConnectionAdapters::AbstractAdapter
|
40
|
+
|
41
|
+
|
37
42
|
module RGeo
|
38
43
|
|
39
44
|
module ActiveRecord
|
@@ -43,29 +48,18 @@ module RGeo
|
|
43
48
|
# databases. Individual adapters may add to or override this list.
|
44
49
|
|
45
50
|
DEFAULT_SPATIAL_COLUMN_CONSTRUCTORS = {
|
46
|
-
:spatial => {:type => 'geometry'},
|
47
|
-
:geometry => {},
|
48
|
-
:point => {},
|
49
|
-
:line_string => {},
|
50
|
-
:polygon => {},
|
51
|
-
:geometry_collection => {},
|
52
|
-
:multi_line_string => {},
|
53
|
-
:multi_point => {},
|
54
|
-
:multi_polygon => {},
|
51
|
+
:spatial => {:type => 'geometry'}.freeze,
|
52
|
+
:geometry => {}.freeze,
|
53
|
+
:point => {}.freeze,
|
54
|
+
:line_string => {}.freeze,
|
55
|
+
:polygon => {}.freeze,
|
56
|
+
:geometry_collection => {}.freeze,
|
57
|
+
:multi_line_string => {}.freeze,
|
58
|
+
:multi_point => {}.freeze,
|
59
|
+
:multi_polygon => {}.freeze,
|
55
60
|
}.freeze
|
56
61
|
|
57
62
|
|
58
|
-
# The default factory generator for ActiveRecord::Base.
|
59
|
-
|
60
|
-
DEFAULT_FACTORY_GENERATOR = ::Proc.new do |config_|
|
61
|
-
if config_.delete(:geographic)
|
62
|
-
::RGeo::Geographic.spherical_factory(config_)
|
63
|
-
else
|
64
|
-
::RGeo::Cartesian.preferred_factory(config_)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
|
69
63
|
# Index definition struct with a spatial flag field.
|
70
64
|
|
71
65
|
class SpatialIndexDefinition < ::Struct.new(:table, :name, :unique, :columns, :lengths, :spatial)
|
@@ -89,46 +83,12 @@ module RGeo
|
|
89
83
|
end
|
90
84
|
|
91
85
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
# Make sure a few things are autoloaded before we modify them.
|
101
|
-
::Arel::Attributes
|
102
|
-
::ActiveRecord::ConnectionAdapters::AbstractAdapter
|
103
|
-
::ActiveRecord::ConnectionAdapters::TableDefinition
|
104
|
-
::ActiveRecord::ConnectionAdapters::Table
|
105
|
-
::ActiveRecord::Base
|
106
|
-
::ActiveRecord::SchemaDumper
|
107
|
-
|
108
|
-
|
109
|
-
# Hack Arel Attributes dispatcher to recognize geometry columns.
|
110
|
-
# This is deprecated but necessary to support legacy Arel versions.
|
111
|
-
|
112
|
-
module Arel
|
113
|
-
module Attributes
|
114
|
-
class << self
|
115
|
-
if method_defined?(:for)
|
116
|
-
alias_method :for_without_rgeo_modification, :for
|
117
|
-
def for(column_)
|
118
|
-
column_.type == :spatial ? Attribute : for_without_rgeo_modification(column_)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
# Provide methods for each geometric subtype during table definitions.
|
127
|
-
|
128
|
-
module ActiveRecord
|
129
|
-
module ConnectionAdapters
|
130
|
-
class TableDefinition
|
131
|
-
|
86
|
+
# :stopdoc:
|
87
|
+
|
88
|
+
|
89
|
+
# Provide methods for each geometric subtype during table definitions.
|
90
|
+
|
91
|
+
::ActiveRecord::ConnectionAdapters::TableDefinition.class_eval do
|
132
92
|
alias_method :method_missing_without_rgeo_modification, :method_missing
|
133
93
|
def method_missing(method_name_, *args_, &block_)
|
134
94
|
if @base.respond_to?(:spatial_column_constructor) && (info_ = @base.spatial_column_constructor(method_name_))
|
@@ -142,18 +102,12 @@ module ActiveRecord
|
|
142
102
|
method_missing_without_rgeo_modification(method_name_, *args_, &block_)
|
143
103
|
end
|
144
104
|
end
|
145
|
-
|
146
105
|
end
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
module ActiveRecord
|
154
|
-
module ConnectionAdapters
|
155
|
-
class Table
|
156
|
-
|
106
|
+
|
107
|
+
|
108
|
+
# Provide methods for each geometric subtype during table changes.
|
109
|
+
|
110
|
+
::ActiveRecord::ConnectionAdapters::Table.class_eval do
|
157
111
|
alias_method :method_missing_without_rgeo_modification, :method_missing
|
158
112
|
def method_missing(method_name_, *args_, &block_)
|
159
113
|
if @base.respond_to?(:spatial_column_constructor) && (info_ = @base.spatial_column_constructor(method_name_))
|
@@ -167,62 +121,43 @@ module ActiveRecord
|
|
167
121
|
method_missing_without_rgeo_modification(method_name_, *args_, &block_)
|
168
122
|
end
|
169
123
|
end
|
170
|
-
|
171
124
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
125
|
+
|
126
|
+
|
127
|
+
# Hack schema dumper to output spatial index flag
|
128
|
+
|
129
|
+
::ActiveRecord::SchemaDumper.class_eval do
|
130
|
+
private
|
131
|
+
def indexes(table_, stream_)
|
132
|
+
if (indexes_ = @connection.indexes(table_)).any?
|
133
|
+
add_index_statements_ = indexes_.map do |index_|
|
134
|
+
statement_parts_ = [
|
135
|
+
('add_index ' + index_.table.inspect),
|
136
|
+
index_.columns.inspect,
|
137
|
+
(':name => ' + index_.name.inspect),
|
138
|
+
]
|
139
|
+
statement_parts_ << ':unique => true' if index_.unique
|
140
|
+
statement_parts_ << ':spatial => true' if index_.respond_to?(:spatial) && index_.spatial
|
141
|
+
index_lengths_ = (index_.lengths || []).compact
|
142
|
+
statement_parts_ << (':length => ' + ::Hash[*index_.columns.zip(index_.lengths).flatten].inspect) unless index_lengths_.empty?
|
143
|
+
' ' + statement_parts_.join(', ')
|
188
144
|
end
|
145
|
+
stream_.puts add_index_statements_.sort.join("\n")
|
146
|
+
stream_.puts
|
189
147
|
end
|
190
|
-
@columns
|
191
|
-
end
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
|
197
|
-
# Hack schema dumper to output spatial index flag
|
198
|
-
|
199
|
-
module ActiveRecord
|
200
|
-
class SchemaDumper
|
201
|
-
private
|
202
|
-
def indexes(table_, stream_)
|
203
|
-
if (indexes_ = @connection.indexes(table_)).any?
|
204
|
-
add_index_statements_ = indexes_.map do |index_|
|
205
|
-
statement_parts_ = [ ('add_index ' + index_.table.inspect) ]
|
206
|
-
statement_parts_ << index_.columns.inspect
|
207
|
-
statement_parts_ << (':name => ' + index_.name.inspect)
|
208
|
-
statement_parts_ << ':unique => true' if index_.unique
|
209
|
-
statement_parts_ << ':spatial => true' if index_.respond_to?(:spatial) && index_.spatial
|
210
|
-
index_lengths_ = index_.lengths.compact if index_.lengths.is_a?(::Array)
|
211
|
-
statement_parts_ << (':length => ' + ::Hash[*index_.columns.zip(index_.lengths).flatten].inspect) if index_lengths_.present?
|
212
|
-
' ' + statement_parts_.join(', ')
|
213
|
-
end
|
214
|
-
stream_.puts add_index_statements_.sort.join("\n")
|
215
|
-
stream_.puts
|
216
148
|
end
|
217
149
|
end
|
150
|
+
|
151
|
+
|
152
|
+
# Tell ActiveRecord to cache spatial attribute values so they don't get
|
153
|
+
# re-parsed on every access.
|
154
|
+
|
155
|
+
::ActiveRecord::Base.attribute_types_cached_by_default << :spatial
|
156
|
+
|
157
|
+
|
158
|
+
# :startdoc:
|
159
|
+
|
160
|
+
|
218
161
|
end
|
162
|
+
|
219
163
|
end
|
220
|
-
|
221
|
-
|
222
|
-
# Tell ActiveRecord to cache spatial attribute values so they don't get
|
223
|
-
# re-parsed on every access.
|
224
|
-
|
225
|
-
::ActiveRecord::Base.attribute_types_cached_by_default << :spatial
|
226
|
-
|
227
|
-
|
228
|
-
# :startdoc:
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: rgeo-activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.4.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Daniel Azuma
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-08-15 00:00:00 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rgeo
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ">="
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 0.3.
|
23
|
+
version: 0.3.2
|
24
24
|
type: :runtime
|
25
25
|
version_requirements: *id001
|
26
26
|
- !ruby/object:Gem::Dependency
|
@@ -91,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
91
|
requirements: []
|
92
92
|
|
93
93
|
rubyforge_project: virtuoso
|
94
|
-
rubygems_version: 1.8.
|
94
|
+
rubygems_version: 1.8.7
|
95
95
|
signing_key:
|
96
96
|
specification_version: 3
|
97
97
|
summary: An RGeo module providing spatial extensions to ActiveRecord.
|