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.
- checksums.yaml +4 -4
- data/LICENSE.txt +29 -0
- data/lib/rgeo-activerecord.rb +0 -1
- data/lib/rgeo/active_record.rb +5 -64
- data/lib/rgeo/active_record/adapter_test_helper.rb +0 -56
- data/lib/rgeo/active_record/ar_factory_settings.rb +1 -81
- data/lib/rgeo/active_record/arel_spatial_queries.rb +13 -111
- data/lib/rgeo/active_record/common_adapter_elements.rb +35 -77
- data/lib/rgeo/active_record/geometry_mixin.rb +0 -49
- data/lib/rgeo/active_record/spatial_expressions.rb +5 -49
- data/lib/rgeo/active_record/version.rb +1 -52
- data/test/tc_basic.rb +2 -56
- data/test/test_helper.rb +8 -13
- metadata +21 -20
- data/Version +0 -1
- data/lib/rgeo/active_record/task_hacker.rb +0 -105
@@ -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
|
-
#
|
162
|
-
#
|
163
|
-
|
164
|
-
|
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
|
-
|
167
|
-
|
168
|
-
|
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
|
-
|
173
|
-
|
174
|
-
include ::RGeo::ActiveRecord::SpatialExpressions
|
104
|
+
def spatial_result?
|
105
|
+
@spatial_flags.first
|
175
106
|
end
|
176
107
|
|
177
|
-
|
178
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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)
|