activerecord-postgis-adapter 0.3.5 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,15 @@
1
+ === 0.4.0 / 2011-08-15
2
+
3
+ * Various fixes for Rails 3.1 compatibility.
4
+ * Now requires rgeo-activerecord 0.4.0.
5
+ * INCOMPATIBLE CHANGE: simple queries (e.g. MyClass.where(:latlon => my_point)) use an objective rather than spatial equality test. Earlier versions transformed this form to use st_equals, but now if you need to test for spatial equality, you'll need to call st_equals explicitly. I'm still evaluating which direction we want to go with this in the future, but we may be stuck with the current behavior because the hack required to transform these queries to use spatial equality was egregious and broke in Rails 3.1 with no clear workaround.
6
+
7
+ === 0.3.6 / 2011-06-21
8
+
9
+ * Require latest rgeo-activerecord to get some fixes.
10
+ * Note PostgreSQL 9 requirement in the README. (Reported by Samuel Cochran)
11
+ * Now doesn't throw exceptions if an RGeo cast fails when setting an attribute.
12
+
1
13
  === 0.3.5 / 2011-04-12
2
14
 
3
15
  * The .gemspec was missing the databases.rake file. Fixed.
@@ -89,7 +89,7 @@ Now you can interact with the data using the RGeo types:
89
89
 
90
90
  === Spatial Queries
91
91
 
92
- You can create simple queries based on spatial equality in the same way
92
+ You can create simple queries based on objective equality in the same way
93
93
  you would on a scalar column:
94
94
 
95
95
  rec = MySpatialTable.where(:latlon => RGeo::Geos.factory.point(-122, 47)).first
@@ -111,11 +111,13 @@ write more complex queries in SQL.
111
111
  This adapter has the following requirements:
112
112
 
113
113
  * Ruby 1.8.7 or later. Ruby 1.9.2 or later preferred.
114
+ * PostgreSQL 9.0 or later.
114
115
  * PostGIS 1.5 or later.
115
- * pg gem 0.10 or later.
116
+ * pg gem 0.11 or later.
116
117
  * \ActiveRecord 3.0.3 or later. Earlier versions will not work.
117
- * rgeo gem 0.2.8 or later.
118
- * rgeo-activerecord gem 0.3.3 or later.
118
+ Appears to be compatible with Rails 3.1rc5.
119
+ * rgeo gem 0.3.2 or later.
120
+ * rgeo-activerecord gem 0.4.0 or later.
119
121
 
120
122
  Install this adapter as a gem:
121
123
 
@@ -260,6 +262,8 @@ Contributions are welcome. Fork the project on Github.
260
262
 
261
263
  Report bugs on Github issues at http://github.org/dazuma/activerecord-postgis-adapter/issues
262
264
 
265
+ Support available on the rgeo-users google group at http://groups.google.com/group/rgeo-users
266
+
263
267
  Contact the author at dazuma at gmail dot com.
264
268
 
265
269
  === Acknowledgments
data/Version CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.4.0
@@ -53,6 +53,11 @@ module ActiveRecord
53
53
  @@native_database_types = nil
54
54
 
55
55
 
56
+ def set_rgeo_factory_settings(factory_settings_)
57
+ @rgeo_factory_settings = factory_settings_
58
+ end
59
+
60
+
56
61
  def adapter_name
57
62
  PostGISAdapter::ADAPTER_NAME
58
63
  end
@@ -90,16 +95,30 @@ module ActiveRecord
90
95
  end
91
96
 
92
97
 
98
+ def type_cast(value_, column_)
99
+ if ::RGeo::Feature::Geometry.check_type(value_)
100
+ ::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value_)
101
+ else
102
+ super
103
+ end
104
+ end
105
+
106
+
93
107
  def columns(table_name_, name_=nil)
108
+ # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
109
+ # We needed to return a spatial column subclass.
94
110
  table_name_ = table_name_.to_s
95
111
  spatial_info_ = spatial_column_info(table_name_)
96
112
  column_definitions(table_name_).collect do |name_, type_, default_, notnull_|
