Skip to content

Commit

Permalink
fixed support for composite primary keys for tables with LOBs
Browse files Browse the repository at this point in the history
  • Loading branch information
rsim committed Jun 7, 2009
1 parent b8f3669 commit c3e0cff
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 18 deletions.
15 changes: 13 additions & 2 deletions lib/active_record/connection_adapters/oracle_enhanced_adapter.rb
Expand Up @@ -518,15 +518,26 @@ def insert_fixture(fixture, table_name)

# Writes LOB values from attributes, as indicated by the LOB columns of klass.
def write_lobs(table_name, klass, attributes)
id = quote(attributes[klass.primary_key])
# is class with composite primary key>
is_with_cpk = klass.respond_to?(:composite?) && klass.composite?
if is_with_cpk
id = klass.primary_key.map {|pk| attributes[pk.to_s] }
else
id = quote(attributes[klass.primary_key])
end
klass.columns.select { |col| col.sql_type =~ /LOB$/i }.each do |col|
value = attributes[col.name]
# RSI: changed sequence of next two lines - should check if value is nil before converting to yaml
next if value.nil? || (value == '')
value = value.to_yaml if col.text? && klass.serialized_attributes[col.name]
uncached do
lob = select_one("SELECT #{col.name} FROM #{table_name} WHERE #{klass.primary_key} = #{id} FOR UPDATE",
if is_with_cpk
lob = select_one("SELECT #{col.name} FROM #{table_name} WHERE #{klass.composite_where_clause(id)} FOR UPDATE",
'Writable Large Object')[col.name]
else
lob = select_one("SELECT #{col.name} FROM #{table_name} WHERE #{klass.primary_key} = #{id} FOR UPDATE",
'Writable Large Object')[col.name]
end
@connection.write_lob(lob, value, col.type == :binary)
end
end
Expand Down
98 changes: 82 additions & 16 deletions spec/active_record/connection_adapters/oracle_enhanced_cpk_spec.rb
Expand Up @@ -3,35 +3,101 @@
describe "OracleEnhancedAdapter composite_primary_keys support" do

before(:all) do
if defined?(ActiveRecord::ConnectionAdapters::OracleAdapter)
@old_oracle_adapter = ActiveRecord::ConnectionAdapters::OracleAdapter
ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
if defined?(::ActiveRecord::ConnectionAdapters::OracleAdapter)
@old_oracle_adapter = ::ActiveRecord::ConnectionAdapters::OracleAdapter
::ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
end
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
require 'composite_primary_keys'
class ::JobHistory < ActiveRecord::Base
set_table_name "job_history"
set_primary_keys :employee_id, :start_date
if $cpk_oracle_adapter
::ActiveRecord::ConnectionAdapters::OracleAdapter = $cpk_oracle_adapter
$cpk_oracle_adapter = nil
end
require 'composite_primary_keys'
end

after(:all) do
Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
Object.send(:remove_const, 'JobHistory') if defined?(JobHistory)
# Object.send(:remove_const, 'CompositePrimaryKeys') if defined?(CompositePrimaryKeys)
if defined?(::ActiveRecord::ConnectionAdapters::OracleAdapter)
$cpk_oracle_adapter = ::ActiveRecord::ConnectionAdapters::OracleAdapter
::ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
end
if @old_oracle_adapter
ActiveRecord::ConnectionAdapters.send(:remove_const, :OracleAdapter)
ActiveRecord::ConnectionAdapters::OracleAdapter = @old_oracle_adapter
::ActiveRecord::ConnectionAdapters::OracleAdapter = @old_oracle_adapter
@old_oracle_adapter = nil
end
end

it "should tell ActiveRecord that count distinct is not supported" do
ActiveRecord::Base.connection.supports_count_distinct?.should be_false
end
describe "do not use count distinct" do
before(:all) do
class ::JobHistory < ActiveRecord::Base
set_table_name "job_history"
set_primary_keys :employee_id, :start_date
end
end

after(:all) do
Object.send(:remove_const, 'JobHistory') if defined?(JobHistory)
end

it "should tell ActiveRecord that count distinct is not supported" do
ActiveRecord::Base.connection.supports_count_distinct?.should be_false
end

it "should execute correct SQL COUNT DISTINCT statement on table with composite primary keys" do
lambda { JobHistory.count(:distinct => true) }.should_not raise_error
it "should execute correct SQL COUNT DISTINCT statement on table with composite primary keys" do
lambda { JobHistory.count(:distinct => true) }.should_not raise_error
end
end

describe "table with LOB" do
before(:all) do
ActiveRecord::Schema.define do
suppress_messages do
create_table :cpk_write_lobs_test, :primary_key => [:type_category, :date_value], :force => true do |t|
t.string :type_category, :limit => 15, :null => false
t.date :date_value, :null => false
t.text :results, :null => false
t.timestamps
end
create_table :non_cpk_write_lobs_test, :force => true do |t|
t.date :date_value, :null => false
t.text :results, :null => false
t.timestamps
end
end
end
class ::CpkWriteLobsTest < ActiveRecord::Base
set_table_name 'cpk_write_lobs_test'
set_primary_keys :type_category, :date_value
end
class ::NonCpkWriteLobsTest < ActiveRecord::Base
set_table_name 'non_cpk_write_lobs_test'
end
end

after(:all) do
ActiveRecord::Schema.define do
suppress_messages do
drop_table :cpk_write_lobs_test
drop_table :non_cpk_write_lobs_test
end
end
Object.send(:remove_const, "CpkWriteLobsTest")
Object.send(:remove_const, "NonCpkWriteLobsTest")
end

it "should create new record in table with CPK and LOB" do
lambda {
CpkWriteLobsTest.create(:type_category => 'AAA', :date_value => Date.today, :results => 'DATA '*10)
}.should_not raise_error
end

it "should create new record in table without CPK and with LOB" do
lambda {
NonCpkWriteLobsTest.create(:date_value => Date.today, :results => 'DATA '*10)
}.should_not raise_error
end
end

# Other testing was done based on composite_primary_keys tests

end

0 comments on commit c3e0cff

Please sign in to comment.