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,
}
);
のように使える。

Leave a comment