Plagger の context に model を追加して勝手にウハウハ

| 0 Comments | 0 TrackBacks

Plagger で、いろんなプラグインから model を使ってみたいなぁと思った。

Catalyst だと、$c->model('foo') として使うので、Plagger もそのようにしたい。

Catalyst の sub model を読んでると、default_model を config から指定できたりして便利機能があることが今回わかった。今後マネをしていきたい。

というわけで、Plagger::Plugin::Store::DBIC をベースにして、context に model を追加するための Plagger のコアの diff と Plagger::Model 。

Index: lib/Plagger.pm
===================================================================
--- lib/Plagger.pm	(revision 1898)
+++ lib/Plagger.pm	(working copy)
@@ -26,6 +26,7 @@
 use Plagger::Template;
 use Plagger::Update;
 use Plagger::UserAgent; # use to define $XML::Feed::RSS::PREFERRED_PARSER
+use Plagger::Model;
 
 my $context;
 sub context     { $context }
@@ -40,7 +41,8 @@
         subscription => Plagger::Subscription->new,
         plugins_path => {},
         plugins => [],
-        rewrite_tasks => []
+        rewrite_tasks => [],
+        _models => {},
     }, $class;
 
     my $loader = Plagger::ConfigLoader->new;
@@ -61,9 +63,21 @@
     $self->load_plugins(@{ $config->{plugins} || [] });
     $self->rewrite_config if @{ $self->{rewrite_tasks} };
 
+    for my $model (keys %{$self->{conf}->{model}}) {
+        my $modelclass = Plagger::Model->new($self->{conf}->{model}->{$model});
+        $self->{_models}->{$model} = $modelclass;
+    }
+
     $self;
 }
 
+sub model {
+    my($self, $name) = @_;
+    Plagger->error("no such model named $name")
+        unless exists $self->{_models}->{$name};
+    return $self->{_models}->{$name}->schema;
+}
+
 sub bootstrap {
     my $class = shift;
     my $self = $class->new(@_);
Index: lib/Plagger/Model.pm
===================================================================
--- lib/Plagger/Model.pm	(revision 0)
+++ lib/Plagger/Model.pm	(revision 0)
@@ -0,0 +1,22 @@
+package Plagger::Model;
+use strict;
+
+use base qw( Class::Accessor::Fast );
+__PACKAGE__->mk_accessors( qw(schema) );
+
+sub new {
+    my $class = shift;
+    my $self = bless { schema => {} }, $class;
+
+    my $opt = shift;
+    unless ( $opt->{schema_class} and $opt->{connect_info} ) {
+        die('schema_class and connect_info are required');
+    }
+    $opt->{schema_class}->require
+        or die(qq/Can't load schema class "@{[ $opt->{schema_class} ]}", $@/);
+    $self->{schema}  = $opt->{schema_class}->connect( @{ $opt->{connect_info} } );
+
+    return $self;
+}
+
+1;

使い方としては、以下のような config を書いて、

global:
  model:
    DBIC:
      schema_class: Plagger::Schema::SQLite
      connect_info: [ 'dbi:SQLite:/path/to/plagger.db', ]

plugins:
  - module: Store::Model
    config:
      model: DBIC

Store::Model の中では、

sub store {
    my ( $self, $c, $args ) = @_;

    # feed
    my $model = $c->model( $self->conf->{model} );
    my $feed = $model->resultset('Feed')->find_or_new(
        {   link => $args->{feed}->link,
            type => $args->{feed}->type,
        }
    );

のように使える。

No TrackBacks

TrackBack URL: http://blog.woremacx.com/MT/mt-tb.cgi/153

Leave a comment