rgeo-ar 0.6.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 +7 -0
- data/History.rdoc +98 -0
- data/README.rdoc +95 -0
- data/lib/rgeo/active_record/adapter_test_helper.rb +186 -0
- data/lib/rgeo/active_record/ar_factory_settings.rb +229 -0
- data/lib/rgeo/active_record/arel_spatial_queries.rb +215 -0
- data/lib/rgeo/active_record/common_adapter_elements.rb +177 -0
- data/lib/rgeo/active_record/geometry_mixin.rb +108 -0
- data/lib/rgeo/active_record/spatial_expressions.rb +314 -0
- data/lib/rgeo/active_record/task_hacker.rb +105 -0
- data/lib/rgeo/active_record/version.rb +39 -0
- data/lib/rgeo/active_record.rb +83 -0
- data/lib/rgeo-activerecord.rb +36 -0
- data/test/support/fake_record.rb +124 -0
- data/test/tc_basic.rb +109 -0
- data/test/test_helper.rb +10 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c6450384669367d1c94d13c408784df96c62f410
|
4
|
+
data.tar.gz: a569d6e0b7c8ed5f0bf2981e15d8df5c3877c353
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8cb09d66ed6ffcc134563e065f95b0d1311cd672fe49cec0aa0e3bd57ad6ede7ad83ebb8b1301418dce2511dfa366306012c6c4c3127e6f0e1a0d413e2b25606
|
7
|
+
data.tar.gz: e6b2c1824c98ad1f8004d51c9fa4cab9ee1ce19b42ba089ad603b5e56b5ccac6a4b2ce50849e58cf6ff9ba8436cc5f385b824fb3fc60e5d2a37324bf814bc699
|
data/History.rdoc
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
=== 0.5.0 / 2013-02-27
|
2
|
+
|
3
|
+
* No changes. Rereleased as 0.5.0 final.
|
4
|
+
|
5
|
+
=== 0.5.0.beta2 / 2013-02-04
|
6
|
+
|
7
|
+
* Revert change made to SpatialIndexDefinition in beta1.
|
8
|
+
* Fix some deprecations in the post-test cache cleanup.
|
9
|
+
|
10
|
+
=== 0.5.0.beta1 / 2013-02-04
|
11
|
+
|
12
|
+
* Updates for compatibility with Rails 4 and support of Rails 4 oriented adapters.
|
13
|
+
* Testing tool is better factored to allow customization of cleanup
|
14
|
+
|
15
|
+
=== 0.4.6 / 2012-12-11
|
16
|
+
|
17
|
+
* You can now provide both a default and an override database config file in the test helper.
|
18
|
+
* The gemspec no longer includes the timestamp in the version, so that bundler can pull from github. (Reported by corneverbruggen)
|
19
|
+
|
20
|
+
=== 0.4.5 / 2012-04-13
|
21
|
+
|
22
|
+
* Task hacker failed ungracefully when attempting to hack a nonexistent task. Fixed.
|
23
|
+
|
24
|
+
=== 0.4.4 / 2012-04-12
|
25
|
+
|
26
|
+
* Support cartesian bounding boxes in queries.
|
27
|
+
|
28
|
+
=== 0.4.3 / 2012-02-22
|
29
|
+
|
30
|
+
* Some fixes for Rails 3.2 compatibility.
|
31
|
+
|
32
|
+
=== 0.4.2 / 2012-01-09
|
33
|
+
|
34
|
+
* Added an "rgeo-activerecord.rb" wrapper so bundler's auto-require will work without modification. (Reported by Mauricio Pasquier Juan.)
|
35
|
+
* Fixed unit tests so they actually pass...
|
36
|
+
|
37
|
+
=== 0.4.1 / 2011-10-26
|
38
|
+
|
39
|
+
* Fixed wrong variable name crash in rgeo_factory_for_column (patch by Andy Allan).
|
40
|
+
|
41
|
+
=== 0.4.0 / 2011-08-15
|
42
|
+
|
43
|
+
* Several compatibility fixes for Rails 3.1.
|
44
|
+
* Revamped factory setter mechanism with a system that should be more robust.
|
45
|
+
* Some general code cleanup.
|
46
|
+
|
47
|
+
=== 0.3.4 / 2011-05-23
|
48
|
+
|
49
|
+
* 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.)
|
50
|
+
|
51
|
+
=== 0.3.3 / 2011-04-11
|
52
|
+
|
53
|
+
* A .gemspec file is now available for gem building and bundler git integration.
|
54
|
+
|
55
|
+
=== 0.3.2 / 2011-02-28
|
56
|
+
|
57
|
+
* Fixed a bug that sometimes caused spatial column detection to fail, which could result in exceptions or incorrect spatial queries.
|
58
|
+
|
59
|
+
=== 0.3.1 / 2011-02-28
|
60
|
+
|
61
|
+
* Fixed a bug that could cause some spatial ActiveRecord adapters to fail to create multiple spatial columns in a migration.
|
62
|
+
|
63
|
+
=== 0.3.0 / 2011-01-26
|
64
|
+
|
65
|
+
* Experimental support for complex spatial queries. (Requires Arel 2.1, which is expected to be released with Rails 3.1.) Currently, only a low-level Arel-based interface is supported.
|
66
|
+
* Better support for geography types in PostGIS.
|
67
|
+
* Adapters can now define additional column constructors.
|
68
|
+
* Support for spatial column constructors on change_table.
|
69
|
+
* Fixed column type inference for some cases where the column included Z and/or M.
|
70
|
+
* IS NULL predicates now work properly with spatial types.
|
71
|
+
* Preferred attribute type is now :spatial rather than :geometry.
|
72
|
+
* The gem version is now accessible via an api.
|
73
|
+
* Some code reorganization.
|
74
|
+
|
75
|
+
=== 0.2.4 / 2011-01-13
|
76
|
+
|
77
|
+
* Fixed a problem that caused a hang during rake db:rollback, as well as probably certain other functions that use ActiveRecord::Base directly rather than a subclass. (Reported by Alexander Graefe.)
|
78
|
+
|
79
|
+
=== 0.2.3 / 2011-01-07
|
80
|
+
|
81
|
+
* Updated gem dependencies to include Arel 2.0.6, since some earlier Arel versions weren't working. (Reported by Pirmin Kalberer.)
|
82
|
+
|
83
|
+
=== 0.2.2 / 2011-01-06
|
84
|
+
|
85
|
+
* Some adjustments to the Arel integration for future Arel compatibility. (Thanks to Aaron Patterson.)
|
86
|
+
* Support code for hacking ActiveRecord's rake tasks.
|
87
|
+
|
88
|
+
=== 0.2.1 / 2010-12-27
|
89
|
+
|
90
|
+
* Support for RGeo features as nodes in the Arel AST.
|
91
|
+
* Basic utility Arel visitor methods for handling spatial equality nodes in where-expressions.
|
92
|
+
|
93
|
+
=== 0.2.0 / 2010-12-07
|
94
|
+
|
95
|
+
* Initial public alpha release. Spun rgeo-activerecord off from the core rgeo gem.
|
96
|
+
* Support for setting factory by column.
|
97
|
+
|
98
|
+
For earlier history, see the History file for the rgeo gem.
|
data/README.rdoc
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
== RGeo::ActiveRecord
|
2
|
+
|
3
|
+
|
4
|
+
RGeo::ActiveRecord is an optional {RGeo}[http://github.com/dazuma/rgeo]
|
5
|
+
module providing spatial extensions for \ActiveRecord, as well as a set
|
6
|
+
of helpers for writing spatial \ActiveRecord adapters based on \RGeo.
|
7
|
+
|
8
|
+
==== FORK NOTICE
|
9
|
+
|
10
|
+
This project is released as the `rgeo-ar` gem. It only works
|
11
|
+
with ActiveRecord 4.1+. It works with this PostGIS ActiveRecord extension:
|
12
|
+
https://github.com/neighborland/activerecord-postgis-adapter
|
13
|
+
|
14
|
+
|
15
|
+
=== Summary
|
16
|
+
|
17
|
+
\RGeo is a key component for writing location-aware applications in the
|
18
|
+
Ruby programming language. At its core is an implementation of the
|
19
|
+
industry standard OGC Simple Features Specification, which provides data
|
20
|
+
representations of geometric objects such as points, lines, and polygons,
|
21
|
+
along with a set of geometric analysis operations. See the README for the
|
22
|
+
"rgeo" gem for more information.
|
23
|
+
|
24
|
+
RGeo::ActiveRecord is an optional \RGeo add-on module providing spatial
|
25
|
+
extensions for \ActiveRecord, as well as a set of helpers for writing
|
26
|
+
spatial \ActiveRecord adapters based on \RGeo.
|
27
|
+
|
28
|
+
=== Installation
|
29
|
+
|
30
|
+
RGeo::ActiveRecord has the following requirements:
|
31
|
+
|
32
|
+
* Ruby 2.0.0+
|
33
|
+
* rgeo 0.3.20+
|
34
|
+
* ActiveRecord 4.1.0+
|
35
|
+
* arel 5.0.0+
|
36
|
+
|
37
|
+
Generally, \ActiveRecord adapters which depend on this module should be
|
38
|
+
installed as gems, and they will install this module automatically as
|
39
|
+
a dependency. However, you can also install it manually as a gem:
|
40
|
+
|
41
|
+
gem install rgeo
|
42
|
+
gem install rgeo-ar
|
43
|
+
|
44
|
+
See the README for the "rgeo" gem, a required dependency, for further
|
45
|
+
installation information.
|
46
|
+
|
47
|
+
=== Development and support
|
48
|
+
|
49
|
+
Documentation is available at http://dazuma.github.com/rgeo-activerecord/rdoc
|
50
|
+
|
51
|
+
Original source code is hosted on Github at http://github.com/dazuma/rgeo-activerecord
|
52
|
+
|
53
|
+
Contributions are welcome. Fork the project on Github.
|
54
|
+
|
55
|
+
Report bugs on Github issues at http://github.org/dazuma/rgeo-activerecord/issues
|
56
|
+
|
57
|
+
Support available on the rgeo-users google group at http://groups.google.com/group/rgeo-users
|
58
|
+
|
59
|
+
Contact the author at dazuma at gmail dot com.
|
60
|
+
|
61
|
+
=== Acknowledgments
|
62
|
+
|
63
|
+
\RGeo is written by Daniel Azuma (http://www.daniel-azuma.com).
|
64
|
+
|
65
|
+
Development is supported by Pirq. (http://pirq.com).
|
66
|
+
|
67
|
+
=== License
|
68
|
+
|
69
|
+
Copyright 2010-2013 Daniel Azuma
|
70
|
+
|
71
|
+
All rights reserved.
|
72
|
+
|
73
|
+
Redistribution and use in source and binary forms, with or without
|
74
|
+
modification, are permitted provided that the following conditions are met:
|
75
|
+
|
76
|
+
* Redistributions of source code must retain the above copyright notice,
|
77
|
+
this list of conditions and the following disclaimer.
|
78
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
79
|
+
this list of conditions and the following disclaimer in the documentation
|
80
|
+
and/or other materials provided with the distribution.
|
81
|
+
* Neither the name of the copyright holder, nor the names of any other
|
82
|
+
contributors to this software, may be used to endorse or promote products
|
83
|
+
derived from this software without specific prior written permission.
|
84
|
+
|
85
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
86
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
87
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
88
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
89
|
+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
90
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
91
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
92
|
+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
93
|
+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
94
|
+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
95
|
+
POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,186 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Helper methods for ActiveRecord adapter tests
|
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 'rgeo/active_record'
|
38
|
+
require 'yaml'
|
39
|
+
require 'logger'
|
40
|
+
|
41
|
+
|
42
|
+
module RGeo
|
43
|
+
module ActiveRecord
|
44
|
+
|
45
|
+
|
46
|
+
# A helper module for creating unit tests for adapters.
|
47
|
+
|
48
|
+
module AdapterTestHelper
|
49
|
+
|
50
|
+
@class_num = 0
|
51
|
+
|
52
|
+
|
53
|
+
# When this module is included in a test case class, it
|
54
|
+
# automatically attempts to load the database config file from the
|
55
|
+
# path specified by constants defined in the class. It first tries
|
56
|
+
# OVERRIDE_DATABASE_CONFIG_PATH, and then falls back on
|
57
|
+
# DATABASE_CONFIG_PATH.
|
58
|
+
# It then defines the DATABASE_CONFIG and DEFAULT_AR_CLASS constants
|
59
|
+
# in the testcase class.
|
60
|
+
#
|
61
|
+
# When you define your test methods, you should wrap them in a call
|
62
|
+
# to the class method define_test_methods. This will cause them to
|
63
|
+
# be defined conditionally based on whether the database config is
|
64
|
+
# present.
|
65
|
+
|
66
|
+
def self.included(klass_)
|
67
|
+
database_config_ = ::YAML.load_file(klass_.const_get(:OVERRIDE_DATABASE_CONFIG_PATH)) rescue nil
|
68
|
+
database_config_ ||= ::YAML.load_file(klass_.const_get(:DATABASE_CONFIG_PATH)) rescue nil
|
69
|
+
if database_config_
|
70
|
+
database_config_.stringify_keys!
|
71
|
+
if klass_.respond_to?(:before_open_database)
|
72
|
+
klass_.before_open_database(:config => database_config_)
|
73
|
+
end
|
74
|
+
klass_.const_set(:DATABASE_CONFIG, database_config_)
|
75
|
+
ar_class_ = AdapterTestHelper.new_class(database_config_)
|
76
|
+
klass_.const_set(:DEFAULT_AR_CLASS, ar_class_)
|
77
|
+
if klass_.respond_to?(:initialize_database)
|
78
|
+
klass_.initialize_database(:ar_class => ar_class_, :connection => ar_class_.connection)
|
79
|
+
end
|
80
|
+
def klass_.define_test_methods
|
81
|
+
yield
|
82
|
+
end
|
83
|
+
else
|
84
|
+
def klass_.define_test_methods
|
85
|
+
def test_warning
|
86
|
+
puts "WARNING: Couldn't find database.yml; skipping tests."
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
def self.new_class(param_) # :nodoc:
|
94
|
+
base_ = param_.kind_of?(::Class) ? param_ : ::ActiveRecord::Base
|
95
|
+
config_ = param_.kind_of?(::Hash) ? param_ : nil
|
96
|
+
klass_ = ::Class.new(base_)
|
97
|
+
@class_num += 1
|
98
|
+
self.const_set("Klass#{@class_num}".to_sym, klass_)
|
99
|
+
klass_.class_eval do
|
100
|
+
establish_connection(config_) if config_
|
101
|
+
self.table_name = :spatial_test
|
102
|
+
end
|
103
|
+
klass_
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
# Default setup method that calls cleanup_tables.
|
108
|
+
# It also defines a couple of useful factories: @factory (a
|
109
|
+
# cartesian factory) and @geographic_factory (a spherical factory)
|
110
|
+
|
111
|
+
def setup
|
112
|
+
@factory = ::RGeo::Cartesian.preferred_factory(:srid => 3785)
|
113
|
+
@geographic_factory = ::RGeo::Geographic.spherical_factory(:srid => 4326)
|
114
|
+
cleanup_tables
|
115
|
+
cleanup_caches
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Default teardown method that calls cleanup_tables.
|
120
|
+
|
121
|
+
def teardown
|
122
|
+
cleanup_tables
|
123
|
+
cleanup_caches
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# Utility method that attempts to clean up any table that was
|
128
|
+
# created by a test method. Normally called automatically at setup
|
129
|
+
# and teardown. If you override those methods, you'll need to call
|
130
|
+
# this from your method.
|
131
|
+
|
132
|
+
def cleanup_tables
|
133
|
+
klass_ = self.class.const_get(:DEFAULT_AR_CLASS)
|
134
|
+
if klass_.connection.tables.include?('spatial_test')
|
135
|
+
klass_.connection.drop_table(:spatial_test)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
# Utility method that cleans up any schema info that was cached by
|
141
|
+
# ActiveRecord during a test. Normally called automatically at setup
|
142
|
+
# and teardown. If you override those methods, you'll need to call
|
143
|
+
# this from your method.
|
144
|
+
|
145
|
+
def cleanup_caches
|
146
|
+
klass_ = self.class.const_get(:DEFAULT_AR_CLASS)
|
147
|
+
|
148
|
+
# Clear any RGeo factory settings.
|
149
|
+
klass_.connection_pool.rgeo_factory_settings.clear!
|
150
|
+
|
151
|
+
# Clear out any ActiveRecord caches that are present.
|
152
|
+
# Different Rails versions use different types of caches.
|
153
|
+
has_schema_cache_ = false
|
154
|
+
klass_.connection_pool.with_connection do |c_|
|
155
|
+
if c_.respond_to?(:schema_cache)
|
156
|
+
# 3.2.x and 4.0.x
|
157
|
+
c_.schema_cache.clear!
|
158
|
+
has_schema_cache_ = true
|
159
|
+
end
|
160
|
+
if c_.respond_to?(:clear_cache!)
|
161
|
+
# 3.1 and above
|
162
|
+
c_.clear_cache!
|
163
|
+
end
|
164
|
+
# All 3.x and 4.0
|
165
|
+
c_.clear_query_cache
|
166
|
+
end
|
167
|
+
if !has_schema_cache_ && klass_.connection_pool.respond_to?(:clear_cache!)
|
168
|
+
# 3.1.x only
|
169
|
+
klass_.connection_pool.clear_cache!
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
# Utility method that creates and returns a new ActiveRecord class
|
175
|
+
# subclassing the DEFAULT_AR_CLASS.
|
176
|
+
|
177
|
+
def create_ar_class(opts_={})
|
178
|
+
@ar_class = AdapterTestHelper.new_class(self.class.const_get(:DEFAULT_AR_CLASS))
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Additions to ActiveRecord::Base for factory settings
|
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_record'
|
38
|
+
|
39
|
+
|
40
|
+
module RGeo
|
41
|
+
|
42
|
+
module ActiveRecord
|
43
|
+
|
44
|
+
|
45
|
+
# The default factory generator for ActiveRecord::Base.
|
46
|
+
|
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
|
54
|
+
|
55
|
+
|
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
|
+
DEFAULT = self.new
|
118
|
+
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
# Additional class methods on ::ActiveRecord::Base that provide
|
124
|
+
# a way to control the RGeo factory used for ActiveRecord objects.
|
125
|
+
|
126
|
+
module ActiveRecordBaseFactorySettings
|
127
|
+
|
128
|
+
|
129
|
+
# Return the RGeoFactorySettings object associated with this
|
130
|
+
# class's connection.
|
131
|
+
|
132
|
+
def rgeo_factory_settings
|
133
|
+
pool_ = begin
|
134
|
+
connection_pool
|
135
|
+
rescue ::ActiveRecord::ConnectionNotEstablished
|
136
|
+
nil
|
137
|
+
end
|
138
|
+
pool_ ? pool_.rgeo_factory_settings : RGeoFactorySettings::DEFAULT
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
# The value of this attribute is a RGeo::Feature::FactoryGenerator
|
143
|
+
# that is used to generate the proper factory when loading geometry
|
144
|
+
# objects from the database. For example, if the data being loaded
|
145
|
+
# has M but not Z coordinates, and an embedded SRID, then this
|
146
|
+
# FactoryGenerator is called with the appropriate configuration to
|
147
|
+
# obtain a factory with those properties. This factory is the one
|
148
|
+
# associated with the actual geometry properties of the ActiveRecord
|
149
|
+
# object. The result of this generator can be overridden by setting
|
150
|
+
# an explicit factory for a given class and column using the
|
151
|
+
# column_rgeo_factory method.
|
152
|
+
|
153
|
+
def rgeo_factory_generator
|
154
|
+
rgeo_factory_settings.get_factory_generator(table_name)
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
# Set the rgeo_factory_generator attribute
|
159
|
+
|
160
|
+
def rgeo_factory_generator=(gen_)
|
161
|
+
rgeo_factory_settings.set_factory_generator(table_name, gen_)
|
162
|
+
end
|
163
|
+
|
164
|
+
|
165
|
+
# This is a convenient way to set the rgeo_factory_generator by
|
166
|
+
# passing a block.
|
167
|
+
|
168
|
+
def to_generate_rgeo_factory(&block_)
|
169
|
+
rgeo_factory_settings.set_factory_generator(table_name, block_)
|
170
|
+
end
|
171
|
+
|
172
|
+
|
173
|
+
# Set a specific factory for this ActiveRecord class and the given
|
174
|
+
# column name. This setting, if present, overrides the result of the
|
175
|
+
# rgeo_factory_generator.
|
176
|
+
|
177
|
+
def set_rgeo_factory_for_column(column_name_, factory_)
|
178
|
+
rgeo_factory_settings.set_column_factory(table_name, column_name_, factory_)
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
# Returns the factory generator or specific factory to use for this
|
183
|
+
# ActiveRecord class and the given column name.
|
184
|
+
# If an explicit factory was set for the given column, returns it.
|
185
|
+
# Otherwise, if a params hash is given, passes that hash to the
|
186
|
+
# rgeo_factory_generator for this class, and returns the resulting
|
187
|
+
# factory. Otherwise, if no params hash is given, just returns the
|
188
|
+
# rgeo_factory_generator for this class.
|
189
|
+
|
190
|
+
def rgeo_factory_for_column(column_name_, params_=nil)
|
191
|
+
rgeo_factory_settings.get_column_factory(table_name, column_name_, params_)
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
::ActiveRecord::Base.extend(ActiveRecordBaseFactorySettings)
|
198
|
+
|
199
|
+
|
200
|
+
# :stopdoc:
|
201
|
+
|
202
|
+
|
203
|
+
# Patch for connection pool to track geo factories per table name
|
204
|
+
|
205
|
+
::ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
|
206
|
+
|
207
|
+
def rgeo_factory_settings
|
208
|
+
@_rgeo_factory_settings ||= RGeoFactorySettings.new
|
209
|
+
end
|
210
|
+
|
211
|
+
private
|
212
|
+
alias_method :new_connection_without_rgeo_modification, :new_connection
|
213
|
+
def new_connection
|
214
|
+
result_ = new_connection_without_rgeo_modification
|
215
|
+
if result_.respond_to?(:set_rgeo_factory_settings)
|
216
|
+
result_.set_rgeo_factory_settings(rgeo_factory_settings)
|
217
|
+
end
|
218
|
+
result_
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
# :startdoc:
|
225
|
+
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|