2008-03-05 22:25:06

Catalyst::Plugin::Authentication 新版

[Catalyst]

知らなかった
ex) http://catalyst.g.hatena.ne.jp/lapis25/20070806
ex) http://search.cpan.org/~jayk/Catalyst-Plugin-Authentication/
試してみる
$ vim lib/MyApp.pm

use Catalyst qw/
       (略)
       Authentication
       Authentication::Store::DBIC
       Authentication::Credential::Password
       /;

use Catalyst qw/
        (略)
        Authentication
        /;

$ vim myapp.yml

authentication:
  dbic:
    user_class: MyAppDB::User
    user_field: email
    password_field: password

authentication:
  default_realm: members
  realms:
    members:
      credential:
        class: Password
        password_field: password
        password_type: clear
      store:
        class: DBIx::Class
        user_class: MyAppDB::User
        id_field: email

$ vim lib/MyApp/Controller/Auth.pm

if ($c->login($c->stash->{email}, $password)) {
    $c->res->redirect( $c->req->{uri} );
}

if ($c->authenticate({email => $c->stash->{email}, password => $password})) {
    $c->res->redirect( $c->req->{uri} );
}

嬉しいこと。
こういうテーブルの時

+------------------+--------------+------+-----+-------------------+----------------+
| Field            | Type         | Null | Key | Default           | Extra          |
+------------------+--------------+------+-----+-------------------+----------------+
| id               | int(11)      | NO   | PRI | NULL              | auto_increment |
| email            | varchar(255) | NO   |     |                   |                |
| password         | varchar(255) | NO   |     |                   |                |
+------------------+--------------+------+-----+-------------------+----------------+
email と password で認証すると、以前は Catalyst::Plugin::Authentication::User の為 $c->user->id に email の値が入ってしまっていて不便だった。

今はテーブルの id が入るようになった!

同一アプリケーションで認証を複数別々に使う場合
$ vim myapp.yml

authentication:
  default_realm: bluegroup
  realms:
    bluegroup:
      credential:
        class: Password
        password_field: password
        password_type: clear
      store:
        class: DBIx::Class
        user_class: MyAppDB::Blue
        id_field: email
    redgroup:
      credential:    #bluegroupとは異なるcredentialと内容が使える
        class: Password
        password_field: password
        password_type: clear
      store:    #bluegroupとは異なるstoreと内容が使える
        class: DBIx::Class
        user_class: MyAppDB::Red
        id_field: nickname

$ vim lib/MyApp/Controller/Auth.pm
#デフォルト(bluegroup)の場合は
if ($c->authenticate({email => $c->stash->{email}, password => $password})) {
    $c->res->redirect( $c->req->{uri} );
}
#デフォルトじゃない(redgroup)場合は
if ($c->authenticate({nickname => $c->stash->{nickname}, password => $password},'redgroup')) {
    $c->res->redirect( $c->req->{uri} );
}

if (!$c->user_exists or ( $c->user->get('hoge') ne $c->stash->{hoge}) ) {
    $c->detach('login');
}
のように $c->user_exists プラスアルファで認証確認

2008-03-05 22:21:07

取得してないフォームパラメータを追加する

[Catalyst]

ex) http://search.cpan.org/~mramberg/Catalyst-Runtime-5.7012/lib/Catalyst/Request.pm#$req->param
$c->request->parameters->{name} = 'hoge';
or
$c->req->params->{name} = 'hoge';
or
$c->req->param('name','hoge');

2008-03-05 22:19:57

Catalyst::Plugin::Unicode の中身

[Catalyst]

フォーム入力時、UTF8フラグをつける(utf8::decode)
HTML出力時、UTF8フラグを全て落とす(utf8::encode)

package Catalyst::Plugin::Unicode;
use strict;
our $VERSION = '0.8';
sub finalize {
    my $c = shift; 
    if ( $c->response->{body} && utf8::is_utf8($c->response->{body}) ){
        utf8::encode( $c->response->{body} );
    }
    return $c->NEXT::finalize;
}
sub prepare_parameters {
    my $c = shift;
    $c->NEXT::prepare_parameters;
    for my $value ( values %{ $c->request->{parameters} } ) {
        if ( ref $value && ref $value ne 'ARRAY' ) {
            next;
        }
        utf8::decode($_) for ( ref($value) ? @{$value} : $value );
    }
}
1;

2008-03-05 22:17:51

Perl の バイト列→Unicode 処理について

[Perl]

ニパターンある

※バイト列の文字コードはUTF8とする。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use Encode;
use Unicode::RecursiveDowngrade;

my $str = 'utf8';
#my $str = 'ユーティーエフ';

# Pattern A
utf8::decode($str); #これのみだと $str = 'utf8' は素通りされてフラグがたたない
utf8::upgrade($str); #これのみだとフラグはたつが $str = 'ユーティーエフ' は文字化けで戻せなくなる

# Pattern B
$str = decode_utf8($str); # Need use Encode;

if ( utf8::is_utf8($str) ) {
        print "On\n";
}
else {
        print "Off\n";
}
print Dumper($str);

my $rd = Unicode::RecursiveDowngrade->new;
my $strz = $rd->downgrade($str);

if ( utf8::is_utf8($strz) ) {
        print "On\n";
}
else {
        print "Off\n";
}
print Dumper($strz);

ex) http://subtech.g.hatena.ne.jp/miyagawa/20080218
ex) http://blog.livedoor.jp/dankogai/archives/51004472.html
ex) http://subtech.g.hatena.ne.jp/miyagawa/20060820/1156076116

ex2) http://d.hatena.ne.jp/dayflower/20080219/1203493616

2008-03-05 22:12:08

Perl5.10 で Catalyst

[Catalyst]

Fedora7(i386)環境

