rgeo-activerecord 0.6.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|