rgeo-activerecord 0.6.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,44 +1,5 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # Various Arel hacks to support spatial queries
4
- #
5
- # -----------------------------------------------------------------------------
6
- # Copyright 2010-2012 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
1
  module RGeo
38
-
39
2
  module ActiveRecord
40
-
41
-
42
3
  # A set of common Arel visitor hacks for spatial ToSql visitors.
43
4
  # Generally, a spatial ActiveRecord adapter should provide a custom
44
5
  # ToSql Arel visitor that includes and customizes this module.
@@ -47,7 +8,6 @@ module RGeo
47
8
 
48
9
  module SpatialToSql
49
10
 
50
-
51
11
  # Map a standard OGC SQL function name to the actual name used by
52
12
  # a particular database. This method should take a name and
53
13
  # return either the changed name or the original name.
@@ -56,7 +16,6 @@ module RGeo
56
16
  standard_name_
57
17
  end
58
18
 
59
-
60
19
  # Visit the SpatialNamedFunction node. This operates similarly to
61
20
  # the standard NamedFunction node, but it performs function name
62
21
  # mapping for the database, and it also uses the type information
@@ -71,11 +30,9 @@ module RGeo
71
30
  "#{name_}(#{node_.distinct ? 'DISTINCT ' : ''}#{exprs_.join(', ')})#{node_.alias ? " AS #{visit(node_.alias, *args)}" : ''}"
72
31
  end
73
32
 
74
-
75
33
  # Generates SQL for a spatial node.
76
34
  # The node must be a string (in which case it is treated as WKT),
77
35
  # an RGeo feature, or a spatial attribute.
78
-
79
36
  def visit_in_spatial_context(node_, *args)
80
37
  case node_
81
38
  when ::String
@@ -88,50 +45,24 @@ module RGeo
88
45
  visit(node_, *args)
89
46
  end
90
47
  end
91
-
92
-
93
48
  end
94
49
 
95
-
96
50
  # This node wraps an RGeo feature and gives it spatial expression
97
51
  # constructors.
98
-
99
52
  class SpatialConstantNode
100
-
101
53
  include ::RGeo::ActiveRecord::SpatialExpressions
102
54
 
103
-
104
55
  # The delegate should be the RGeo feature.
105
-
106
56
  def initialize(delegate_)
107
57
  @delegate = delegate_
108
58
  end
109
59
 
110
-
111
60
  # Return the RGeo feature
112
-
113
61
  attr_reader :delegate
114
-
115
-
116
62
  end
117
63
 
118
-
119
64
  # :stopdoc:
120
65
 
121
-
122
- # Hack Arel Attributes dispatcher to recognize geometry columns.
123
- # This is deprecated but necessary to support legacy Arel versions.
124
-
125
- if ::Arel::Attributes.method_defined?(:for)
126
- module ArelAttributesLegacyClassMethods
127
- def for(column_)
128
- column_.type == :spatial ? Attribute : super
129
- end
130
- end
131
- ::Arel::Attributes.extend(ArelAttributesLegacyClassMethods)
132
- end
133
-
134
-
135
66
  # Make sure the standard Arel visitors can handle RGeo feature objects
136
67
  # by default.
137
68
 
@@ -158,58 +89,29 @@ module RGeo
158
89
  end
159
90
 
160
91
 
161
- # Add tools to build spatial structures in the AST.
162
- # This stuff requires Arel 2.1 or later.
163
-
164
- if defined?(::Arel::Nodes::NamedFunction)
92
+ # A NamedFunction subclass that keeps track of the spatial-ness of
93
+ # the arguments and return values, so that it can provide context to
94
+ # visitors that want to interpret syntax differently when dealing with
95
+ # spatial elements.
96
+ class SpatialNamedFunction < ::Arel::Nodes::NamedFunction
97
+ include ::RGeo::ActiveRecord::SpatialExpressions
165
98
 
166
- # Allow chaining of predications from named functions
167
- # (Some older versions of Arel didn't do this.)
168
- ::Arel::Nodes::NamedFunction.class_eval do
169
- include ::Arel::Predications unless include?(::Arel::Predications)
99
+ def initialize(name_, expr_, spatial_flags_=[], aliaz_=nil)
100
+ super(name_, expr_, aliaz_)
101
+ @spatial_flags = spatial_flags_
170
102
  end
171
103
 
172
- # Allow chaining of spatial expressions from attributes
173
- ::Arel::Attribute.class_eval do
174
- include ::RGeo::ActiveRecord::SpatialExpressions
104
+ def spatial_result?
105
+ @spatial_flags.first
175
106
  end
176
107
 