Catalyst::Plugin::FormValidator::Simple
絡みの
FormValidator::Simple::Plugin::Japanese
から
Unicode-RecursiveDowngrade-0.03
を入れるときにエラーとなる

パッチあてる
--- Unicode-RecursiveDowngrade-0.03/lib/Unicode/RecursiveDowngrade.pm
+++ Unicode-RecursiveDowngrade-new/lib/Unicode/RecursiveDowngrade.pm
@@ -2,6 +2,7 @@
 
 use strict;
 use Carp;
+use bytes;
 use vars qw($DowngradeFunc $VERSION);
 $VERSION = 0.03;

2008-03-07 0:16追記
作者の方にお送りした patch を適用していただいた → Unicode-RecursiveDowngrade-0.04
よって今後、上記記述は無視


FormValidator-Simple-Plugin-Number-Phone-JP
は結構前(Number-Phone-JP-0.10 ~)からエラーとなる
テストパターンが古いためなので気にせずforce install
or
パッチあてる
--- FormValidator-Simple-Plugin-Number-Phone-JP-0.02/t/01_number_phone_jp.t
+++ FormValidator-Simple-Plugin-Number-Phone-JP-new/t/01_number_phone_jp.t
@@ -28,29 +28,29 @@
 }
 
 __DATA__
-011 1234567
-0164 123456
-01646 12345
-01652 12345
-016528 1234
-01653 12345
-016532 1234
-016534 1234
-03 12345678
-04 12345678
-06 12345678
-0460 12345
-0578 12345
-011 123456
-0164 12345
-01646 1234
-01652 1234
-016528 123
-01653 1234
-016532 123
-016534 123
-03 1234567
-04 1234567
-06 1234567
-0460 123456
-0578 123456
+001 12345678
+009120 12345678
+0120 000123
+011 2001234
+050 10001234
+080 10012345
+020 46012345
+070 50112345
+0990 500123
+0570 000123
+060 33001234
+0255 731234
+096 3471234
+00299 12345678
+009197 12345678
+0800 9231234
+0997 711234
+050 99991234
+080 99912345
+020 49812345
+070 68912345
+0570 998123
+060 49991234
+06 43391234
+0778 891234
+0997 381234

2008-03-10 0:00追記
作者の方にお送りした patch を適用していただいた → FormValidator-Simple-Plugin-Number-Phone-JP-0.03
よって今後、上記記述は無視

他は普通に入った。

2008-03-05 22:07:23

CatalystアプリケーションのUnicode化2

[Catalyst] [DBIx::Class] [MySQL]

・FillInForm安全対策

cpan[1]> install Catalyst::Plugin::FillInForm::ForceUTF8
ex) http://blog.hide-k.net/archives/2007/03/catalyst_2.php
※Catalyst::Plugin::FillInForm だと Catalyst::Plugin::Unicode の前にロードする必要があり、多分いつかハマるのでNG

・DBIx::Class で mysql 使う時

方法1 - DBD::mysql のオプションを使う
(http://search.cpan.org/~capttofu/DBD-mysql-4.006/lib/DBD/mysql.pm)
$ vim lib/MyApp/Model/MyAppDB.pm

package MyApp::Model::MyAppDB;
use strict;
use base 'Catalyst::Model::DBIC::Schema';
__PACKAGE__->config(
    schema_class => 'MyApp::Schema',
    connect_info => [
        'dbi:mysql:myappdb',
        'user',
        'password',
        {
            mysql_enable_utf8 => 1
        }
    ],
);
1;

方法2 - DBIx::Class::UTF8Columns を使う
(http://search.cpan.org/~jrobinson/DBIx-Class-0.08009/lib/DBIx/Class/UTF8Columns.pm)
$ vim lib/MyApp/Schema/Hoge.pm

package MyApp::Schema::Hoge;
use strict;
use warnings;
use base 'DBIx::Class';
__PACKAGE__->load_components(qw/UTF8Columns Core/);
__PACKAGE__->table("tag");
__PACKAGE__->add_columns(
  "shop",
  { data_type => "INT", default_value => "", is_nullable => 0, size => 11 },
  "id",
  { data_type => "SMALLINT", default_value => "", is_nullable => 0, size => 5 },
  "name",
  { data_type => "VARCHAR", default_value => "", is_nullable => 0, size => 255 },
);
__PACKAGE__->set_primary_key("shop", "id");
__PACKAGE__->utf8_columns(qw/name/);    #static で作った場合、add_columns の後に記述すること
1;

どちらでもフラグ付きで放り込んで、フラグ付きで取り出せる。
もちろんmysqlでも普通に見える。
備考:方法1のほうが便利・・・しかし
This option is experimental and may change in future versions.
ex) http://search.cpan.org/~capttofu/DBD-mysql-4.006/lib/DBD/mysql.pm

さらに参考
http://search.cpan.org/~cfranks/HTML-FormFu-0.02004/lib/HTML/FormFu/Manual/Unicode.pod

2008-03-05 22:05:01

DBIC 本番稼動後の カラムの追加

[DBIx::Class]

1.DBにSQLでカラム追加
ALTER TABLE table_name ADD column_name varchar(255);

2.スキーマにカラム追加(staticで作った場合)
  "column_name",
  {
    data_type => "VARCHAR",
    default_value => undef,
    is_nullable => 1,
    size => 255,
  },

3.アプリケーションの記述変更
mod_perl 等、必要なら apache の restart

2008-03-05 22:00:31

DBICでMySQLのtimestamp

[Catalyst] [DBIx::Class] [MySQL]

TIMESTAMP型のカラムは CatalystのHelperでスキーマを作ると

  "time",
  {
    data_type => "TIMESTAMP",
    default_value => "CURRENT_TIMESTAMP",
    is_nullable => 0,
    size => 14,
  },

こんなのができる。
insert や他のカラムをupdateすると現在時刻が入る。

意識的に入れるときは undef を入れる。
$c->model('MyAppDB::Hoge')->update_or_create({
    time => undef,
});

Fedora-7,MySQL-5.0.41,DBIC-0.08009,Perl-5.10.0

2008-03-05 21:54:26

負数の剰余

[Perl]

配列の最初の添え字の一つ前は最後の添え字にしてループしたかった。

例:
配列の最後の添え字が 5、今の添え字が x、前に戻る数を y、戻った時の添え字が z
1.x=1,y=2,z=4
2.x=1,y=3,z=3
3.x=1,y=5,z=1
4.x=1,y=8,z=3
5.x=1,y=9,z=2
6.x=1,y=10,z=1
7.x=0,y=1,z=4
8.x=4,y=5,z=4
9.x=3,y=8,z=0

z = (x - y) % 5

ex) http://oshiete1.goo.ne.jp/kotaeru.php3?q=1057715
ex) http://www.hokuriku.ne.jp/fukiyo/math-qa/amari.htm
ex) http://d.hatena.ne.jp/kazusato77/20080121/1200871085
google 電卓は Perl/Pythonと同じ。

