perlモジュールのバージョンを一発で調べられるコマンド
$ pmvers DBIx::Cutom 0.168
cpanmがインストールしてあれば
$ cpanm pmvers
でインストールできます。
もうこんな事しなくていいんです。
perl -MDBI -e 'print $DBIx::Custom::VERSION'
perlモジュールのバージョンを一発で調べられるコマンド
$ pmvers DBIx::Cutom 0.168
cpanmがインストールしてあれば
$ cpanm pmvers
でインストールできます。
もうこんな事しなくていいんです。
perl -MDBI -e 'print $DBIx::Custom::VERSION'
DBIx::Customが生SQL感覚でも使えてお気に入りなのだけれど、ちょっこしハマったのでメモ。
DBIx::Custom – search.cpan.org
MySQL(に限らないと思う)でwhereに関数を利用したい時は多々あると思います。
例えば、更新時刻を見て7日以上古ければ選択しないという条件をwhereに指定したい時、
CREATE TABLE `table` ( `name` VARCHAR( 5 ) , `update_time` TIMESTAMP ) SELECT * FROM `table` WHERE update_time > SUBDATE(NOW(), INTERVAL 7 DAY);
このようなSQLだとします。
行の選択 select / DBIx::Custom リファレンス – サンプルコードによるPerl入門によれば、where句の設定は、
と、ハッシュリファレンスで渡すことになっています。
= 以外での比較は DBIx::Custom::Whereオブジェクト を作成して渡すことになっているのですが、ハッシュリファレンスで SUBDATE(NOW(), interval 7 day) を渡すとうまくいかないので悩んでいました。
append => ” で文字列を追加できるので、無理やり実装してみたのですが作者にツイートしてみたところ、
がーん、そうなのか。恥ずかしい。。さらに、
がーん、DBIx::Custom::Where でも文字列が指定できたのか。。。(恥恥
という事で、
use DBIx::Custom; my $dbi = DBIx::Custom->connect( ........... 端折ります ); my $result = $dbi->select( table => 'table', where => 'create_time > SUBDATE(NOW(), interval 7 day)', );
あるいは、
use DBIx::Custom; my $where = $dbi->where; $where->clause([ 'and', 'create_time > SUBDATE(NOW(), interval 7 day)' ]); my $result = $dbi->select( table => 'table', where => $where, );
で、出来るって事なんですね。(ソース嫁!)
id:perlcodesampleさんありがとうございました!
DBIx::Customいいよー。
SYNOPSYSにあるinsertとかupdateとかが失敗するのはボクの日頃の行いが悪いせいでしょうか?
# Insert $dbi->insert({title => 'Perl', author => 'Ken'}, table => 'book'); # Update $dbi->update({title => 'Perl', author => 'Ken'}, table => 'book', where => {id => 5});
# Insert $dbi->insert( param => {title => 'Perl', author => 'Ken'}, table => 'book' ); # Update $dbi->update( param => {title => 'Perl', author => 'Ken'}, table => 'book', where => {id => 5} );
だと性交いや、成功するのですが。
param が必要??(だからソース嫁!)
追記:DBIx::Customのバージョンが 0.168 だったからのようです…APIが追加された模様。
やっと出来たのでメモ。
起動スクリプト mojo.cgiを
#!/usr/bin/env perl
use strict;
use warnings;
use lib "../lib";
use App;
app->start('cgi');
exit;
こんな感じで呼び出すと通常のCGIとしてならなんの問題もなく実行出来るのだけれど、SpeedyCGIで実行しようとすると初回実行時に不具合が出る(テンプレートが読み込まれない?)上記実行方法でも2回目以降(キャッシュ後)は動作している感じ。
FastCGIやmod_perlでのエントリーは見かけるんだけど、いかんせんマイナーなSpeedyCGI。結構便利なのにあまり使われていないのかなぁ。
で、とりあえず解決方法が見つかったのでメモ。結論から言えば起動スクリプトで Mojo::Server::CGI を使ってアプリを実行すればいいみたい。
起動用スクリプトを mojoアプリケーション本体と同じディレクトリに置く。これは必須ではないので公開するときには配置を変えたり出来る。
(例えば App/public/mojo.cgi として App/public を公開ディレクトリにするなど)
__DATA__セクションにテンプレートを書けるけど、ここではテストのため外部ファイル化している。
App +
- App.pm
- mojo.cgi
- templates +
- index.html.ep
起動用スクリプト mojo.cgi
#!/usr/bin/env speedy
use strict;
use warnings;
use Mojo::Server::CGI;
$ENV{MOJO_APP} = 'App';
#$ENV{SCRIPT_NAME} = '';
Mojo::Server::CGI->new->run;
exit;
App.pm と 起動スクリプトが同じディレクトリの場合は use lib; しなくても大丈夫のようだ。別のディレクトリに起動スクリプトを置く場合、例えばApp/public/mojo.cgi とするなら use “../”; が必要になる。
mojoアプリケーション本体 App.pm
package App; use strict; # use Mojolicious::Lite;で自動でされるが明示的に use warnings; # しておく。 use utf8; use Mojolicious::Lite; # テンプレートへ渡すハッシュリファレンス my $params = {}; # インデックスページ get '/' => sub { my $self = shift; $params->{title}="Hello World!"; $params->{messe} = "ようこそ 世界へ!"; $self->stash(params => $params); } => 'index'; # mojo.cgi/任意の文字に対応 get '/:foo' => sub { my $self = shift; $params->{title}= $self->param('foo'); $params->{messe} = "このページは" . $self->param('foo') . "です"; $self->stash(params => $params); } => 'index';
テンプレートファイル templates/index.html.ep
<!doctype html>
<html>
<head>
<title><%= $params->{title} %></title>
</head>
<body>
<h1><%= $params->{messe} %></h1>
</body>
</html>
上記は最低限のファイル構成だけれど、テンプレートでレイアウト使っても動作していたのでSpeedyCGI化もこの方法なら大丈夫そう。
参考
id:tokuhirom氏作の Email::MIME::MobileJP::Template を発見したので使ってみる。
PODにあるコードは動作しないので注意。renderメソッドのAPIが変わったのかな?ソースを見ると引数の最初に送り先のメールアドレスを指定しないとダメみたい。
それと、Email::MIME::MobileJP にあるソースも間違えているので注意。syntax=>’TTerse’ は newする時に引数で指定する事。
use Email::MIME::MobileJP::Template;
use Email::Sender::Simple;
my $token='123';
my $to_email = '<foo@hoge.jp>'; # <>で囲わないとdocomoで受信したときToがおかしなことに。
my $mail_maker = Email::MIME::MobileJP::Template->new(
'Text::Xslate' => {
syntax => 'TTerse',
path => ['email_tmpl/'] # テンプレートの保存場所
}
);
my $mail = $mail_maker->render(
$to_email, # 送信先
'signup.eml', # テンプレートファイル
{token => $token} # テンプレートで利用する変数
);
# メールを送信
Email::Sender::Simple->send($mail);
path で指定したディレクトリにテンプレートファイルを作成する。MIMEヘッダはテンプレートでしか指定できない。Fromは記述しないと致命的なエラーとなるので注意。
./email_tmpl/signup.eml
Subject: [Example] サインアップ!
From: <name@hoge.com>
以下をクリックせよ
http://example.com/signup/[% token %]
perlスクリプトをSpeedyCGIスクリプトとして動作させる場合、グローバル変数の値は保持され続ける。なので、一度接続したデータベースハンドルを使い回すことでデータベースへの接続コストを削減できる。
テスト用スクリプト …つづきを読む