activerecord-postgis-adapter 0.4.0 → 0.4.1

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.
@@ -1,3 +1,8 @@
1
+ === 0.4.1 / 2012-02-22
2
+
3
+ * Some compatibility fixes for Rails 3.2. (Reported by Ryan Williams with implementation help from Radek Paviensky.)
4
+ * Now requires rgeo-activerecord 0.4.3.
5
+
1
6
  === 0.4.0 / 2011-08-15
2
7
 
3
8
  * Various fixes for Rails 3.1 compatibility.
@@ -115,9 +115,9 @@ This adapter has the following requirements:
115
115
  * PostGIS 1.5 or later.
116
116
  * pg gem 0.11 or later.
117
117
  * \ActiveRecord 3.0.3 or later. Earlier versions will not work.
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.
118
+ Should be compatible with Rails versions through 3.2.x.
119
+ * rgeo gem 0.3.4 or later.
120
+ * rgeo-activerecord gem 0.4.3 or later.
121
121
 
122
122
  Install this adapter as a gem:
123
123
 
@@ -271,7 +271,7 @@ Contact the author at dazuma at gmail dot com.
271
271
  The PostGIS Adapter and its supporting libraries (including RGeo) are
272
272
  written by Daniel Azuma (http://www.daniel-azuma.com).
273
273
 
274
- Development of RGeo is sponsored by GeoPage, Inc. (http://www.geopage.com).
274
+ Development is supported by Pirq. (http://www.pirq.com).
275
275
 
276
276
  This adapter implementation owes some debt to the spatial_adapter plugin
277
277
  (http://github.com/fragility/spatial_adapter). Although we made some
data/Version CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.4.1
@@ -1,15 +1,15 @@
1
1
  # -----------------------------------------------------------------------------
2
- #
2
+ #
3
3
  # PostGIS adapter for ActiveRecord
4
- #
4
+ #
5
5
  # -----------------------------------------------------------------------------
6
- # Copyright 2010 Daniel Azuma
7
- #
6
+ # Copyright 2010-2012 Daniel Azuma
7
+ #
8
8
  # All rights reserved.
9
- #
9
+ #
10
10
  # Redistribution and use in source and binary forms, with or without
11
11
  # modification, are permitted provided that the following conditions are met:
12
- #
12
+ #
13
13
  # * Redistributions of source code must retain the above copyright notice,
14
14
  # this list of conditions and the following disclaimer.
15
15
  # * Redistributions in binary form must reproduce the above copyright notice,
@@ -18,7 +18,7 @@
18
18
  # * Neither the name of the copyright holder, nor the names of any other
19
19
  # contributors to this software, may be used to endorse or promote products
20
20
  # derived from this software without specific prior written permission.
21
- #
21
+ #
22
22
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
23
  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
24
  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -42,19 +42,19 @@ require 'active_record/connection_adapters/postgresql_adapter'
42
42
  # connection adapter into ActiveRecord.
43
43
 
44
44
  module ActiveRecord
45
-
46
-
45
+
46
+
47
47
  # ActiveRecord looks for the postgis_connection factory method in
48
48
  # this class.
49
-
49
+
50
50
  class Base
51
-
52
-
51
+
52
+
53
53
  # Create a postgis connection adapter.
54
-
54
+
55
55
  def self.postgis_connection(config_)
56
56
  require 'pg'
57
-
57
+
58
58
  config_ = config_.symbolize_keys
59
59
  host_ = config_[:host]
60
60
  port_ = config_[:port] || 5432
@@ -65,30 +65,30 @@ module ActiveRecord
65
65
  else
66
66
  raise ::ArgumentError, "No database specified. Missing argument: database."
67
67
  end
68
-
68
+
69
69
  # The postgres drivers don't allow the creation of an unconnected PGconn object,
70
70
  # so just pass a nil connection object for the time being.
71
71
  ::ActiveRecord::ConnectionAdapters::PostGISAdapter::MainAdapter.new(nil, logger, [host_, port_, nil, nil, database_, username_, password_], config_)
72
72
  end
73
-
74
-
73
+
74
+
75
75
  end
76
-
77
-
76
+
77
+
78
78
  # All ActiveRecord adapters go in this namespace.
79
79
  module ConnectionAdapters
80
-
80
+
81
81
  # The PostGIS Adapter
82
82
  module PostGISAdapter
83
-
83
+
84
84
  # The name returned by the adapter_name method of this adapter.
85
85
  ADAPTER_NAME = 'PostGIS'.freeze
86
-
86
+
87
87
  end
88
-
88
+
89
89
  end
90
-
91
-
90
+
91
+
92
92
  end
93
93
 
94
94
 
@@ -1,15 +1,15 @@
1
1
  # -----------------------------------------------------------------------------
2
- #
2
+ #
3
3
  # PostGIS adapter for ActiveRecord
4
- #
4
+ #
5
5
  # -----------------------------------------------------------------------------
6
- # Copyright 2010 Daniel Azuma
7
- #
6
+ # Copyright 2010-2012 Daniel Azuma
7
+ #
8
8
  # All rights reserved.
9
- #
9
+ #
10
10
  # Redistribution and use in source and binary forms, with or without
11
11
  # modification, are permitted provided that the following conditions are met:
12
- #
12
+ #
13
13
  # * Redistributions of source code must retain the above copyright notice,
14
14
  # this list of conditions and the following disclaimer.
15
15
  # * Redistributions in binary form must reproduce the above copyright notice,
@@ -18,7 +18,7 @@
18
18
  # * Neither the name of the copyright holder, nor the names of any other
19
19
  # contributors to this software, may be used to endorse or promote products
20
20
  # derived from this software without specific prior written permission.
21
- #
21
+ #
22
22
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
23
  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
24
  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -38,25 +38,25 @@
38
38
 
39
39
  module Arel
40
40
  module Visitors
41
-
41
+
42
42
  class PostGIS < PostgreSQL
43
-
43
+
44
44
  FUNC_MAP = {
45
45
  'st_wkttosql' => 'ST_GeomFromEWKT',
46
46
  }
47
-
47
+
48
48
  include ::RGeo::ActiveRecord::SpatialToSql
49
-
49
+
50
50
  def st_func(standard_name_)
51
51
  FUNC_MAP[standard_name_.downcase] || standard_name_
52
52
  end
53
-
53
+
54
54
  alias_method :visit_in_spatial_context, :visit
55
-
55
+
56
56
  end
57
-
57
+
58
58
  VISITORS['postgis'] = ::Arel::Visitors::PostGIS
59
-
59
+
60
60
  end
61
61
  end
62
62
 
@@ -1,15 +1,15 @@
1
1
  # -----------------------------------------------------------------------------
2
- #
2
+ #
3
3
  # Rakefile changes for PostGIS adapter
4
- #
4
+ #
5
5
  # -----------------------------------------------------------------------------
6
- # Copyright 2010 Daniel Azuma
7
- #
6
+ # Copyright 2010-2012 Daniel Azuma
7
+ #
8
8
  # All rights reserved.
9
- #
9
+ #
10
10
  # Redistribution and use in source and binary forms, with or without
11
11
  # modification, are permitted provided that the following conditions are met:
12
- #
12
+ #
13
13
  # * Redistributions of source code must retain the above copyright notice,
14
14
  # this list of conditions and the following disclaimer.
15
15
  # * Redistributions in binary form must reproduce the above copyright notice,
@@ -18,7 +18,7 @@
18
18
  # * Neither the name of the copyright holder, nor the names of any other
19
19
  # contributors to this software, may be used to endorse or promote products
20
20
  # derived from this software without specific prior written permission.
21
- #
21
+ #
22
22
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
23
  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
24
  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -51,14 +51,14 @@ def create_database(config_)
51
51
  username_ = config_['username'] # regular user name
52
52
  su_username_ = config_['su_username'] || username_ # superuser name
53
53
  su_password_ = config_['su_password'] || config_['password'] # superuser password
54
-
54
+
55
55
  # Create the database. Optionally do so as the given superuser.
56
56
  # But make sure the database is owned by the regular user.
57
57
  ::ActiveRecord::Base.establish_connection(config_.merge('database' => 'postgres', 'schema_search_path' => 'public', 'username' => su_username_, 'password' => su_password_))
58
58
  extra_configs_ = {'encoding' => @encoding}
59
59
  extra_configs_['owner'] = username_ if has_su_
60
60
  ::ActiveRecord::Base.connection.create_database(config_['database'], config_.merge(extra_configs_))
61
-
61
+
62
62
  # Initial setup of the database: Add schemas from the search path.
63
63
  # If a superuser is given, we log in as the superuser, but we make sure
64
64
  # the schemas are owned by the regular user.
@@ -70,7 +70,7 @@ def create_database(config_)
70
70
  search_path_.each do |schema_|
71
71
  conn_.execute("CREATE SCHEMA #{schema_}#{auth_}") unless schema_.downcase == 'public'
72
72
  end
73
-
73
+
74
74
  # Define the postgis stuff, if the script_dir is provided.
75
75
  # Note: a superuser is required to run the postgis definitions.
76
76
  # If a separate superuser is provided, we need to grant privileges on
@@ -89,7 +89,7 @@ def create_database(config_)
89
89
  conn_.execute("GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA #{postgis_schema_} TO #{username_}")
90
90
  end
91
91
  end
92
-
92
+
93
93
  # Done
94
94
  ::ActiveRecord::Base.establish_connection(config_)
95
95
  rescue ::Exception => e_
@@ -1,15 +1,15 @@
1
1
  # -----------------------------------------------------------------------------
2
- #
2
+ #
3
3
  # PostGIS adapter for ActiveRecord
4
- #
4
+ #
5
5
  # -----------------------------------------------------------------------------
6
- # Copyright 2010 Daniel Azuma
7
- #
6
+ # Copyright 2010-2012 Daniel Azuma
7
+ #
8
8
  # All rights reserved.
9
- #
9
+ #
10
10
  # Redistribution and use in source and binary forms, with or without
11
11
  # modification, are permitted provided that the following conditions are met:
12
- #
12
+ #
13
13
  # * Redistributions of source code must retain the above copyright notice,
14
14
  # this list of conditions and the following disclaimer.
15
15
  # * Redistributions in binary form must reproduce the above copyright notice,
@@ -18,7 +18,7 @@
18
18
  # * Neither the name of the copyright holder, nor the names of any other
19
19
  # contributors to this software, may be used to endorse or promote products
20
20
  # derived from this software without specific prior written permission.
21
- #
21
+ #
22
22
  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
23
  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
24
  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -37,55 +37,64 @@
37
37
  # :stopdoc:
38
38
 
39
39
  module ActiveRecord
40
-
40
+
41
41
  module ConnectionAdapters
42
-
42
+
43
43
  module PostGISAdapter
44
-
45
-
44
+
45
+
46
46
  class MainAdapter < PostgreSQLAdapter
47
-
48
-
47
+
48
+
49
49
  SPATIAL_COLUMN_CONSTRUCTORS = ::RGeo::ActiveRecord::DEFAULT_SPATIAL_COLUMN_CONSTRUCTORS.merge(
50
50
  :geography => {:type => 'geometry', :geographic => true}
51
51
  )
52
-
52
+
53
53
  @@native_database_types = nil
54
-
55
-
54
+
55
+
56
+ def initialize(*args_)
57
+ super
58
+ # Rails 3.2 way of defining the visitor: do so in the constructor
59
+ if defined?(@visitor) && @visitor
60
+ @visitor = ::Arel::Visitors::PostGIS.new(self)
61
+ end
62
+ end
63
+
64
+
56
65
  def set_rgeo_factory_settings(factory_settings_)
57
66
  @rgeo_factory_settings = factory_settings_
58
67
  end
59
-
60
-
68
+
69
+
61
70
  def adapter_name
62
71
  PostGISAdapter::ADAPTER_NAME
63
72
  end
64
-
65
-
73
+
74
+
66
75
  def spatial_column_constructor(name_)
67
76
  SPATIAL_COLUMN_CONSTRUCTORS[name_]
68
77
  end
69
-
70
-
78
+
79
+
71
80
  def native_database_types
72
81
  @@native_database_types ||= super.merge(:spatial => {:name => 'geometry'})
73
82
  end
74
-
75
-
83
+
84
+
76
85
  def postgis_lib_version
77
86
  unless defined?(@postgis_lib_version)
78
87
  @postgis_lib_version = select_value("SELECT PostGIS_Lib_Version()") rescue nil
79
88
  end
80
89
  @postgis_lib_version
81
90
  end
82
-
83
-
91
+
92
+
84
93
  def srs_database_columns
85
94
  {:srtext_column => 'srtext', :proj4text_column => 'proj4text', :auth_name_column => 'auth_name', :auth_srid_column => 'auth_srid'}
86
95
  end
87
-
88
-
96
+
97
+
89
98
  def quote(value_, column_=nil)
90
99
  if ::RGeo::Feature::Geometry.check_type(value_)
91
100
  "'#{::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value_)}'"
@@ -93,8 +102,8 @@ module ActiveRecord
93
102
  super
94
103
  end
95
104
  end
96
-
97
-
105
+
106
+
98
107
  def type_cast(value_, column_)
99
108
  if ::RGeo::Feature::Geometry.check_type(value_)
100
109
  ::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value_)
@@ -102,29 +111,29 @@ module ActiveRecord
102
111
  super
103
112
  end
104
113
  end
105
-
106
-
114
+
115
+
107
116
  def columns(table_name_, name_=nil)
108
117
  # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
109
118
  # We needed to return a spatial column subclass.
110
119
  table_name_ = table_name_.to_s
111
120
  spatial_info_ = spatial_column_info(table_name_)
112
121
  column_definitions(table_name_).collect do |name_, type_, default_, notnull_|
113
- SpatialColumn.new(@rgeo_factory_settings, table_name_.to_s, name_, default_, type_,
122
+ SpatialColumn.new(@rgeo_factory_settings, table_name_, name_, default_, type_,
114
123
  notnull_ == 'f', type_ =~ /geometry/i ? spatial_info_[name_] : nil)
115
124
  end
116
125
  end
117
-
118
-
126
+
127
+
119
128
  def indexes(table_name_, name_=nil)
120
129
  # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
121
130
  # We needed to modify the catalog queries to pull the index type info.
122
-
131
+
123
132
  # Remove postgis from schemas
124
133
  schemas_ = schema_search_path.split(/,/)
125
134
  schemas_.delete('postgis')
126
135
  schemas_ = schemas_.map{ |p_| quote(p_) }.join(',')
127
-
136
+
128
137
  # Get index type by joining with pg_am.
129
138
  result_ = query(<<-SQL, name_)
130
139
  SELECT DISTINCT i.relname, d.indisunique, d.indkey, t.oid, am.amname
@@ -138,14 +147,14 @@ module ActiveRecord
138
147
  AND i.relam = am.oid
139
148
  ORDER BY i.relname
140
149
  SQL
141
-
150
+
142
151
  result_.map do |row_|
143
152
  index_name_ = row_[0]
144
153
  unique_ = row_[1] == 't'
145
154
  indkey_ = row_[2].split(" ")
146
155
  oid_ = row_[3]
147
156
  indtype_ = row_[4]
148
-
157
+
149
158
  columns_ = query(<<-SQL, "Columns for index #{row_[0]} on #{table_name_}").inject({}){ |h_, r_| h_[r_[0]] = [r_[1], r_[2]]; h_ }
150
159
  SELECT a.attnum, a.attname, t.typname
151
160
  FROM pg_attribute a, pg_type t
@@ -153,14 +162,14 @@ module ActiveRecord
153
162
  AND a.attnum IN (#{indkey_.join(",")})
154
163
  AND a.atttypid = t.oid
155
164
  SQL
156
-
165
+
157
166
  spatial_ = indtype_ == 'gist' && columns_.size == 1 && (columns_.values.first[1] == 'geometry' || columns_.values.first[1] == 'geography')
158
167
  column_names_ = columns_.values_at(*indkey_).compact.map{ |a_| a_[0] }
159
168
  column_names_.empty? ? nil : ::RGeo::ActiveRecord::SpatialIndexDefinition.new(table_name_, index_name_, unique_, column_names_, nil, spatial_)
160
169
  end.compact
161
170
  end
162
-
163
-
171
+
172
+
164
173
  def create_table(table_name_, options_={})
165
174
  # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
166
175
  # Note: we have to do a full replacement for Rails 3.0 because
@@ -175,13 +184,13 @@ module ActiveRecord
175
184
  if options_[:force] && table_exists?(table_name_)
176
185
  drop_table(table_name_, options_)
177
186
  end
178
-
187
+
179
188
  create_sql_ = "CREATE#{' TEMPORARY' if options_[:temporary]} TABLE "
180
189
  create_sql_ << "#{quote_table_name(table_name_)} ("
181
190
  create_sql_ << table_definition_.to_sql
182
191
  create_sql_ << ") #{options_[:options]}"
183
192
  execute create_sql_
184
-
193
+
185
194
  table_definition_.non_geographic_spatial_columns.each do |col_|
186
195
  type_ = col_.spatial_type.gsub('_', '').upcase
187
196
  has_z_ = col_.has_z?
@@ -193,14 +202,14 @@ module ActiveRecord
193
202
  execute("SELECT AddGeometryColumn('#{quote_string(table_name_)}', '#{quote_string(col_.name.to_s)}', #{col_.srid}, '#{quote_string(type_)}', #{dimensions_})")
194
203
  end
195
204
  end
196
-
197
-
198
- def drop_table(table_name_, options_={})
205
+
206
+
207
+ def drop_table(table_name_, *options_)
199
208
  execute("DELETE from geometry_columns where f_table_name='#{quote_string(table_name_.to_s)}'")
200
209
  super
201
210
  end
202
-
203
-
211
+
212
+
204
213
  def add_column(table_name_, column_name_, type_, options_={})
205
214
  table_name_ = table_name_.to_s
206
215
  if (info_ = spatial_column_constructor(type_.to_sym))
@@ -234,8 +243,8 @@ module ActiveRecord
234
243
  super
235
244
  end
236
245
  end
237
-
238
-
246
+
247
+
239
248
  def remove_column(table_name_, *column_names_)
240
249
  column_names_ = column_names_.flatten.map{ |n_| n_.to_s }
241
250
  spatial_info_ = spatial_column_info(table_name_)
@@ -251,8 +260,8 @@ module ActiveRecord
251
260
  super(table_name_, *remaining_column_names_)
252
261
  end
253
262
  end
254
-
255
-
263
+
264
+
256
265
  def add_index(table_name_, column_name_, options_={})
257
266
  # FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
258
267
  # We have to fully-replace because of the gist_clause.
@@ -277,8 +286,8 @@ module ActiveRecord
277
286
  quoted_column_names_ = quoted_columns_for_index(column_names_, options_).join(", ")
278
287
  execute "CREATE #{index_type_} INDEX #{quote_column_name(index_name_)} ON #{quote_table_name(table_name_)} #{gist_clause_} (#{quoted_column_names_})"
279
288
  end
280
-
281
-
289
+
290
+
282
291
  def spatial_column_info(table_name_)
283
292
  info_ = query("SELECT * FROM geometry_columns WHERE f_table_name='#{quote_string(table_name_.to_s)}'")
284
293
  result_ = {}
@@ -300,15 +309,15 @@ module ActiveRecord
300
309
  end
301
310
  result_
302
311
  end
303
-
304
-
312
+
313
+
305
314
  end
306
-
307
-
315
+
316
+
308
317
  end
309
-
318
+
310
319
  end
311
-
320
+
312
321
  end
313
322
 
314
323
  # :startdoc: