diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2013-03-25 11:45:31 -0700 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2013-03-25 11:45:31 -0700 |
commit | fc8411ad6c939cb4d39910d4b012291e8a9e148d (patch) | |
tree | baf3e92717bbd0f0fe3fa7d68ab5a82e3e95a295 /activerecord/lib | |
parent | c2e203173221991e104a9eb872025788b9fc4763 (diff) | |
parent | f8675eb064e5aa052da7a5b9b5d3aa390822bf47 (diff) | |
download | rails-fc8411ad6c939cb4d39910d4b012291e8a9e148d.tar.gz rails-fc8411ad6c939cb4d39910d4b012291e8a9e148d.tar.bz2 rails-fc8411ad6c939cb4d39910d4b012291e8a9e148d.zip |
Merge pull request #7324 from MSch/pg-geometric
Add support for pg geometric datatypes point and box
Diffstat (limited to 'activerecord/lib')
4 files changed, 48 insertions, 10 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb index fcbd8fd88a..14ef07a75e 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/cast.rb @@ -2,6 +2,17 @@ module ActiveRecord module ConnectionAdapters class PostgreSQLColumn < Column module Cast + def point_to_string(point) + "(#{point[0]},#{point[1]})" + end + + def string_to_point(string) + if string[0] == '(' && string[-1] == ')' + string = string[1...-1] + end + string.split(',').map{ |v| Float(v) } + end + def string_to_time(string) return string unless String === string diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb index 68f2f2ca7b..51f377dfd7 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid.rb @@ -63,6 +63,16 @@ module ActiveRecord end end + class Point < Type + def type_cast(value) + if String === value + ConnectionAdapters::PostgreSQLColumn.string_to_point value + else + value + end + end + end + class Array < Type attr_reader :subtype def initialize(subtype) @@ -330,6 +340,7 @@ module ActiveRecord register_type 'time', OID::Time.new register_type 'path', OID::Identity.new + register_type 'point', OID::Point.new register_type 'polygon', OID::Identity.new register_type 'circle', OID::Identity.new register_type 'hstore', OID::Hstore.new diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index 49b93e5626..61e5e76f83 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -28,10 +28,14 @@ module ActiveRecord super end when Array - if column.array - "'#{PostgreSQLColumn.array_to_string(value, column, self)}'" + case sql_type + when 'point' then super(PostgreSQLColumn.point_to_string(value)) else - super + if column.array + "'#{PostgreSQLColumn.array_to_string(value, column, self)}'" + else + super + end end when Hash case sql_type @@ -79,9 +83,10 @@ module ActiveRecord def type_cast(value, column, array_member = false) return super(value, column) unless column + sql_type = type_to_sql(column.type, column.limit, column.precision, column.scale) case value when Range - return super(value, column) unless /range$/ =~ column.sql_type + return super(value, column) unless /range$/ =~ sql_type PostgreSQLColumn.range_to_string(value) when NilClass if column.array && array_member @@ -92,19 +97,23 @@ module ActiveRecord super(value, column) end when Array - return super(value, column) unless column.array - PostgreSQLColumn.array_to_string(value, column, self) + case sql_type + when 'point' then PostgreSQLColumn.point_to_string(value) + else + return super(value, column) unless column.array + PostgreSQLColumn.array_to_string(value, column, self) + end when String - return super(value, column) unless 'bytea' == column.sql_type + return super(value, column) unless 'bytea' == sql_type { :value => value, :format => 1 } when Hash - case column.sql_type + case sql_type when 'hstore' then PostgreSQLColumn.hstore_to_string(value) when 'json' then PostgreSQLColumn.json_to_string(value) else super(value, column) end when IPAddr - return super(value, column) unless ['inet','cidr'].include? column.sql_type + return super(value, column) unless ['inet','cidr'].include? sql_type PostgreSQLColumn.cidr_to_string(value) else super(value, column) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index fd7d58616a..d26b676335 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -711,7 +711,14 @@ module ActiveRecord # populate composite types nodes.find_all { |row| OID::TYPE_MAP.key? row['typelem'].to_i }.each do |row| - vector = OID::Vector.new row['typdelim'], OID::TYPE_MAP[row['typelem'].to_i] + if OID.registered_type? row['typname'] + # this composite type is explicitly registered + vector = OID::NAMES[row['typname']] + else + # use the default for composite types + vector = OID::Vector.new row['typdelim'], OID::TYPE_MAP[row['typelem'].to_i] + end + OID::TYPE_MAP[row['oid'].to_i] = vector end |