rgeo-activerecord 6.1.0 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10cec86fb0fe82c2495de189762e89b07e8cb7128d778ba41c882d7d7954dece
4
- data.tar.gz: 8c2f7e726217eb8d4261b2b25427b789701d10552a23b0bd00d7cb5fb3ec0c73
3
+ metadata.gz: 32e44e9ec5d1c3416c4acddd27a1abbf2eb1e7d60e1d3bffa32576b16c1c1cc7
4
+ data.tar.gz: 109a5c4b94e7a770ec55125ac19f810441c19cd97ba1a580c90114025d0a8dcf
5
5
  SHA512:
6
- metadata.gz: d49c78a9f23c7d30625bb9114c7a25e7248aa9376f4f309097556fcc8f29f35466b00f9f132b9868b5f7c3c99779e7292151ae984fdecf71e940b8d137734160
7
- data.tar.gz: 02f84c73e57d1e179b5f7aed60e0f18e6ccb743ad123e5f929c1d312d9ad00bf4e65c1aed2535cd0530b30cf914290d27d318e1174ba329d5c5905ec2cf89848
6
+ metadata.gz: fe3abd106906d2e1882f3bd23e19f6d31d75df521ea5f00f5024070590739cf478b2acc8cad400f4c6908f879b29dfad94076d53dcec87268bdd25898147a81e
7
+ data.tar.gz: 461b289050ed2a49013609ec71a06e3e1326fad4464e62adb06808e7ec6415cb140889afef68ebbad27c3ec664c65270b0a922f4063bdc7c853c0c48b2ce86d6
data/History.md CHANGED
@@ -1,3 +1,26 @@
1
+ ### 7.0.1 / 2021-02-23
2
+
3
+ * Fix malformed Arel queries using `as` (ugisozols)
4
+
5
+ ### 7.0.0 / 2020-12-15
6
+
7
+ * Update visit_* methods and Arel interface to support RGeo features.
8
+ * Rework SpatialFactoryStore to support hierarchical matches and fallbacks.
9
+
10
+ ### 6.2.2 / 2020-11-20
11
+
12
+ * Removed `Arel::Visitor::DepthFirst` for ActiveRecord 6.1 compatibility (kamipo)
13
+
14
+ ### 6.2.1 / 2019-07-01
15
+
16
+ * Include GeometryMixin in Cartesian modules (#52, andreasknoepfle)
17
+
18
+
19
+ ### 6.2.0 / 2019-05-09
20
+
21
+ * Allow ActiveRecord 6.0 (#50, corneverbruggen)
22
+
23
+
1
24
  ### 6.1.0 / 2018-12-01
2
25
 
3
26
  * Allow rgeo 2.0
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  ## RGeo::ActiveRecord
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/rgeo-activerecord.svg)](http://badge.fury.io/rb/rgeo-activerecord)
4
- [![Build Status](https://travis-ci.org/rgeo/rgeo-activerecord.svg?branch=master)](https://travis-ci.org/rgeo/rgeo-activerecord)
3
+ [![Gem version](https://img.shields.io/gem/v/rgeo-activerecord)](https://rubygems.org/gems/rgeo-activerecord)
4
+ [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/rgeo/rgeo-activerecord/Tests)](https://github.com/rgeo/rgeo-activerecord/actions?query=workflow%3A%22Tests%22)
5
5
  [![Code Climate](https://codeclimate.com/github/rgeo/rgeo-activerecord.png)](https://codeclimate.com/github/rgeo/rgeo-activerecord)
6
6
 
7
- RGeo::ActiveRecord is an optional [RGeo](http://github.com/dazuma/rgeo) module
7
+ RGeo::ActiveRecord is an optional [RGeo](http://github.com/rgeo/rgeo) module
8
8
  providing spatial extensions for ActiveRecord, as well as a set of helpers for
9
9
  writing spatial ActiveRecord adapters based on RGeo.
10
10
 
@@ -28,9 +28,12 @@ Gemfile:
28
28
  ```ruby
29
29
  gem 'rgeo-activerecord'
30
30
  ```
31
- Version `6.1` supports ActiveRecord 5.0, 5.1, and 5.2 with `rgeo` 1.0+.
32
31
 
33
- Version `6.0` supports ActiveRecord 5.0, 5.1, and 5.2 with `rgeo` 1.x.
32
+ Version `6.2+` supports ActiveRecord 5.x and 6.x with `rgeo` 1.0+
33
+
34
+ Version `6.1` supports ActiveRecord 5.x and 6.0 with `rgeo` 1.0+.
35
+
36
+ Version `6.0` supports ActiveRecord 5.x with `rgeo` 1.x.
34
37
 
35
38
  Version `5.0` supports ActiveRecord 5.0 and 5.1, with `rgeo` 0.6.
36
39
 
@@ -40,32 +43,28 @@ Version `1.1.0` supports ActiveRecord 4.0 and 4.1
40
43
 
41
44
  Version `0.6.0` supports earlier versions of ruby and ActiveRecord:
42
45
 
43
- * Ruby 1.8.7 or later
44
- * ActiveRecord 3.0.3 - 3.2.x
45
- * rgeo 0.3.20 or later
46
- * arel 2.0.6 or later
46
+ - Ruby 1.8.7 or later
47
+ - ActiveRecord 3.0.3 - 3.2.x
48
+ - rgeo 0.3.20 or later
49
+ - arel 2.0.6 or later
47
50
 
48
51
  ### Spatial Factories for Columns
49
52
 
50
- `rgeo_factory_generator` and related methods were removed in version 4.0, since column types
51
- are no longer tied to their database column in ActiveRecord 4.2.
53
+ **_This is an introduction. More details are available in the [wiki entry](https://github.com/rgeo/rgeo-activerecord/wiki/Spatial-Factory-Store)._**
52
54
 
53
- Register spatial factories in the `SpatialFactoryStore` singleton class. Each spatial type
54
- in your ActiveRecord models will use the `SpatialFactoryStore` to retrieve
55
- a factory matching the properties of its type. For example, you can set a different
56
- spatial factory for point types, or for types matching a specific SRID, or having
55
+ Register spatial factories in the `SpatialFactoryStore` singleton class to parse spatial data. Each spatial column
56
+ in your models will use the `SpatialFactoryStore` to parse the stored WKB into an RGeo Feature. The factory from the `SpatialFactoryStore` is chosen based on metadata from the spatial column and the attributes with which the factory was registered to the store. For example, you can set a factory for point types, for types matching a specific SRID, having
57
57
  a Z coordinate, or any combination of attributes.
58
58
 
59
- The supported keys when registering a spatial type are listed here with their default values
60
- and other allowed values:
59
+ The supported keys when registering a spatial type are listed here with their expected values:
61
60
 
62
61
  ```
63
- geo_type: "geometry", # point, polygon, line_string, geometry_collection,
64
- # multi_line_string, multi_point, multi_polygon
65
- has_m: false, # true
66
- has_z: false, # true
67
- sql_type: "geometry", # geography
68
- srid: 0, # (any valid SRID)
62
+ geo_type: string # geometry, point, polygon, line_string, geometry_collection,
63
+ # multi_line_string, multi_point, multi_polygon
64
+ has_m: boolean # true, false
65
+ has_z: boolean # true, false
66
+ sql_type: string # geometry, geography
67
+ srid: int # (any valid SRID)
69
68
  ```
70
69
 
71
70
  The default factories are `RGeo::Geographic.spherical_factory` for
@@ -73,7 +72,7 @@ geographic types, and `RGeo::Cartesian.preferred_factory` for geometric types.
73
72
 
74
73
  Here is an example setup:
75
74
 
76
- ```ruby
75
+ ```rb
77
76
  RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
78
77
  # By default, use the GEOS implementation for spatial columns.
79
78
  config.default = RGeo::Geos.factory_generator
@@ -83,6 +82,33 @@ RGeo::ActiveRecord::SpatialFactoryStore.instance.tap do |config|
83
82
  end
84
83
  ```
85
84
 
85
+ _NOTE: `rgeo_factory_generator` and related methods were removed in version 4.0, since column types
86
+ are no longer tied to their database column in ActiveRecord 4.2._
87
+
88
+ ### Spatial Queries
89
+
90
+ RGeo-ActiveRecord provides an Arel interface to use functions commonly found in spatial databases. The interface also allows for the creation of your own spatial functions if they are not defined.
91
+
92
+ Here is an example using `st_contains`:
93
+
94
+ ```rb
95
+ point = RGeo::Geos.factory(srid: 0).point(1,1)
96
+
97
+ buildings = Building.arel_table
98
+ containing_buiildings = Building.where(buildings[:geom].st_contains(point))
99
+ ```
100
+
101
+ or using the `Arel.spatial` node:
102
+
103
+ ```rb
104
+ point = "SRID=0;POINT(1,1)"
105
+
106
+ buildings = Building.arel_table
107
+ containing_buiildings = Building.where(buildings[:geom].st_contains(Arel.spatial(point)))
108
+ ```
109
+
110
+ _Note: If you pass a WKT representation into an st_function, you should prepend the string with SRID=your_srid, otherwise the database will assume SRID=0 which may cause errors on certain operations._
111
+
86
112
  ### RGeo Dependency
87
113
 
88
114
  See the README for the [rgeo](https://github.com/rgeo/rgeo) gem, a dependency, for further
@@ -107,15 +133,17 @@ http://groups.google.com/group/rgeo-users
107
133
  ### Acknowledgments
108
134
 
109
135
  [Daniel Azuma](http://www.daniel-azuma.com) created RGeo.
110
- [Tee Parham](http://twitter.com/teeparham) is the current maintainer.
136
+ [Tee Parham](http://twitter.com/teeparham) is a former maintainer.
137
+ [Keith Doggett](http://www.github.com/keithdoggett) is a current maintainer.
138
+ [Ulysse Buonomo](http://www.github.com/BuonOmo) is a current maintainer.
111
139
 
112
140
  Development is supported by:
113
141
 
114
- * [Pirq](http://pirq.com)
115
- * [Neighborland](https://neighborland.com)
142
+ - [Klaxit](https://www.klaxit.com)
143
+ - Goldfish Ads
116
144
 
117
145
  ### License
118
146
 
119
- Copyright 2015 Daniel Azuma, Tee Parham
147
+ Copyright 2020 Daniel Azuma, Tee Parham
120
148
 
121
149
  https://github.com/rgeo/rgeo-activerecord/blob/master/LICENSE.txt
@@ -24,16 +24,18 @@ module RGeo
24
24
 
25
25
  def visit_RGeo_ActiveRecord_SpatialNamedFunction(node, collector)
26
26
  name = st_func(node.name)
27
- exprs = []
28
- node.expressions.each_with_index do |expr, index|
29
- exprs << (node.spatial_argument?(index) ? visit_in_spatial_context(expr, collector) : visit(expr, collector))
30
- end
31
27
  collector << name
32
28
  collector << "("
33
29
  collector << "DISTINCT " if node.distinct
34
- collector << exprs.join(", ")
30
+ node.expressions.each_with_index do |expr, index|
31
+ node.spatial_argument?(index) ? visit_in_spatial_context(expr, collector) : visit(expr, collector)
32
+ collector << ", " unless index == node.expressions.size - 1
33
+ end
35
34
  collector << ")"
36
- collector << " AS #{visit(node.alias, collector)}" if node.alias
35
+ if node.alias
36
+ collector << " AS "
37
+ visit node.alias, collector
38
+ end
37
39
  collector
38
40
  end
39
41
 
@@ -41,13 +43,15 @@ module RGeo
41
43
  # The node must be a string (in which case it is treated as WKT),
42
44
  # an RGeo feature, or a spatial attribute.
43
45
  def visit_in_spatial_context(node, collector)
44
- case node
45
- when String
46
- collector << "#{st_func('ST_WKTToSQL')}(#{quote(node)})"
47
- when RGeo::Feature::Instance
48
- collector << visit_RGeo_Feature_Instance(node, collector)
49
- when RGeo::Cartesian::BoundingBox
50
- collector << visit_RGeo_Cartesian_BoundingBox(node, collector)
46
+ if node.is_a?(String)
47
+ collector << "#{st_func('ST_GeomFromText')}(#{quote(node)})"
48
+ elsif node.is_a?(RGeo::Feature::Instance)
49
+ srid = node.srid
50
+ collector << "#{st_func('ST_GeomFromText')}(#{quote(node.to_s)}, #{srid})"
51
+ elsif node.is_a?(RGeo::Cartesian::BoundingBox)
52
+ geom = node.to_geometry
53
+ srid = geom.srid
54
+ collector << "#{st_func('ST_GeomFromText')}(#{quote(geom.to_s)}, #{srid})"
51
55
  else
52
56
  visit(node, collector)
53
57
  end
@@ -86,16 +90,6 @@ module RGeo
86
90
  alias :visit_RGeo_Cartesian_BoundingBox :visit_String
87
91
  end
88
92
 
89
- Arel::Visitors::DepthFirst.class_eval do
90
- alias :visit_RGeo_Feature_Instance :terminal
91
- alias :visit_RGeo_Cartesian_BoundingBox :terminal
92
- end
93
-
94
- Arel::Visitors::ToSql.class_eval do
95
- alias :visit_RGeo_Feature_Instance :visit_String
96
- alias :visit_RGeo_Cartesian_BoundingBox :visit_String
97
- end
98
-
99
93
  # A NamedFunction subclass that keeps track of the spatial-ness of
100
94
  # the arguments and return values, so that it can provide context to
101
95
  # visitors that want to interpret syntax differently when dealing with
@@ -82,6 +82,16 @@ module RGeo
82
82
  Geos::ZMMultiPolygonImpl,
83
83
  Geos::ZMPointImpl,
84
84
  Geos::ZMPolygonImpl,
85
+
86
+ Cartesian::GeometryCollectionImpl,
87
+ Cartesian::LinearRingImpl,
88
+ Cartesian::LineImpl,
89
+ Cartesian::LineStringImpl,
90
+ Cartesian::MultiLineStringImpl,
91
+ Cartesian::MultiPointImpl,
92
+ Cartesian::MultiPolygonImpl,
93
+ Cartesian::PointImpl,
94
+ Cartesian::PolygonImpl
85
95
  ].each { |klass| klass.include(GeometryMixin) }
86
96
 
87
97
  if RGeo::Geos.capi_supported?
@@ -4,16 +4,17 @@ module RGeo
4
4
  module ActiveRecord
5
5
  class SpatialFactoryStore
6
6
  include Singleton
7
+ Entry = Struct.new(:attrs, :factory)
7
8
 
8
9
  attr_accessor :registry
9
10
 
10
11
  def initialize
11
- @registry = {}
12
+ @registry = []
12
13
  @default = nil
13
14
  end
14
15
 
15
16
  def register(factory, attrs = {})
16
- registry[key(attrs)] = factory
17
+ registry.push(Entry.new(filter_attrs(attrs), factory))
17
18
  end
18
19
 
19
20
  def default(attrs = {})
@@ -25,11 +26,11 @@ module RGeo
25
26
  end
26
27
 
27
28
  def factory(attrs)
28
- registry[key(attrs)] || default(attrs)
29
+ closest_factory(attrs) || default(attrs)
29
30
  end
30
31
 
31
32
  def clear
32
- @registry = {}
33
+ @registry = []
33
34
  end
34
35
 
35
36
  private
@@ -50,14 +51,53 @@ module RGeo
50
51
  }
51
52
  end
52
53
 
53
- def key(attrs)
54
- {
55
- geo_type: "geometry",
56
- has_m: false,
57
- has_z: false,
58
- sql_type: "geometry",
59
- srid: 0,
60
- }.merge(attrs).hash
54
+ def filter_attrs(attrs)
55
+ attrs.slice(:geo_type, :has_m, :has_z, :sql_type, :srid)
56
+ end
57
+
58
+ ##
59
+ # Match attrs to the closest equal to or less specific factory
60
+ #
61
+ # That means that attrs can at most be matched to an Entry with the same
62
+ # number of keys as it. But could match with a factory with only 1 key
63
+ # in its attrs.
64
+ #
65
+ # Examples:
66
+ # attrs = {sql_type: "geometry" }, entry_attrs = {sql_type: "geometry", geo_type: "point"}
67
+ # is not a match because the entry is more specific than attrs
68
+ #
69
+ # attrs = {sql_type: "geometry", geo_type: "point"}, entry_attrs = {sql_type: "geometry"}
70
+ # is a match because the entry is less specific than attrs and would be the fallback for all "geometry" types
71
+ #
72
+ # attrs = {sql_type: "geometry", geo_type: "point"}, entry_attrs = {sql_type: "geometry", geo_type: "linestring"}
73
+ # is not a match because there are mismatched keys
74
+ #
75
+ # If there is no match, nil is returned
76
+ def closest_factory(attrs)
77
+ max_matches = 0
78
+ registry.reduce(nil) do |selected_fac, entry|
79
+ cmp = cmp_attrs(attrs, entry.attrs)
80
+ if cmp > max_matches
81
+ max_matches = cmp
82
+ entry.factory
83
+ else
84
+ selected_fac
85
+ end
86
+ end
87
+ end
88
+
89
+ ##
90
+ # Returns number of common key/values
91
+ # or -1 if oth is bigger than attrs, or they have a mismatched key/value pair
92
+ def cmp_attrs(attrs, oth)
93
+ return -1 if oth.size > attrs.size
94
+ matches = 0
95
+ attrs.each do |k, v|
96
+ next if oth[k].nil?
97
+ return -1 unless v == oth[k]
98
+ matches += 1
99
+ end
100
+ matches
61
101
  end
62
102
  end
63
103
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RGeo
4
4
  module ActiveRecord
5
- VERSION = "6.1.0"
5
+ VERSION = "7.0.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,27 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgeo-activerecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.0
4
+ version: 7.0.1
5
5
  platform: ruby
6
6
  authors:
7
- - Daniel Azuma, Tee Parham
7
+ - Daniel Azuma
8
+ - Tee Parham
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2018-12-01 00:00:00.000000000 Z
12
+ date: 2021-02-23 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activerecord
15
16
  requirement: !ruby/object:Gem::Requirement
16
17
  requirements:
17
- - - "~>"
18
+ - - ">="
18
19
  - !ruby/object:Gem::Version
19
20
  version: '5.0'
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
- - - "~>"
25
+ - - ">="
25
26
  - !ruby/object:Gem::Version
26
27
  version: '5.0'
27
28
  - !ruby/object:Gem::Dependency
@@ -122,10 +123,27 @@ dependencies:
122
123
  - - ">="
123
124
  - !ruby/object:Gem::Version
124
125
  version: 1.0.0
126
+ - !ruby/object:Gem::Dependency
127
+ name: simplecov
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: 0.20.0
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 0.20.0
125
140
  description: RGeo is a geospatial data library for Ruby. RGeo::ActiveRecord is an
126
141
  optional RGeo module providing some spatial extensions to ActiveRecord, as well
127
142
  as common tools used by RGeo-based spatial adapters.
128
- email: dazuma@gmail.com, parhameter@gmail.com
143
+ email:
144
+ - dazuma@gmail.com
145
+ - parhameter@gmail.com
146
+ - kfdoggett@gmail.com
129
147
  executables: []
130
148
  extensions: []
131
149
  extra_rdoc_files: []
@@ -142,7 +160,8 @@ files:
142
160
  - lib/rgeo/active_record/spatial_factory_store.rb
143
161
  - lib/rgeo/active_record/version.rb
144
162
  homepage: https://github.com/rgeo/rgeo-activerecord
145
- licenses: []
163
+ licenses:
164
+ - BSD-3-Clause
146
165
  metadata: {}
147
166
  post_install_message:
148
167
  rdoc_options: []
@@ -152,15 +171,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
171
  requirements:
153
172
  - - ">="
154
173
  - !ruby/object:Gem::Version
155
- version: 2.3.0
174
+ version: 2.5.0
156
175
  required_rubygems_version: !ruby/object:Gem::Requirement
157
176
  requirements:
158
177
  - - ">="
159
178
  - !ruby/object:Gem::Version
160
179
  version: '0'
161
180
  requirements: []
162
- rubyforge_project:
163
- rubygems_version: 2.7.8
181
+ rubygems_version: 3.0.8
164
182
  signing_key:
165
183
  specification_version: 4
166
184
  summary: An RGeo module providing spatial extensions to ActiveRecord.