177
-
178
- # A NamedFunction subclass that keeps track of the spatial-ness of
179
- # the arguments and return values, so that it can provide context to
180
- # visitors that want to interpret syntax differently when dealing with
181
- # spatial elements.
182
-
183
- class SpatialNamedFunction < ::Arel::Nodes::NamedFunction
184
-
185
- include ::RGeo::ActiveRecord::SpatialExpressions
186
-
187
- def initialize(name_, expr_, spatial_flags_=[], aliaz_=nil)
188
- super(name_, expr_, aliaz_)
189
- @spatial_flags = spatial_flags_
190
- end
191
-
192
- def spatial_result?
193
- @spatial_flags.first
194
- end
195
-
196
- def spatial_argument?(index_)
197
- @spatial_flags[index_+1]
198
- end
199
-
108
+ def spatial_argument?(index_)
109
+ @spatial_flags[index_+1]
200
110
  end
201
111
 
202
- else
203
-
204
- # A dummy SpatialNamedFunction for pre-2.1 versions of Arel.
205
- class SpatialNamedFunction; end
206
-
207
112
  end
208
113
 
209
-
210
114
  # :startdoc:
211
115
 
212
-
213
116
  end
214
-
215
117
  end
@@ -1,55 +1,10 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # Common tools for spatial adapters for ActiveRecord
4
- #
5
- # -----------------------------------------------------------------------------
6
- # Copyright 2010-2012 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 'active_support/core_ext/class' # Workaround for a missing require in ActiveRecord 3.2.1
38
- require 'active_record'
39
-
40
- # Force AbstractAdapter to autoload
41
- if ::ActiveRecord::ConnectionAdapters::AbstractAdapter
42
- end
43
-
1
+ # autoload AbstractAdapter
2
+ ::ActiveRecord::ConnectionAdapters::AbstractAdapter
44
3
 
45
4
  module RGeo
46
-
47
5
  module ActiveRecord
48
-
49
-
50
6
  # Some default column constructors specifications for most spatial
51
7
  # databases. Individual adapters may add to or override this list.
52
-
53
8
  DEFAULT_SPATIAL_COLUMN_CONSTRUCTORS = {
54
9
  :spatial => {:type => 'geometry'}.freeze,
55
10
  :geometry => {}.freeze,
@@ -62,13 +17,11 @@ module RGeo
62
17
  :multi_polygon => {}.freeze,
63
18
  }.freeze
64
19
 
65
-
66
20
  # Index definition struct with a spatial flag field.
67
21
 
68
22
  class SpatialIndexDefinition < Struct.new(:table, :name, :unique, :columns, :lengths, :orders, :where, :spatial)
69
23
  end
70
24
 
71
-
72
25
  # Returns a feature type module given a string type.
73
26
 
74
27
  def self.geometric_type_from_name(name_)
@@ -85,17 +38,18 @@ module RGeo
85
38
  end
86
39
  end
87
40
 
88
-
89
41
  # :stopdoc:
90
42
 
91
-
92
43
  # Provide methods for each geometric subtype during table definitions.
44
+ module GeoTableDefinitions
45
+ def self.included(base)
46
+ base.class_eval do
47
+ alias_method :method_missing_without_rgeo, :method_missing
48
+ alias_method :method_missing, :method_missing_with_rgeo
49
+ end
50
+ end
93
51
 
94
- ::ActiveRecord::ConnectionAdapters::TableDefinition.class_eval do
95
-
96
- alias_method :method_missing_without_rgeo_modification, :method_missing
97
-
98
- def method_missing(method_name_, *args_, &block_)
52
+ def method_missing_with_rgeo(method_name_, *args_, &block_)
99
53
  if @base.respond_to?(:spatial_column_constructor) && (info_ = @base.spatial_column_constructor(method_name_))
100
54
  info_ = info_.dup
101
55
  type_ = (info_.delete(:type) || method_name_).to_s
@@ -104,20 +58,24 @@ module RGeo
104
58
  column(name_, type_, opts_)
105
59
  end
106
60
  else
107
- method_missing_without_rgeo_modification(method_name_, *args_, &block_)
61
+ method_missing_without_rgeo(method_name_, *args_, &block_)
108
62
  end
109
63
  end
110
-
111
64
  end
112
65
 
66
+ ::ActiveRecord::ConnectionAdapters::TableDefinition.send :include, GeoTableDefinitions
113
67
 
114
- # Provide methods for each geometric subtype during table changes.
115
-
116
- ::ActiveRecord::ConnectionAdapters::Table.class_eval do
117
68
 
