ray_apps_blog

June 28, 2008

ActiveRecord Oracle enhanced adapter version 1.1.1 released

Filed under: oracle,oracle-enhanced,rails,ruby — Raimonds Simanovskis @ 2:27 pm

I just released new version of ActiveRecord Oracle enhanced adapter which includes several new enhancements which could be useful if you use ActiveRecord with legacy Oracle databases:

  • Added ignore_table_columns option for class definitions
  • You can specify which table (or view) columns should be ignored by ActiveRecord – these could be either columns which you do not need in Rails application or which have currently unsupported data types. For example:

        class Employee < ActiveRecord::Base
          ignore_table_columns  :phone_number, :hire_date
        end
    
  • Added support for TIMESTAMP columns
  • You can create tables with :timestamp data type which will create TIMESTAMP columns and you can access values from TIMESTAMP columns. Unfortunately due to current ruby-oci8 limitations when you will retrieve TIMESTAMP values it will be without fractional seconds (but if you pass Time value with fractional seconds then it will be stored in database).

  • NLS_DATE_FORMAT and NLS_TIMESTAMP_FORMAT independent DATE and TIMESTAMP columns support
  • By default Oracle adapter (and enhanced adapter as well) changes NLS_DATE_FORMAT and NLS_TIMESTAMP_FORMAT to ‘DD-MON-YYYY HH24:MI:SS’. But if you are working with some legacy database which requires different NLS date settings then now you can change these settings to different ones. You can put in some initialization file some other NLS settings, e.g.:

    ActiveRecord::Base.connection.execute %q{alter session set nls_date_format = 'DD-MON-YYYY HH24:MI:SS'}
    ActiveRecord::Base.connection.execute %q{alter session set nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS'}
    

    and ActiveRecord will continue to work correctly with date values.

Also one Rails 2.1 related issue was solved. Previously Oracle enhanced adapter always added after_save callback to ActiveRecord session store which stores BLOB data in the database (as in Rails 2.0 there was issue that this callback was not added). Now in Rails 2.1 this callback is added by ActiveRecord therefore Oracle enhanced adapter checks if this callback is already added or not. So now this should work correctly both in Rails 2.0 and Rails 2.1.

Also I have noticed that in some Rails 2.1 applications Oracle adapter is failing on ActiveRecord session store updates when partial updates are enabled. If you also have such issue then put this into your initialization file which will work as workaround until I will find what is causing this problem:

CGI::Session::ActiveRecordStore::Session.partial_updates = false

To get the new release just do:

sudo gem install activerecord-oracle_enhanced-adapter

Source code of Oracle enhanced adapter is located at GitHub. And you can submit bug reports and enhancement requests in Lighthouse. There you can see also some identified enhancements – please add comments to them if you also would like to have them. Then it will be easier for me to select what to include in next version of adapter.

19 Comments »

  1. Thx Raimonds, great job!

    Comment by Liming Lian — June 30, 2008 @ 9:35 am | Reply

  2. This is really great news – That BLOB bug made it really difficult for me to keep pushing Ruby at work. I put something together (not something I’d submit as a fix, it was too much of a hack!) so that I could use AR for a data acquisition program. Good ORMs that REALLY support Oracle haven’t shown up yet, AFAIK.

    I will definitely check out the new version of the PLSQL gem also. Thanks for continuing support for Oracle!

    Comment by Jamie — June 30, 2008 @ 9:40 am | Reply

  3. Thanks!  I just submited a feature request: support for ‘oci’ as the adapter name .

    Comment by Jesse Hu — July 1, 2008 @ 7:36 am | Reply

  4. hey raimond,
    ever thought of maintaining the current activerecord-oracle-adapter?

    Comment by Roob — July 8, 2008 @ 3:26 pm | Reply

  5. I tried to use it (Rails 2.0.2/Oracle 10g), but I’m getting:

    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/base.rb:1532:in `method_missing’:NoMethodError: undefined method `after_save_callback_chain’ for #

    Comment by Thomas — July 8, 2008 @ 4:25 pm | Reply

  6. @Roob
    I offered to maintain current activerecord-oracle-adapter but it seems that current maintainers are not interested to do any major improvements. Therefore I forked original one and doing further development – and there are no differences if you use original or mine – just use what suits better your needs :)

    @Thomas
    Yes, I found a bug that version 1.1.1 was not correcly adding after_save callback to ActiveRecord session store. Therefore I just corrected this bug and released version 1.1.2.
    So just do “sudo gem install activerecord-oracle_enhanced-adapter” and you will get the latest version where this bug should be solved.

    Comment by Raimonds Simanovskis — July 8, 2008 @ 9:36 pm | Reply

  7. First, thanks for all of your work. I’ve downloaded the adapter and after turning off partial updates, all seems well.
    Second, a more serious issue: It seems to me that you have (inadvertantly or otherwise) set yourself up as the defacto maintainer of the oracle adapter. I don’t see that much activity on the “actual” adapter, and it seems that at the very least they might have back/cross-ported some of your enhancements that qualify as fixes.
    I know that the rails core team can have an attitude that is almost antipathetic towards the non-preferred databases.
    But I wonder, just how many people are using RoR with Oracle? I would like to know the size of the community. This matters to me not just because I’m using RoR with Oracle but also because I think it’s a completely valid choice. Perhaps it’s time to do a bit of a census of that community and see about being a voice in RoR. I don’t want Oracle support to be cast-off particularly at a time when I think RoR itself is ready for the next step in expansion into mainstream enterprise development.
    Anyhow..sorry to rant on your blog, but I think you are a potential point-man for this community.
    Thanks again for the good work.

    Comment by Todd F — July 10, 2008 @ 5:32 pm | Reply

  8. @Todd

    I think that it is good that core team has moved Oracle support out of core Rails. They are not using Oracle database and therefore it’s hard for them to provide quality support for that. And as they have defined more or less precise API how to write your own database adapters and plug them into Rails then it is not so difficult to add any database support in Rails.

    In our company we now have several Rails projects on Oracle and therefore we have practical experience and real issues to solve. And therefore I prefer to maintain my own Oracle adapter where I can quickly add and publish new changes. And I am happy if others find my work and support for Rails on Oracle useful :) That’s the way how Rails originated and how it is developing further – each solves problems from real projects and then extracts these common solutions into framework or plugins or gems.

    As I see in http://gems.rubyforge.org/stats.html statistics Oracle enhanced gem downloads are increasing all the time (today’s total was 365). So it seams that there are quite enough developers interested in Rails on Oracle. And also inside Oracle there are people how push Rails on Oracle further (like mix.oracle.com team) so I think Rails on Oracle will become more and more popular. During Oracle OpenWorld conference there will be tutorial on using Rails on Oracle – I will be around there as well and there it would be good discuss with other people who are using Rails on Oracle.

    Comment by Raimonds Simanovskis — July 11, 2008 @ 10:27 am | Reply

  9. I’m having this problem:

    OCIError (ORA-22920: row containing the LOB value is not locked):
    lob.c:181:in oci8lib.so
    /usr/local/lib/site_ruby/1.8/oci8.rb:1005:in `write’
    /usr/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.1.4/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb:383:in `write_lobs’
    /usr/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.1.4/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb:377:in `each’
    /usr/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.1.4/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb:377:in `write_lobs’
    /usr/lib/ruby/gems/1.8/gems/activerecord-oracle_enhanced-adapter-1.1.4/lib/active_record/connection_adapters/oracle_enhanced_adapter.rb:65:in `enhanced_write_lobs’

    Comment by Guilherme — July 22, 2008 @ 8:03 pm | Reply

  10. As I wrote in my post this sometimes happens if partial updates are allowed – I could not repeat the problems so far to identify what is causing this. The workaround is to turn partial updates off.
    If this is because of session store then do
    CGI::Session::ActiveRecordStore::Session.partial_updates = false
    If this is because of other ActiveRecord models then do
    ActiveRecord::Base.partial_updates = false
    or just do
    self.partial_updates = false
    in the particular model class definition where you have this issue with CLOB columns.

    Comment by Raimonds Simanovskis — July 22, 2008 @ 9:35 pm | Reply

  11. Ah! I’d tried
    CGI::Session::ActiveRecordStore::Session.partial_updates = false
    before with no success.

    But with
    ActiveRecord::Base.partial_updates = false
    it works! Thanks!

    Comment by Guilherme — July 22, 2008 @ 11:41 pm | Reply

  12. I was getting
    ORA-22920 row containing the LOB value is not locked
    and
    ORA-22990: LOB locators cannot span transactions
    under rails 2.1, and setting partial_updates = false didn’t fix them all.

    I finally had to actually debug it.
    I made two changes to the ‘write_lobs’ method, adding ‘FOR UPDATE’ to the select and running the ‘select_one’ and ‘write’ statements in an ‘uncached’ block.

    See http://blog.potatocanyon.com/2008/07/rails-21-and-oracle_23.html for the gory details.

    I now have partial_updates = true and all of my tests run without error.

    Raimonds, any chance of getting these changes in the advanced adapter? Is there something I can do to help?

    Comment by Sandi Metz — July 24, 2008 @ 1:00 am | Reply

  13. Sandi, thank you very much :)

    Tried this change on our projects and it seems that it has solved the issue and now everything works with partial_updates enabled.

    I will include this change in the next release of Oracle enhanced adapter.

    Comment by Raimonds Simanovskis — July 24, 2008 @ 11:55 am | Reply

  14. This fix for partial_updates is now included in Oracle enhanced adapter version 1.1.5.

    Comment by Raimonds Simanovskis — July 27, 2008 @ 9:12 pm | Reply

  15. Raimonds,

    Thanks. You rock.

    Comment by Sandi Metz — July 28, 2008 @ 3:25 am | Reply

  16. I have been having a problem similar to the one below in connecting to Oracle with the enhanced oracle adapter. This is taken from a similar post elsewhere. Do you have any ideas?

    /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/dependencies.
    rb:275:in `load_missing_constant’: uninitialized constant
    ActiveRecord::Connecti
    onAdapters::OracleEnhancedAdapter (NameError)
    from
    /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
    dependencies.rb:467:in `const_missing’
    from
    /home/scheng/rails/ServerMonitoringSystem/config/initializers/oracl
    e_enhanced.rb:1
    from
    /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
    dependencies.rb:502:in `load’
    from
    /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
    dependencies.rb:502:in `load’
    from
    /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
    dependencies.rb:354:in `new_constants_in’
    from
    /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
    dependencies.rb:502:in `load’
    from
    /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:475:in `
    load_application_initializers’
    from
    /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/initializer.rb:474:in `
    each’
    … 7 levels…
    from
    /usr/lib/ruby/gems/1.8/gems/rails-2.1.0/lib/commands/runner.rb:39
    from
    /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_
    original_require’
    from
    /usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `requ
    ire’

    —-
    Peter

    Comment by Peter Jones — December 10, 2008 @ 4:27 pm | Reply

  17. @Peter

    It’s quite hard to tell what exactly is problem in your case.

    Please verify that
    1. Oracle Instant Client is installed correctly.
    Can you connect to database using sqlnet?

    2. ruby-oci8 1.0.3 is installed correctly.
    Try something like:

    ruby -r oci8 -e “OCI8.new(‘user’, ‘password’,'database’).exec(‘select * from dual’) do |r| puts r.join(‘,’); end”

    to verify that ruby-oci8 is working

    3. activerecord-oracle_enhanced-adapter is installed correctly
    Try
    gem list activerecord-oracle_enhanced-adapter
    to verify that it is installed.

    Btw if you have further issues please use http://groups.google.com/group/oracle-enhanced discussion group – it will be more appropriate than long comments here :)

    Comment by Raimonds Simanovskis — December 10, 2008 @ 7:13 pm | Reply

  18. Whoops! I missed the point about loading oci8 – seems OK now – at least the server starts.
    Thanks

    Peter

    Comment by Peter Jones — December 15, 2008 @ 11:40 am | Reply

  19. great post ! i managed to implement it correctly, looking forward some more information.

    Comment by Mobile WebSite — July 7, 2010 @ 10:00 am | Reply


RSS feed for comments on this post.

Leave a comment

Blog at WordPress.com.