Skip to content

Commit

Permalink
Merge pull request #2234 from yahonda/backport_2203_to_release70
Browse files Browse the repository at this point in the history
Merge pull request #2203 from akostadinov/master
  • Loading branch information
yahonda authored Dec 21, 2021
2 parents 39d595c + 65d14d7 commit 55c27ea
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,9 @@ def write_lobs(table_name, klass, attributes, columns) # :nodoc:
value = attributes[col.name]
# changed sequence of next two lines - should check if value is nil before converting to yaml
next unless value
if klass.attribute_types[col.name].is_a? Type::Serialized
value = klass.attribute_types[col.name].serialize(value)
# value can be nil after serialization because ActiveRecord serializes [] and {} as nil
next unless value
end
value = klass.attribute_types[col.name].serialize(value)
# value can be nil after serialization because ActiveRecord serializes [] and {} as nil
next unless value
uncached do
unless lob_record = select_one(sql = <<~SQL.squish, "Writable Large Object")
SELECT #{quote_column_name(col.name)} FROM #{quote_table_name(table_name)}
Expand Down
88 changes: 88 additions & 0 deletions spec/active_record/oracle_enhanced/type/custom_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# frozen_string_literal: true

describe "OracleEnhancedAdapter custom types handling" do
include SchemaSpecHelper

before(:all) do
ActiveRecord::Base.establish_connection(CONNECTION_PARAMS)
schema_define do
create_table :test_employees, force: true do |t|
t.string :first_name, limit: 20
t.string :last_name, limit: 25
t.text :signature
end
end

class TestEmployee < ActiveRecord::Base
class AttributeSignature < ActiveRecord::Type::Text
def cast(value)
case value
when Signature
value
when nil
nil
else
Signature.new(Base64.decode64 value)
end
end

def serialize(value)
Base64.encode64 value.raw
end

def changed_in_place?(raw_old_value, new_value)
new_value != cast(raw_old_value)
end
end

class Signature
attr_reader :raw

def initialize(raw_value)
@raw = raw_value
end

def to_s
"Signature nice string #{raw[0..5]}"
end

def ==(object)
raw == object&.raw
end
alias eql? ==
end

attribute :signature, AttributeSignature.new
end
end

after(:all) do
schema_define do
drop_table :test_employees
end
Object.send(:remove_const, "TestEmployee")
ActiveRecord::Base.clear_cache!
end

it "should serialize LOBs when creating a record" do
raw_signature = "peter'ssignature"
signature = TestEmployee::Signature.new(raw_signature)
@employee = TestEmployee.create!(first_name: "Peter", last_name: "Doe", signature: signature)
@employee.reload
expect(@employee.signature).to eql(signature)
expect(@employee.signature).to_not be(signature)
expect(TestEmployee.first.read_attribute_before_type_cast(:signature)).to eq(Base64.encode64 raw_signature)
end

it "should serialize LOBs when updating a record" do
raw_signature = "peter'ssignature"
signature = TestEmployee::Signature.new(raw_signature)
@employee = TestEmployee.create!(first_name: "Peter", last_name: "Doe", signature: TestEmployee::Signature.new("old signature"))
@employee.signature = signature
@employee.save!
@employee.reload
expect(@employee.signature).to eql(signature)
expect(@employee.signature).to_not be(signature)
expect(TestEmployee.first.read_attribute_before_type_cast(:signature)).to eq(Base64.encode64 raw_signature)
end
end

0 comments on commit 55c27ea

Please sign in to comment.