cLive ;-) has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I'm writing a module to call common requests I make through DBI for a job I'm on. I could open and close my DB handle for each request, or hard code them into my scripts, but what I was wondering is, "Is there a standard way to check whether a $dbh object exists and is open?".

ie, when I call a data query sub in the module, it only opens a handle if one is not already open? That way I could just call a "dbh_tidy()" sub at the end to close the dbh and exit.

All thoughts, as always, appreciated :)

cLive ;-)

PS - Hope the above makes sense...

Replies are listed 'Best First'.
Re: checking whether DBI connection made
by chromatic (Archbishop) on Aug 16, 2001 at 06:08 UTC
    If it's object-oriented, you could use a singleton pattern. (There's a non OO approach that looks very similar.)
    my $single; sub new { return $single if defined $single; # set up args $self->{dbh} = DBI->connect(@args); $single = bless($self, $class); return $single; } # procedural { my $dbh; sub get_handle { return $dbh if defined $dbh; # handle arguments $dbh = DBI->connect(@args); } }
Re: checking whether DBI connection made
by dga (Hermit) on Aug 16, 2001 at 05:40 UTC

    try DBI->connect_cached. (like so)

    use DBI; ... $dbh=DBI->connect_cached( ... ) or die ...;

    After this call your $dbh handle is live and connected and ready to use. If the handle is already connected it just uses that if not it reconnects for you.

    Your parameters to the connect must be identical for this to reuse an existing connection (this is normally the case and shouldn't be a problem)

    you could even put it in an eval to handle the die condition maybe sleeping and trying again depending on the specific error.

    There is also prepare_cached etc.

    Enjoy

Re: checking whether DBI connection made
by blakem (Monsignor) on Aug 16, 2001 at 03:12 UTC
    how about

    die "no database handle" unless ($dbh && $dbh->ping)

    -Blake

Re: checking whether DBI connection made
by faure (Sexton) on Aug 16, 2001 at 06:25 UTC
    Or-equals won't test the connection and it involves some redundant typing...

    But if you have more than one potential data source (or if you like the visual effect ;) you can use it to wait and initialize the objects as needed.

    #!/usr/bin/perl -w use strict; package Queries; my ($db_handle, $ldap_connection); sub data_query_one { $db_handle ||= new Sybase::DBlib(); ... } sub data_query_two { $db_handle ||= new Sybase::DBlib(); ... } sub ldap_query_one { $ldap_connection ||= new LDAP::Conn(); ... } # &c. sub clean_up { $ldap_connection->close if $ldap_connection; $db_handle->release if $db_handle; } 1;
(elbie): checking whether DBI connection made
by elbie (Curate) on Aug 16, 2001 at 17:57 UTC
    There have been a lot of good suggestions so far. I just wanted to add my .16th of a bit (as in shave-and-a-haircut bits, not the memory bits).

    If a DBI->connect fails, there will be an error string set in DBI::errstr. This is analogous to the $dbh->errstr when you have an open db handle. The perldoc on DBI will have more info.

    e.g.

    my $dbh = DBI->connect('DBI:stack_of_papers_on_my_desk', 'user', 'pw') or die DBI::errstr;

    elbieelbieelbie