[CDBI] Set utf8 character set on class connection?

Birgit Kellner birgit.kellner at univie.ac.at
Mon Nov 21 17:52:35 GMT 2005


Hi Brian,

Brian Phillips wrote:

> You can avoid the "set names..." trick by indicating in your my.cnf 
> file that you want the default character set for the connection to be 
> utf8.  For instance, in a my.cnf file somewhere on your system 
> (/var/lib/mysql/my.cnf on mine), place the following:
>
> [perl]
> default-character-set=utf8
>
> And then when you specify your connection in your Class::DBI module, 
> you'll need to do something like the following:
>
> __PACKAGE__->connection(
>    'dbi:mysql:localhost;mysql_read_default_group=perl;mysql_read_default_file=/var/lib/mysql/my.cnf'
> );
>  
> This keeps the MySQL server from translating data in the DB from utf8 
> (which is how it's stored) into latin1 (or whatever the default 
> character set of the client is).  Executing a 'set names utf8' 
> accomplishes the same thing but this method avoids having to run that 
> query everytime you connect.
>  


I've done that, but in itself it doesn't suffice to set the character 
set straight.
I've tried the same code without Class::DBI in a script that runs just 
plain DBI:

$dbh = 
db_connect("localhost;mysql_read_default_group=perl;mysql_read_default_file=/etc/my.cnf", 
"$db", "$usr", "$pwd");
This *doesn't* replace "set names utf8" - if I leave out "set names 
utf8", utf8 just doesn't get displayed correctly.

Have I used a wrong syntax?

With Class::DBI, I tried this:
ILKB::DBI->connection("dbi:mysql:ilkb_test;mysql_read_default_group=mysql;mysql_read_default_file=/etc/my.cnf",'$usr','$pwd');


> Even after that, you still need to tell Perl that the data is utf8 
> encoded using Encode (this is messy code, someone can probably point 
> out a better way of doing this):
>
> __PACKAGE__->add_trigger(
>     select => sub {
>         my $obj = shift;
>         foreach (qw( my_text_column1 my_text_column2 )) {
>             if ( $obj->_attribute_exists($_) ) {
>                 Encode::_utf8_on( $obj->{$_} );
>             }
>         }
>     }
> );
>
>
I presume it wouldn't just have to be called on select, but also on 
insert and update. Would I have to list all text columns separately or 
could I just set the trigger on all columns?
Also: would this behaviour be inherited? If I have to manually specify 
the columns, I guess not.

I'm asking because I have probably about 30 or so classes, and would 
prefer some centralized code.

Thanks for the advice,

best regards,

Birgit








More information about the ClassDBI mailing list