• このエントリーをはてなブックマークに追加

はじめに

これで、Amon2::Plugin::DBI をロードしています。Amon2 はプラグイン機構によって無限の拡張性を演出しております。このプラグインをロードすることにより $c->dbh() というメソッドが追加され、DB へ簡単にアクセスできるようになります。このメソッドは Amon2::DBI のインスタンスをかえします。
TinyURLをつくってみよう ~ 軽量フレームワークAmon2入門 (4) ~ – TokuLog 改メ tokuhirom’s blog

開発者ご本人によるこのチュートリアルを進めてみて,プラグインのしくみと便利さがが少しわかりました.

そこで,プラグイン機構への理解をもう1歩進めるため,Amon2::Plugin::DBI を参考に,MongoDB の特定のデータベースへのアクセスを行うためのプラグインを書いてみました.

以下,その辺のまとめです.

ファイル構成

プラグインの読み込みは,(ライブラリのパスが通ってさえいれば)どこにあっても可能なのですが,まぁプロジェクト向けプラグインということで,次のように,ディレクトリ lib/MyApp/Plugin を準備し,その下に入れることにしました:

lib
├── MyApp
│   ├── Plugin
│   │   └── MongoDB.pm
│   ├── Web
│   │   └── Dispatcher.pm
│   └── Web.pm
└── MyApp.pm

ソースコードについては後ほど.

プラグインを読み込む

MyApp::Web 内で,次のようにすれば読み込めます:

__PACKAGE__->load_plugins('+MyApp::Plugin::MongoDB');

実際には,次のように追記すればよいかと:

diff --git a/lib/MyApp/Web.pm b/lib/MyApp/Web.pm
index 991c904..7dbe878 100644
--- a/lib/MyApp/Web.pm
+++ b/lib/MyApp/Web.pm
@@ -37,6 +37,7 @@ use Text::Xslate;
 # load plugins
 use HTTP::Session::Store::File;
 __PACKAGE__->load_plugins(
+    '+MyApp::Plugin::MongoDB',
     'Web::FillInFormLite',
     'Web::NoCache', # do not cache the dynamic content by default
     'Web::CSRFDefender',

コンフィグを追加する

コンフィグに,MongoDBへの接続設定を追記します:

+{
    ...
 
    'MongoDB' => {
        host     => 'localhost',
        port     => '27017',
        username => '',
        password => '',
        database => 'foo',
    },
 
    ...
};

できあがり

$c->db という形で,先のコンフィグで設定したデータベースに関する MongoDB::Database オブジェクトが返ってきます.

any '/' => sub {
    my ($c) = @_;
 
    use Data::Dumper;
    warn Dumper $c->db;
 
    $c->render('index.tx');
};
$VAR1 = bless( {
                 '_connection' => bless( {
                                           'find_master' => 0,
                                           'query_timeout' => 30000,
                                           'w' => 1,
                                           '_servers' => {},
                                           'right_port' => 27017,
                                           'wtimeout' => 1000,
                                           'timeout' => 20000,
                                           'auto_connect' => 1,
                                           'auto_reconnect' => 1,
                                           'db_name' => 'admin',
                                           'ts' => 0,
                                           'port' => '27017',
                                           'left_port' => 27017,
                                           'host' => 'localhost',
                                           'username' => 'admin',
                                           'max_bson_size' => 16777216
                                         }, 'MongoDB::Connection' ),
                 'name' => 'foo'
               }, 'MongoDB::Database' );

ソースコード

Amon2::Plugin::DBI の内容をそのままMongoDB向けに置き換えた感じです.MongoDB::Database オブジェクトを,ラップなどせずにそのまま返しています.

package MyApp::Plugin::MongoDB;
use strict;
use warnings;
use utf8;
use MongoDB;
 
 
sub init {
    my ($class, $c, $params) = @_;
 
    no strict 'refs';
    *{"$c\::db"} = \&_db;
}
 
 
sub _db {
    my ($self) = @_;
 
    if ( !defined $self->{db} ) {
        my $conf = $self->config->{'MongoDB'}
            or die "missing configuration for 'MongoDB'";
 
        my $dbname = $conf->{database}
            or die "missing 'MongoDB.database'";
 
        my %params_conn = (
            host => $conf->{host} || 'localhost',
            port => $conf->{port} || '27017',
        );
        $params_conn{username} = $conf->{username}  if $conf->{username};
        $params_conn{password} = $conf->{password}  if $conf->{password};
 
        my $conn = MongoDB::Connection->new(%params_conn);
 
        $self->{db} = $conn->$dbname;
    }
 
    return $self->{db};
}
 
 
1;

おわりに

以上,Amon2でMongoDBを利用するためのプラグインを練習がてら書いてみたお話でした.

さて,MongoDBの使い方を覚えねば...