JavaScriptはまた違うし、これはハマる。

2008-03-05 21:48:44

Catalystテストサーバでの DBICのSQLログ表示

[Catalyst] [DBIx::Class]

一時的には
環境変数をenvセットでテストサーバ駆動
$ env DBIC_TRACE=1 ./script/myapp_server.pl -r

いつも出す時は
MyApp.pm に
$ENV{'DBIC_TRACE'} = 1;
と書き込んでおく。

Apache等の本番環境に移した後は気になるところだけ
$c->model('DBIC')->storage->debug(1);
$c->model('DBIC')->storage->debugfh(IO::File->new('/log/DBIC.log', 'w'));

通常のDBIC(non Catalyst)では
my $schema = DB::Hoge->connect('dbi:mysql:dbname;localhost','ID','PW');

$schema->storage->debug(1);
$schema->storage->debugfh(IO::File->new('/log/DBIC.log', 'w'));

2008-01-26 22:04:40

fsckでサルベージ

[Linux]

突然の電源断で CentOS4.4 (x86_64) が正常にシャットダウンできなくなった。
read only うんぬんで各種デーモンの pid が消えない等のエラーが出力される。

異常終了後、サーバを起動させるとオートの fsck が試みられたが失敗。
root のパスワードを入れて手動で対処するよう OS に促された。
そこで root パスワード入力後 fsck 実行。オプション無し。
Enter でデフォルトの Yes 回答を繰り返す。

再起動後、
/lost+found
にデータの残骸がある。

[root@server lost+found]# ls -alth
total 52K
drwxr-xr-x  24 root     root     4.0K Jan  9 11:44 ..
-rw-------   1 postgres postgres    6 Jan  7 09:57 #46531638
-rw-r--r--   1 user    user     15K Jan  4 09:36 #7161585
-rw-------   1 postgres postgres  505 Jan  4 09:00 #46531560
-rw-r--r--   1 user    user     407 Jan  4 07:00 #10165485
drwx------   2 root     root      16K Feb 10  2006 .
[root@server lost+found]# file *
#10165485: Non-ISO extended-ASCII text
#46531560: data
#46531638: data
#7161585:  Non-ISO extended-ASCII text, with very long lines, with LF, NEL line terminators

バイナリはあきらめて、vi で中身がわかるものだけサルベージ。
その後、すぐバックアップ。

2008-01-26 21:46:58

PostgreSQLが起動しない

[PostgreSQL]

突然の電源断でPostgreSQL(CentOS4.4 x86_64)が起動しなくなった。

[root@server ~]# su - postgres
-bash-3.00$ postmaster
LOG:  database system was interrupted while in recovery at 2008-01-07 10:43:32 JST
HINT:  This probably means that some data is corrupted and you will have to use the last backup for recovery.
LOG:  checkpoint record is at 9C/40879F60
LOG:  redo record is at 9C/40879F60; undo record is at 0/0; shutdown TRUE
LOG:  next transaction ID: 794151748; next OID: 260490482
LOG:  database system was not properly shut down; automatic recovery in progress
LOG:  redo starts at 9C/40879FA8
PANIC:  could not access status of transaction 794151753
DETAIL:  could not read from file "/var/lib/pgsql/data/pg_clog/02F5" at offset 90112: Success
LOG:  startup process (PID 4893) was terminated by signal 6
LOG:  aborting startup due to startup process failure

/var/lib/pgsql/data/pg_clog/02F5 が壊れてるようだ。
http://ton.xii.jp/b/2006/09/06/145749-000263.html
を真似てみる。

[root@server ~]# cd /var/lib/pgsql/data/pg_clog/
[root@server pg_clog]# ls -alth | less
total 193M
drwx------  6 postgres postgres 4.0K Jan  7 11:09 ..
-rw-------  1 postgres postgres  72K Jan  4 09:36 02F5
drwx------  2 postgres postgres  20K Jan  4 09:11 .
-rw-------  1 postgres postgres 256K Jan  4 09:11 02F4
[root@server pg_clog]# rm -f 02F5
[root@server pg_clog]# dd if=/dev/zero bs=8k count=1 >>02F5
[root@server pg_clog]# chmod 600 02F5
[root@server pg_clog]# chown postgres.postgres 02F5
[root@server pg_clog]# ls -alth | less
total 193M
drwx------  6 postgres postgres 4.0K Jan  7 11:15 ..
drwx------  2 postgres postgres  20K Jan  7 11:13 .
-rw-------  1 postgres postgres 8.0K Jan  7 11:13 02F5
-rw-------  1 postgres postgres 256K Jan  4 09:11 02F4
[root@server pg_clog]# /etc/init.d/postgresql start
Starting postgresql service:                               [FAILED]

起動失敗。
サイズを変えて他と同じになるようにする。

