From 4544d2bc90bea93c38bb21d912dba00f51cf620f Mon Sep 17 00:00:00 2001 From: Dan McClain Date: Sun, 19 Aug 2012 18:02:34 -0400 Subject: Moves column dump specific code to a module included in AbstractAdapter Having column related schema dumper code in the AbstractAdapter. The code remains the same, but by placing it in the AbstractAdapter, we can then overwrite it with Adapter specific methods that will help with Adapter specific data types. The goal of moving this code here is to create a new migration key for PostgreSQL's array type. Since any datatype can be an array, the goal is to have ':array => true' as a migration option, turning the datatype into an array. I've implemented this in postgres_ext, the syntax is shown here: https://github.com/dockyard/postgres_ext#arrays Adds array migration support Adds array_test.rb outlining the test cases for array data type Adds pg_array_parser to Gemfile for testing Adds pg_array_parser to postgresql_adapter (unused in this commit) Adds schema dump support for arrays Adds postgres array type casting support Updates changelog, adds note for inet and cidr support, which I forgot to add before Removing debugger, Adds pg_array_parser to JRuby platform Removes pg_array_parser requirement, creates ArrayParser module used by PostgreSQLAdapter --- .../test/cases/adapters/postgresql/array_test.rb | 98 ++++++++++++++++++++++ .../cases/adapters/postgresql/datatype_test.rb | 12 +-- activerecord/test/cases/schema_dumper_test.rb | 14 +++- 3 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 activerecord/test/cases/adapters/postgresql/array_test.rb (limited to 'activerecord/test/cases') diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb new file mode 100644 index 0000000000..8774bf626f --- /dev/null +++ b/activerecord/test/cases/adapters/postgresql/array_test.rb @@ -0,0 +1,98 @@ +# encoding: utf-8 +require "cases/helper" +require 'active_record/base' +require 'active_record/connection_adapters/postgresql_adapter' + +class PostgresqlArrayTest < ActiveRecord::TestCase + class PgArray < ActiveRecord::Base + self.table_name = 'pg_arrays' + end + + def setup + @connection = ActiveRecord::Base.connection + @connection.transaction do + @connection.create_table('pg_arrays') do |t| + t.string 'tags', :array => true + end + end + @column = PgArray.columns.find { |c| c.name == 'tags' } + end + + def teardown + @connection.execute 'drop table if exists pg_arrays' + end + + def test_column + assert_equal :string, @column.type + assert @column.array + end + + def test_type_cast_array + assert @column + + data = '{1,2,3}' + oid_type = @column.instance_variable_get('@oid_type').subtype + # we are getting the instance variable in this test, but in the + # normal use of string_to_array, it's called from the OID::Array + # class and will have the OID instance that will provide the type + # casting + array = @column.class.string_to_array data, oid_type + assert_equal(['1', '2', '3'], array) + assert_equal(['1', '2', '3'], @column.type_cast(data)) + + assert_equal([], @column.type_cast('{}')) + assert_equal([nil], @column.type_cast('{NULL}')) + end + + def test_rewrite + @connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')" + x = PgArray.first + x.tags = ['1','2','3','4'] + assert x.save! + end + + def test_select + @connection.execute "insert into pg_arrays (tags) VALUES ('{1,2,3}')" + x = PgArray.first + assert_equal(['1','2','3'], x.tags) + end + + def test_multi_dimensional + assert_cycle([['1','2'],['2','3']]) + end + + def test_strings_with_quotes + assert_cycle(['this has','some "s that need to be escaped"']) + end + + def test_strings_with_commas + assert_cycle(['this,has','many,values']) + end + + def test_strings_with_array_delimiters + assert_cycle(['{','}']) + end + + def test_strings_with_null_strings + assert_cycle(['NULL','NULL']) + end + + def test_contains_nils + assert_cycle(['1',nil,nil]) + end + + private + def assert_cycle array + # test creation + x = PgArray.create!(:tags => array) + x.reload + assert_equal(array, x.tags) + + # test updating + x = PgArray.create!(:tags => []) + x.tags = array + x.save! + x.reload + assert_equal(array, x.tags) + end +end diff --git a/activerecord/test/cases/adapters/postgresql/datatype_test.rb b/activerecord/test/cases/adapters/postgresql/datatype_test.rb index a7f6d9c580..c7ce43d71e 100644 --- a/activerecord/test/cases/adapters/postgresql/datatype_test.rb +++ b/activerecord/test/cases/adapters/postgresql/datatype_test.rb @@ -70,8 +70,8 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase end def test_data_type_of_array_types - assert_equal :string, @first_array.column_for_attribute(:commission_by_quarter).type - assert_equal :string, @first_array.column_for_attribute(:nicknames).type + assert_equal :integer, @first_array.column_for_attribute(:commission_by_quarter).type + assert_equal :text, @first_array.column_for_attribute(:nicknames).type end def test_data_type_of_tsvector_types @@ -112,8 +112,8 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase end def test_array_values - assert_equal '{35000,21000,18000,17000}', @first_array.commission_by_quarter - assert_equal '{foo,bar,baz}', @first_array.nicknames + assert_equal [35000,21000,18000,17000], @first_array.commission_by_quarter + assert_equal ['foo','bar','baz'], @first_array.nicknames end def test_tsvector_values @@ -170,7 +170,7 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase end def test_update_integer_array - new_value = '{32800,95000,29350,17000}' + new_value = [32800,95000,29350,17000] assert @first_array.commission_by_quarter = new_value assert @first_array.save assert @first_array.reload @@ -182,7 +182,7 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase end def test_update_text_array - new_value = '{robby,robert,rob,robbie}' + new_value = ['robby','robert','rob','robbie'] assert @first_array.nicknames = new_value assert @first_array.save assert @first_array.reload diff --git a/activerecord/test/cases/schema_dumper_test.rb b/activerecord/test/cases/schema_dumper_test.rb index 80d2670f94..80f46c6b08 100644 --- a/activerecord/test/cases/schema_dumper_test.rb +++ b/activerecord/test/cases/schema_dumper_test.rb @@ -79,9 +79,9 @@ class SchemaDumperTest < ActiveRecord::TestCase def test_arguments_line_up column_definition_lines.each do |column_set| - assert_line_up(column_set, /:default => /) - assert_line_up(column_set, /:limit => /) - assert_line_up(column_set, /:null => /) + assert_line_up(column_set, /default: /) + assert_line_up(column_set, /limit: /) + assert_line_up(column_set, /null: /) end end @@ -278,6 +278,14 @@ class SchemaDumperTest < ActiveRecord::TestCase end end + def test_schema_dump_includes_arrays_shorthand_definition + output = standard_dump + if %r{create_table "postgresql_arrays"} =~ output + assert_match %r[t.text\s+"nicknames",\s+array: true], output + assert_match %r[t.integer\s+"commission_by_quarter",\s+array: true], output + end + end + def test_schema_dump_includes_tsvector_shorthand_definition output = standard_dump if %r{create_table "postgresql_tsvectors"} =~ output -- cgit v1.2.3