class TestPostgresArray < DBDConfig.testbase(:postgresql) def test_array_type assert_nothing_raised do cols = @dbh.columns("array_test") assert_equal( [ { :name =>"foo", :default =>nil, :primary =>nil, :scale =>nil, :sql_type =>DBI::SQL_INTEGER, :nullable =>true, :indexed =>false, :precision =>-1, :type_name =>"integer", :unique =>nil, :array_of_type => true }, { :name =>"bar", :default =>nil, :primary =>nil, :scale =>nil, :sql_type =>DBI::SQL_INTEGER, :nullable =>true, :indexed =>false, :precision =>-1, :type_name =>"integer", :unique =>nil, :array_of_type => true }, { :name =>"baz", :default =>nil, :primary =>nil, :scale =>nil, :sql_type =>DBI::SQL_INTEGER, :nullable =>true, :indexed =>false, :precision =>-1, :type_name =>"integer", :unique =>nil, :array_of_type => true }, { :array_of_type=>true, :unique=>nil, :precision=>-1, :name=>"quux", :default=>nil, :indexed=>false, :scale=>nil, :primary=>nil, :sql_type=>12, :nullable=>true, :type_name=>"character varying" } ], cols.collect { |x| x.reject { |key, value| key == :dbi_type } } ) assert_equal(([DBI::DBD::Pg::Type::Array] * 4), cols.collect { |x| x["dbi_type"].class }) assert_equal((([DBI::Type::Integer] * 3) + [DBI::Type::Varchar]), cols.collect { |x| x["dbi_type"].base_type }) end end def test_array_parser # string representation assert_nothing_raised do sth = @dbh.prepare('insert into array_test (foo) values (?)') sth.execute('{1,2,3}') sth.finish end assert_nothing_raised do sth = @dbh.prepare('insert into array_test (foo) values (?)') sth.execute([1,2,3]) sth.finish end assert_nothing_raised do sth = @dbh.prepare('insert into array_test (quux) values (?)') sth.execute(["Hello\\ World", "Again\\"]) sth.finish end assert_nothing_raised do sth = @dbh.prepare('select foo from array_test where foo is not null') sth.execute assert_equal( [ [[1,2,3]], [[1,2,3]], ], sth.fetch_all ) sth.finish sth = @dbh.prepare('select quux from array_test where quux is not null') sth.execute assert_equal( [ [["Hello\\ World", "Again\\"]] ], sth.fetch_all ) sth.finish end end def test_array_boundaries # bar has a max extents of 3 sth = @dbh.prepare('insert into array_test (bar) values (?)') assert_nothing_raised do sth.execute('{1,2,3}') end # XXX postgresql does not enforce extents on single-dimension arrays assert_nothing_raised do sth.execute('{1,2,3,4}') end sth.finish sth = @dbh.prepare('insert into array_test(baz) values (?)') assert_nothing_raised do sth.execute('{{1,2,3}, {1,2,3}}') end assert_nothing_raised do # XXX for the record, I have no fucking idea why this works, what # it's technically represented as and what backwards array # implementation would allow it to work. # # I'm hoping it'll break on some future version of postgresql so I # can fix it. sth.execute('{1,2,3}') end assert_raise(DBI::ProgrammingError) do sth.execute('{{1,2,3,4}, {1,2,3}}') end assert_raise(DBI::ProgrammingError) do sth.execute('{{1,2,3}, {1,2,3,4}}') end sth.finish end def test_array_type_parser pc = DBI::DBD::Pg::Type::Array assert_nothing_raised do po = pc.new(DBI::Type::Integer) assert_equal([1,2,3], po.parse("{1,2,3}")) assert_equal([[1,2,3],[4,5,6]], po.parse("{{1,2,3},{4,5,6}}")) end assert_nothing_raised do po = pc.new(DBI::Type::Varchar) assert_equal(["one", "two", "three"], po.parse("{\"one\",\"two\",\"three\"}")) assert_equal([["one"], ["two\\"]], po.parse("{{\"one\"},{\"two\\\\\"}}")) assert_equal([["one", "two\\"], ["three\\", "four"]], po.parse("{{\"one\",\"two\\\\\"},{\"three\\\\\",\"four\"}}")) end end def test_array_generator pg = DBI::DBD::Pg assert_nothing_raised do assert_equal("{1,2,3}", pg.generate_array([1,2,3])) assert_equal("{{1,2,3},{1,2,3}}", pg.generate_array([[1,2,3],[1,2,3]])) assert_equal("{\"one\",\"two\"}", pg.generate_array(["one", "two"])) assert_equal("{\"hello\\\\ world\",\"again\"}", pg.generate_array(["hello\\ world", "again"])) end end end