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