[root@server pg_clog]# dd if=/dev/zero bs=256k count=1 >02F5
1+0 records in
1+0 records out
[root@server pg_clog]# ls -alth | less
total 193M
-rw-------  1 postgres postgres 256K Jan  7 11:20 02F5
drwx------  6 postgres postgres 4.0K Jan  7 11:17 ..
drwx------  2 postgres postgres  20K Jan  7 11:13 .
-rw-------  1 postgres postgres 256K Jan  4 09:11 02F4
[root@server pg_clog]# /etc/init.d/postgresql start
Starting postgresql service:                               [  OK  ]
[root@server pg_clog]# /etc/init.d/postgresql status
postmaster (pid 5458 5457 5455) is running...

なんとか動いた。
その後、すぐバックアップ。

2008-01-05 12:37:21

vim オートインデントをオフにする

[Linux]

Fedora7での話。
いつからか、改行時に自動でインデントされるようになった気がする。・・・とても不便。

/etc/vimrc で

filetype plugin on

となっているとプラグインが全て使われるようだ。
そのためオートインデントも有効になってしまう。

filetype plugin on
filetype indent off

上記のようにオートインデントのみ打ち消せばOK

2008-01-05 12:29:29

Catalyst で FastCGI

[Catalyst]

Fedora7で。

yum install mod_fcgid

vim /etc/httpd/conf/httpd.conf

Listen 8086
NameVirtualHost 192.168.0.1:8086
<VirtualHost 192.168.0.1:8086>
    Alias /static /home/user/www/MyApp/root/static
    <Location /static>
        SetHandler default-handler
    </Location>
    Alias / /home/user/www/MyApp/script/myapp_fastcgi.pl
    <Location />
        Options All
        Order allow,deny
        Allow from all
        AddHandler fcgid-script .pl
    </Location>
    ErrorLog logs/8086-error_log
    CustomLog logs/8086-access_log combined
</VirtualHost>

2008-01-05 12:26:31

CatalystアプリケーションでのUnicode化

[Catalyst]

cpan[1]> install Catalyst::Pligin::Unicode
cpan[2]> install Catalyst::View::TT::ForceUTF8

vim lib/MyApp.pm

use Catalyst qw/
 Unicode ←追加
/;

vim lib/MyApp/View/TT.pm

use base 'Catalyst::View::TT';
↓変更
use base 'Catalyst::View::TT::ForceUTF8';

__PACKAGE__->config({
 DEFAULT_ENCODING => 'utf-8', ←追加
});

内部はフラグ付、外部出力時はフラグ無しのUTF8となる。

2008-01-05 11:36:34

prefetch と join の使い分け

[DBIx::Class]

とてもわかりやすい
http://perldoc.jp/docs/modules/DBIx-Class-0.07006/lib/DBIx/Class/Manual/Cookbook.pod
リレーション先の値を、後々出力で使う場合は prefetch 、検索・ソートにしか使用しない場合は join 。

2008-01-05 11:35:22

DBICでLEFT JOIN

[DBIx::Class]

from アトリビュートを使用する。
http://search.cpan.org/~ash/DBIx-Class-0.08008/lib/DBIx/Class/ResultSet.pm#from

belongs_to を使用してリレーションしていると
普通の join (INNER JOIN) となる。
場合によって、left join を使用しなければならない時、
以下のように from アトリビュートを使用する。

my $it = $schema->resultset('Goods')->search(
 {
  'stock.quantity' => {is => undef},
 },
 {
  columns => [qw/goods_id/],
  from => [
   { me => 'goods' }, #ここで goods テーブルを指定するのがポイント
   [
    { stock => 'stock', -join_type => 'left' },
    { 'stock.goods' => 'me.goods_id' }
   ],
  ],
 }
);

これで
SELECT me.goods_id FROM goods me LEFT JOIN stock stock ON ( stock.goods = me.goods_id ) WHERE ( stock.quantity IS NULL );
となる。

どんなSQLが発行されているかは DBIC_TRACE をオンにすると見ることが出来る。
$ENV{DBIC_TRACE} = 1;
ex) http://www.rwds.net/wiki?page=DBIx%3A%3AClass%A4%CE%B3%D0%BD%F1

2007-09-06 20:33:42

mod_cband

[Linux]

SRPM取得
$ wget http://ftp.riken.jp/pub/Linux/fedora/releases/test/7.90/Fedora/source/SRPMS/mod_cband-0.9.7.5-1.fc7.src.rpm

$ rpm -ivh mod_cband-0.9.7.5-1.fc7.src.rpm

そのままでは入らない。
apxsの場所を指定するようspec書き換え
$ vim /home/user/rpmbuild/SPECS/mod_cband.spec

%build
%configure \
    --with-apxs=/usr/sbin/apxs ←追加
make %{?_smp_mflags}

ビルド
$ rpmbuild -ba /home/user/rpmbuild/SPECS/mod_cband.spec

インストール
# cd /home/user/rpmbuild/RPMS/i386
# rpm -ivh mod_cband-0.9.7.5-1.fc7.i386.rpm mod_cband-debuginfo-0.9.7.5-1.fc7.i386.rpm

設定
#vim /etc/httpd/conf/httpd.conf

CBandRemoteSpeed 10240kb/s 40 5

とりあえず CBandRemoteSpeed のみ設定

#設定2
#vim /etc/httpd/conf.d/mod_cband.conf

<Location /cband-status>
SetHandler cband-status
Order allow,deny
Allow from 192.168.0.2 ←ブラウザ確認用IPアドレス
</Location>


ブラウザで確認
http://192.168.0.1/cband-status

ex)
http://www.howtoforge.com/mod_cband_apache2_bandwidth_quota_throttling

2007-09-06 20:31:54

fedora7のcron問題

[Linux]

/etc/cron.daily/
の中身の実行結果メールが届かなくなった。

