Sunday, September 03, 2006

Using the ActiveRecord-JDBC Adapter

Ola Bini, Nick Sieger, and others have been making great progress on the ActiveRecord-JDBC adapter lately. I figure it's a good time for a brief update on progress, and a short walkthrough on how to use it.

Where We Are, Where We're Going

There has been one official release of the ActiveRecord-JDBC adapter, a 0.1 that has basic SQL support for MySQL. It's available as a gem called "ActiveRecord-JDBC" (case-insensitive). It provides normal MySQL support for most major ActiveRecord operations today, and it's mostly the same code we used for our JavaOne demo.

Although the JDBC libraries give us plenty of information on database typing and precision, they provide practically nothing for generating DDL. Because of this, a large part of current ActiveRecord capabilities have to be written outside of the JDBC-aware code. DDL differs between databases, so like the core Rails project, we're forced to implement the various schema-related methods of ActiveRecord differently for different database vendors.

Currently, we're just reproducing the same code available in core Rails, with a little manipulation to work with ActiveRecord-JDBC, but we're hoping to work with the Rails team to abstract out the non-driver-specific portions of the core ActiveRecord adapters so the JDBC version can leverage the same code. I'm also hoping we'll be able to get the "jdbc" adapter name added to core Rails in the active_record.rb file where such adapters are listed. This will allow JRuby users to install Rails and the JDBC adapter and immediately start using them, without additional steps.

We are planning a second release of the JDBC adapter very shortly. It should have reasonably solid migrations/DDL support for MySQL, Oracle, and Firebird, as well as some level of support for HSQLDB, Derby, and others. It's moving along quickly now that it's been spun off into its own jruby-extras project. You can go there or to the jruby-extras SVN repository to grab the bleeding-edge source from SVN.

Getting up and running with ActiveRecord-JDBC

Despite the design complexities and our DDL woes, getting an ActiveRecord-based app up and running on JDBC is now very simple. This walkthrough proceeds from a stock JRuby install, and is based on current JRuby trunk (though it may work ok with 0.9.0 as well...we'll have a new release out soon).

  1. Ensure JRuby is set up and working correctly via the normal setup procedures
  2. gem install rails -y --no-rdoc --no-ri (ri and rdoc generation are still too slow under JRuby)
  3. gem install ActiveRecord-JDBC --no-rdoc --no-ri (this is the 0.1 version for now, but hopefully we'll have 0.2 out this week)
  4. Edit lib/ruby/gems/1.8/gems/activerecord.../lib/active_record.rb, adding jdbc to the list of RAILS_CONNECTION_ADAPTERS toward the bottom of the file:
    RAILS_CONNECTION_ADAPTERS = %w( jdbc mysql postgresql sqlite firebird sqlserver db2 oracle sybase openbase )
  5. Modify database.yml for your settings. For example, using MySQL:
    development:
    adapter: jdbc
    url: jdbc:mysql://localhost/testapp
    driver: com.mysql.jdbc.Driver
    username: testapp
    password: testapp
  6. As always, ensure the appropriate JDBC jar files are in your CLASSPATH
That's pretty much all there is to it. We'll get that second release out in a day or two so that migrations work and additional databases are supported, but these instructions won't change. I'll post here when that release is out.

How Well Does It Work?

It seems to work very well so far. As part of my JRuby on Rails presentation at RailsConf, I'll be demonstrating the new Depot application from Agile Web Development with Rails 2nd Ed. The entire app seems to work very well under JRuby, and I only had to make one additional manual change in the database because JRuby doesn't yet work well with edge rails (on which the book's examples are currently based). It's quick and responsive, and will only improve as we continue on.

Also keep in mind that the DDL issue only limits the JDBC adapter's usefulness for migrations or schema-manipulation purposes. Without DDL generation, it will still work with many, many databases without major modifications, since JDBC really shines here. Hopefully a future version of JDBC will provide DDL metadata or tools for manipulating database schemas. Until then, we'll continue to work with the Rails folks to find a good solution for DDL under the ActiveRecord-JDBC adapter.