activerecord-postgis-adapter 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Documentation.rdoc +6 -8
- data/History.rdoc +5 -0
- data/README.rdoc +22 -22
- data/lib/active_record/connection_adapters/postgis_adapter.rb +9 -14
- data/lib/active_record/connection_adapters/postgis_adapter/rails4/create_connection.rb +11 -13
- data/lib/active_record/connection_adapters/postgis_adapter/rails4/main_adapter.rb +122 -102
- data/lib/active_record/connection_adapters/postgis_adapter/rails4/postgis_database_tasks.rb +20 -44
- data/lib/active_record/connection_adapters/postgis_adapter/rails4/spatial_column.rb +48 -69
- data/lib/active_record/connection_adapters/postgis_adapter/rails4/spatial_table_definition.rb +52 -55
- data/lib/active_record/connection_adapters/postgis_adapter/shared/arel_tosql.rb +2 -2
- data/lib/active_record/connection_adapters/postgis_adapter/shared/common_adapter_methods.rb +9 -9
- data/lib/active_record/connection_adapters/postgis_adapter/shared/setup.rb +1 -11
- data/lib/active_record/connection_adapters/postgis_adapter/version.rb +1 -1
- data/test/basic_test.rb +190 -0
- data/test/ddl_test.rb +279 -0
- data/test/{tc_nested_class.rb → nested_class_test.rb} +7 -15
- data/test/setup_test.rb +17 -0
- data/test/spatial_queries_test.rb +105 -0
- data/test/test_helper.rb +8 -0
- data/test/test_tasks.rb +111 -0
- metadata +24 -34
- data/test/tc_basic.rb +0 -212
- data/test/tc_ddl.rb +0 -279
- data/test/tc_spatial_queries.rb +0 -126
- data/test/tc_tasks.rb +0 -112
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ce9c5498b97818ea15208bc26dcba1ae43815443
|
4
|
+
data.tar.gz: 278397fdce7c4d48c6c4b1dbf730249ef39c3fb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a9b10d39cc0eb914432b66b8d65eab3888e0bdd3a5dc1b1860ceccd45083da9310201d53e2a67d6ff541ee9bc0ab263df6732676c593937bc239bd701a185a4
|
7
|
+
data.tar.gz: d8c6c6404887acadc2040b4344cbe5a116d8572b87ce36ffd4e08024a2b707afc8d68df55cf8061f30a244787d596ddb237275a8dddb7ca374a43650f7454139
|
data/Documentation.rdoc
CHANGED
@@ -6,24 +6,22 @@ This document provides basic how-to information that should help get you started
|
|
6
6
|
* How to set up and configure spatial columns and tables.
|
7
7
|
* How to read, write, and query spatial data.
|
8
8
|
|
9
|
-
This document is part of the distribution for the activerecord-postgis-adapter gem. For more information, please visit http://
|
9
|
+
This document is part of the distribution for the activerecord-postgis-adapter gem. For more information, please visit http://rgeo.github.com/activerecord-postgis-adapter.
|
10
10
|
|
11
11
|
== Installation and Configuration
|
12
12
|
|
13
|
-
===
|
13
|
+
=== Dependencies
|
14
14
|
|
15
|
-
Generally, we recommend starting with the latest versions of Ruby, Rails, PostgreSQL, and PostGIS.
|
15
|
+
Generally, we recommend starting with the latest versions of Ruby, Rails, PostgreSQL, and PostGIS. The minimum supported configuration is the following:
|
16
16
|
|
17
17
|
* Ruby 1.8.7
|
18
18
|
* Rails 3.0.3
|
19
19
|
* PostgreSQL 9.0
|
20
20
|
* PostGIS 1.5
|
21
21
|
|
22
|
-
|
22
|
+
We recommend using the latest available if possible.
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
JRuby and the JDBC Postgres Adapter is supported. But, as of this writing, the JDBC adapters themselves are not yet compatible with Rails 4.
|
24
|
+
JRuby and the JDBC Postgres Adapter are supported for Rails 3.x. Support is coming soon for Rails 4.
|
27
25
|
|
28
26
|
=== Creating a Spatial Rails App
|
29
27
|
|
@@ -237,7 +235,7 @@ The RGeo factory for the value is determined by how you configured the \ActiveRe
|
|
237
235
|
|
238
236
|
You can set a spatial attribute by providing an RGeo geometry object, or by providing the WKT string representation of the geometry. If a string is provided, the activerecord-postgis-adapter will attempt to parse it as WKT and set the value accordingly.
|
239
237
|
|
240
|
-
record.lonlat = 'POINT(-122
|
238
|
+
record.lonlat = 'POINT(-122 47)' # sets the value to the given point
|
241
239
|
|
242
240
|
If the WKT parsing fails, the value currently will be silently set to nil. In the future, however, this will raise an exception.
|
243
241
|
|
data/History.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
== PostGIS \ActiveRecord Adapter
|
2
2
|
|
3
|
-
The activerecord-postgis-adapter is a plugin that provides access to features of the PostGIS geospatial database from \ActiveRecord. Technically, it extends the standard postgresql adapter to provide support for the spatial data types and features added by the PostGIS extension. It uses the {RGeo}[http://github.com/
|
3
|
+
The activerecord-postgis-adapter is a plugin that provides access to features of the PostGIS geospatial database from \ActiveRecord. Technically, it extends the standard postgresql adapter to provide support for the spatial data types and features added by the PostGIS extension. It uses the {RGeo}[http://github.com/rgeo/rgeo] library to represent spatial data in Ruby.
|
4
4
|
|
5
5
|
== About the PostGIS Adapter
|
6
6
|
|
@@ -16,29 +16,31 @@ Second, it recognizes spatial types and casts them properly to RGeo geometry obj
|
|
16
16
|
|
17
17
|
Third, it lets you include simple spatial data in queries. WKT format data and RGeo objects can be embedded in where clauses. If you include the Squeel gem, the adapter also supports advanced queries utilizing the standard SQL spatial function set.
|
18
18
|
|
19
|
-
===
|
19
|
+
=== Install
|
20
20
|
|
21
|
-
The adapter
|
21
|
+
The adapter requires PostgreSQL 9.0+.
|
22
22
|
|
23
|
-
|
24
|
-
* PostgreSQL 9.0 or later.
|
25
|
-
* PostGIS 1.5, PostGIS 2.0, or later.
|
26
|
-
* \ActiveRecord 3.0.3 or later. Earlier versions will not work. Rails 4.0 is supported on an experimental basis.
|
27
|
-
* The rgeo and rgeo-activerecord gems are also required.
|
23
|
+
===== Version 1.1.x: ActiveRecord 4.0+
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
To install this adapter in a Rails application, add it to your Gemfile:
|
25
|
+
Requirements:
|
26
|
+
ActiveRecord 4.0+
|
27
|
+
Ruby 1.9.3+
|
28
|
+
PostGIS 2.0+
|
34
29
|
|
30
|
+
Gemfile:
|
35
31
|
gem 'activerecord-postgis-adapter'
|
36
32
|
|
37
|
-
|
33
|
+
Support for JRuby will be added soon.
|
38
34
|
|
39
|
-
|
35
|
+
===== Version 0.6.x: ActiveRecord 3.x
|
40
36
|
|
41
|
-
|
37
|
+
Requirements:
|
38
|
+
ActiveRecord 3.x only
|
39
|
+
Ruby 1.8.7+, JRuby, Rubinius
|
40
|
+
PostGIS 1.5+
|
41
|
+
|
42
|
+
Gemfile:
|
43
|
+
gem 'activerecord-postgis-adapter', '~> 0.6.6'
|
42
44
|
|
43
45
|
Please note that this adapter uses the rgeo gem, which may have additional dependencies. Please see the \README documentation for rgeo for more information.
|
44
46
|
|
@@ -46,17 +48,15 @@ Once you have installed the adapter, you'll need to edit your config/database.ym
|
|
46
48
|
|
47
49
|
== Development and Support
|
48
50
|
|
49
|
-
\Documentation is available at http://
|
51
|
+
\Documentation is available at http://rgeo.github.com/activerecord-postgis-adapter/rdoc
|
50
52
|
|
51
|
-
Source code is hosted on Github at http://github.com/
|
53
|
+
Source code is hosted on Github at http://github.com/rgeo/activerecord-postgis-adapter
|
52
54
|
|
53
55
|
Contributions are welcome. Fork the project on Github.
|
54
56
|
|
55
|
-
Report
|
56
|
-
|
57
|
-
Support available on the rgeo-users google group at http://groups.google.com/group/rgeo-users
|
57
|
+
Report issues at http://github.com/rgeo/activerecord-postgis-adapter/issues
|
58
58
|
|
59
|
-
|
59
|
+
Support is available on the rgeo-users google group at http://groups.google.com/group/rgeo-users
|
60
60
|
|
61
61
|
== Acknowledgments
|
62
62
|
|
@@ -19,20 +19,15 @@ require 'active_record'
|
|
19
19
|
require 'active_record/connection_adapters/postgresql_adapter'
|
20
20
|
require 'rgeo/active_record'
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
require 'active_record/connection_adapters/postgis_adapter/rails4/create_connection'
|
32
|
-
require 'active_record/connection_adapters/postgis_adapter/rails4/postgis_database_tasks.rb'
|
33
|
-
else
|
34
|
-
raise "Unsupported ActiveRecord version #{::ActiveRecord::VERSION::STRING}"
|
35
|
-
end
|
22
|
+
require 'active_record/connection_adapters/postgis_adapter/version.rb'
|
23
|
+
require 'active_record/connection_adapters/postgis_adapter/shared/common_adapter_methods.rb'
|
24
|
+
require 'active_record/connection_adapters/postgis_adapter/rails4/main_adapter.rb'
|
25
|
+
require 'active_record/connection_adapters/postgis_adapter/rails4/spatial_table_definition.rb'
|
26
|
+
require 'active_record/connection_adapters/postgis_adapter/rails4/spatial_column.rb'
|
27
|
+
require 'active_record/connection_adapters/postgis_adapter/shared/arel_tosql.rb'
|
28
|
+
require 'active_record/connection_adapters/postgis_adapter/shared/setup.rb'
|
29
|
+
require 'active_record/connection_adapters/postgis_adapter/rails4/create_connection'
|
30
|
+
require 'active_record/connection_adapters/postgis_adapter/rails4/postgis_database_tasks.rb'
|
36
31
|
|
37
32
|
::ActiveRecord::ConnectionAdapters::PostGISAdapter.initial_setup
|
38
33
|
|
@@ -1,29 +1,27 @@
|
|
1
|
-
|
1
|
+
require 'pg'
|
2
2
|
|
3
|
+
module ActiveRecord # :nodoc:
|
3
4
|
module ConnectionHandling # :nodoc:
|
4
|
-
require 'pg'
|
5
5
|
|
6
|
-
# Based on the default <tt>postgresql_connection</tt> definition from
|
7
|
-
#
|
8
|
-
|
9
|
-
def postgis_connection(config_)
|
6
|
+
# Based on the default <tt>postgresql_connection</tt> definition from ActiveRecord.
|
7
|
+
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
|
8
|
+
def postgis_connection(config)
|
10
9
|
# FULL REPLACEMENT because we need to create a different class.
|
11
|
-
|
10
|
+
conn_params = config.symbolize_keys
|
12
11
|
|
13
|
-
|
12
|
+
conn_params.delete_if { |_, v| v.nil? }
|
14
13
|
|
15
14
|
# Map ActiveRecords param names to PGs.
|
16
|
-
|
17
|
-
|
15
|
+
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
|
16
|
+
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
18
17
|
|
19
18
|
# Forward only valid config params to PGconn.connect.
|
20
|
-
|
19
|
+
conn_params.keep_if { |k, _| VALID_CONN_PARAMS.include?(k) }
|
21
20
|
|
22
21
|
# The postgres drivers don't allow the creation of an unconnected PGconn object,
|
23
22
|
# so just pass a nil connection object for the time being.
|
24
|
-
::ActiveRecord::ConnectionAdapters::PostGISAdapter::MainAdapter.new(nil, logger,
|
23
|
+
::ActiveRecord::ConnectionAdapters::PostGISAdapter::MainAdapter.new(nil, logger, conn_params, config)
|
25
24
|
end
|
26
25
|
|
27
26
|
end
|
28
|
-
|
29
27
|
end
|
@@ -2,7 +2,7 @@ module ActiveRecord # :nodoc:
|
|
2
2
|
module ConnectionAdapters # :nodoc:
|
3
3
|
module PostGISAdapter # :nodoc:
|
4
4
|
class MainAdapter < PostgreSQLAdapter # :nodoc:
|
5
|
-
def initialize(*
|
5
|
+
def initialize(*args)
|
6
6
|
# Overridden to change the visitor
|
7
7
|
super
|
8
8
|
@visitor = ::Arel::Visitors::PostGIS.new(self)
|
@@ -19,127 +19,137 @@ module ActiveRecord # :nodoc:
|
|
19
19
|
:geography => {:name => 'geography'})
|
20
20
|
end
|
21
21
|
|
22
|
-
def type_cast(
|
23
|
-
if ::RGeo::Feature::Geometry.check_type(
|
24
|
-
::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(
|
22
|
+
def type_cast(value, column, array_member = false)
|
23
|
+
if ::RGeo::Feature::Geometry.check_type(value)
|
24
|
+
::RGeo::WKRep::WKBGenerator.new(:hex_format => true, :type_format => :ewkb, :emit_ewkb_srid => true).generate(value)
|
25
25
|
else
|
26
26
|
super
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def columns(
|
30
|
+
def columns(table_name, name = nil)
|
31
31
|
# FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
|
32
32
|
# We needed to return a spatial column subclass.
|
33
|
-
|
34
|
-
spatial_info_ = spatial_column_info(
|
35
|
-
column_definitions(
|
36
|
-
|
33
|
+
table_name = table_name.to_s
|
34
|
+
spatial_info_ = spatial_column_info(table_name)
|
35
|
+
column_definitions(table_name).collect do |col_name, type, default, notnull, oid, fmod|
|
36
|
+
oid = column_type_map.fetch(oid.to_i, fmod.to_i) {
|
37
37
|
OID::Identity.new
|
38
38
|
}
|
39
|
-
SpatialColumn.new(@rgeo_factory_settings,
|
40
|
-
|
39
|
+
SpatialColumn.new(@rgeo_factory_settings,
|
40
|
+
table_name,
|
41
|
+
col_name,
|
42
|
+
default,
|
43
|
+
oid,
|
44
|
+
type,
|
45
|
+
notnull == 'f',
|
46
|
+
type =~ /geometry/i ? spatial_info_[col_name] : nil)
|
41
47
|
end
|
42
48
|
end
|
43
49
|
|
44
|
-
def indexes(
|
50
|
+
def indexes(table_name, name = nil)
|
45
51
|
# FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
|
46
|
-
|
52
|
+
result = query(<<-SQL, 'SCHEMA')
|
47
53
|
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid
|
48
54
|
FROM pg_class t
|
49
55
|
INNER JOIN pg_index d ON t.oid = d.indrelid
|
50
56
|
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
51
57
|
WHERE i.relkind = 'i'
|
52
58
|
AND d.indisprimary = 'f'
|
53
|
-
AND t.relname = '#{
|
59
|
+
AND t.relname = '#{table_name}'
|
54
60
|
AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
|
55
61
|
ORDER BY i.relname
|
56
62
|
SQL
|
57
63
|
|
58
|
-
|
59
|
-
index_name_ =
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
+
result.map do |row|
|
65
|
+
index_name_ = row[0]
|
66
|
+
unique = row[1] == 't'
|
67
|
+
indkey = row[2].split(" ")
|
68
|
+
inddef = row[3]
|
69
|
+
oid = row[4]
|
64
70
|
|
65
|
-
|
71
|
+
columns = query(<<-SQL, "SCHEMA")
|
66
72
|
SELECT a.attnum, a.attname, t.typname
|
67
73
|
FROM pg_attribute a, pg_type t
|
68
|
-
WHERE a.attrelid = #{
|
69
|
-
AND a.attnum IN (#{
|
74
|
+
WHERE a.attrelid = #{oid}
|
75
|
+
AND a.attnum IN (#{indkey.join(",")})
|
70
76
|
AND a.atttypid = t.oid
|
71
77
|
SQL
|
72
|
-
|
73
|
-
|
78
|
+
columns = columns.inject({}){ |h, r| h[r[0].to_s] = [r[1], r[2]]; h }
|
79
|
+
column_names = columns.values_at(*indkey).compact.map{ |a| a[0] }
|
74
80
|
|
75
81
|
# add info on sort order for columns (only desc order is explicitly specified, asc is the default)
|
76
|
-
desc_order_columns_ =
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
(
|
82
|
+
desc_order_columns_ = inddef.scan(/(\w+) DESC/).flatten
|
83
|
+
orders = desc_order_columns_.any? ? Hash[desc_order_columns_.map {|order_column_| [order_column_, :desc]}] : {}
|
84
|
+
where = inddef.scan(/WHERE (.+)$/).flatten[0]
|
85
|
+
spatial = inddef =~ /using\s+gist/i && columns.size == 1 &&
|
86
|
+
(columns.values.first[1] == 'geometry' || columns.values.first[1] == 'geography')
|
81
87
|
|
82
|
-
if
|
88
|
+
if column_names.empty?
|
83
89
|
nil
|
84
90
|
else
|
85
|
-
::RGeo::ActiveRecord::SpatialIndexDefinition.new(
|
91
|
+
::RGeo::ActiveRecord::SpatialIndexDefinition.new(table_name, index_name_, unique, column_names, [], orders, where, !!spatial)
|
86
92
|
end
|
87
93
|
end.compact
|
88
94
|
end
|
89
95
|
|
90
|
-
def create_table_definition(
|
91
|
-
# Override to create a spatial table definition
|
92
|
-
|
96
|
+
def create_table_definition(name, temporary, options, as = nil)
|
97
|
+
# Override to create a spatial table definition
|
98
|
+
if ActiveRecord::VERSION::STRING > '4.1'
|
99
|
+
PostGISAdapter::TableDefinition.new(native_database_types, name, temporary, options, as, self)
|
100
|
+
else
|
101
|
+
PostGISAdapter::TableDefinition.new(native_database_types, name, temporary, options, self)
|
102
|
+
end
|
93
103
|
end
|
94
104
|
|
95
|
-
def create_table(
|
96
|
-
|
105
|
+
def create_table(table_name, options = {}, &block)
|
106
|
+
table_name = table_name.to_s
|
97
107
|
# Call super and snag the table definition
|
98
|
-
|
99
|
-
super(
|
100
|
-
|
101
|
-
|
108
|
+
table_definition = nil
|
109
|
+
super(table_name, options) do |td|
|
110
|
+
block.call(td) if block
|
111
|
+
table_definition = td
|
102
112
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
113
|
+
table_definition.non_geographic_spatial_columns.each do |col|
|
114
|
+
type = col.spatial_type.gsub('_', '').upcase
|
115
|
+
has_z = col.has_z?
|
116
|
+
has_m = col.has_m?
|
117
|
+
type = "#{type}M" if has_m && !has_z
|
108
118
|
dimensions_ = 2
|
109
|
-
dimensions_ += 1 if
|
110
|
-
dimensions_ += 1 if
|
111
|
-
execute("SELECT AddGeometryColumn('#{quote_string(
|
119
|
+
dimensions_ += 1 if has_z
|
120
|
+
dimensions_ += 1 if has_m
|
121
|
+
execute("SELECT AddGeometryColumn('#{quote_string(table_name)}', '#{quote_string(col.name.to_s)}', #{col.srid}, '#{quote_string(type)}', #{dimensions_})")
|
112
122
|
end
|
113
123
|
end
|
114
124
|
|
115
|
-
def add_column(
|
116
|
-
|
117
|
-
|
118
|
-
if (
|
119
|
-
|
120
|
-
if
|
121
|
-
(
|
125
|
+
def add_column(table_name, column_name, type, options = {})
|
126
|
+
table_name = table_name.to_s
|
127
|
+
column_name = column_name.to_s
|
128
|
+
if (info = spatial_column_constructor(type.to_sym))
|
129
|
+
limit = options[:limit]
|
130
|
+
if type.to_s == 'geometry' &&
|
131
|
+
(options[:no_constraints] || limit.is_a?(::Hash) && limit[:no_constraints])
|
122
132
|
then
|
123
|
-
|
133
|
+
options.delete(:limit)
|
124
134
|
super
|
125
135
|
else
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
if
|
132
|
-
|
133
|
-
|
134
|
-
execute("ALTER TABLE #{quote_table_name(
|
135
|
-
change_column_default(
|
136
|
-
change_column_null(
|
136
|
+
options.merge!(limit) if limit.is_a?(::Hash)
|
137
|
+
type = (options[:type] || info[:type] || type).to_s.gsub('_', '').upcase
|
138
|
+
has_z = options[:has_z]
|
139
|
+
has_m = options[:has_m]
|
140
|
+
srid = (options[:srid] || PostGISAdapter::DEFAULT_SRID).to_i
|
141
|
+
if options[:geographic]
|
142
|
+
type << 'Z' if has_z
|
143
|
+
type << 'M' if has_m
|
144
|
+
execute("ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} GEOGRAPHY(#{type},#{srid})")
|
145
|
+
change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
|
146
|
+
change_column_null(table_name, column_name, false, options[:default]) if options[:null] == false
|
137
147
|
else
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
execute("SELECT AddGeometryColumn('#{quote_string(
|
148
|
+
type = "#{type}M" if has_m && !has_z
|
149
|
+
dimensions = 2
|
150
|
+
dimensions += 1 if has_z
|
151
|
+
dimensions += 1 if has_m
|
152
|
+
execute("SELECT AddGeometryColumn('#{quote_string(table_name)}', '#{quote_string(column_name)}', #{srid}, '#{quote_string(type)}', #{dimensions})")
|
143
153
|
end
|
144
154
|
end
|
145
155
|
else
|
@@ -147,46 +157,56 @@ module ActiveRecord # :nodoc:
|
|
147
157
|
end
|
148
158
|
end
|
149
159
|
|
150
|
-
def remove_column(
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
if
|
155
|
-
execute("SELECT DropGeometryColumn('#{quote_string(
|
160
|
+
def remove_column(table_name, column_name, type = nil, options = {})
|
161
|
+
table_name = table_name.to_s
|
162
|
+
column_name = column_name.to_s
|
163
|
+
spatial_info = spatial_column_info(table_name)
|
164
|
+
if spatial_info.include?(column_name)
|
165
|
+
execute("SELECT DropGeometryColumn('#{quote_string(table_name)}','#{quote_string(column_name)}')")
|
156
166
|
else
|
157
167
|
super
|
158
168
|
end
|
159
169
|
end
|
160
170
|
|
161
|
-
def add_index(
|
171
|
+
def add_index(table_name, column_name, options = {})
|
162
172
|
# FULL REPLACEMENT. RE-CHECK ON NEW VERSIONS.
|
163
173
|
# We have to fully-replace because of the gist_clause.
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
execute "CREATE #{
|
174
|
+
options ||= {}
|
175
|
+
gist_clause = options.delete(:spatial) ? ' USING GIST' : ''
|
176
|
+
index_name, index_type, index_columns, index_options = add_index_options(table_name, column_name, options)
|
177
|
+
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}#{gist_clause} (#{index_columns})#{index_options}"
|
168
178
|
end
|
169
179
|
|
170
|
-
def spatial_column_info(
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
:name =>
|
182
|
-
:type =>
|
183
|
-
:dimension =>
|
184
|
-
:srid =>
|
185
|
-
:has_z =>
|
186
|
-
:has_m =>
|
180
|
+
def spatial_column_info(table_name)
|
181
|
+
info = query("SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='#{quote_string(table_name.to_s)}'")
|
182
|
+
result = {}
|
183
|
+
info.each do |row|
|
184
|
+
name = row[0]
|
185
|
+
type = row[3]
|
186
|
+
dimension = row[1].to_i
|
187
|
+
has_m = !!(type =~ /m$/i)
|
188
|
+
type.sub!(/m$/, '')
|
189
|
+
has_z = dimension > 3 || dimension == 3 && !has_m
|
190
|
+
result[name] = {
|
191
|
+
:name => name,
|
192
|
+
:type => type,
|
193
|
+
:dimension => dimension,
|
194
|
+
:srid => row[2].to_i,
|
195
|
+
:has_z => has_z,
|
196
|
+
:has_m => has_m,
|
187
197
|
}
|
188
198
|
end
|
189
|
-
|
199
|
+
result
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
def column_type_map
|
205
|
+
if defined?(type_map) # ActiveRecord 4.1+
|
206
|
+
type_map
|
207
|
+
else # ActiveRecord 4.0.x
|
208
|
+
OID::TYPE_MAP
|
209
|
+
end
|
190
210
|
end
|
191
211
|
|
192
212
|
end
|