97
- SpatialColumn.new(name_, default_, type_, notnull_ == 'f', type_ =~ /geometry/i ? spatial_info_[name_] : nil)
113
+ SpatialColumn.new(@rgeo_factory_settings, table_name_.to_s, name_, default_, type_,
114
+ notnull_ == 'f', type_ =~ /geometry/i ? spatial_info_[name_] : nil)
98
115
  end
99
116
  end
100
117
 
101
118
 
102
119
  def indexes(table_name_, name_=nil)
120
+ # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
121
+ # We needed to modify the catalog queries to pull the index type info.
103
122
 
104
123
  # Remove postgis from schemas
105
124
  schemas_ = schema_search_path.split(/,/)
@@ -143,6 +162,12 @@ module ActiveRecord
143
162
 
144
163
 
145
164
  def create_table(table_name_, options_={})
165
+ # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
166
+ # Note: we have to do a full replacement for Rails 3.0 because
167
+ # there is no way to override the creation of the table
168
+ # definition object. In Rails 3.1, this has been factored out
169
+ # into the table_definition method, so we could rewrite this
170
+ # to call super if we're willing to go 3.1 only.
146
171
  table_name_ = table_name_.to_s
147
172
  table_definition_ = SpatialTableDefinition.new(self)
148
173
  table_definition_.primary_key(options_[:primary_key] || ::ActiveRecord::Base.get_primary_key(table_name_.singularize)) unless options_[:id] == false
@@ -229,6 +254,8 @@ module ActiveRecord
229
254
 
230
255
 
231
256
  def add_index(table_name_, column_name_, options_={})
257
+ # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
258
+ # We have to fully-replace because of the gist_clause.
232
259
  table_name_ = table_name_.to_s
233
260
  column_names_ = ::Array.wrap(column_name_)
234
261
  index_name_ = index_name(table_name_, :column => column_names_)
@@ -46,7 +46,9 @@ module ActiveRecord
46
46
  class SpatialColumn < ConnectionAdapters::PostgreSQLColumn
47
47
 
48
48
 
49
- def initialize(name_, default_, sql_type_=nil, null_=true, opts_=nil)
49
+ def initialize(factory_settings_, table_name_, name_, default_, sql_type_=nil, null_=true, opts_=nil)
50
+ @factory_settings = factory_settings_
51
+ @table_name = table_name_
50
52
  super(name_, default_, sql_type_, null_)
51
53
  @geographic = sql_type_ =~ /geography/i ? true : false
52
54
  if opts_
@@ -92,12 +94,6 @@ module ActiveRecord
92
94
  @limit = {:no_constraints => true}
93
95
  end
94
96
  end
95
- @ar_class = ::ActiveRecord::Base
96
- end
97
-
98
-
99
- def set_ar_class(val_)
100
- @ar_class = val_
101
97
  end
102
98
 
103
99
 
@@ -129,8 +125,8 @@ module ActiveRecord
129
125
 
130
126
  def type_cast(value_)
131
127
  if type == :spatial
132
- SpatialColumn.convert_to_geometry(value_, @ar_class, name, @geographic,
133
- @srid, @has_z, @has_m)
128
+ SpatialColumn.convert_to_geometry(value_, @factory_settings, @table_name, name,
129
+ @geographic, @srid, @has_z, @has_m)
134
130
  else
135
131
  super
136
132
  end
@@ -140,8 +136,9 @@ module ActiveRecord
140
136
  def type_cast_code(var_name_)
141
137
  if type == :spatial
142
138
  "::ActiveRecord::ConnectionAdapters::PostGISAdapter::SpatialColumn.convert_to_geometry("+
143
- "#{var_name_}, self.class, #{name.inspect}, #{@geographic ? 'true' : 'false'}, "+
144
- "#{@srid.inspect}, #{@has_z ? 'true' : 'false'}, #{@has_m ? 'true' : 'false'})"
139
+ "#{var_name_}, self.class.rgeo_factory_settings, self.class.table_name, "+
140
+ "#{name.inspect}, #{@geographic ? 'true' : 'false'}, #{@srid.inspect}, "+
141
+ "#{@has_z ? 'true' : 'false'}, #{@has_m ? 'true' : 'false'})"
145
142
  else
146
143
  super
147
144
  end
@@ -156,7 +153,7 @@ module ActiveRecord
156
153
  end
157
154
 
158
155
 
159
- def self.convert_to_geometry(input_, ar_class_, column_, geographic_, srid_, has_z_, has_m_)
156
+ def self.convert_to_geometry(input_, factory_settings_, table_name_, column_, geographic_, srid_, has_z_, has_m_)
160
157
  if srid_
161
158
  constraints_ = {:geographic => geographic_, :has_z_coordinate => has_z_,
162
159
  :has_m_coordinate => has_m_, :srid => srid_}
@@ -165,18 +162,16 @@ module ActiveRecord
165
162
  end
166
163
  case input_
167
164
  when ::RGeo::Feature::Geometry
168
- factory_ = ar_class_.rgeo_factory_for_column(column_, constraints_)
169
- ::RGeo::Feature.cast(input_, factory_)
165
+ factory_ = factory_settings_.get_column_factory(table_name_, column_, constraints_)
166
+ ::RGeo::Feature.cast(input_, factory_) rescue nil
170
167
  when ::String
171
168
  if input_.length == 0
172
169
  nil
173
170
  else
174
- factory_ = ar_class_.rgeo_factory_for_column(column_, constraints_)
171
+ factory_ = factory_settings_.get_column_factory(table_name_, column_, constraints_)
175
172
  marker_ = input_[0,1]
176
- if marker_ == "\x00" || marker_ == "\x01"
173
+ if marker_ == "\x00" || marker_ == "\x01" || input_[0,4] =~ /[0-9a-fA-F]{4}/
177
174
  ::RGeo::WKRep::WKBParser.new(factory_, :support_ewkb => true).parse(input_) rescue nil
178
- elsif input_[0,4] =~ /[0-9a-fA-F]{4}/
179
- ::RGeo::WKRep::WKBParser.new(factory_, :support_ewkb => true).parse_hex(input_) rescue nil
180
175
  else
181
176
  ::RGeo::WKRep::WKTParser.new(factory_, :support_ewkt => true).parse(input_) rescue nil
182
177
  end
@@ -192,10 +187,8 @@ module ActiveRecord
192
187
 
193
188
  end
194
189
 
195
-
196
190
  end
197
191
 
198
-
199
192
  end
200
193
 
201
194
  # :startdoc:
@@ -53,9 +53,9 @@ module RGeo
53
53
  def populate_ar_class(content_)
54
54
  klass_ = create_ar_class
55
55
  case content_
56
- when :latlon_point
56
+ when :mercator_point
57
57
  klass_.connection.create_table(:spatial_test) do |t_|
58
- t_.column 'latlon', :point, :srid => 4326
58
+ t_.column 'latlon', :point, :srid => 3785
59
59
  end
60
60
  when :latlon_point_geographic
61
61
  klass_.connection.create_table(:spatial_test) do |t_|
@@ -83,34 +83,34 @@ module RGeo
83
83
 
84
84
 
85
85
  def test_set_and_get_point
86
- klass_ = populate_ar_class(:latlon_point)
86
+ klass_ = populate_ar_class(:mercator_point)
87
87
  obj_ = klass_.new
88
88
  assert_nil(obj_.latlon)
89
89
  obj_.latlon = @factory.point(1, 2)
90
90
  assert_equal(@factory.point(1, 2), obj_.latlon)
91
- assert_equal(4326, obj_.latlon.srid)
91
+ assert_equal(3785, obj_.latlon.srid)
92
92
  end
93
93
 
94
94
 
95
95
  def test_set_and_get_point_from_wkt
96
- klass_ = populate_ar_class(:latlon_point)
96
+ klass_ = populate_ar_class(:mercator_point)
97
97
  obj_ = klass_.new
98
98
  assert_nil(obj_.latlon)
99
99
  obj_.latlon = 'POINT(1 2)'
100
100
  assert_equal(@factory.point(1, 2), obj_.latlon)
