[Dbix-class] connect_info vs. Readonly

Marcello Romani mromani at ottotecnica.com
Mon Aug 6 16:45:44 GMT 2007


Hallo,
     I found that when trying to connect to a database to obtain a =

$schema object, if the options hash is readonly, an exception is thrown.

Here is my code:


use Readonly;
use MyDB;
use Carp qw(croak)

Readonly my $dbi_dsn    =3D> "dbi:Pg:mydb"
Readonly my $user       =3D> "user";
Readonly my $pass       =3D> "pass";
Readonly my %dbi_params =3D> (
     Autocommit =3D> 0,
     RaiseError =3D> 1,
     PrintError =3D> 1,
);


eval {
     $schema MyDB->connect($dbi_dsn, $user, $pass, \%dbi_params);
};
croak "Cannot connect to database: $@"
     if ($@);



And here's the output that this simple script gives me:


Cannot connect to database: Modification of a read-only value attempted =

at /usr/lib/perl5/site_perl/5.8.8/DBIx/Class/Storage/DBI.pm line 483



So I looked there and I found this:


  480   my $last_info =3D $dbi_info->[-1];
  481   if(ref $last_info eq 'HASH') {
  482     for my $storage_opt (qw/on_connect_do disable_sth_caching =

unsafe/) {
  483       if(my $value =3D delete $last_info->{$storage_opt}) {
  484         $self->$storage_opt($value);
  485       }
  486     }
  487     for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
  488       if(my $opt_val =3D delete $last_info->{$sql_maker_opt}) {
  489         $self->_sql_maker_opts->{$sql_maker_opt} =3D $opt_val;
  490       }
  491     }
  492
  493     # Get rid of any trailing empty hashref
  494     pop(@$dbi_info) if !keys %$last_info;
  495   }
  496   $self->_dbi_connect_info($dbi_info);


My suggestion is to create a copy of the $last_info hash and use that =

instead of the original argument.

Patch attached.

-- =

Marcello Romani
Responsabile IT
Ottotecnica s.r.l.
http://www.ottotecnica.com
-------------- next part --------------
--- /usr/lib/perl5/site_perl/5.8.8/DBIx/Class/Storage/DBI.pm.original   200=
7-08-06 17:42:31.000000000 +0200
+++ /usr/lib/perl5/site_perl/5.8.8/DBIx/Class/Storage/DBI.pm    2007-08-06 =
17:44:20.000000000 +0200
@@ -479,19 +479,20 @@

   my $last_info =3D $dbi_info->[-1];
   if(ref $last_info eq 'HASH') {
+    my %last_info_copy =3D %{ $last_info };
     for my $storage_opt (qw/on_connect_do disable_sth_caching unsafe/) {
-      if(my $value =3D delete $last_info->{$storage_opt}) {
+      if(my $value =3D delete $last_info_copy{$storage_opt}) {
         $self->$storage_opt($value);
       }
     }
     for my $sql_maker_opt (qw/limit_dialect quote_char name_sep/) {
-      if(my $opt_val =3D delete $last_info->{$sql_maker_opt}) {
+      if(my $opt_val =3D delete $last_info_copy{$sql_maker_opt}) {
         $self->_sql_maker_opts->{$sql_maker_opt} =3D $opt_val;
       }
     }

     # Get rid of any trailing empty hashref
-    pop(@$dbi_info) if !keys %$last_info;
+    pop(@$dbi_info) if !keys %last_info_copy;
   }
   $self->_dbi_connect_info($dbi_info);


More information about the DBIx-Class mailing list