通常のcrontab登録したものの結果は届いている。

ググると
crontabs.noarch 1.10-15.fc7
の問題だった。
https://bugzilla.redhat.com/show_bug.cgi?id=269961

解決
crontabs.noarch 1.10-16.fc7

2007-09-06 20:30:22

mod_expires

[Apache]

キャッシュコントロール
コンテンツ更新を確認させないので、負荷軽減
# vi /etc/httpd/conf/httpd.conf

ExpiresActive On
#ExpiresDefault "access plus 1 year"
ExpiresByType image/gif "access plus 5 minutes"
ExpiresByType image/jpeg "access plus 5 minutes"
ExpiresByType application/x-shockwave-flash "access plus 30 minutes"
#ExpiresByType text/html "access plus 15 minutes"
ExpiresByType application/rss+xml "access plus 30 minutes"
ExpiresByType application/x-javascript "access plus 30 minutes"
ExpiresByType text/css "access plus 30 minutes"

2007-09-06 00:54:24

mysqlの便利だけど忘れるコマンド

[MySQL]

チェック
check table country,format,stock;

チェック2
check table goods extended;

リペア
repair table country,format,stock;

最適化
optimize table country,format,stock;

インデックスのみ最適化
analyze table country,format,stock;

置換
update goods set review=REPLACE(review,'&lt;','<');
update goods set format=REPLACE(format,'&quot;','"');
update goods set title=REPLACE(title,'&amp;','&');

ファイル書き出し(エクスポート)
select * into outfile '/home/user/country.sql' from country;

インデックス確認
show index from goods;

インデックス作成
create index open_date_index on goods (open_date);
create index open_close_index on goods (open_date,close_date);

インデックス削除
drop index open_date_index on goods;

スレーブ確認
show slave status \G;

インデックス動作確認
explain SELECT me.goods_id, me.title FROM goods me ORDER BY format \G;

テキストデータインポート(IGNORE で重複ユニークキースキップ)
LOAD DATA INFILE "/tmp/hoge.tab" IGNORE INTO TABLE hoge;

テーブル内容高速削除
TRUNCATE TABLE goods;

遅いログの記録設定
vim /etc/my.cnf
set-variable=log-slow-queries=/var/log/slowsql.log
set-variable=long_query_time=1 ←1秒以上かかったコマンドの記録
set-variable=log-queries-not-using-indexes ←インデックスを使用しないコマンドの記録

スレーブ開始
ex)http://www.irori.org/doc/mysql-rep.html
mysql> CHANGE MASTER TO
    -> MASTER_HOST = 'mymaster',
    -> MASTER_USER = 'repl',
    -> MASTER_PASSWORD = 'qa55wd',
    -> MASTER_LOG_FILE = 'mymaster-bin.001',
    -> MASTER_LOG_POS = 359;
mysql> START SLAVE;

スレイブストップ
STOP SLAVE;

カラムを最後に追加する
ALTER TABLE テーブル名 ADD 追加するカラム名 型;

JOIN 使いつつ ORDER BY で別テーブルの複数キーを指定すると非常に遅い。
非正規化するのが吉。

文字列連結
SELECT CONCAT(name_en, ' ', name_jp) FROM goods WHERE id='X55';
ex)http://dev.mysql.com/doc/refman/5.1/ja/string-functions.html

サブクエリでアップデート+文字列連結
UPDATE goods_data SET search_name = (SELECT CONCAT(name_en, ' ', name_jp) FROM goods WHERE id=goods_data.goods);

使えるテーブルタイプ一覧表示
SHOW TABLE TYPES;

テーブルステータス表示
SHOW TABLE STATUS;

2007-09-06 00:34:18

Template::Filters2.86のuri filterの問題

[Template-Toolkit]

TT2.15で問題なかったアプリケーションが2.19で不具合が出る。
調査するとURLエンコードがおかしなことになっていた。
Template::Filters が問題だった。
TTのMLに送った。

diff -urN Template-Toolkit-2.19/lib/Template/Filters.pm Template-Toolkit-2.19.new/lib/Template/Filters.pm
--- Template-Toolkit-2.19/lib/Template/Filters.pm    2007-04-28 02:56:05.000000000 +0900
+++ Template-Toolkit-2.19.new/lib/Template/Filters.pm    2007-09-04 09:55:09.000000000 +0900
@@ -270,7 +270,7 @@
         map { ( chr($_), sprintf("%%%02X", $_) ) } (0..255),
     };
 
-    if ($] >= 5.008) {
+    if ($] >= 5.008 and utf8::is_utf8($text)) {
         utf8::encode($text);
     }
    
@@ -295,7 +295,7 @@
         map { ( chr($_), sprintf("%%%02X", $_) ) } (0..255),
     };
 
-    if ($] >= 5.008) {
+    if ($] >= 5.008 and utf8::is_utf8($text)) {
         utf8::encode($text);
     }

2007-09-06 00:23:53

mod_rewrite

[Apache]

/hogehoge/detail.php?id=XZ666

/hogehoge/st/detail/XZ666

RewriteCond %{REQUEST_URI} ^/[a-z]+/detail\.php$
RewriteCond %{QUERY_STRING} ^id=([A-Za-z0-9_\-]+)$
RewriteRule ^/([a-z]+)/detail\.php /$1/st/detail/%1? [R,L]

ex)
http://www.nanbu.com/blog/blog1/detail-201.html

2007-09-06 00:13:50

SCPコマンド

[Linux]

すぐ忘れる。

get
scp user@192.168.0.1:/home/usr/Hoge.tar.gz .

put
scp ./Hoge.tar.gz user@192.168.0.2:/home/user/Hoge.tar.gz

2007-07-25 23:57:20

MeCab-Senna-TritonnのRPMインストールとCatalystでのSearch

[Catalyst] [DBIx::Class] [MySQL]

