Skip to content

Commit

Permalink
Fixed handling of nil number columns on Oracle and cleaned up tests f…
Browse files Browse the repository at this point in the history
…or Oracle in general #2555 [schoenm@earthlink.net]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2741 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information
dhh committed Oct 26, 2005
1 parent 50f7c9a commit dd257a3
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 41 deletions.
2 changes: 2 additions & 0 deletions activerecord/CHANGELOG
@@ -1,5 +1,7 @@
*SVN* *SVN*


* Fixed handling of nil number columns on Oracle and cleaned up tests for Oracle in general #2555 [schoenm@earthlink.net]

* Added quoted_true and quoted_false methods to db2_adapter and cleaned up tests for DB2 #2493 [maik schmidt] * Added quoted_true and quoted_false methods to db2_adapter and cleaned up tests for DB2 #2493 [maik schmidt]




Expand Down
50 changes: 43 additions & 7 deletions activerecord/lib/active_record/connection_adapters/oci_adapter.rb
Expand Up @@ -26,10 +26,15 @@ module ConnectionAdapters #:nodoc:
class OCIColumn < Column #:nodoc: class OCIColumn < Column #:nodoc:
attr_reader :sql_type attr_reader :sql_type


def initialize(name, default, limit, sql_type, scale) def initialize(name, default, sql_type, limit, scale, null)
@name, @limit, @sql_type, @scale, @sequence = name, limit, sql_type, scale @name, @limit, @sql_type, @scale, @null = name, limit, sql_type, scale, null
@type = simplified_type sql_type
@default = type_cast default @type = simplified_type(sql_type)
@default = type_cast(default)

@primary = nil
@text = [:string, :text].include? @type
@number = [:float, :integer].include? @type
end end


def simplified_type(field_type) def simplified_type(field_type)
Expand Down Expand Up @@ -127,6 +132,36 @@ def quote_column_name(name)
name =~ /[A-Z]/ ? "\"#{name}\"" : name name =~ /[A-Z]/ ? "\"#{name}\"" : name
end end


def tables(name = nil)
select_all("select lower(table_name) from user_tables").inject([]) do | tabs, t |
tabs << t.to_a.first.last
end
end

def indexes(table_name, name = nil) #:nodoc:
result = select_all(<<-SQL, name)
SELECT lower(i.index_name) as index_name, i.uniqueness, lower(c.column_name) as column_name
FROM user_indexes i, user_ind_columns c
WHERE c.index_name = i.index_name
AND i.index_name NOT IN (SELECT index_name FROM user_constraints WHERE constraint_type = 'P')
ORDER BY i.index_name, c.column_position
SQL

current_index = nil
indexes = []

result.each do |row|
if current_index != row['index_name']
indexes << IndexDefinition.new(table_name, row['index_name'], row['uniqueness'] == "UNIQUE", [])
current_index = row['index_name']
end

indexes.last.columns << row['column_name']
end

indexes
end

def structure_dump def structure_dump
s = select_all("select sequence_name from user_sequences").inject("") do |structure, seq| s = select_all("select sequence_name from user_sequences").inject("") do |structure, seq|
structure << "create sequence #{seq.to_a.first.last};\n\n" structure << "create sequence #{seq.to_a.first.last};\n\n"
Expand Down Expand Up @@ -211,7 +246,7 @@ def select_one(sql, name = nil)