101
- assert_equal(4326, obj_.latlon.srid)
101
+ assert_equal(3785, obj_.latlon.srid)
102
102
  end
103
103
 
104
104
 
105
105
  def test_save_and_load_point
106
- klass_ = populate_ar_class(:latlon_point)
106
+ klass_ = populate_ar_class(:mercator_point)
107
107
  obj_ = klass_.new
108
108
  obj_.latlon = @factory.point(1, 2)
109
109
  obj_.save!
110
110
  id_ = obj_.id
111
111
  obj2_ = klass_.find(id_)
112
112
  assert_equal(@factory.point(1, 2), obj2_.latlon)
113
- assert_equal(4326, obj2_.latlon.srid)
113
+ assert_equal(3785, obj2_.latlon.srid)
114
114
  assert_equal(true, ::RGeo::Geos.is_geos?(obj2_.latlon))
115
115
  end
116
116
 
@@ -129,14 +129,21 @@ module RGeo
129
129
 
130
130
 
131
131
  def test_save_and_load_point_from_wkt
132
- klass_ = populate_ar_class(:latlon_point)
132
+ klass_ = populate_ar_class(:mercator_point)
133
133
  obj_ = klass_.new
134
134
  obj_.latlon = 'POINT(1 2)'
135
135
  obj_.save!
136
136
  id_ = obj_.id
137
137
  obj2_ = klass_.find(id_)
138
138
  assert_equal(@factory.point(1, 2), obj2_.latlon)
139
- assert_equal(4326, obj2_.latlon.srid)
139
+ assert_equal(3785, obj2_.latlon.srid)
140
+ end
141
+
142
+
143
+ def test_set_point_bad_wkt
144
+ klass_ = populate_ar_class(:mercator_point)
145
+ obj_ = klass_.create(:latlon => 'POINT (x)')
146
+ assert_nil(obj_.latlon)
140
147
  end
141
148
 
142
149
 
@@ -182,6 +189,15 @@ module RGeo
182
189
  end
183
190
 
184
191
 
192
+ def test_point_to_json
193
+ klass_ = populate_ar_class(:mercator_point)
194
+ obj_ = klass_.new
195
+ assert_match(/"latlon":null/, obj_.to_json)
196
+ obj_.latlon = @factory.point(1, 2)
197
+ assert_match(/"latlon":"POINT\s\(1\.0\s2\.0\)"/, obj_.to_json)
198
+ end
199
+
200
+
185
201
  end
186
202
 
187
203
  end
@@ -53,9 +53,9 @@ module RGeo
53
53
  def populate_ar_class(content_)
54
54
  klass_ = create_ar_class
55
55
  case content_
56
- when :latlon_point
56
+ when :mercator_point
57
57
  klass_.connection.create_table(:spatial_test) do |t_|
58
- t_.column 'latlon', :point, :srid => 4326
58
+ t_.column 'latlon', :point, :srid => 3785
59
59
  end
60
60
  when :latlon_point_geographic
61
61
  klass_.connection.create_table(:spatial_test) do |t_|
@@ -63,7 +63,7 @@ module RGeo
63
63
  end
64
64
  when :path_linestring
65
65
  klass_.connection.create_table(:spatial_test) do |t_|
66
- t_.column 'path', :line_string, :srid => 4326
66
+ t_.column 'path', :line_string, :srid => 3785
67
67
  end
68
68
  end
69
69
  klass_
@@ -71,7 +71,7 @@ module RGeo
71
71
 
72
72
 
73
73
  def test_query_point
74
- klass_ = populate_ar_class(:latlon_point)
74
+ klass_ = populate_ar_class(:mercator_point)
75
75
  obj_ = klass_.new
76
76
  obj_.latlon = @factory.point(1, 2)
77
77
  obj_.save!
@@ -84,14 +84,14 @@ module RGeo
84
84
 
85
85
 
86
86
  def test_query_point_wkt
87
- klass_ = populate_ar_class(:latlon_point)
87
+ klass_ = populate_ar_class(:mercator_point)
88
88
  obj_ = klass_.new
