I wrote my first module wrapping DBI years ago, and have used it on a few projects. Basically I've done this for two general objectives. The first is to wrap the DBI->connect call with a connect of my own, using a different name (such as db_connect). The purpose of custom connect isn't to muddle with DBI's internal connection mechanics, but just to handle things like providing some default values and/or retry connecting a few times. Inside my connect method I use DBI->connect and then store the $dbh as an attribute in the the object I bless into my own class and then return. The second reason is to provide a few special methods which all operate on a database. In no place am I trying to override existing DBI methods, just add new ones.

So far I have accomplished this fine by writing my custom DB class as a wrapper. In my custom methods I would use $self->{DBH}->prepare for example, and I use AUTOLOAD to simply pass any call not recognized in my module on to DBI:

sub AUTOLOAD { my $self = shift; my $call = $AUTOLOAD; $call =~ s/.*:://; return $self->{DBH}->$call(@_); } # AUTOLOAD

But I find myself in the middle of a moderate rewrite of an old project too long neglected. While the rest of the modules in the project are becoming more carefully designed classes, I feel an urge to do the same with my custom DBI wrapper, making it instead a subclass of DBI. This would allow me drop AUTOLOAD, but how would it effect my custom methods? If I read the docs correctly, $self->{DBH}->prepare() would just become $self->prepare(); OK, minor improvement.

Which leaves making the database connection, and this is where I found the docs (or mostly the ancillary articles on the subject) a bit confusing, giving some dire words of caution. ... Can I continue to use my own connect method, leaving DBI's available to the user if needed, and just replace $self{DBH} = DBI->connect(...) with $dbh = DBI->connect(..., { RootClass => 'MySubDBI' }) and return that connection handle instead of blessing it myself? Would it be more prudent to override DBI's connect method, calling SUPER::connect internally?

So fellow monks, besides hoping someone with experience could provide advice or sample snippets clarifying my questions above, I humbly ask you: Are the gains of sublassing DBI over wrapping it worth the effort given my simple needs?

Thanks!


In reply to Subclassing DBI instead of wrapping by spq

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.