※Fedora7を使用

[mecab導入]
楽だ。
yum -y mecab mecab-devel mecab-ipadic perl-mecab


[senna導入]
cd /home/hoge/rpmbuild/SOURCES
wget http://iij.dl.sourceforge.jp/senna/25607/senna-1.0.7.tar.gz
tar xzvf senna-1.0.7.tar.gz
SPEC発見。
cp senna-1.0.7/senna.spec /home/hoge/rpmbuild/SPECS/.
cd ../
rpmbuild -bb SPECS/senna.spec

あら、エラーが出た。
error: File /usr/src/redhat/SOURCES/libsenna-1.0.7.tar.gz: No such file or directory

SPEC修正。
vi SPECS/senna.spec

@@ -2,7 +2,7 @@
 %define release 1

 Summary: An Embeddable Fulltext Search Engine
-Name: libsenna
+Name: senna
 Version: %{version}
 Release: %{release}
 License: LGPL

再度ビルド。
rpmbuild -bb SPECS/senna.spec

以下のメッセージが出てRPMができた。
Wrote: /home/hoge/rpmbuild/RPMS/i386/senna-1.0.7-1.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/senna-devel-1.0.7-1.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/senna-debuginfo-1.0.7-1.i386.rpm

インストール
cd RPMS/i386/
rpm -ivh senna-1.0.7-1.i386.rpm senna-debuginfo-1.0.7-1.i386.rpm senna-devel-1.0.7-1.i386.rpm


[Tritonn + MySQL導入]
SennaのMySQLバインディングパッチが Tritonn という名の別プロジェクトになったらしい。
ex) http://qwik.jp/tritonn/about.html

cd SOURCES/
wget http://iij.dl.sourceforge.jp/tritonn/26391/mysql-5.0.41-tritonn-1.0.3.tar.gz
tar xzvf mysql-5.0.41-tritonn-1.0.3.tar.gz
現在使用中のディストリ版MySQLを上書きして使いたいので、RPM化する際に mysql-5.0.41 になってもらうことにする。
mv mysql-5.0.41-tritonn-1.0.3 mysql-5.0.41

Fedoraのtestにmysql-5.0.45-1があがっていたのでSRPMをもらう。
cd ../SRPMS/
wget ftp://ftp.riken.jp/Linux/fedora/updates/testing/7/SRPMS/mysql-5.0.45-1.fc7.src.rpm
rpm -ivh mysql-5.0.45-1.fc7.src.rpm
SPECを流用。
cd ../SPECS/
cp mysql.spec mysql-tritonn.spec
vi mysql-tritonn.spec

以下のように変更。
make testは通らないのでコメントアウトした(普通に./configureしても make test はエラーになったのであきらめた)。
--- mysql.spec  2007-07-23 07:16:27.000000000 +0900
+++ mysql-tritonn.spec  2007-07-25 10:31:57.000000000 +0900
@@ -1,15 +1,15 @@
 Name: mysql
-Version: 5.0.45
+Version: 5.0.41
 Release: 1%{?dist}
-Summary: MySQL client programs and shared libraries
+Summary: MySQL client programs and shared libraries and tritonn
 License: GPL
 Group: Applications/Databases
 URL: http://www.mysql.com

 # Regression tests take a long time, you can skip 'em with this
 %{!?runselftest:%define runselftest 1}

-Source0: http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-%{version}.tar.gz
+Source0: mysql-5.0.41.tar.gz
 Source1: mysql.init
 Source3: my.cnf
 Source4: scriptstub.c
@@ -153,6 +153,8 @@
 export CFLAGS CXXFLAGS

 %configure \
+       --with-senna=/usr \
+       --with-mecab=/usr \
        --with-readline \
        --with-openssl \
        --without-debug \
@@ -189,7 +191,7 @@
   esac
   export MTR_BUILD_THREAD

-  make test
+#  make test
 %endif

 %install


