主に自分用メモ。例えば以下のようなコードからDBIハンドルを取得してるとする
なので、一回SET NAMES 'utf8'を発行したら、それを覚えていたい。だがDBIハンドルはハッシュのように扱えるものの、適当なキーを入れようとすると怒られる:
ということで万事解決。
本件はちらっとつぶやいたら生き字引の@tokuhiromが覚えてたので助かりました。
use strict;で、まぁSET NAMES utf8を自動的に発行したいなーと思ったので、get_dbhに手を入れる
use DBI;
sub get_dbh {
DBI->connect_cached(....);
}
sub foo {
my $dbh = get_dbh();
$dbh->do(...);
}
sub bar {
my $dbh = get_dbh();
$dbh->do(...);
}
foo();
bar();
....
sub get_dbh {そうするとget_dbh()内で DBIハンドル自体はconnect_cached()でキャッシュされた同じハンドルが返ってくるのだが、毎回SET NAMES 'utf8'が発行される。これは無駄だし、例えば一つ手前のステートメントの状態を期待するコードを書くと破綻する:
my $dbh = DBI->connect_cached(...);
$dbh->do("SET NAMES 'utf8'");
return $dbh;
}
{
my $dbh = get_dbh();
$dbh->do("INSERT INTO ...");
}
{
my $dbh = get_dbh();
# get_dbh()にSET NAMES utf8がなければ、直前のステートメントはINSERT INTO
# get_dbh()にSET NAMES utf8があると、直前のステートメントは SET NAMES utf8
my $id = $dbh->{mysql_insertid}; # SET NAMES utf8の後なので、insertidは存在しない
}
なので、一回SET NAMES 'utf8'を発行したら、それを覚えていたい。だがDBIハンドルはハッシュのように扱えるものの、適当なキーを入れようとすると怒られる:
if (! $dbh->{MySuperSpecialFlag}) { # ERRRRRRORRRRRRところがprivate_で始まるキーなら使える!これで勝つる!
$dbh->{MySuperSpecialFlag} = 1; # ERRRRRRORRRRRR
$dbh->do("SET NAMES 'utf8'");
}
sub get_dbh {
my $dbh = DBI->connect_cached(...);
if (! $dbh->{private_my_super_special_flag}) {
$dbh->{private_my_super_special_flag} = 1;
$dbh->do("SET NAMES 'utf8'");
}
return $dbh;
}
ということで万事解決。
本件はちらっとつぶやいたら生き字引の@tokuhiromが覚えてたので助かりました。