118
- alias_method :method_missing_without_rgeo_modification, :method_missing
69
+ # Provide methods for each geometric subtype during table changes.
70
+ module GeoConnectionAdapters
71
+ def self.included(base)
72
+ base.class_eval do
73
+ alias_method :method_missing_without_rgeo, :method_missing
74
+ alias_method :method_missing, :method_missing_with_rgeo
75
+ end
76
+ end
119
77
 
120
- def method_missing(method_name_, *args_, &block_)
78
+ def method_missing_with_rgeo(method_name_, *args_, &block_)
121
79
  if @base.respond_to?(:spatial_column_constructor) && (info_ = @base.spatial_column_constructor(method_name_))
122
80
  info_ = info_.dup
123
81
  type_ = (info_.delete(:type) || method_name_).to_s
@@ -126,22 +84,26 @@ module RGeo
126
84
  @base.add_column(@table_name, name_, type_, opts_)
127
85
  end
128
86
  else
129
- method_missing_without_rgeo_modification(method_name_, *args_, &block_)
87
+ method_missing_without_rgeo(method_name_, *args_, &block_)
130
88
  end
131
89
  end
132
-
133
90
  end
134
91
 
92
+ ::ActiveRecord::ConnectionAdapters::Table.send :include, GeoConnectionAdapters
135
93
 
136
- # Hack schema dumper to output spatial index flag
137
94
 
138
- ::ActiveRecord::SchemaDumper.class_eval do
95
+ # Hack schema dumper to output spatial index flag
96
+ module GeoSchemaDumper
97
+ def self.included(base)
98
+ base.class_eval do
99
+ alias_method :indexes_without_rgeo, :indexes
100
+ alias_method :indexes, :indexes_with_rgeo
101
+ end
102
+ end
139
103
 
140
104
  private
141
105
 
142
- alias_method :_old_indexes_method, :indexes
143
-
144
- def indexes(table_, stream_)
106
+ def indexes_with_rgeo(table_, stream_)
145
107
  if (indexes_ = @connection.indexes(table_)).any?
146
108
  add_index_statements_ = indexes_.map do |index_|
147
109
  statement_parts_ = [
@@ -159,19 +121,15 @@ module RGeo
159
121
  stream_.puts
160
122
  end
161
123
  end
162
-
163
124
  end
164
125
 
126
+ ::ActiveRecord::SchemaDumper.send :include, GeoSchemaDumper
165
127
 
166
- # Tell ActiveRecord to cache spatial attribute values so they don't get
167
- # re-parsed on every access.
168
128
 
169
- ::ActiveRecord::Base.attribute_types_cached_by_default << :spatial
129
+ # Tell ActiveRecord to cache spatial attribute values so they don't get re-parsed on every access.
170
130
 
131
+ ::ActiveRecord::Base.attribute_types_cached_by_default << :spatial
171
132
 
172
133
  # :startdoc:
173
-
174
-
175
134
  end
176
-
177
135
  end
@@ -1,57 +1,15 @@
1
- # -----------------------------------------------------------------------------
2
- #
3
- # Geometry mixin for JSON serialization
4
- #
5
- # -----------------------------------------------------------------------------
6
- # Copyright 2010-2012 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
1
  module RGeo
38
-
39
2
  module ActiveRecord
40
-
41
-
42
3
  # This module is mixed into all geometry objects. It provides an
43
4
  # as_json method so that ActiveRecord knows how to generate JSON
44
5
  # for a geometry-valued field.
45
6
 
46
7
  module GeometryMixin
47
-
48
-
49
8
  # The default JSON generator Proc. Renders geometry fields as WKT.
50
9
  DEFAULT_JSON_GENERATOR = ::Proc.new{ |geom_| geom_.to_s }
51
10
 
52
11
  @json_generator = DEFAULT_JSON_GENERATOR
53
12
 
54
-
55
13
  # Set the style of JSON generation used for geometry fields in an
56
14
  # ActiveRecord model by default. You may pass nil to use
57
15
  # DEFAULT_JSON_GENERATOR, a proc that takes a geometry as the
@@ -78,7 +36,6 @@ module RGeo
78
36
  end
79
37
  end
80
38
 
81
-
82
39
  # Given a feature, returns an object that can be serialized as JSON
83
40
  # (i.e. usually a hash or string), using the current json_generator.
84
41
  # This is used to generate JSON for geometry-valued ActiveRecord
@@ -94,15 +51,9 @@ module RGeo
94
51
  def as_json(opts_=nil)
95
52
  GeometryMixin.generate_json(self)
96
53
  end
97
-
98
-
99
54
  end
100
-
101
-
102
55
  end
103
-
104
56
  end
105
57
 
106
-
107
58
  ::RGeo::Feature::MixinCollection::GLOBAL.for_type(::RGeo::Feature::Geometry).
108
59
  add(::RGeo::ActiveRecord::GeometryMixin)