必要なファイルをコピーする(このままではman 関連が無くてエラーになる - 2007.7.26 0:16追記 mysql-5.0.41-tritonn-1.0.3.tar.gz のソース修正されてman入ったかも~未確認)。
cd ../SOURCES/
tar xzvf mysql-5.0.45.tar.gz
cp mysql-5.0.45/man/* mysql-5.0.41/man/.

mysql-5.041(Tritonn内蔵版)のtarボール作成する。
tar czvf mysql-5.0.41.tar.gz mysql-5.0.41

Build時必要なものをインストール。
yum install gperf readline-devel ncurses-devel

ビルド開始。
cd ../SPECS/
rpmbuild -ba mysql-tritonn.spec

できた。
Wrote: /home/hoge/rpmbuild/SRPMS/mysql-5.0.41-1.fc7.src.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-5.0.41-1.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-libs-5.0.41-1.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-server-5.0.41-1.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-devel-5.0.41-1.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-bench-5.0.41-1.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-test-5.0.41-1.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/mysql-debuginfo-5.0.41-1.fc7.i386.rpm

ここに置いておきます。
mysql-5.0.41-1.fc7.src.rpm
mysql-5.0.41-1.fc7.i386.rpm
mysql-bench-5.0.41-1.fc7.i386.rpm
mysql-debuginfo-5.0.41-1.fc7.i386.rpm
mysql-devel-5.0.41-1.fc7.i386.rpm
mysql-libs-5.0.41-1.fc7.i386.rpm
mysql-server-5.0.41-1.fc7.i386.rpm
mysql-test-5.0.41-1.fc7.i386.rpm

インストールする。
cd /home/hoge/rpmbuild/RPMS/i386/
rpm -Uvh mysql-*

以下URL参照に動作確認した。
http://qwik.jp/senna/check_install.html

念のためyumで上書きされないように yum.conf を編集。
vi /etc/yum.conf
exclude=mysql*


[Catalystで使ってみる]
FULLTEXTインデックスを作る。
mysql> CREATE FULLTEXT INDEX review_index ON goods_att(review);

カラムが text 型の場合、最大値255以下で指定
mysql> drop index review_index on goods_att;
mysql> CREATE FULLTEXT INDEX review_index ON goods_att(review(255));

以下の2パターンが使えるようだ。
ex1) http://asakura.g.hatena.ne.jp/asakura-t/comment?date=20070405
use SQL::Abstract::Fulltext::MySQL;
my $rs = $c->model('GoodsDB::GoodsAtt')->search({
    -fulltext => {
        -match   => 'review',
        -against => $q,
        -boolean => 1,
    },
});

ex2) http://blog.hide-k.net/archives/2006/08/dbixclassfullte.php
my $rs = $c->model('GoodsDB::GoodsAtt')->search({
})->search_literal('match(review) against(?)', $q);

ex1を使うことにする。
SQL::Abstract::Fulltext::MySQLを use して使用することにする。

Bench Mark してみる(マシンスペック - Celeron2.5GHz, Memory 384MB)。
Records: 121141

まずは普通に mysql クライアントから。
mysql> select count(*) from goods_att where match(review) against('強力');
+----------+
| count(*) |
+----------+
|     1492 |
+----------+
1 row in set (0.01 sec)

like 検索と比べる。
mysql> select count(*) from goods_att where review LIKE "%強力%";;
+----------+
| count(*) |
+----------+
|     1492 |
+----------+
1 row in set (0.62 sec)

次にCatalystで比較。4ワードで試した。
senna
0.339656s
0.840683s
6.052170s
0.880074s

like
2.199280s
1.740971s
12.650366s
1.220464s

2007-07-25 22:28:14

latin1で保存されていたEUC-JPをダンプ

[MySQL]

mysqldump -uroot --default-character-set=latin1 DBNAME > DBNAME.sql

- nkfでeuc-jpからutf8変換

nkf -E -w DBNAME.sql > DBNAME_utf8.sql

- viで置換

:%s/NAMES latin1/NAMES binary/g
:%s/CHARSET=latin1;/CHARSET=binary;/g
他は必要な部分を。

- 再度euc-jpへ

nkf -e DBNAME_utf8.sql > DBNAME_euc.sql

- リストア

create database DBNAME CHARACTER SET binary;
mysql -uroot DBNAME < DBNAME_euc.sql

※binaryにしたりeuc-jpに再変換したりしたのはアプリケーション&MySQL設定の都合

2007-07-25 22:21:59

Fedora7 perlのリビルド

[Perl] [Linux]

FedoraのPerlは遅いようだ。
ex) http://buribullet.net/svntrac/buribullet/wiki?p=Fedora%E3%81%AEPerl%E3%81%8C%E9%81%85%E3%81%84%E4%BB%B6

以下を見てリビルドする。
ex)
http://d.hatena.ne.jp/tomisima/20070320/1174407728
http://d.hatena.ne.jp/dayflower/20070320/1174370267

rpmdevtools を初めて知った。

# yum -y install rpmdevtools
$ fedora-buildrpmtree

$ wget http://ftp.riken.jp/Linux/fedora/releases/7/Fedora/source/SRPMS/perl-5.8.8-18.fc7.src.rpm -O rpmbuild/SRPMS/perl-5.8.8-18.fc7.src.rpm

$ rpm -ivh rpmbuild/SRPMS/perl-5.8.8-18.fc7.src.rpm
$ vi rpmbuild/SPECS/perl.spec

@@ -89,8 +89,8 @@
 Patch25:        perl-5.8.8-U27116.patch
 Patch26:        perl-5.8.8-U27391.patch
 Patch27:        perl-5.8.8-U27426.patch
-Patch28:        perl-5.8.8-U27509.patch
-Patch29:        perl-5.8.8-U27512.patch
+#Patch28:        perl-5.8.8-U27509.patch
+#Patch29:        perl-5.8.8-U27512.patch
 Patch30:        perl-5.8.8-U27604.patch
 Patch31:        perl-5.8.8-U27605.patch
 Patch32:        perl-5.8.8-U27914.patch
@@ -316,8 +316,8 @@
 %patch25 -p1
 %patch26 -p1
 %patch27 -p1
-%patch28 -p1
-%patch29 -p1
+#%patch28 -p1
+#%patch29 -p1
 %patch30 -p1
 %patch31 -p1
 %patch32 -p1

リビルド (src.rpm も欲しい場合はオプション -ba)
$ rpmbuild -bb rpmbuild/SPECS/perl.spec

iconv のエラーが出た。
$ which iconv
/usr/local/bin/iconv
$ locate bin/iconv
/usr/bin/iconv
/usr/local/bin/iconv

以前 iconv をソースから入れてた。/usr/local/ 以下のiconv関連を削除した。

再度リビルド
$ rpmbuild -bb rpmbuild/SPECS/perl.spec

以下のメッセージが出た。
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-5.8.8-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-libs-5.8.8-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-devel-5.8.8-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-suidperl-5.8.8-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-CPAN-1.76_02-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-ExtUtils-Embed-1.26-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-ExtUtils-MakeMaker-6.30-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-Test-Harness-2.56-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-Test-Simple-0.62-18.fc7.i386.rpm
Wrote: /home/hoge/rpmbuild/RPMS/i386/perl-debuginfo-5.8.8-18.fc7.i386.rpm

旧rpm削除
# rpm -e --nodeps perl perl-libs perl-devel perl-suidperl perl-CPAN perl-ExtUtils-Embed perl-ExtUtils-MakeMaker perl-Test-Harness perl-Test-Simple perl-debuginfo
# rm -r /usr/lib/perl5/5.8.8
# rm -r /usr/lib/perl5/site-perl/5.8.8

新rpmインストール
# cd /home/hoge/rpmbuild/RPMS/i386
# rpm -Uvh perl-5.8.8-18.fc7.i386.rpm perl-libs-5.8.8-18.fc7.i386.rpm perl-devel-5.8.8-18.fc7.i386.rpm perl-suidperl-5.8.8-18.fc7.i386.rpm perl-CPAN-1.76_02-18.fc7.i386.rpm perl-ExtUtils-Embed-1.26-18.fc7.i386.rpm perl-ExtUtils-MakeMaker-6.30-18.fc7.i386.rpm perl-Test-Harness-2.56-18.fc7.i386.rpm perl-Test-Simple-0.62-18.fc7.i386.rpm perl-debuginfo-5.8.8-18.fc7.i386.rpm

モジュールを最新版に更新
# perl -MCPAN -e 'CPAN::Shell->install(CPAN::Shell->r)'

2007-06-22 19:38:47

Fedora7にupdate

[Linux]

FedoraCore6->Fedora7

RPM取得
wget http://ftp.riken.jp/pub/Linux/fedora/releases/7/Fedora/i386/os/Fedora/fedora-release-7-3.noarch.rpm
wget http://ftp.riken.jp/pub/Linux/fedora/releases/7/Fedora/i386/os/Fedora/fedora-release-notes-7.0.0-1.noarch.rpm

上書き
rpm -Uvh fedora-release-7-3.noarch.rpm fedora-release-notes-7.0.0-1.noarch.rpm

リポジトリ書き換えてると以下のような表示が出る
warning: /etc/yum.repos.d/fedora-updates.repo created as /etc/yum.repos.d/fedora-updates.repo.rpmnew
warning: /etc/yum.repos.d/fedora-extras.repo saved as /etc/yum.repos.d/fedora-extras.repo.rpmsave
warning: /etc/yum.repos.d/fedora-core.repo saved as /etc/yum.repos.d/fedora-core.repo.rpmsave

このままではfedora-updates.repoは古いままなのでリネーム
cd /etc/yum.repos.d/
mv fedora-updates.repo fedora-updates.repo.rpmsave
mv fedora-updates.repo.rpmnew fedora-updates.repo

アップグレードしてみる
yum clean all
yum upgrade

DAGのRPMでmemcached入れていたのでエラーが出た
Error: Missing Dependency: libevent-1.1a.so.1 is needed by package memcached

memcached削除してアップグレード
yum -y remove memcached
yum upgrade

アップグレード完了したのでmemcachedをインストールし直す。
cd /usr/src/redhat/SRPMS/
wget http://dag.wieers.com/rpm/packages/memcached/memcached-1.2.2-1.rf.src.rpm
rpmbuild --rebuild memcached-1.2.2-1.rf.src.rpm

リビルドでエラーが出る
error: Failed build dependencies:
        libevent-devel is needed by memcached-1.2.2-1.rf.i386

libevent-develをインストールして再度memcachedリビルド
yum -y install libevent-devel
rpmbuild --rebuild memcached-1.2.2-1.rf.src.rpm

途中でこんなメッセージが出てRPMができる
Wrote: /usr/src/redhat/RPMS/i386/memcached-1.2.2-1.rf.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/memcached-debuginfo-1.2.2-1.rf.i386.rpm

インストールする
cd /usr/src/redhat/RPMS/i386/
rpm -Uvh memcached-1.2.2-1.rf.i386.rpm memcached-debuginfo-1.2.2-1.rf.i386.rpm

memcachedスタートしてみる
/etc/init.d/memcached start

起動時オン
chkconfig --level 35 memcached on


21:13追記
-Perlのモジュールの依存関係がおかしくなったようで、CPANインストールでもエラー出まくり。
t/hoge...............Errno architecture (i386-linux-thread-multi-2.6.9-34.elsmp) does not match executable architecture (i386-linux-thread-multi-2.6.19-1.2895.fc6xen) at /usr/lib/perl5/site_perl/5.8.8/Errno.pm line 11.

-Cronにも怒られまくり。
Errno architecture (i386-linux-thread-multi-2.6.9-34.elsmp) does not match executable architecture (i386-linux-thread-multi-2.6.19-1.2895.fc6xen) at /usr/lib/perl5/site_perl/5.8.8/Errno.pm line 11.
Compilation failed in require at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/IO/Socket.pm line 17.
BEGIN failed--compilation aborted at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/IO/Socket.pm line 17.

locate Errno.pm すると二つあった
/usr/lib/perl5/5.8.8/i386-linux-thread-multi/Errno.pm
/usr/lib/perl5/site_perl/5.8.8/Errno.pm

削除する
rm -f  /usr/lib/perl5/site_perl/5.8.8/Errno.pm

同じようなモジュールが多々あるようだ(Scalar::Util,Compress::Zlib,String::CRC32)。
各個撃破後やっとCatalystアプリケーションの入ったhttpdを起動できた。
・・・やっぱりアップグレードは嫌。先も考えると精神的にキツい。

2007-06-11 16:24:52

レコード内文字列置換

[MySQL]

tableテーブルの columnカラム内の aaaa を bbbb に置換。

UPDATE `table` SET column=REPLACE(column,'aaaa','bbbb');

2007-05-25 12:43:02

プリンタで改頁印刷

[CSS] [JavaScript]

<html>
<head>
<title>for print</title>
<style type="text/css">
hr {
    page-break-before: always;
}
</style>
<script>
function Print() {
    window.print();
}
</script>
</head>
<body onload="Print()">
aaaaaaaaaaaaaaaaaaaaaaaaa<br>
bbbbbbbbbbbbbbbbbbbbbbbbb<br>
<hr>
ccccccccccccccccccccccccc<br>
ddddddddddddddddddddddddd<br>
<hr>
eeeeeeeeeeeeeeeeeeeeeeeee<br>
fffffffffffffffffffffffff<br>
</body>
</html>

楽。