Question

In my script creates are several different objects that use a wrapper for DBI:

package MY::DB;
use DBI;

sub my_connect {
  my ($class, %p) = @_;
  my $dbh = DBI->connect(...);
  $dbh->do("SET NAMES cp1251");
  return bless {dbh => $dbh}, $class;
}

sub query {
  my ($self, $sql) = @_;
  # sql execution
}
...

I decided to optimize the script using only one connection to the database. Tried two options: a global variable and a method of DBI->connect_cached(..). The result is the same: the connection is actually used one for all objects, but does not process the sql code after connection:

...
sub my_connect {
  my ($class, %p) = @_;
  my $dbh = DBI->connect_cached(...);
  $dbh->do("SET NAMES cp1251"); # no effect :(
  return bless {dbh => $dbh}, $class;
}
...

For example I have classes:

package MY::USER;
use base 'MY::DB';
sub constructor {
    my ($class) = @_;
    return MY::DB::my_connect($class);
}
sub get_info_1 {
  my ($self) = @_;
  $self->query(...);
}
sub get_info_2 {
  my ($self) = @_;
  $self->query();
}

package MY::NEWS;
use base 'MY::DB';
sub constructor {
    my ($class) = @_;
    return MY::DB::my_connect($class);
}
sub get_info {
  my ($self) = @_;
  $self->query(...);
}

Script:

use MY::USER;
use MY::NEWS;

my $user = MY::USER->constructor;
my $news = MY::NEWS->constructor;

$user->get_info_1; # OK
$news->get_info; # OK
$user->get_info_2; # here $dbh->do("set names cp1251") operation no effect
Was it helpful?

Solution

I found answer on my problem!

Main DBI-class has destructor:

sub DESTROY {
    my ($self) = @_;
    $self->{dbh}->disconnect;
}

And all childs of this class have it. Inside NEWS->get_info() called and destroyed same objects, and link to database disconnected... but value of DBH variable is defined!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top