2007年4月アーカイブ

まだExperimentalだけどdeploy()とcreate_ddl_dir()は便利に使わせてもらっています。
MySQL5は問題ないけどMySQL4では各CREATE Tableに「DEFAULT CHARACTER SET =utf8;」追加してい。

CREATE TABLE `are` ( ) Type=InnoDB DEFAULT CHARACTER SET =utf8;
のように。
are bokutin % diff /usr/lib/perl5/site_perl/5.8.5/SQL/Translator/Parser/DBIx/Class.pm lib/SQL/Translator/Parser/DBIx/Class.pm 60a61,63 > > $table->extra('mysql_charset', '=utf8'); >

ちょっと探してしまったので、ここにメモります。

use strict;
use warnings;

use utf8;

use Encode;
use Win32::OLE;
use DBI;

# BEGIN variable
my $FN = 'sample.mdb';
# END variable

if (-e $FN) {
    unlink -e $FN or die;
}

my $dsn = "Provider=Microsoft.Jet.OLEDB.4.0;";
$dsn   .= "Data Source=$FN;";

my $cat = Win32::OLE->new("ADOX.Catalog");
$cat->Create($dsn) or die;
$cat->Close();

my $dbh = DBI->connect("dbi:ADO:$dsn") or die $DBI::errstr;
$dbh->do(
    "Create Table song(id int, artist varchar(255), title varchar(255))"
) or die $DBI::errstr;
my $sth = $dbh->prepare("INSERT INTO song(id,artist,title) VALUES (?,?,?)");
$sth->execute(1, "The Stalin", encode('cp932', 'ロマンチスト'));
$sth->execute(2, "INU", encode('cp932', 'メシ喰うな'));

$dbh->disconnect;

おしまい
DBIx::Class::Loader::ADOなんてのもありますな(・∀・)

Railsムービーで見かけたCocoaMySQLだけど、Navicatの方が好みで、今までずっとこっち使ってた。
Execute Queryっての見っけた。Java製。とりあえずMacでローカルのMySQLに接続でけた。ちょっと使ってみる。
すげー高機能っぽ。

マイコミさんの記事

ピクチャ 5

DBIC Tips Vol.2

| コメント(0)

prefetch & +asした場合は+asのターゲットを定められるよ

グループ has_many ユーザーというのを例にします。
パスワードの長さを調べようと・・・

$schema->resultset('Group')->search(
    {
    },
    {
        prefetch => 'users',
        '+as'     => 'password_length',
        '+select' => { length => 'users.password' },
    }
);

とした場合、group->users->first->get_column('password_length') は例外になってしまいます。 正解は

$schema->resultset('Group')->search(
    {
    },
    {
        prefetch => 'users',
        '+as'     => 'users.password_length',
        '+select' => { length => 'users.password' },
    }
);

+asはDBICが解釈しやすいように、接頭辞を付けてあげられる。

prefetch(multi)した際は、order_byに気をつけること。


$schema->resultset('Area')->search(
    {
    },
    {
        prefetch => 'prefectures',
    }
);

この場合DBICはイテレータ、AreaとArea->Prefecturesに付随するデータをSQL一文で取得するわけです。
prefecturesはareaにとってhas_many(multi)です。
SQLはこんなかんじ。

SELECT me.id, me.name, prefectures.id, prefectures.hira_name,
prefectures.name,
prefectures.ascii_name, prefectures.abbr_name, prefectures.area_id,
prefectures.position FROM area me LEFT JOIN prefecture prefectures
ON ( prefectures.area_id = me.id ) ORDER BY prefectures.area_id

order_byが自動的に付加されています。DBICがArea->Prefecturesのイテレータを構築しやすいようにだと思われます。
結果

ピクチャ 3-3

ハマるポイントはorder_byを指定した場合。上のを基にしてみます。


$schema->resultset('Area')->search(
    {
    },
    {
        prefetch => 'prefectures',
        order_by => 'prefectures.id',
    }
);

これでAreaイテレータを $area_rs->next とやっていくと
問題がおこります。(素直というべきか・・・)
SQLはこんなかんじ。

SELECT me.id, me.name, prefectures.id, prefectures.hira_name,
prefectures.name,
prefectures.ascii_name, prefectures.abbr_name, prefectures.area_id,
prefectures.position FROM area me LEFT JOIN prefecture prefectures
ON ( prefectures.area_id = me.id )
ORDER BY prefectures.id, prefectures.area_id

ORDER BY prefectures.id, prefectures.area_id ではDBICがイテレータを構築するに期待していない並びで結果が返ってしまいます。

ピクチャ 2-3
me.id が 3 -> 2 -> 3 となっている。

つられて $area_rs->next が 1 -> 2 -> 3 -> 2 -> 3 昇ったり降りたりするんです。

正解は


$schema->resultset('Area')->search(
    {
    },
    {
        prefetch => 'prefectures',
        order_by => ['me.id'. 'prefectures.id'],
    }
);

prefetch(multi) & order_byした際は、DBICがイテレータを構築しやすいように、配慮してあげること。

同じ問題に遭遇した方がいらっしゃいました。

HTTP::Bodyのバージョン上げたら直りました。

0.9   2007-03-27 14:00:00
        - Fixed bug where empty fields in multipart/form-data were ignored.
          (Ton Voon)
        - Fixed bug where an uploaded file with the name "0" was ignored.
          (Ton Voon)
        - Small performance improvements to urlencoded parser.