At my current job we've got a large existing code-base built on Class::DBI. For my current project I decided to experiment with using Rose::DB::Object instead, hoping to see less need for hand-written SQL. So far it's been a success, but one issue was quite difficult to get right - getting the two systems to share a DBI handle. If I didn't do this then I was going to see a doubling of total DBI connections when I deployed my new app to the web cluster, which is unacceptable.
I started with the most obvious solution, an over-ridden init_db() in my Rose::DB::Object subclass:
sub init_db { my ($pkg, @args) = @_; My::Rose::DB->new_or_cached(dbh => My::Class::DBI->db_Main(), @args); }
That worked great at first - when Rose needs a DB connection it gets one pre-loaded with my Class::DBI handle. (And as a side-note, the fact that the Class::DBI handle uses DBIx::ContextualFetch doesn't cause Rose problems.)
However, sometimes for unknown reasons Rose will decide it needs to reconnect after the initial connection is established. To intercept these calls I added an overridden dbh() method to my Rose::DB sub-class:
sub dbh { my $self = shift; unless (@_) { $self->{dbh} ||= My::Class::DBI->db_Main(); } return $self->SUPER::dbh(@_); }
Another useful hint which helped me notice very quickly when Rose decided to reconnect - I gave Rose::DB an invalid password in my call to register_db. That way Rose would have all the correct information about the connection, but wouldn't be able to initiate new connections.
I hope this helps other suffering Class::DBI users to give Rose a try!
-sam