AR JDBC Oracle does not handle writing of LOBS correctly.
---------------------------------------------------------
Key: JRUBY-1223
URL: http://jira.codehaus.org/browse/JRUBY-1223
Project: JRuby
Issue Type: Bug
Components: ActiveRecord-JDBC
Environment: Oracle 10G
Reporter: Michael Schubert
Assignee: Thomas E Enebo
Currently with AR JDBC when you save a record to a table that has a BLOB or
CLOB column, it correctly substitutes the value on the initial save with either
empty_blob() or empty_clob() but it never implemented the after_save mechanism
used by Rails w/ OCI to use an after save to write back.
Below is the original code from rails that is missing:
{code:title=oracle_adapter.rb|borderStyle=solid}
...
# After setting large objects to empty, select the OCI8::LOB
# and write back the data.
after_save :write_lobs
def write_lobs() #:nodoc:
if connection.is_a?(ConnectionAdapters::OracleAdapter)
self.class.columns.select { |c| c.sql_type =~ /LOB$/i }.each { |c|
value = self[c.name]
value = value.to_yaml if unserializable_attribute?(c.name, c)
next if value.nil? || (value == '')
lob = connection.select_one(
"SELECT #{c.name} FROM #{self.class.table_name} WHERE
#{self.class.primary_key} = #{quote_value(id)}",
'Writable Large Object')[c.name]
lob.write value
}
end
end
private :write_lobs
...
{code:}
However the last line, "lob.write value" will only work if the return from
connection.select_one is actually a special object created by the private
_select method in the original oracle_adapter.rb, which has logic that is
currently not implemented. First pass I made at trying to fix this stopped me
here since it looks like you may need to have @connection.execute_query handle
the logic below (this also handles time differently?):
{code:title=oracle_adapter.rb|borderStyle=solid}
...
def select(sql, name = nil)
cursor = execute(sql, name)
cols = cursor.get_col_names.map { |x| oracle_downcase(x) }
rows = []
while row = cursor.fetch
hash = Hash.new
cols.each_with_index do |col, i|
hash[col] =
case row[i]
when OCI8::LOB
name == 'Writable Large Object' ? row[i]: row[i].read
when OraDate
(row[i].hour == 0 and row[i].minute == 0 and row[i].second ==
0) ?
row[i].to_date : row[i].to_time
else row[i]
end unless col == 'raw_rnum_'
end
rows << hash
end
rows
ensure
cursor.close if cursor
end
...
{code}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
---------------------------------------------------------------------
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email