def columns(table_name, name = nil) def columns(table_name, name = nil)
select_all(%Q{ select_all(%Q{
select column_name, data_type, data_default, data_length, data_scale select column_name, data_type, data_default, data_length, data_scale, nullable
from user_catalog cat, user_synonyms syn, all_tab_columns col from user_catalog cat, user_synonyms syn, all_tab_columns col
where cat.table_name = '#{table_name.upcase}' where cat.table_name = '#{table_name.upcase}'
and syn.synonym_name (+)= cat.table_name and syn.synonym_name (+)= cat.table_name
Expand All @@ -221,9 +256,10 @@ def columns(table_name, name = nil)
OCIColumn.new( OCIColumn.new(
oci_downcase(row['column_name']), oci_downcase(row['column_name']),
row['data_default'], row['data_default'],
row['data_length'],
row['data_type'], row['data_type'],
row['data_scale'] row['data_length'],
row['data_scale'],
row['nullable'] == 'Y'
) )
end end
end end
Expand Down
12 changes: 8 additions & 4 deletions activerecord/test/base_test.rb
Expand Up @@ -594,7 +594,9 @@ def test_multiparameter_attributes_on_date
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" } attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "24" }
topic = Topic.find(1) topic = Topic.find(1)
topic.attributes = attributes topic.attributes = attributes
assert_equal Date.new(2004, 6, 24).to_s, topic.last_read.to_s # note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
assert_equal Date.new(2004, 6, 24).to_s, topic.last_read.to_date.to_s
end end


def test_multiparameter_attributes_on_date_with_empty_date def test_multiparameter_attributes_on_date_with_empty_date
Expand All @@ -606,7 +608,9 @@ def test_multiparameter_attributes_on_date_with_empty_date
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" } attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" }
topic = Topic.find(1) topic = Topic.find(1)
topic.attributes = attributes topic.attributes = attributes
assert_equal Date.new(2004, 6, 1).to_s, topic.last_read.to_s # note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
assert_equal Date.new(2004, 6, 1).to_s, topic.last_read.to_date.to_s
end end


def test_multiparameter_attributes_on_date_with_all_empty def test_multiparameter_attributes_on_date_with_all_empty
Expand Down Expand Up @@ -647,8 +651,8 @@ def test_multiparameter_mass_assignment_protector


def test_attributes_on_dummy_time def test_attributes_on_dummy_time
# Oracle does not have a TIME datatype. # Oracle does not have a TIME datatype.
if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter if ActiveRecord::ConnectionAdapters.const_defined? :OCIAdapter
return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter) return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OCIAdapter)
end end
# Sqlserver doesn't either . # Sqlserver doesn't either .
if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter if ActiveRecord::ConnectionAdapters.const_defined? :SQLServerAdapter
Expand Down
18 changes: 6 additions & 12 deletions activerecord/test/finder_test.rb
Expand Up @@ -47,20 +47,14 @@ def test_find_all_with_limit
end end


def test_find_all_with_prepared_limit_and_offset def test_find_all_with_prepared_limit_and_offset
if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 1)
if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter)
assert_raises(ArgumentError) { Entrant.find(:all, :order => 'id ASC', :limit => 2, :offset => 1) }
end
else
entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 1)


assert_equal(2, entrants.size) assert_equal(2, entrants.size)
assert_equal(entrants(:second).name, entrants.first.name) assert_equal(entrants(:second).name, entrants.first.name)


entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 2) entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 2)
assert_equal(1, entrants.size) assert_equal(1, entrants.size)
assert_equal(entrants(:third).name, entrants.first.name) assert_equal(entrants(:third).name, entrants.first.name)
end
end end


def test_find_with_entire_select_statement def test_find_with_entire_select_statement
Expand Down
@@ -1,5 +0,0 @@
sqlplus arunit/arunit @ drop_oracle_tables
sqlplus arunit/arunit @ oracle
sqlplus arunit2/arunit2 @ drop_oracle_tables2
sqlplus arunit2/arunit2 @ oracle2

5 changes: 0 additions & 5 deletions activerecord/test/fixtures/db_definitions/create_oracle_db.sh
@@ -1,5 +0,0 @@
sqlplus arunit/arunit @ drop_oracle_tables
sqlplus arunit/arunit @ oracle
sqlplus arunit2/arunit2 @ drop_oracle_tables2
sqlplus arunit2/arunit2 @ oracle2

2 changes: 2 additions & 0 deletions activerecord/test/fixtures/db_definitions/oci.sql
Expand Up @@ -259,3 +259,5 @@ create table keyboards (
key_number integer not null, key_number integer not null,
name varchar(50) default null name varchar(50) default null
); );
create sequence keyboards_seq minvalue 10000;

5 changes: 5 additions & 0 deletions activerecord/test/fixtures_test.rb
Expand Up @@ -52,6 +52,11 @@ def test_inserts
end end


def test_inserts_with_pre_and_suffix def test_inserts_with_pre_and_suffix
# not supported yet in OCI adapter
if ActiveRecord::ConnectionAdapters.const_defined? :OCIAdapter
return true if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OCIAdapter)
end

ActiveRecord::Base.connection.create_table :prefix_topics_suffix do |t| ActiveRecord::Base.connection.create_table :prefix_topics_suffix do |t|
t.column :title, :string t.column :title, :string
t.column :author_name, :string t.column :author_name, :string
Expand Down
21 changes: 13 additions & 8 deletions activerecord/test/schema_dumper_test.rb
Expand Up @@ -4,16 +4,21 @@


if ActiveRecord::Base.connection.respond_to?(:tables) if ActiveRecord::Base.connection.respond_to?(:tables)


class SchemaDumperTest < Test::Unit::TestCase unless ActiveRecord::ConnectionAdapters.const_defined?(:OCIAdapter) && \
def test_schema_dump ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OCIAdapter)
stream = StringIO.new
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
output = stream.string


assert_match %r{create_table "accounts"}, output class SchemaDumperTest < Test::Unit::TestCase
assert_match %r{create_table "authors"}, output def test_schema_dump
assert_no_match %r{create_table "schema_info"}, output stream = StringIO.new
ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
output = stream.string

assert_match %r{create_table "accounts"}, output
assert_match %r{create_table "authors"}, output
assert_no_match %r{create_table "schema_info"}, output
end
end end

end end


end end

0 comments on commit dd257a3

Please sign in to comment.