そもそも、配列型のカラムなんてものを初めて知ったのですが、、、新しい業界標準「SQL99」詳細解説 - 第二章 柔軟さを増したデータ構造(1)PostgreSQL v8では、このSQL99に準拠して配列型というカラムが使えます。例えば、あるカラムが整数値の配列を持つ場合、
CREATE TABLE hoge
(
....
fuga INTEGER[],
....
)
みたいに書けるのです。この場合、普通にコマンドラインクライアント(PostgreSQLであればpsql)からこのカラムをSELECTすると、"{val1,val2,...}"という様に、整数値がカンマ区切りで繋がれ、中括弧でくくられた文字列値として見えます。
プログラムからデータを取得する場合は、例えばPerlのDBI/DBD::Pgの場合、このカラムを取得したデータ型は、Perlの無名リストへの参照として自動的に展開されます(注1)。
正直言って、SELECT文一発でカラムデータが検索出来なそうな感じがするので、あまり使いたい気はしないんだけれど、こういうデータ型が便利なシチュエーションもあるのかも知れないなあとも思う。
(注1) ちなみにこの挙動はDBD::Pgのバージョンが2.0以上でないと利用できないっぽい。バージョン1.4では、単なる"{val1,val2,...}"という文字列を取得してしまった。。。
PHP5のPostgreSQLバインドは、まだこの配列型に対応していないっぽいです。いちいち"{val1,val2,...}"をパースして配列に展開する作業が鬱陶しいです、正直なところ。
*****
その後、色々とテストしてみると、DBD::Pg v2.0以降であればINSERT/UPDATE/SELECTにおいて、配列型カラムの値はPerlのリストへの参照と等価であることが分かりました。両者の変換はドライバによってシームレスに行われます。
これはちょっと便利かも。
私のPerl知識はPerl5のごくごく初期のレベルで止まっているわけだが、今日もまた新たな発見があった。かつてはPerlで日本語文字コードを変換を行うには、jcodeモジュールを使う(明示的にjcode.plをどこからか持ってきてrequireしてた気が)のが一般的だったが、今やPerl5標準でEncodeというモジュールがあるようだ。use Encode;my $decoded = Encode::decode("euc-jp", $target);my $encoded = Encode::encode("shiftjis", $decoded);とかっていう風に使う。ここで「decode」や「encode」の概念がイマイチ分かりにくいが、要するに「内部エンコーディングであるUTF-8へdecodeする/からencodeする」という事のようである。
ちなみに、上記の2つの処理をいっぺんに行うfrom_toという関数もあるのだが、どうも上手く動かないようだった。環境はMacPortsのPerl5 (MacOS X 10.5)及びActivePerlのPerl5 (Windows XP Pro)であった。理由は不明だ。
Perlのアドオンモジュール集であるCPANを使ってみることに。ちなみに、MacOS XデフォルトのPerlにもCPANモジュールは入っているが、MacPortsで入れたCPANモジュールを使うことにする。% su -% /opt/local/bin/cpan
ここで設定をゴチャゴチャと行う。ほぼデフォルトでOKだが、MacOS Xの端末アプリはUTF-8がデフォルト文字セットなので、文字セットを「ISO-8859-1?」と聞かれたらnoと答える。CPANアーカイブは、Asia→Japanと指定し、適当にアーカイブサイトを選ぶ。これは恐らくネットワーク的な距離と好みによって変わって良いと思う。
さて、色々と答えるとCPANの設定が完了してプロンプトが返ってくる。
cpan>
ここでまずは以下のコマンドを叩く。正直、意味は良く分からない(←おい)
cpan> install Module::Install
Running install for module Module::InstallRunning make for A/AD/ADAMK/Module-Install-0.79.tar.gz Is already unwrapped into directory /var/root/.cpan/build/Module-Install-0.79 Makefile.PL returned status 65280Running make test Make had some problems, maybe interrupted? Won't testRunning make install Make had some problems, maybe interrupted? Won't installああ、、、なんかエラーが。。。激しく意気消沈。
気を取り直して、本来入れたかったLWP::UserAgentを入れてみることに。
cpan> install LWP::UserAgent
あれ、なんかフツーに入った。何故だろう(汗
更にCrypt::SSLeayを入れる。
cpan> install Crypt::SSLeay
SSLがある場所を聞かれただけで、フツーに入った。Live testも問題なし。
Data::DumperというのはPerlのモジュールです。とある仕事で教えてもらいましたが、便利です。
Perlのデータ構造を、そのままPerlコードとしてテキスト化してくれます。テキスト化したコードは、evalに与えるとそのままPerlとして解釈されます。その為、Data::Dumperでダンプしたコードをテキストファイルとして保存し、後ほど読み出してevalに与える、という形でデータ構造のシリアライズ/デシリアライズが可能です。
使い方はこんな感じ:
use Data::Dumper;
my %hoge = ("key1" => "val1", "key2" => "val2");
print Dumper(¥%hoge);
出力結果はこんな感じ。
$VAR1 = {"key1" => "val1", "key2" => "val2"};
"$VAR1"という変数名は勝手にDumperが名付けるんですが、これを無くす方が都合がよい場合は、
$Data::Dumper::Terse = 1;
というコードをDumper呼び出し前に挿入します。こうしておくと、例えば上記のテキストが保存された変数を$hogeとすると、
$fuga = eval $hoge;
という形でevalすれば、$fugaに上記の$VAR1に相当する連想配列へのレファレンスが代入されます。
ちなみに、Dumperに渡す引数はレファレンスであることにご注意を。
PerlにはLWPという非常に便利なモジュールがあり、HTTP及びHTTPS (SSL)によるウェブサーバへのアクセスが、僅か数行のコードで書けてしまいます。しかも、このモジュールはHTTP Proxyもサポートしているのです。ああ、何て素晴らしいモジュール!しかし、そんなLWPにも弱点があります。それは、Proxyを通したHTTPSアクセスが出来ない、という点です。これはバグらしいのですが、たまたま私の顧客がこの方法を使う必要があり、大変困りました。CPAN: #1894: LWP::UserAgent can't reach https sites via proxyさて、どうしようか、いっそのことJavaで書き直すか、なんて悲壮な決意をしていたところ、素敵なウェブリソースを発見しました。Perlから、https(SSL)のコンテンツをProxy経由で取得するううむ。世の中には似た様な事をやる人がいるものですね。いやはや、大変参考になります。このページで書かれている事を要約すると、以下の様になります。- LWP::UserAgentのProxyアクセスはHTTPであれば問題無い
- LWP::UserAgentのProxyアクセスはHTTPSでは問題がある為、代わりに
ちょっとかっこ悪いコードではありますがPerlのまま目的が達成できるだけ良いです。これをJavaで作り直す事を考えたら・・・ああ、卒倒しそう。
というわけで、今回は何とか問題を回避出来そうです。
Perlの連想配列が入れ子に出来るかもって話を仕入れた。具体的には、%hoge = (x => y, ...);と書くと hoge には連想配列の実体が格納されるが、$hoge = {x => y, ...}と書くと hoge には連想配列の参照が格納されるという話。違いは、丸括弧か中括弧かということである。まだ実際にコードを書いて試してみたわけではないが、備忘録代わりに書いておくことに。
なんか、久々にPerlを書こうとすると色々と敷居が高い。連想配列の値に連想配列を入れる、という初期化の仕方が出来ないらしい。つまり、my %hoge = ("key1" => ("key11" => "val11", "key12" => "val12"), ...);みたいな感じのコードが書けない。う~、じれったい!Perlは連想配列があるので構造体は無いらしい。うぅぅ・・・クラスを作ってオブジェクト指向しろと、そういうことですか・・・。
あ、ちなみに処理系はCygwinのPerl 5.10.0です。。。
前の日記でCPANにDBD::mysqlをインストールしたが、その際にはビルドエラーが発生する場合がある。ちなみに、私の場合は発生した。解決方法に関しては、[[mac][perl]Mac OS XにDBD::mysqlをインストールする]を参考にさせて頂く。もしかすると、MacOS XでPerlとDBD::mysqlを使う場合特有の問題かも知れない。
ちなみに、"DBD::MySQL"の様にMySQLとキャピタリゼーションして表記するのは間違いの様だ。"DBD::mysql"と小文字で書くのが正しい。
私のMacBookは、主としてドキュメント作成と画像編集にしか使っておらず、以前は仕事でプログラムも書いたのだがそれでもPHPやJavaで事足りていた。しかし、最近になってDBアクセスも含めてPerlを使いこなす必要が生じた為、急遽環境を整備する必要に。
PerlのDBアクセスはDBIというフレームワークを使うのが一般的で、私のMacにも既にPerlとDBIはインストールされている。しかし、MySQLへ接続する為の個別のモジュール(DBD)が無い為、CPANを使ってDBD::MySQLを入れることにする。
私はPerl歴は結構長いのだがCPANはあまり使ったことが無かったので、[CPAN経由でLinuxにモジュールを組み込む]を参考にさせて頂き、CPANをチェックしてみる。
% perl -MCPAN -e shell
すると、手動でのCPAN設定が開始される。ここで気付いたのが、CPANに必要なlynxやwget等のツールが無いということ。通常のMacOS X向けのユニバーサルバイナリを探したのだが、ネット上にはtar-ballからのインストール情報が溢れていたので、気を取り直してMacPortsを使うことにする。
というか、MacBookを使い始めてもう1年半以上経つのに、未だにMacPortsを入れていないことがバレてしまった。。。UNIX使いとして失格である。
さて、MacPortsというパッケージシステム自体はユニバーサルバイナリで提供されている為、MacPortsのサイトからダウンロードする。
画面左側のメニューから[Installing MacPorts]をクリックし、画面右側のリンク[Leopard (Universal)]をダウンロードし、MacPortsをインストールする。但し、画面右側の下部に記載されている様に、MacOS X 10.5 LeopardではXcode 3.0がインストールされている必要がある。私のMacBookには既にインストールされているので問題ないが、未導入の場合はMacBook付属のCD-ROMからインストールする必要がある。
MacPortsが入ったら、後はターミナルで操作を行う。
MacPortsでインストールしたいパッケージ(hoge)を検索する際:
% port search hoge
MacPortsでパッケージ(hoge)のオプションを検索する際:
% port variants hoge
MacPortsでパッケージ(hoge)をインストールする際:
% sudo port install hoge
後は、MacPortsを使って必要なコマンドをインストールする。注意点としては、CPANが要求するコマンド名と、MacPortsのパッケージ名が必ずしも一致しない事だ。lynxコマンドやwgetコマンドはパッケージ名もlynx及びwgetだが、ncftpgetコマンドのパッケージ名はncftpであり、gpgコマンドのパッケージ名はgnupgだ。後は設定に関する質問に答えていけば、CPANの設定は完了する。
CPANの設定が完了するとCPANのコマンドラインプロンプトが表示されるので、やっと念願であったDBD::MySQLのインストールが出来る。インストールは以下のコマンドで実行する。
cpan> install Bundle::DBD::MySQL
ちなみに、このインストール作業中にCPAN自体のアップデート(?)も推奨されるので、以下のコマンドも実行する。
cpan> install Bundle::CPAN
cpan> reload cpan
以上で(やっとこさ) PerlスクリプトからMySQLに接続する準備が整った。さて、書くか。。。