89
89
  obj_.latlon = @factory.point(1, 2)
90
90
  obj_.save!
91
91
  id_ = obj_.id
92
- obj2_ = klass_.where(:latlon => 'SRID=4326;POINT(1 2)').first
92
+ obj2_ = klass_.where(:latlon => 'SRID=3785;POINT(1 2)').first
93
93
  assert_equal(id_, obj2_.id)
94
- obj3_ = klass_.where(:latlon => 'SRID=4326;POINT(2 2)').first
94
+ obj3_ = klass_.where(:latlon => 'SRID=3785;POINT(2 2)').first
95
95
  assert_nil(obj3_)
96
96
  end
97
97
 
@@ -100,27 +100,27 @@ module RGeo
100
100
 
101
101
 
102
102
  def test_query_st_distance
103
- klass_ = populate_ar_class(:latlon_point)
103
+ klass_ = populate_ar_class(:mercator_point)
104
104
  obj_ = klass_.new
105
105
  obj_.latlon = @factory.point(1, 2)
106
106
  obj_.save!
107
107
  id_ = obj_.id
108
- obj2_ = klass_.where(klass_.arel_table[:latlon].st_distance('SRID=4326;POINT(2 3)').lt(2)).first
108
+ obj2_ = klass_.where(klass_.arel_table[:latlon].st_distance('SRID=3785;POINT(2 3)').lt(2)).first
109
109
  assert_equal(id_, obj2_.id)
110
- obj3_ = klass_.where(klass_.arel_table[:latlon].st_distance('SRID=4326;POINT(2 3)').gt(2)).first
110
+ obj3_ = klass_.where(klass_.arel_table[:latlon].st_distance('SRID=3785;POINT(2 3)').gt(2)).first
111
111
  assert_nil(obj3_)
112
112
  end
113
113
 
114
114
 
115
115
  def test_query_st_distance_from_constant
116
- klass_ = populate_ar_class(:latlon_point)
116
+ klass_ = populate_ar_class(:mercator_point)
117
117
  obj_ = klass_.new
118
118
  obj_.latlon = @factory.point(1, 2)
119
119
  obj_.save!
120
120
  id_ = obj_.id
121
- obj2_ = klass_.where(::Arel.spatial('SRID=4326;POINT(2 3)').st_distance(klass_.arel_table[:latlon]).lt(2)).first
121
+ obj2_ = klass_.where(::Arel.spatial('SRID=3785;POINT(2 3)').st_distance(klass_.arel_table[:latlon]).lt(2)).first
122
122
  assert_equal(id_, obj2_.id)
123
- obj3_ = klass_.where(::Arel.spatial('SRID=4326;POINT(2 3)').st_distance(klass_.arel_table[:latlon]).gt(2)).first
123
+ obj3_ = klass_.where(::Arel.spatial('SRID=3785;POINT(2 3)').st_distance(klass_.arel_table[:latlon]).gt(2)).first
124
124
  assert_nil(obj3_)
125
125
  end
126
126
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: activerecord-postgis-adapter
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.5
5
+ version: 0.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Daniel Azuma
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-13 00:00:00 Z
13
+ date: 2011-08-15 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rgeo-activerecord
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ~>
22
22
  - !ruby/object:Gem::Version
23
- version: 0.3.3
23
+ version: 0.4.0
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
26
  - !ruby/object:Gem::Dependency
@@ -31,7 +31,7 @@ dependencies:
31
31
  requirements:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 0.10.0
34
+ version: 0.11.0
35
35
  type: :runtime
36
36
  version_requirements: *id002
37
37
  description: This is an ActiveRecord connection adapter for PostGIS. It is based on the stock PostgreSQL adapter, but provides built-in support for the spatial extensions provided by PostGIS. It uses the RGeo library to represent spatial data in Ruby.
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  requirements: []
83
83
 
84
84
  rubyforge_project: virtuoso
85
- rubygems_version: 1.7.2
85
+ rubygems_version: 1.8.7
86
86
  signing_key:
87
87
  specification_version: 3
88
88
  summary: An ActiveRecord adapter for PostGIS, based on RGeo.