rgeo-activerecord 2.1.1 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -3
- data/lib/rgeo-activerecord.rb +0 -34
- data/lib/rgeo/active_record.rb +1 -11
- data/lib/rgeo/active_record/spatial_factory_store.rb +61 -0
- data/lib/rgeo/active_record/version.rb +1 -1
- data/test/basic_test.rb +4 -35
- data/test/spatial_factory_store_test.rb +45 -0
- data/test/support/fake_record.rb +17 -5
- metadata +6 -6
- data/lib/rgeo/active_record/adapter_test_helper.rb +0 -130
- data/lib/rgeo/active_record/ar_factory_settings.rb +0 -146
- data/test/common_adapter_elements_test.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f60cf6ae67e0e2e1a73d57c4a0bad86f534f96c0
|
4
|
+
data.tar.gz: 17c3e5ecc8458e01eab3dc4531622ec3460cb193
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7296946f83cabf48737cd6e5b7f3b8af4af78ba3c69b77e86618bdbff65be11a05d8c32c44084a8ced839f5952c9a560f8d6912db0fe5c6fd953cc12c89bc2a8
|
7
|
+
data.tar.gz: 2a2239bd24fa6d7e4940da9a61253fa9b427457e6b01120d94f822428c476544d698463f72b240ad83c826c954bb8ad21e74f8c4037c7f99b65999f9f679ee3f
|
data/README.md
CHANGED
data/lib/rgeo-activerecord.rb
CHANGED
@@ -1,35 +1 @@
|
|
1
|
-
# -----------------------------------------------------------------------------
|
2
|
-
#
|
3
|
-
# ActiveRecord extensions for RGeo
|
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
1
|
require 'rgeo/active_record'
|
data/lib/rgeo/active_record.rb
CHANGED
@@ -4,21 +4,11 @@
|
|
4
4
|
# ActiveRecord, and a set of tools and helpers for writing RGeo-based
|
5
5
|
# spatial connection adapters.
|
6
6
|
|
7
|
-
module RGeo
|
8
|
-
# This module contains a set of ActiveRecord extensions for RGeo.
|
9
|
-
# Generally, you will not need to interact with the contents of this
|
10
|
-
# module directly, unless you are writing a spatial ActiveRecord
|
11
|
-
# connection adapter.
|
12
|
-
|
13
|
-
module ActiveRecord
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
7
|
require 'rgeo'
|
18
8
|
require 'active_record'
|
19
9
|
require 'rgeo/active_record/version'
|
20
10
|
require 'rgeo/active_record/spatial_expressions'
|
11
|
+
require 'rgeo/active_record/spatial_factory_store'
|
21
12
|
require 'rgeo/active_record/arel_spatial_queries'
|
22
13
|
require 'rgeo/active_record/common_adapter_elements'
|
23
|
-
require 'rgeo/active_record/ar_factory_settings'
|
24
14
|
require 'rgeo/active_record/geometry_mixin'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module RGeo
|
2
|
+
module ActiveRecord
|
3
|
+
class SpatialFactoryStore
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
attr_accessor :registry
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@registry = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def register(factory, attrs = {})
|
13
|
+
registry[key(attrs)] = factory
|
14
|
+
end
|
15
|
+
|
16
|
+
def default(attrs = {})
|
17
|
+
@default || default_for_attrs(attrs)
|
18
|
+
end
|
19
|
+
|
20
|
+
def default=(factory)
|
21
|
+
@default = factory
|
22
|
+
end
|
23
|
+
|
24
|
+
def factory(attrs)
|
25
|
+
registry[key(attrs)] || default(attrs)
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear
|
29
|
+
@registry = {}
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def default_for_attrs(attrs)
|
35
|
+
if attrs[:sql_type] =~ /geography/
|
36
|
+
RGeo::Geographic.spherical_factory(to_factory_attrs(attrs))
|
37
|
+
else
|
38
|
+
RGeo::Cartesian.preferred_factory(to_factory_attrs(attrs))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_factory_attrs(attrs)
|
43
|
+
{
|
44
|
+
has_m_coordinate: attrs[:has_m],
|
45
|
+
has_z_coordinate: attrs[:has_z],
|
46
|
+
srid: (attrs[:srid] || 0),
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def key(attrs)
|
51
|
+
{
|
52
|
+
geo_type: "geometry",
|
53
|
+
has_m: false,
|
54
|
+
has_z: false,
|
55
|
+
sql_type: "geometry",
|
56
|
+
srid: 0,
|
57
|
+
}.merge(attrs).hash
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/test/basic_test.rb
CHANGED
@@ -1,43 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class BasicTest < Minitest::Test
|
4
|
-
class MyTable <
|
3
|
+
class BasicTest < Minitest::Test
|
4
|
+
class MyTable < ActiveRecord::Base
|
5
5
|
end
|
6
6
|
|
7
|
-
def
|
7
|
+
def test_version
|
8
8
|
assert RGeo::ActiveRecord::VERSION
|
9
9
|
end
|
10
10
|
|
11
|
-
def test_default_factory_generator
|
12
|
-
MyTable.rgeo_factory_generator = nil
|
13
|
-
factory = MyTable.rgeo_factory_for_column(:hello).call(has_z_coordinate: true, srid: 4326)
|
14
|
-
assert_equal true, factory.property(:has_z_coordinate)
|
15
|
-
assert_equal true, factory.property(:is_cartesian)
|
16
|
-
assert_nil factory.property(:is_geographic)
|
17
|
-
assert_equal 4326, factory.srid
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_set_factory_generator
|
21
|
-
MyTable.rgeo_factory_generator = RGeo::Geographic.method(:spherical_factory)
|
22
|
-
factory = MyTable.rgeo_factory_for_column(:hello, has_z_coordinate: true, srid: 4326)
|
23
|
-
assert_equal true, factory.property(:has_z_coordinate)
|
24
|
-
assert_equal true, factory.property(:is_geographic)
|
25
|
-
assert_nil factory.property(:is_cartesian)
|
26
|
-
assert_equal false, factory.has_projection?
|
27
|
-
assert_equal 4326, factory.srid
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_specific_factory_for_column
|
31
|
-
MyTable.rgeo_factory_generator = nil
|
32
|
-
MyTable.set_rgeo_factory_for_column(:foo, RGeo::Geographic.simple_mercator_factory(has_z_coordinate: true))
|
33
|
-
factory = MyTable.rgeo_factory_for_column(:foo)
|
34
|
-
assert_equal true, factory.property(:has_z_coordinate)
|
35
|
-
assert_equal true, factory.property(:is_geographic)
|
36
|
-
assert_nil factory.property(:is_cartesian)
|
37
|
-
assert_equal true, factory.has_projection?
|
38
|
-
assert_equal 4326, factory.srid
|
39
|
-
end
|
40
|
-
|
41
11
|
def test_default_as_json_wkt
|
42
12
|
RGeo::ActiveRecord::GeometryMixin.set_json_generator(nil)
|
43
13
|
factory = RGeo::Cartesian.preferred_factory
|
@@ -61,7 +31,6 @@ class BasicTest < Minitest::Test # :nodoc:
|
|
61
31
|
private
|
62
32
|
|
63
33
|
def arel_visitor
|
64
|
-
Arel::Visitors::PostgreSQL.new(
|
34
|
+
Arel::Visitors::PostgreSQL.new(FakeRecord::Connection.new)
|
65
35
|
end
|
66
|
-
|
67
36
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class SpatialFactoryStoreTest < Minitest::Test
|
4
|
+
def test_default
|
5
|
+
store.default = nil
|
6
|
+
assert RGeo::Cartesian.preferred_factory === store.default
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_set_default
|
10
|
+
store.clear
|
11
|
+
default_factory = Object.new
|
12
|
+
store.default = default_factory
|
13
|
+
assert_equal default_factory, store.default
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_register
|
17
|
+
store.clear
|
18
|
+
default_factory = Object.new
|
19
|
+
store.default = default_factory
|
20
|
+
|
21
|
+
point_factory = Object.new
|
22
|
+
store.register point_factory, geo_type: "point", srid: 4326
|
23
|
+
assert_equal point_factory, store.factory(geo_type: "point", srid: 4326)
|
24
|
+
assert_equal 1, store.registry.size
|
25
|
+
assert_equal point_factory, store.factory(geo_type: "point", srid: 4326)
|
26
|
+
assert_equal 1, store.registry.size
|
27
|
+
|
28
|
+
polygon_factory = Object.new
|
29
|
+
store.register polygon_factory, geo_type: "polygon"
|
30
|
+
assert_equal polygon_factory, store.factory(geo_type: "polygon")
|
31
|
+
assert_equal 2, store.registry.size
|
32
|
+
|
33
|
+
z_point_factory = Object.new
|
34
|
+
store.register z_point_factory, geo_type: "point", has_z: true
|
35
|
+
assert_equal z_point_factory, store.factory(geo_type: "point", has_z: true)
|
36
|
+
|
37
|
+
assert_equal default_factory, store.factory(geo_type: "linestring")
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def store
|
43
|
+
RGeo::ActiveRecord::SpatialFactoryStore.instance
|
44
|
+
end
|
45
|
+
end
|
data/test/support/fake_record.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# From https://github.com/rails/arel/
|
1
|
+
# From https://github.com/rails/arel/master/test/support/fake_record.rb
|
2
2
|
module FakeRecord
|
3
3
|
class Column < Struct.new(:name, :type)
|
4
4
|
end
|
@@ -61,12 +61,20 @@ module FakeRecord
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def quote thing, column = nil
|
64
|
-
if column &&
|
65
|
-
|
66
|
-
|
64
|
+
if column && !thing.nil?
|
65
|
+
case column.type
|
66
|
+
when :integer
|
67
|
+
thing = thing.to_i
|
68
|
+
when :string
|
69
|
+
thing = thing.to_s
|
70
|
+
end
|
67
71
|
end
|
68
72
|
|
69
73
|
case thing
|
74
|
+
when DateTime
|
75
|
+
"'#{thing.strftime("%Y-%m-%d %H:%M:%S")}'"
|
76
|
+
when Date
|
77
|
+
"'#{thing.strftime("%Y-%m-%d")}'"
|
70
78
|
when true
|
71
79
|
"'t'"
|
72
80
|
when false
|
@@ -76,7 +84,7 @@ module FakeRecord
|
|
76
84
|
when Numeric
|
77
85
|
thing
|
78
86
|
else
|
79
|
-
"'#{thing}'"
|
87
|
+
"'#{thing.to_s.gsub("'", "\\\\'")}'"
|
80
88
|
end
|
81
89
|
end
|
82
90
|
end
|
@@ -108,6 +116,10 @@ module FakeRecord
|
|
108
116
|
def schema_cache
|
109
117
|
connection
|
110
118
|
end
|
119
|
+
|
120
|
+
def quote thing, column = nil
|
121
|
+
connection.quote thing, column
|
122
|
+
end
|
111
123
|
end
|
112
124
|
|
113
125
|
class Base
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgeo-activerecord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma, Tee Parham
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rgeo
|
@@ -93,15 +93,14 @@ files:
|
|
93
93
|
- README.md
|
94
94
|
- lib/rgeo-activerecord.rb
|
95
95
|
- lib/rgeo/active_record.rb
|
96
|
-
- lib/rgeo/active_record/adapter_test_helper.rb
|
97
|
-
- lib/rgeo/active_record/ar_factory_settings.rb
|
98
96
|
- lib/rgeo/active_record/arel_spatial_queries.rb
|
99
97
|
- lib/rgeo/active_record/common_adapter_elements.rb
|
100
98
|
- lib/rgeo/active_record/geometry_mixin.rb
|
101
99
|
- lib/rgeo/active_record/spatial_expressions.rb
|
100
|
+
- lib/rgeo/active_record/spatial_factory_store.rb
|
102
101
|
- lib/rgeo/active_record/version.rb
|
103
102
|
- test/basic_test.rb
|
104
|
-
- test/
|
103
|
+
- test/spatial_factory_store_test.rb
|
105
104
|
- test/support/fake_record.rb
|
106
105
|
- test/test_helper.rb
|
107
106
|
homepage: http://github.com/rgeo/rgeo-activerecord
|
@@ -129,6 +128,7 @@ specification_version: 4
|
|
129
128
|
summary: An RGeo module providing spatial extensions to ActiveRecord.
|
130
129
|
test_files:
|
131
130
|
- test/basic_test.rb
|
132
|
-
- test/
|
131
|
+
- test/spatial_factory_store_test.rb
|
133
132
|
- test/support/fake_record.rb
|
134
133
|
- test/test_helper.rb
|
134
|
+
has_rdoc:
|
@@ -1,130 +0,0 @@
|
|
1
|
-
require 'rgeo/active_record'
|
2
|
-
require 'yaml'
|
3
|
-
require 'logger'
|
4
|
-
|
5
|
-
module RGeo
|
6
|
-
module ActiveRecord
|
7
|
-
# A helper module for creating unit tests for adapters.
|
8
|
-
module AdapterTestHelper
|
9
|
-
@class_num = 0
|
10
|
-
|
11
|
-
# When this module is included in a test case class, it
|
12
|
-
# automatically attempts to load the database config file from the
|
13
|
-
# path specified by constants defined in the class. It first tries
|
14
|
-
# OVERRIDE_DATABASE_CONFIG_PATH, and then falls back on
|
15
|
-
# DATABASE_CONFIG_PATH.
|
16
|
-
# It then defines the DATABASE_CONFIG and DEFAULT_AR_CLASS constants
|
17
|
-
# in the testcase class.
|
18
|
-
#
|
19
|
-
# When you define your test methods, you should wrap them in a call
|
20
|
-
# to the class method define_test_methods. This will cause them to
|
21
|
-
# be defined conditionally based on whether the database config is
|
22
|
-
# present.
|
23
|
-
|
24
|
-
def self.included(klass_)
|
25
|
-
database_config_ = ::YAML.load_file(klass_.const_get(:OVERRIDE_DATABASE_CONFIG_PATH)) rescue nil
|
26
|
-
database_config_ ||= ::YAML.load_file(klass_.const_get(:DATABASE_CONFIG_PATH)) rescue nil
|
27
|
-
if database_config_
|
28
|
-
database_config_.stringify_keys!
|
29
|
-
if klass_.respond_to?(:before_open_database)
|
30
|
-
klass_.before_open_database(:config => database_config_)
|
31
|
-
end
|
32
|
-
klass_.const_set(:DATABASE_CONFIG, database_config_)
|
33
|
-
ar_class_ = AdapterTestHelper.new_class(database_config_)
|
34
|
-
klass_.const_set(:DEFAULT_AR_CLASS, ar_class_)
|
35
|
-
if klass_.respond_to?(:initialize_database)
|
36
|
-
klass_.initialize_database(:ar_class => ar_class_, :connection => ar_class_.connection)
|
37
|
-
end
|
38
|
-
def klass_.define_test_methods
|
39
|
-
yield
|
40
|
-
end
|
41
|
-
else
|
42
|
-
def klass_.define_test_methods
|
43
|
-
def test_warning
|
44
|
-
puts "WARNING: Couldn't find database.yml; skipping tests."
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.new_class(param_) # :nodoc:
|
51
|
-
base_ = param_.kind_of?(::Class) ? param_ : ::ActiveRecord::Base
|
52
|
-
config_ = param_.kind_of?(::Hash) ? param_ : nil
|
53
|
-
klass_ = ::Class.new(base_)
|
54
|
-
@class_num += 1
|
55
|
-
self.const_set("Klass#{@class_num}".to_sym, klass_)
|
56
|
-
klass_.class_eval do
|
57
|
-
establish_connection(config_) if config_
|
58
|
-
self.table_name = :spatial_test
|
59
|
-
end
|
60
|
-
klass_
|
61
|
-
end
|
62
|
-
|
63
|
-
# Default setup method that calls cleanup_tables.
|
64
|
-
# It also defines a couple of useful factories: @factory (a
|
65
|
-
# cartesian factory) and @geographic_factory (a spherical factory)
|
66
|
-
|
67
|
-
def setup
|
68
|
-
@factory = ::RGeo::Cartesian.preferred_factory(:srid => 3785)
|
69
|
-
@geographic_factory = ::RGeo::Geographic.spherical_factory(:srid => 4326)
|
70
|
-
cleanup_tables
|
71
|
-
cleanup_caches
|
72
|
-
end
|
73
|
-
|
74
|
-
# Default teardown method that calls cleanup_tables.
|
75
|
-
|
76
|
-
def teardown
|
77
|
-
cleanup_tables
|
78
|
-
cleanup_caches
|
79
|
-
end
|
80
|
-
|
81
|
-
# Utility method that attempts to clean up any table that was
|
82
|
-
# created by a test method. Normally called automatically at setup
|
83
|
-
# and teardown. If you override those methods, you'll need to call
|
84
|
-
# this from your method.
|
85
|
-
|
86
|
-
def cleanup_tables
|
87
|
-
klass_ = self.class.const_get(:DEFAULT_AR_CLASS)
|
88
|
-
if klass_.connection.tables.include?('spatial_test')
|
89
|
-
klass_.connection.drop_table(:spatial_test)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
# Utility method that cleans up any schema info that was cached by
|
95
|
-
# ActiveRecord during a test. Normally called automatically at setup
|
96
|
-
# and teardown. If you override those methods, you'll need to call
|
97
|
-
# this from your method.
|
98
|
-
|
99
|
-
def cleanup_caches
|
100
|
-
klass_ = self.class.const_get(:DEFAULT_AR_CLASS)
|
101
|
-
|
102
|
-
# Clear any RGeo factory settings.
|
103
|
-
klass_.connection_pool.rgeo_factory_settings.clear!
|
104
|
-
|
105
|
-
# Clear out any ActiveRecord caches that are present.
|
106
|
-
# Different Rails versions use different types of caches.
|
107
|
-
klass_.connection_pool.with_connection do |c_|
|
108
|
-
if c_.respond_to?(:schema_cache)
|
109
|
-
# 3.2.x and 4.0.x
|
110
|
-
c_.schema_cache.clear!
|
111
|
-
end
|
112
|
-
if c_.respond_to?(:clear_cache!)
|
113
|
-
# 3.1 and above
|
114
|
-
c_.clear_cache!
|
115
|
-
end
|
116
|
-
# All 3.x and 4.0
|
117
|
-
c_.clear_query_cache
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
# Utility method that creates and returns a new ActiveRecord class
|
122
|
-
# subclassing the DEFAULT_AR_CLASS.
|
123
|
-
|
124
|
-
def create_ar_class(opts_={})
|
125
|
-
@ar_class = AdapterTestHelper.new_class(self.class.const_get(:DEFAULT_AR_CLASS))
|
126
|
-
end
|
127
|
-
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
@@ -1,146 +0,0 @@
|
|
1
|
-
module RGeo
|
2
|
-
module ActiveRecord
|
3
|
-
# The default factory generator for ActiveRecord::Base.
|
4
|
-
|
5
|
-
DEFAULT_FACTORY_GENERATOR = ::Proc.new do |config|
|
6
|
-
if config.delete(:geographic)
|
7
|
-
::RGeo::Geographic.spherical_factory(config)
|
8
|
-
else
|
9
|
-
::RGeo::Cartesian.preferred_factory(config)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# An object that manages the RGeo factories for a ConnectionPool.
|
14
|
-
class RGeoFactorySettings
|
15
|
-
|
16
|
-
def initialize # :nodoc:
|
17
|
-
@factory_generators = {}
|
18
|
-
@column_factories = {}
|
19
|
-
end
|
20
|
-
|
21
|
-
# Get the default factory generator for the given table
|
22
|
-
def get_factory_generator(table_name)
|
23
|
-
@factory_generators[table_name.to_s] || ::RGeo::ActiveRecord::DEFAULT_FACTORY_GENERATOR
|
24
|
-
end
|
25
|
-
|
26
|
-
# Set the default factory generator for the given table
|
27
|
-
def set_factory_generator(table_name, generator)
|
28
|
-
@factory_generators[table_name.to_s] = generator
|
29
|
-
end
|
30
|
-
|
31
|
-
# Get the factory or factory generator for the given table name and column name.
|
32
|
-
def get_column_factory(table_name, column_name, params = nil)
|
33
|
-
table_name = table_name.to_s
|
34
|
-
column_name = column_name.to_s
|
35
|
-
result = (@column_factories[table_name] ||= {})[column_name] ||
|
36
|
-
@factory_generators[table_name] || ::RGeo::ActiveRecord::DEFAULT_FACTORY_GENERATOR
|
37
|
-
if params && !result.kind_of?(::RGeo::Feature::Factory::Instance)
|
38
|
-
result = result.call(params)
|
39
|
-
end
|
40
|
-
result
|
41
|
-
end
|
42
|
-
|
43
|
-
# Set the factory or factory generator for the given table name and column name.
|
44
|
-
def set_column_factory(table_name, column_name, factory)
|
45
|
-
(@column_factories[table_name.to_s] ||= {})[column_name.to_s] = factory
|
46
|
-
end
|
47
|
-
|
48
|
-
# Clear settings for the given table name, or for all tables
|
49
|
-
def clear!(table_name = nil)
|
50
|
-
if table_name
|
51
|
-
table_name = table_name.to_s
|
52
|
-
@factory_generators.delete(table_name)
|
53
|
-
@column_factories.delete(table_name)
|
54
|
-
else
|
55
|
-
@factory_generators.clear
|
56
|
-
@column_factories.clear
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
DEFAULT = self.new
|
61
|
-
end
|
62
|
-
|
63
|
-
# Additional class methods on ::ActiveRecord::Base that provide
|
64
|
-
# a way to control the RGeo factory used for ActiveRecord objects.
|
65
|
-
module ActiveRecordBaseFactorySettings
|
66
|
-
# Return the RGeoFactorySettings object associated with this class's connection.
|
67
|
-
def rgeo_factory_settings
|
68
|
-
pool = begin
|
69
|
-
connection_pool
|
70
|
-
rescue ::ActiveRecord::ConnectionNotEstablished
|
71
|
-
nil
|
72
|
-
end
|
73
|
-
pool ? pool.rgeo_factory_settings : RGeoFactorySettings::DEFAULT
|
74
|
-
end
|
75
|
-
|
76
|
-
# The value of this attribute is a RGeo::Feature::FactoryGenerator
|
77
|
-
# that is used to generate the proper factory when loading geometry
|
78
|
-
# objects from the database. For example, if the data being loaded
|
79
|
-
# has M but not Z coordinates, and an embedded SRID, then this
|
80
|
-
# FactoryGenerator is called with the appropriate configuration to
|
81
|
-
# obtain a factory with those properties. This factory is the one
|
82
|
-
# associated with the actual geometry properties of the ActiveRecord
|
83
|
-
# object. The result of this generator can be overridden by setting
|
84
|
-
# an explicit factory for a given class and column using the
|
85
|
-
# column_rgeo_factory method.
|
86
|
-
|
87
|
-
def rgeo_factory_generator
|
88
|
-
rgeo_factory_settings.get_factory_generator(table_name)
|
89
|
-
end
|
90
|
-
|
91
|
-
# Set the rgeo_factory_generator attribute
|
92
|
-
def rgeo_factory_generator=(generator)
|
93
|
-
rgeo_factory_settings.set_factory_generator(table_name, generator)
|
94
|
-
end
|
95
|
-
|
96
|
-
# This is a convenient way to set the rgeo_factory_generator by
|
97
|
-
# passing a block.
|
98
|
-
def to_generate_rgeo_factory(&block)
|
99
|
-
rgeo_factory_settings.set_factory_generator(table_name, block)
|
100
|
-
end
|
101
|
-
|
102
|
-
# Set a specific factory for this ActiveRecord class and the given
|
103
|
-
# column name. This setting, if present, overrides the result of the
|
104
|
-
# rgeo_factory_generator.
|
105
|
-
def set_rgeo_factory_for_column(column_name, factory)
|
106
|
-
rgeo_factory_settings.set_column_factory(table_name, column_name, factory)
|
107
|
-
end
|
108
|
-
|
109
|
-
# Returns the factory generator or specific factory to use for this
|
110
|
-
# ActiveRecord class and the given column name.
|
111
|
-
# If an explicit factory was set for the given column, returns it.
|
112
|
-
# Otherwise, if a params hash is given, passes that hash to the
|
113
|
-
# rgeo_factory_generator for this class, and returns the resulting
|
114
|
-
# factory. Otherwise, if no params hash is given, just returns the
|
115
|
-
# rgeo_factory_generator for this class.
|
116
|
-
def rgeo_factory_for_column(column_name, params = nil)
|
117
|
-
rgeo_factory_settings.get_column_factory(table_name, column_name, params)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
::ActiveRecord::Base.extend(ActiveRecordBaseFactorySettings)
|
122
|
-
|
123
|
-
# :stopdoc:
|
124
|
-
|
125
|
-
# Patch for connection pool to track geo factories per table name
|
126
|
-
::ActiveRecord::ConnectionAdapters::ConnectionPool.class_eval do
|
127
|
-
def rgeo_factory_settings
|
128
|
-
@_rgeo_factory_settings ||= RGeoFactorySettings.new
|
129
|
-
end
|
130
|
-
|
131
|
-
private
|
132
|
-
|
133
|
-
alias_method :new_connection_without_rgeo_modification, :new_connection
|
134
|
-
def new_connection
|
135
|
-
result = new_connection_without_rgeo_modification
|
136
|
-
if result.respond_to?(:set_rgeo_factory_settings)
|
137
|
-
result.set_rgeo_factory_settings(rgeo_factory_settings)
|
138
|
-
end
|
139
|
-
result
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
# :startdoc:
|
144
|
-
|
145
|
-
end
|
146
|
-
end
|