activerecord-postgis-adapter 5.2.2 → 7.1.0
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.
- checksums.yaml +4 -4
- data/lib/active_record/connection_adapters/postgis/arel_tosql.rb +18 -16
- data/lib/active_record/connection_adapters/postgis/column_methods.rb +10 -10
- data/lib/active_record/connection_adapters/postgis/create_connection.rb +12 -7
- data/lib/active_record/connection_adapters/postgis/databases.rake +9 -8
- data/lib/active_record/connection_adapters/postgis/oid/spatial.rb +25 -20
- data/lib/active_record/connection_adapters/postgis/postgis_database_tasks.rb +27 -26
- data/lib/active_record/connection_adapters/postgis/schema_statements.rb +43 -45
- data/lib/active_record/connection_adapters/postgis/spatial_column.rb +14 -19
- data/lib/active_record/connection_adapters/postgis/spatial_table_definition.rb +3 -3
- data/lib/active_record/connection_adapters/postgis/type.rb +22 -0
- data/lib/active_record/connection_adapters/postgis/version.rb +1 -1
- data/lib/active_record/connection_adapters/postgis_adapter.rb +39 -23
- metadata +16 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fcaaf2a57395c122e6541b1e40bd416f5f31fd1e512c250e5222ec5bb3feb650
|
4
|
+
data.tar.gz: 2772452b3ea880ecab759cb5add73d2ed22a89a78e12eae087aff60a061a8f20
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 743b335ad32f5d872eebd7c512d7557102ed137664e4336a8c26154fe5f3b2bc3ded2b8e0ebe73195e05e8bb9affb538f7dde93e2aa095b142078e464c2fed98
|
7
|
+
data.tar.gz: 8cfc035141871044857863337a94f4c854423afc784f305853cd1a838dde14ec729a941c50a14edc5841829e8c21ce8c4f04c1826611ecb853d8239fb95401f4
|
@@ -1,5 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module RGeo
|
4
|
+
module ActiveRecord
|
5
|
+
##
|
6
|
+
# Extend rgeo-activerecord visitors to use PostGIS specific functionality
|
7
|
+
module SpatialToPostGISSql
|
8
|
+
def visit_in_spatial_context(node, collector)
|
9
|
+
# Use ST_GeomFromEWKT for EWKT geometries
|
10
|
+
if node.is_a?(String) && node =~ /SRID=[\d+]{0,};/
|
11
|
+
collector << "#{st_func('ST_GeomFromEWKT')}(#{quote(node)})"
|
12
|
+
else
|
13
|
+
super(node, collector)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RGeo::ActiveRecord::SpatialToSql.prepend RGeo::ActiveRecord::SpatialToPostGISSql
|
20
|
+
|
3
21
|
module Arel # :nodoc:
|
4
22
|
module Visitors # :nodoc:
|
5
23
|
# Different super-class under JRuby JDBC adapter.
|
@@ -11,22 +29,6 @@ module Arel # :nodoc:
|
|
11
29
|
|
12
30
|
class PostGIS < PostGISSuperclass # :nodoc:
|
13
31
|
include RGeo::ActiveRecord::SpatialToSql
|
14
|
-
|
15
|
-
FUNC_MAP = {
|
16
|
-
"st_wkttosql" => "ST_GeomFromEWKT",
|
17
|
-
}
|
18
|
-
|
19
|
-
def st_func(standard_name)
|
20
|
-
FUNC_MAP[standard_name.downcase] || standard_name
|
21
|
-
end
|
22
|
-
|
23
|
-
def visit_String(node, collector)
|
24
|
-
collector << "#{st_func('ST_WKTToSQL')}(#{quote(node)})"
|
25
|
-
end
|
26
|
-
|
27
|
-
def visit_RGeo_ActiveRecord_SpatialNamedFunction(node, collector)
|
28
|
-
aggregate(st_func(node.name), node, collector)
|
29
|
-
end
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -6,43 +6,43 @@ module ActiveRecord
|
|
6
6
|
module ColumnMethods
|
7
7
|
def spatial(name, options = {})
|
8
8
|
raise "You must set a type. For example: 't.spatial type: :st_point'" unless options[:type]
|
9
|
-
column(name, options[:type], options)
|
9
|
+
column(name, options[:type], **options)
|
10
10
|
end
|
11
11
|
|
12
12
|
def geography(name, options = {})
|
13
|
-
column(name, :geography, options)
|
13
|
+
column(name, :geography, **options)
|
14
14
|
end
|
15
15
|
|
16
16
|
def geometry(name, options = {})
|
17
|
-
column(name, :geometry, options)
|
17
|
+
column(name, :geometry, **options)
|
18
18
|
end
|
19
19
|
|
20
20
|
def geometry_collection(name, options = {})
|
21
|
-
column(name, :geometry_collection, options)
|
21
|
+
column(name, :geometry_collection, **options)
|
22
22
|
end
|
23
23
|
|
24
24
|
def line_string(name, options = {})
|
25
|
-
column(name, :line_string, options)
|
25
|
+
column(name, :line_string, **options)
|
26
26
|
end
|
27
27
|
|
28
28
|
def multi_line_string(name, options = {})
|
29
|
-
column(name, :multi_line_string, options)
|
29
|
+
column(name, :multi_line_string, **options)
|
30
30
|
end
|
31
31
|
|
32
32
|
def multi_point(name, options = {})
|
33
|
-
column(name, :multi_point, options)
|
33
|
+
column(name, :multi_point, **options)
|
34
34
|
end
|
35
35
|
|
36
36
|
def multi_polygon(name, options = {})
|
37
|
-
column(name, :multi_polygon, options)
|
37
|
+
column(name, :multi_polygon, **options)
|
38
38
|
end
|
39
39
|
|
40
40
|
def st_point(name, options = {})
|
41
|
-
column(name, :st_point, options)
|
41
|
+
column(name, :st_point, **options)
|
42
42
|
end
|
43
43
|
|
44
44
|
def st_polygon(name, options = {})
|
45
|
-
column(name, :st_polygon, options)
|
45
|
+
column(name, :st_polygon, **options)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -10,7 +10,11 @@ module ActiveRecord # :nodoc:
|
|
10
10
|
module ConnectionHandling # :nodoc:
|
11
11
|
if RUBY_ENGINE == "jruby"
|
12
12
|
|
13
|
+
# modified from https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/connection_methods.rb#L3
|
13
14
|
def postgis_connection(config)
|
15
|
+
config = config.deep_dup
|
16
|
+
config = symbolize_keys_if_necessary(config)
|
17
|
+
|
14
18
|
config[:adapter_class] = ConnectionAdapters::PostGISAdapter
|
15
19
|
postgresql_connection(config)
|
16
20
|
end
|
@@ -23,21 +27,22 @@ module ActiveRecord # :nodoc:
|
|
23
27
|
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
|
24
28
|
# FULL REPLACEMENT because we need to create a different class.
|
25
29
|
def postgis_connection(config)
|
26
|
-
conn_params = config.symbolize_keys
|
27
|
-
|
28
|
-
conn_params.delete_if { |_, v| v.nil? }
|
30
|
+
conn_params = config.symbolize_keys.compact
|
29
31
|
|
30
32
|
# Map ActiveRecords param names to PGs.
|
31
33
|
conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
|
32
34
|
conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
|
33
35
|
|
34
|
-
# Forward only valid config params to
|
36
|
+
# Forward only valid config params to PG.connect
|
35
37
|
valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
|
36
38
|
conn_params.slice!(*valid_conn_param_keys)
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
ConnectionAdapters::PostGISAdapter.new(
|
41
|
+
ConnectionAdapters::PostGISAdapter.new_client(conn_params),
|
42
|
+
logger,
|
43
|
+
conn_params,
|
44
|
+
config
|
45
|
+
)
|
41
46
|
end
|
42
47
|
|
43
48
|
end
|
@@ -2,17 +2,18 @@
|
|
2
2
|
|
3
3
|
namespace :db do
|
4
4
|
namespace :gis do
|
5
|
-
desc
|
5
|
+
desc 'Setup PostGIS data in the database'
|
6
6
|
task setup: [:load_config] do
|
7
7
|
environments = [Rails.env]
|
8
|
-
environments <<
|
9
|
-
|
10
|
-
.
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
ActiveRecord::ConnectionAdapters::PostGIS::PostGISDatabaseTasks.new(
|
8
|
+
environments << 'test' if Rails.env.development?
|
9
|
+
environments.each do |environment|
|
10
|
+
ActiveRecord::Base.configurations
|
11
|
+
.configs_for(env_name: environment)
|
12
|
+
.reject { |env| env.configuration_hash[:database].blank? }
|
13
|
+
.each do |env|
|
14
|
+
ActiveRecord::ConnectionAdapters::PostGIS::PostGISDatabaseTasks.new(env).setup_gis
|
15
15
|
end
|
16
|
+
end
|
16
17
|
end
|
17
18
|
end
|
18
19
|
end
|
@@ -4,16 +4,17 @@ module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
5
5
|
module PostGIS
|
6
6
|
module OID
|
7
|
+
# OID used to represent geometry/geography database types and attributes.
|
8
|
+
#
|
9
|
+
# Accepts `geo_type`, `srid`, `has_z`, `has_m`, and `geographic` as parameters.
|
10
|
+
# Responsible for parsing sql_types returned from the database and WKT features.
|
7
11
|
class Spatial < Type::Value
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def initialize(oid, sql_type)
|
15
|
-
@sql_type = sql_type
|
16
|
-
@geo_type, @srid, @has_z, @has_m = self.class.parse_sql_type(sql_type)
|
12
|
+
def initialize(geo_type: 'geometry', srid: 0, has_z: false, has_m: false, geographic: false)
|
13
|
+
@geo_type = geo_type
|
14
|
+
@srid = srid
|
15
|
+
@has_z = has_z
|
16
|
+
@has_m = has_m
|
17
|
+
@geographic = geographic
|
17
18
|
end
|
18
19
|
|
19
20
|
# sql_type: geometry, geometry(Point), geometry(Point,4326), ...
|
@@ -43,30 +44,24 @@ module ActiveRecord
|
|
43
44
|
# otherType(a,b)
|
44
45
|
geo_type = sql_type
|
45
46
|
end
|
46
|
-
|
47
|
+
geographic = sql_type.match?(/geography/)
|
48
|
+
|
49
|
+
[geo_type, srid, has_z, has_m, geographic]
|
47
50
|
end
|
48
51
|
|
49
52
|
def spatial_factory
|
50
53
|
@spatial_factory ||=
|
51
54
|
RGeo::ActiveRecord::SpatialFactoryStore.instance.factory(
|
52
|
-
|
53
|
-
has_m: @has_m,
|
54
|
-
has_z: @has_z,
|
55
|
-
sql_type: @sql_type,
|
56
|
-
srid: @srid
|
55
|
+
factory_attrs
|
57
56
|
)
|
58
57
|
end
|
59
58
|
|
60
|
-
def geographic?
|
61
|
-
@sql_type =~ /geography/
|
62
|
-
end
|
63
|
-
|
64
59
|
def spatial?
|
65
60
|
true
|
66
61
|
end
|
67
62
|
|
68
63
|
def type
|
69
|
-
geographic
|
64
|
+
@geographic ? :geography : :geometry
|
70
65
|
end
|
71
66
|
|
72
67
|
# support setting an RGeo object or a WKT string
|
@@ -107,6 +102,16 @@ module ActiveRecord
|
|
107
102
|
RGeo::WKRep::WKTParser.new(spatial_factory, support_ewkt: true, default_srid: @srid)
|
108
103
|
end
|
109
104
|
end
|
105
|
+
|
106
|
+
def factory_attrs
|
107
|
+
{
|
108
|
+
geo_type: @geo_type.underscore,
|
109
|
+
has_m: @has_m,
|
110
|
+
has_z: @has_z,
|
111
|
+
srid: @srid,
|
112
|
+
sql_type: type.to_s
|
113
|
+
}
|
114
|
+
end
|
110
115
|
end
|
111
116
|
end
|
112
117
|
end
|
@@ -4,7 +4,7 @@ module ActiveRecord # :nodoc:
|
|
4
4
|
module ConnectionAdapters # :nodoc:
|
5
5
|
module PostGIS # :nodoc:
|
6
6
|
class PostGISDatabaseTasks < ::ActiveRecord::Tasks::PostgreSQLDatabaseTasks # :nodoc:
|
7
|
-
def initialize(
|
7
|
+
def initialize(db_config)
|
8
8
|
super
|
9
9
|
ensure_installation_configs
|
10
10
|
end
|
@@ -14,19 +14,19 @@ module ActiveRecord # :nodoc:
|
|
14
14
|
if extension_names
|
15
15
|
setup_gis_from_extension
|
16
16
|
end
|
17
|
-
establish_connection(
|
17
|
+
establish_connection(db_config)
|
18
18
|
end
|
19
19
|
|
20
20
|
# Override to set the database owner and call setup_gis
|
21
21
|
def create(master_established = false)
|
22
22
|
establish_master_connection unless master_established
|
23
|
-
extra_configs = {
|
24
|
-
extra_configs[
|
25
|
-
connection.create_database(
|
23
|
+
extra_configs = { encoding: encoding }
|
24
|
+
extra_configs[:owner] = username if has_su?
|
25
|
+
connection.create_database(db_config.database, configuration_hash.merge(extra_configs))
|
26
26
|
setup_gis
|
27
27
|
rescue ::ActiveRecord::StatementInvalid => error
|
28
28
|
if /database .* already exists/ === error.message
|
29
|
-
raise ::ActiveRecord::
|
29
|
+
raise ::ActiveRecord::DatabaseAlreadyExists
|
30
30
|
else
|
31
31
|
raise
|
32
32
|
end
|
@@ -36,24 +36,24 @@ module ActiveRecord # :nodoc:
|
|
36
36
|
|
37
37
|
# Override to use su_username and su_password
|
38
38
|
def establish_master_connection
|
39
|
-
establish_connection(
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
39
|
+
establish_connection(configuration_hash.merge(
|
40
|
+
database: "postgres",
|
41
|
+
password: su_password,
|
42
|
+
schema_search_path: "public",
|
43
|
+
username: su_username
|
44
44
|
))
|
45
45
|
end
|
46
46
|
|
47
47
|
def establish_su_connection
|
48
|
-
establish_connection(
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
establish_connection(configuration_hash.merge(
|
49
|
+
password: su_password,
|
50
|
+
schema_search_path: "public",
|
51
|
+
username: su_username
|
52
52
|
))
|
53
53
|
end
|
54
54
|
|
55
55
|
def username
|
56
|
-
@username ||=
|
56
|
+
@username ||= configuration_hash[:username]
|
57
57
|
end
|
58
58
|
|
59
59
|
def quoted_username
|
@@ -61,29 +61,30 @@ module ActiveRecord # :nodoc:
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def password
|
64
|
-
@password ||=
|
64
|
+
@password ||= configuration_hash[:password]
|
65
65
|
end
|
66
66
|
|
67
67
|
def su_username
|
68
|
-
@su_username ||=
|
68
|
+
@su_username ||= configuration_hash.fetch(:su_username, username)
|
69
69
|
end
|
70
70
|
|
71
71
|
def su_password
|
72
|
-
@su_password ||=
|
72
|
+
@su_password ||= configuration_hash.fetch(:su_password, password)
|
73
73
|
end
|
74
74
|
|
75
75
|
def has_su?
|
76
|
-
@has_su
|
77
|
-
|
76
|
+
return @has_su if defined?(@has_su)
|
77
|
+
|
78
|
+
@has_su = configuration_hash.include?(:su_username)
|
78
79
|
end
|
79
80
|
|
80
81
|
def search_path
|
81
|
-
@search_path ||=
|
82
|
+
@search_path ||= configuration_hash[:schema_search_path].to_s.strip.split(",").map(&:strip)
|
82
83
|
end
|
83
84
|
|
84
85
|
def extension_names
|
85
86
|
@extension_names ||= begin
|
86
|
-
extensions =
|
87
|
+
extensions = configuration_hash[:postgis_extension]
|
87
88
|
case extensions
|
88
89
|
when ::String
|
89
90
|
extensions.split(",")
|
@@ -96,11 +97,11 @@ module ActiveRecord # :nodoc:
|
|
96
97
|
end
|
97
98
|
|
98
99
|
def ensure_installation_configs
|
99
|
-
if
|
100
|
+
if configuration_hash[:setup] == "default" && !configuration_hash[:postgis_extension]
|
100
101
|
share_dir = `pg_config --sharedir`.strip rescue "/usr/share"
|
101
102
|
control_file = ::File.expand_path("extension/postgis.control", share_dir)
|
102
103
|
if ::File.readable?(control_file)
|
103
|
-
|
104
|
+
@configuration_hash = configuration_hash.merge(postgis_extension: "postgis").freeze
|
104
105
|
end
|
105
106
|
end
|
106
107
|
end
|
@@ -113,7 +114,7 @@ module ActiveRecord # :nodoc:
|
|
113
114
|
end
|
114
115
|
connection.execute("CREATE EXTENSION IF NOT EXISTS #{extname} SCHEMA topology")
|
115
116
|
else
|
116
|
-
if (postgis_schema =
|
117
|
+
if (postgis_schema = configuration_hash[:postgis_schema])
|
117
118
|
schema_clause = "WITH SCHEMA #{postgis_schema}"
|
118
119
|
unless schema_exists?(postgis_schema)
|
119
120
|
connection.execute("CREATE SCHEMA #{postgis_schema}")
|
@@ -5,46 +5,37 @@ module ActiveRecord
|
|
5
5
|
module PostGIS
|
6
6
|
module SchemaStatements
|
7
7
|
# override
|
8
|
-
#
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
cast_type = get_oid_type(oid.to_i, fmod.to_i, column_name, type)
|
16
|
-
default_value = extract_value_from_default(default)
|
8
|
+
# https://github.com/rails/rails/blob/6-0-stable/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb#L624
|
9
|
+
# Create a SpatialColumn instead of a PostgreSQL::Column
|
10
|
+
def new_column_from_field(table_name, field)
|
11
|
+
column_name, type, default, notnull, oid, fmod, collation, comment = field
|
12
|
+
type_metadata = fetch_type_metadata(column_name, type, oid.to_i, fmod.to_i)
|
13
|
+
default_value = extract_value_from_default(default)
|
14
|
+
default_function = extract_default_function(default_value, default)
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
# override
|
25
|
-
def new_column(table_name, column_name, default, cast_type, sql_type_metadata = nil,
|
26
|
-
null = true, default_function = nil, collation = nil, comment = nil)
|
27
|
-
# JDBC gets true/false in Rails 4, where other platforms get 't'/'f' strings.
|
28
|
-
if null.is_a?(String)
|
29
|
-
null = (null == "t")
|
30
|
-
end
|
16
|
+
serial =
|
17
|
+
if (match = default_function&.match(/\Anextval\('"?(?<sequence_name>.+_(?<suffix>seq\d*))"?'::regclass\)\z/))
|
18
|
+
sequence_name_from_parts(table_name, column_name, match[:suffix]) == match[:sequence_name]
|
19
|
+
end
|
31
20
|
|
32
|
-
|
21
|
+
# {:dimension=>2, :has_m=>false, :has_z=>false, :name=>"latlon", :srid=>0, :type=>"GEOMETRY"}
|
22
|
+
spatial = spatial_column_info(table_name).get(column_name, type_metadata.sql_type)
|
33
23
|
|
34
|
-
SpatialColumn.new(
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
24
|
+
SpatialColumn.new(
|
25
|
+
column_name,
|
26
|
+
default_value,
|
27
|
+
type_metadata,
|
28
|
+
!notnull,
|
29
|
+
default_function,
|
30
|
+
collation: collation,
|
31
|
+
comment: comment.presence,
|
32
|
+
serial: serial,
|
33
|
+
spatial: spatial
|
34
|
+
)
|
44
35
|
end
|
45
36
|
|
46
37
|
# override
|
47
|
-
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb#
|
38
|
+
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb#L544
|
48
39
|
#
|
49
40
|
# returns Postgresql sql type string
|
50
41
|
# examples:
|
@@ -54,12 +45,12 @@ module ActiveRecord
|
|
54
45
|
# note: type alone is not enough to detect the sql type,
|
55
46
|
# so `limit` is used to pass the additional information. :(
|
56
47
|
#
|
57
|
-
# type_to_sql(:geography, "Point,4326")
|
48
|
+
# type_to_sql(:geography, limit: "Point,4326")
|
58
49
|
# => "geography(Point,4326)"
|
59
|
-
def type_to_sql(type,
|
60
|
-
case type
|
61
|
-
when
|
62
|
-
"#{type}(#{
|
50
|
+
def type_to_sql(type, limit: nil, precision: nil, scale: nil, array: nil, **)
|
51
|
+
case type.to_s
|
52
|
+
when "geometry", "geography"
|
53
|
+
"#{type}(#{limit})"
|
63
54
|
else
|
64
55
|
super
|
65
56
|
end
|
@@ -83,8 +74,8 @@ module ActiveRecord
|
|
83
74
|
end
|
84
75
|
|
85
76
|
# override
|
86
|
-
def create_table_definition(*args)
|
87
|
-
PostGIS::TableDefinition.new(*args)
|
77
|
+
def create_table_definition(*args, **kwargs)
|
78
|
+
PostGIS::TableDefinition.new(self, *args, **kwargs)
|
88
79
|
end
|
89
80
|
|
90
81
|
# memoize hash of column infos for tables
|
@@ -94,8 +85,6 @@ module ActiveRecord
|
|
94
85
|
end
|
95
86
|
|
96
87
|
def initialize_type_map(map = type_map)
|
97
|
-
super
|
98
|
-
|
99
88
|
%w(
|
100
89
|
geography
|
101
90
|
geometry
|
@@ -107,10 +96,19 @@ module ActiveRecord
|
|
107
96
|
st_point
|
108
97
|
st_polygon
|
109
98
|
).each do |geo_type|
|
110
|
-
map.register_type(geo_type) do |
|
111
|
-
|
99
|
+
map.register_type(geo_type) do |_, _, sql_type|
|
100
|
+
# sql_type is a string that comes from the database definition
|
101
|
+
# examples:
|
102
|
+
# "geometry(Point,4326)"
|
103
|
+
# "geography(Point,4326)"
|
104
|
+
# "geometry(Polygon,4326) NOT NULL"
|
105
|
+
# "geometry(Geography,4326)"
|
106
|
+
geo_type, srid, has_z, has_m, geographic = OID::Spatial.parse_sql_type(sql_type)
|
107
|
+
OID::Spatial.new(geo_type: geo_type, srid: srid, has_z: has_z, has_m: has_m, geographic: geographic)
|
112
108
|
end
|
113
109
|
end
|
110
|
+
|
111
|
+
super
|
114
112
|
end
|
115
113
|
end
|
116
114
|
end
|
@@ -7,19 +7,17 @@ module ActiveRecord # :nodoc:
|
|
7
7
|
# sql_type examples:
|
8
8
|
# "Geometry(Point,4326)"
|
9
9
|
# "Geography(Point,4326)"
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
default_function = nil, collation = nil, comment = nil, cast_type = nil, opts = nil)
|
15
|
-
@cast_type = cast_type
|
10
|
+
def initialize(name, default, sql_type_metadata = nil, null = true,
|
11
|
+
default_function = nil, collation: nil, comment: nil,
|
12
|
+
serial: nil, spatial: nil)
|
13
|
+
@sql_type_metadata = sql_type_metadata
|
16
14
|
@geographic = !!(sql_type_metadata.sql_type =~ /geography\(/i)
|
17
|
-
if
|
15
|
+
if spatial
|
18
16
|
# This case comes from an entry in the geometry_columns table
|
19
|
-
set_geometric_type_from_name(
|
20
|
-
@srid =
|
21
|
-
@has_z = !!
|
22
|
-
@has_m = !!
|
17
|
+
set_geometric_type_from_name(spatial[:type])
|
18
|
+
@srid = spatial[:srid].to_i
|
19
|
+
@has_z = !!spatial[:has_z]
|
20
|
+
@has_m = !!spatial[:has_m]
|
23
21
|
elsif @geographic
|
24
22
|
# Geographic type information is embedded in the SQL type
|
25
23
|
@srid = 4326
|
@@ -32,7 +30,8 @@ module ActiveRecord # :nodoc:
|
|
32
30
|
# @geometric_type = geo_type_from_sql_type(sql_type)
|
33
31
|
build_from_sql_type(sql_type_metadata.sql_type)
|
34
32
|
end
|
35
|
-
super(name, default, sql_type_metadata, null,
|
33
|
+
super(name, default, sql_type_metadata, null, default_function,
|
34
|
+
collation: collation, comment: comment, serial: serial)
|
36
35
|
if spatial?
|
37
36
|
if @srid
|
38
37
|
@limit = { srid: @srid, type: to_type_name(geometric_type) }
|
@@ -54,15 +53,11 @@ module ActiveRecord # :nodoc:
|
|
54
53
|
alias :has_m? :has_m
|
55
54
|
|
56
55
|
def limit
|
57
|
-
|
58
|
-
@limit
|
59
|
-
else
|
60
|
-
super
|
61
|
-
end
|
56
|
+
spatial? ? @limit : super
|
62
57
|
end
|
63
58
|
|
64
59
|
def spatial?
|
65
|
-
|
60
|
+
%i[geometry geography].include?(@sql_type_metadata.type)
|
66
61
|
end
|
67
62
|
|
68
63
|
private
|
@@ -72,7 +67,7 @@ module ActiveRecord # :nodoc:
|
|
72
67
|
end
|
73
68
|
|
74
69
|
def build_from_sql_type(sql_type)
|
75
|
-
geo_type, @srid, @has_z, @has_m = OID::Spatial.parse_sql_type(sql_type)
|
70
|
+
geo_type, @srid, @has_z, @has_m, @geographic = OID::Spatial.parse_sql_type(sql_type)
|
76
71
|
set_geometric_type_from_name(geo_type)
|
77
72
|
end
|
78
73
|
|
@@ -7,7 +7,7 @@ module ActiveRecord # :nodoc:
|
|
7
7
|
include ColumnMethods
|
8
8
|
|
9
9
|
# super: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
|
10
|
-
def new_column_definition(name, type, options)
|
10
|
+
def new_column_definition(name, type, **options)
|
11
11
|
if (info = PostGISAdapter.spatial_column_options(type.to_sym))
|
12
12
|
if (limit = options.delete(:limit))
|
13
13
|
options.merge!(limit) if limit.is_a?(::Hash)
|
@@ -18,9 +18,9 @@ module ActiveRecord # :nodoc:
|
|
18
18
|
|
19
19
|
options[:limit] = ColumnDefinitionUtils.limit_from_options(geo_type, options)
|
20
20
|
options[:spatial_type] = geo_type
|
21
|
-
column = super(name, base_type, options)
|
21
|
+
column = super(name, base_type, **options)
|
22
22
|
else
|
23
|
-
column = super(name, type, options)
|
23
|
+
column = super(name, type, **options)
|
24
24
|
end
|
25
25
|
|
26
26
|
column
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module ConnectionAdapters
|
5
|
+
module PostGIS
|
6
|
+
module Type
|
7
|
+
# Look for :postgis types first, then check for :postgresql
|
8
|
+
# types to simulate a kind of Type inheritance.
|
9
|
+
def lookup(*args, adapter: current_adapter_name, **kwargs)
|
10
|
+
super(*args, adapter: adapter, **kwargs)
|
11
|
+
rescue ArgumentError => e
|
12
|
+
raise e unless current_adapter_name == :postgis
|
13
|
+
|
14
|
+
super(*args, adapter: :postgresql, **kwargs)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Type uses `class << self` syntax so we have to prepend to the singleton_class
|
21
|
+
Type.singleton_class.prepend(ActiveRecord::ConnectionAdapters::PostGIS::Type)
|
22
|
+
end
|
@@ -7,13 +7,7 @@
|
|
7
7
|
|
8
8
|
require "rgeo/active_record"
|
9
9
|
|
10
|
-
|
11
|
-
module ActiveRecord
|
12
|
-
module ConnectionAdapters
|
13
|
-
AbstractAdapter
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
10
|
+
require "active_record/connection_adapters"
|
17
11
|
require "active_record/connection_adapters/postgresql_adapter"
|
18
12
|
require "active_record/connection_adapters/postgis/version"
|
19
13
|
require "active_record/connection_adapters/postgis/column_methods"
|
@@ -24,6 +18,7 @@ require "active_record/connection_adapters/postgis/spatial_column"
|
|
24
18
|
require "active_record/connection_adapters/postgis/arel_tosql"
|
25
19
|
require "active_record/connection_adapters/postgis/setup"
|
26
20
|
require "active_record/connection_adapters/postgis/oid/spatial"
|
21
|
+
require "active_record/connection_adapters/postgis/type" # has to be after oid/*
|
27
22
|
require "active_record/connection_adapters/postgis/create_connection"
|
28
23
|
require "active_record/connection_adapters/postgis/postgis_database_tasks"
|
29
24
|
|
@@ -38,7 +33,7 @@ end
|
|
38
33
|
module ActiveRecord
|
39
34
|
module ConnectionAdapters
|
40
35
|
class PostGISAdapter < PostgreSQLAdapter
|
41
|
-
|
36
|
+
ADAPTER_NAME = 'PostGIS'
|
42
37
|
|
43
38
|
SPATIAL_COLUMN_OPTIONS =
|
44
39
|
{
|
@@ -57,22 +52,10 @@ module ActiveRecord
|
|
57
52
|
# http://postgis.17.x6.nabble.com/Default-SRID-td5001115.html
|
58
53
|
DEFAULT_SRID = 0
|
59
54
|
|
60
|
-
|
61
|
-
def initialize(connection, logger, connection_parameters, config)
|
62
|
-
super
|
63
|
-
|
64
|
-
@visitor = Arel::Visitors::PostGIS.new(self)
|
65
|
-
# copy from https://github.com/rails/rails/blob/6ece7df8d80c6d93db43878fa4c0278a0204072c/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L199
|
66
|
-
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
|
67
|
-
@prepared_statements = true
|
68
|
-
@visitor.extend(DetermineIfPreparableVisitor)
|
69
|
-
else
|
70
|
-
@prepared_statements = false
|
71
|
-
end
|
72
|
-
end
|
55
|
+
include PostGIS::SchemaStatements
|
73
56
|
|
74
|
-
def
|
75
|
-
|
57
|
+
def arel_visitor # :nodoc:
|
58
|
+
Arel::Visitors::PostGIS.new(self)
|
76
59
|
end
|
77
60
|
|
78
61
|
def self.spatial_column_options(key)
|
@@ -105,6 +88,39 @@ module ActiveRecord
|
|
105
88
|
super
|
106
89
|
end
|
107
90
|
end
|
91
|
+
|
92
|
+
# PostGIS specific types
|
93
|
+
[
|
94
|
+
:geography,
|
95
|
+
:geometry,
|
96
|
+
:geometry_collection,
|
97
|
+
:line_string,
|
98
|
+
:multi_line_string,
|
99
|
+
:multi_point,
|
100
|
+
:multi_polygon,
|
101
|
+
:st_point,
|
102
|
+
:st_polygon,
|
103
|
+
].each do |geo_type|
|
104
|
+
ActiveRecord::Type.register(geo_type, PostGIS::OID::Spatial, adapter: :postgis)
|
105
|
+
end
|
108
106
|
end
|
109
107
|
end
|
110
108
|
end
|
109
|
+
|
110
|
+
# if using JRUBY, create ArJdbc::PostGIS module
|
111
|
+
# and prepend it to the PostgreSQL adapter since
|
112
|
+
# it is the default adapter_spec.
|
113
|
+
# see: https://github.com/jruby/activerecord-jdbc-adapter/blob/master/lib/arjdbc/postgresql/adapter.rb#27
|
114
|
+
if RUBY_ENGINE == "jruby"
|
115
|
+
module ArJdbc
|
116
|
+
module PostGIS
|
117
|
+
ADAPTER_NAME = 'PostGIS'
|
118
|
+
|
119
|
+
def adapter_name
|
120
|
+
ADAPTER_NAME
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
ArJdbc::PostgreSQL.prepend(ArJdbc::PostGIS)
|
126
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-postgis-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 7.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Daniel Azuma
|
7
|
+
- Daniel Azuma
|
8
|
+
- Tee Parham
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-03-28 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: activerecord
|
@@ -16,28 +17,28 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
+
version: '6.1'
|
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
|
-
version: '
|
27
|
+
version: '6.1'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: rgeo-activerecord
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
32
|
- - "~>"
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
+
version: 7.0.0
|
34
35
|
type: :runtime
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
39
|
- - "~>"
|
39
40
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
41
|
+
version: 7.0.0
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
43
|
name: rake
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -97,7 +98,10 @@ dependencies:
|
|
97
98
|
description: ActiveRecord connection adapter for PostGIS. It is based on the stock
|
98
99
|
PostgreSQL adapter, and adds built-in support for the spatial extensions provided
|
99
100
|
by PostGIS. It uses the RGeo library to represent spatial data in Ruby.
|
100
|
-
email:
|
101
|
+
email:
|
102
|
+
- dazuma@gmail.com
|
103
|
+
- parhameter@gmail.com
|
104
|
+
- kfdoggett@gmail.com
|
101
105
|
executables: []
|
102
106
|
extensions: []
|
103
107
|
extra_rdoc_files: []
|
@@ -115,12 +119,13 @@ files:
|
|
115
119
|
- lib/active_record/connection_adapters/postgis/spatial_column.rb
|
116
120
|
- lib/active_record/connection_adapters/postgis/spatial_column_info.rb
|
117
121
|
- lib/active_record/connection_adapters/postgis/spatial_table_definition.rb
|
122
|
+
- lib/active_record/connection_adapters/postgis/type.rb
|
118
123
|
- lib/active_record/connection_adapters/postgis/version.rb
|
119
124
|
- lib/active_record/connection_adapters/postgis_adapter.rb
|
120
125
|
- lib/activerecord-postgis-adapter.rb
|
121
126
|
homepage: http://github.com/rgeo/activerecord-postgis-adapter
|
122
127
|
licenses:
|
123
|
-
- BSD
|
128
|
+
- BSD-3-Clause
|
124
129
|
metadata: {}
|
125
130
|
post_install_message:
|
126
131
|
rdoc_options: []
|
@@ -130,15 +135,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
135
|
requirements:
|
131
136
|
- - ">="
|
132
137
|
- !ruby/object:Gem::Version
|
133
|
-
version: 2.
|
138
|
+
version: 2.5.0
|
134
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
140
|
requirements:
|
136
141
|
- - ">="
|
137
142
|
- !ruby/object:Gem::Version
|
138
143
|
version: '0'
|
139
144
|
requirements: []
|
140
|
-
|
141
|
-
rubygems_version: 2.7.8
|
145
|
+
rubygems_version: 3.0.8
|
142
146
|
signing_key:
|
143
147
|
specification_version: 4
|
144
148
|
summary: ActiveRecord adapter for PostGIS, based on RGeo.
|