提交 9feeaab3 编写于 作者: Y Yves Senn

Merge pull request #22304 from kamipo/schema_dumping_support_for_postgresql_geometric_types

Add schema dumping support for PostgreSQL geometric data types
* Add schema dumping support for PostgreSQL geometric data types.
*Ryuta Kamizono*
* Except keys of `build_record`'s argument from `create_scope` in `initialize_attributes`.
Fixes #21893.
......
......@@ -100,6 +100,12 @@ class PostgreSQLAdapter < AbstractAdapter
ltree: { name: "ltree" },
citext: { name: "citext" },
point: { name: "point" },
line: { name: "line" },
lseg: { name: "lseg" },
box: { name: "box" },
path: { name: "path" },
polygon: { name: "polygon" },
circle: { name: "circle" },
bit: { name: "bit" },
bit_varying: { name: "bit varying" },
money: { name: "money" },
......@@ -455,15 +461,15 @@ def initialize_type_map(m) # :nodoc:
m.register_type 'macaddr', OID::SpecializedString.new(:macaddr)
m.register_type 'citext', OID::SpecializedString.new(:citext)
m.register_type 'ltree', OID::SpecializedString.new(:ltree)
m.register_type 'line', OID::SpecializedString.new(:line)
m.register_type 'lseg', OID::SpecializedString.new(:lseg)
m.register_type 'box', OID::SpecializedString.new(:box)
m.register_type 'path', OID::SpecializedString.new(:path)
m.register_type 'polygon', OID::SpecializedString.new(:polygon)
m.register_type 'circle', OID::SpecializedString.new(:circle)
# FIXME: why are we keeping these types as strings?
m.alias_type 'interval', 'varchar'
m.alias_type 'path', 'varchar'
m.alias_type 'line', 'varchar'
m.alias_type 'polygon', 'varchar'
m.alias_type 'circle', 'varchar'
m.alias_type 'lseg', 'varchar'
m.alias_type 'box', 'varchar'
register_class_with_precision m, 'time', Type::Time
register_class_with_precision m, 'timestamp', OID::DateTime
......
......@@ -167,16 +167,18 @@ def test_legacy_mutation
end
class PostgresqlGeometricTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
class PostgresqlGeometric < ActiveRecord::Base; end
setup do
@connection = ActiveRecord::Base.connection
@connection.create_table("postgresql_geometrics") do |t|
t.column :a_line_segment, :lseg
t.column :a_box, :box
t.column :a_path, :path
t.column :a_polygon, :polygon
t.column :a_circle, :circle
t.lseg :a_line_segment
t.box :a_box
t.path :a_path
t.polygon :a_polygon
t.circle :a_circle
end
end
......@@ -233,4 +235,142 @@ def test_geometric_function
objs = PostgresqlGeometric.find_by_sql "SELECT isclosed(a_path) FROM postgresql_geometrics ORDER BY id ASC"
assert_equal [false, true], objs.map(&:isclosed)
end
def test_schema_dumping
output = dump_table_schema("postgresql_geometrics")
assert_match %r{t\.lseg\s+"a_line_segment"$}, output
assert_match %r{t\.box\s+"a_box"$}, output
assert_match %r{t\.path\s+"a_path"$}, output
assert_match %r{t\.polygon\s+"a_polygon"$}, output
assert_match %r{t\.circle\s+"a_circle"$}, output
end
end
class PostgreSQLGeometricLineTest < ActiveRecord::PostgreSQLTestCase
include SchemaDumpingHelper
class PostgresqlLine < ActiveRecord::Base; end
setup do
unless ActiveRecord::Base.connection.send(:postgresql_version) >= 90400
skip("line type is not fully implemented")
end
@connection = ActiveRecord::Base.connection
@connection.create_table("postgresql_lines") do |t|
t.line :a_line
end
end
teardown do
@connection.drop_table 'postgresql_lines', if_exists: true
end
def test_geometric_line_type
g = PostgresqlLine.new(
a_line: '{2.0, 3, 5.5}'
)
g.save!
h = PostgresqlLine.find(g.id)
assert_equal '{2,3,5.5}', h.a_line
end
def test_alternative_format_line_type
g = PostgresqlLine.new(
a_line: '(2.0, 3), (4.0, 6.0)'
)
g.save!
h = PostgresqlLine.find(g.id)
assert_equal '{1.5,-1,0}', h.a_line
end
def test_schema_dumping_for_line_type
output = dump_table_schema("postgresql_lines")
assert_match %r{t\.line\s+"a_line"$}, output
end
end
class PostgreSQLGeometricTypesTest < ActiveRecord::PostgreSQLTestCase
attr_reader :connection, :table_name
def setup
super
@connection = ActiveRecord::Base.connection
@table_name = :testings
end
def test_creating_column_with_point_type
connection.create_table(table_name) do |t|
t.point :foo_point
end
assert_column_exists(:foo_point)
assert_type_correct(:foo_point, :point)
end
def test_creating_column_with_line_type
connection.create_table(table_name) do |t|
t.line :foo_line
end
assert_column_exists(:foo_line)
assert_type_correct(:foo_line, :line)
end
def test_creating_column_with_lseg_type
connection.create_table(table_name) do |t|
t.lseg :foo_lseg
end
assert_column_exists(:foo_lseg)
assert_type_correct(:foo_lseg, :lseg)
end
def test_creating_column_with_box_type
connection.create_table(table_name) do |t|
t.box :foo_box
end
assert_column_exists(:foo_box)
assert_type_correct(:foo_box, :box)
end
def test_creating_column_with_path_type
connection.create_table(table_name) do |t|
t.path :foo_path
end
assert_column_exists(:foo_path)
assert_type_correct(:foo_path, :path)
end
def test_creating_column_with_polygon_type
connection.create_table(table_name) do |t|
t.polygon :foo_polygon
end
assert_column_exists(:foo_polygon)
assert_type_correct(:foo_polygon, :polygon)
end
def test_creating_column_with_circle_type
connection.create_table(table_name) do |t|
t.circle :foo_circle
end
assert_column_exists(:foo_circle)
assert_type_correct(:foo_circle, :circle)
end
private
def assert_column_exists(column_name)
assert connection.column_exists?(table_name, column_name)
end
def assert_type_correct(column_name, type)
column = connection.columns(table_name).find { |c| c.name == column_name.to_s }
assert_equal type, column.type
end
end
require 'cases/helper'
module ActiveRecord
class Migration
class PostgreSQLGeometricTypesTest < ActiveRecord::TestCase
attr_reader :connection, :table_name
def setup
super
@connection = ActiveRecord::Base.connection
@table_name = :testings
end
if current_adapter?(:PostgreSQLAdapter)
def test_creating_column_with_point_type
connection.create_table(table_name) do |t|
t.point :foo_point
end
assert_column_exists(:foo_point)
assert_type_correct(:foo_point, :point)
end
def test_creating_column_with_line_type
connection.create_table(table_name) do |t|
t.line :foo_line
end
assert_column_exists(:foo_line)
assert_type_correct(:foo_line, :line)
end
def test_creating_column_with_lseg_type
connection.create_table(table_name) do |t|
t.lseg :foo_lseg
end
assert_column_exists(:foo_lseg)
assert_type_correct(:foo_lseg, :lseg)
end
def test_creating_column_with_box_type
connection.create_table(table_name) do |t|
t.box :foo_box
end
assert_column_exists(:foo_box)
assert_type_correct(:foo_box, :box)
end
def test_creating_column_with_path_type
connection.create_table(table_name) do |t|
t.path :foo_path
end
assert_column_exists(:foo_path)
assert_type_correct(:foo_path, :path)
end
def test_creating_column_with_polygon_type
connection.create_table(table_name) do |t|
t.polygon :foo_polygon
end
assert_column_exists(:foo_polygon)
assert_type_correct(:foo_polygon, :polygon)
end
def test_creating_column_with_circle_type
connection.create_table(table_name) do |t|
t.circle :foo_circle
end
assert_column_exists(:foo_circle)
assert_type_correct(:foo_circle, :circle)
end
end
private
def assert_column_exists(column_name)
columns = connection.columns(table_name)
assert columns.map(&:name).include?(column_name.to_s)
end
def assert_type_correct(column_name, type)
columns = connection.columns(table_name)
column = columns.select{ |c| c.name == column_name.to_s }.first
assert_equal type.to_s, column.sql_type
end
end
end
end
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册