Writing an ActiveRecord-JDBC Adapter

23 04 2008

Rails 2.0 made writing your own ActiveRecord adapters easier. Combine
that with JDBC and you have some really nice tools for creating data
driven ruby applications working against any number of databases.

So, How Do I Write One?

Like a lot of things in the Ruby and Rails world, once you understand
the conventions, everything else is easy. So much so that, once you
know what you are looking for, writing an adapter is about copying the
patterns that have already been laid out in the other adapters.

The key steps for creating an adapter are:

- create a new lib/jdbc_adapter/jdbc_<adaptername>.rb

- update lib/active_record/connection_adapters/jdbc_adapter_spec.rb to
require ‘jdbc_adapter/jdbc_<adaptername>’

- create a new test/<adaptername>_simple_test.rb and an associated
test/db/<adaptername>.rb

- add test rake task to the Rakefile.

(these were basically stolen from an email on the JRuby Users mailing list).

What Goes Where?

For the most part, you can figure out everything else you need to know
by reading the code. If you aren’t sure how to do something, there’s
probably already an example of it in the code somewhere.
Here are some things I think I’ve figured out:

- Most of the magic happens in the
lib/jdbc_adapter/jdbc_<adaptername>.rb file. The rest of these
points describe points of interest in that file.

- ::JdbcSpec::ActiveRecordExtensions is where you put the connection
method, <adaptername>_connection. This is what Rails will call when
someone sets the adapter name to <adaptername>. You can use this to
turn Rails flavored config hashes into nasty JDBC URLs. Users will
thank you.

- Create a ::JdbcSpec::<AdapterName> module. Make sure you follow the
conventions for self.column_selector and
self.adapter_selector. There’s no reason not to.

- Lots of crazy stuff happens in the ::JdbcSpec::<AdapterName>
module. Write a custom create_table method. Rewrite “LIMIT 1″
queries for dialects that don’t support the LIMIT keyword. Support
migration behaviors that aren’t natively supported by the
database. Many more examples exist.

- Create a ::JdbcSpec::<AdapterName>::Column module. This is where
individual field customization happens. You can customize quoting
and unquoting of fields and column names. You can cast special types
(like bit to boolean). You can modify types on the fly.

Anything Else?

Eh, probably. I can’t think of anything else that you necessarily need
to know. I suppose you could do all of your modules in Java as part of
a Ruby Service. If your database driver has a friendly enough license,
you could distribute that as its own gem. This simplifies distribution
and installation for end users. I haven’t tried that yet, but it looks
simple enough. Leave a comment if can think of something I missed.

About these ads

Actions

Information

3 responses

29 05 2008
Leigh

Probably really obvious, but where is the jdbc driver name referenced ? Where should it be placed (i.e. is there a convention) in the jruby heirachy ?

Thanks.

29 05 2008
kofno

The driver class name is set as in the database config as the driver: value. One way to do that is to leave it for the user to specify in their database yaml file.

Here’s an example of that using a plain old jdbc adapter and Oracle:

#ORACLE
development:
adapter: jdbc
driver: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@myOracleHost:1521:mySID
username: myUser
password: myPass

If there is a driver that is the one most people will use, you can code your adapter to guess that driver for them. Here’s some code that I wrote that does that for InterSystems Cache DB:

http://tinyurl.com/9n6wy9

20 06 2009
Geronimo

Hi,

it would be great if you could give a simple example, how a new adapter could be written (for example just the framework, or just the methods which implementation are mandatory) – it would help a lot us, who has to create new jdbc-adapter(s).

Thanks and Regards,
-Geronimo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




Follow

Get every new post delivered to your Inbox.

%d bloggers like this: