File Coverage

blib/lib/Aniki/Handler.pm
Criterion Covered Total %
statement 22 23 95.6
branch 0 2 0.0
condition 0 3 0.0
subroutine 18 20 90.0
pod 4 12 33.3
total 44 60 73.3


line stmt bran cond sub pod time code
1             package Aniki::Handler;
2 28     28   1445 use 5.014002;
  28         105  
3              
4 28     28   168 use namespace::autoclean;
  28         64  
  28         195  
5 28     28   1987 use Mouse;
  28         84  
  28         205  
6              
7 28     28   23210 use DBIx::Handler 0.12;
  28         532147  
  28         10411  
8              
9             has connect_info => (
10             is => 'ro',
11             required => 1,
12             );
13              
14             has on_connect_do => (
15             is => 'ro',
16             );
17              
18             has on_disconnect_do => (
19             is => 'ro',
20             );
21              
22             has trace_query => (
23             is => 'ro',
24             default => 0,
25             );
26              
27             has trace_ignore_if => (
28             is => 'ro',
29             default => sub { \&_noop },
30             );
31              
32             has handler => (
33             is => 'rw',
34             lazy => 1,
35             builder => 'connect',
36             clearer => 'disconnect',
37             );
38              
39       0     sub _noop {}
40              
41             sub connect :method {
42 25     25 1 106 my $self = shift;
43 25         62 my ($dsn, $user, $pass, $attr) = @{ $self->connect_info };
  25         146  
44 25         156 my $trace_ignore_if = $self->trace_ignore_if;
45             return $self->_handler_class->new($dsn, $user, $pass, $attr, {
46             on_connect_do => $self->on_connect_do,
47             on_disconnect_do => $self->on_disconnect_do,
48             trace_query => $self->trace_query,
49 0 0 0 0   0 trace_ignore_if => sub { $_[0]->isa('Aniki') || $_[0]->isa('Aniki::Handler') || $trace_ignore_if->(@_) },
50 25         126 });
51             }
52              
53 305     305   1632 sub _handler_class { 'DBIx::Handler' }
54 30     30   156 sub _proxy_methods { qw/dbh trace_query_set_comment run txn_manager txn in_txn txn_scope txn_begin txn_rollback txn_commit/ }
55              
56             for my $name (__PACKAGE__->_proxy_methods) {
57             my $code = __PACKAGE__->_handler_class->can($name);
58             __PACKAGE__->meta->add_method($name => sub {
59 736     736 1 2559 @_ = (shift->handler, @_);
        736 0    
        736 0    
        736 0    
        736 0    
        736 0    
        736 0    
        736 1    
        736 0    
        736 0    
60 736         3083 goto $code;
61             });
62             }
63              
64             sub DEMOLISH {
65 25     25 1 7507 my $self = shift;
66 25         257 $self->disconnect();
67             }
68              
69             __PACKAGE__->meta->make_immutable();
70             __END__
71              
72             =pod
73              
74             =encoding utf-8
75              
76             =head1 NAME
77              
78             Aniki::Handler - Database handler manager
79              
80             =head1 SYNOPSIS
81              
82             # define custom database handler class
83             pakcage MyApp::DB::Handler {
84             use Mouse;
85             extends qw/Aniki::Handler/;
86              
87             has '+connect_info' => (
88             is => 'rw',
89             );
90              
91             has servers => (
92             is => 'ro',
93             isa => 'ArrayRef[Str]',
94             );
95              
96             sub _choice { @_[int rand scalar @_] }
97              
98             around connect => sub {
99             my $self = shift;
100             my ($dsn, $user, $pass, $attr) = @{ $self->connect_info };
101             $attr->{host} = _choice(@{ $self->servers });
102             $self->connect_info([$dsn, $user, $pass, $attr]);
103             return DBIx::Handler->new($dsn, $user, $pass, $attr, {
104             on_connect_do => $self->on_connect_do,
105             on_disconnect_do => $self->on_disconnect_do,
106             });
107             };
108             };
109              
110             # and use it
111             package MyApp::DB {
112             use Mouse;
113             extends qw/Aniki::Handler/;
114              
115             __PACKAGE__->setup(
116             handler => 'MyApp::DB::Handler',
117             );
118             }
119              
120             1;
121              
122             =head1 DESCRIPTION
123              
124             This is database handler manager.
125              
126             =head1 METHODS
127              
128             =head2 CLASS METHODS
129              
130             =head3 C<new(%args) : Aniki::Handler>
131              
132             Create instance of Aniki::Handler.
133              
134             =head4 Arguments
135              
136             =over 4
137              
138             =item C<connect_info : ArrayRef>
139              
140             Auguments for L<DBI>'s connect method.
141              
142             =item on_connect_do : CodeRef|ArrayRef[Str]|Str
143             =item on_disconnect_do : CodeRef|ArrayRef[Str]|Str
144              
145             Execute SQL or CodeRef when connected/disconnected.
146              
147             =back
148              
149             =head2 INSTANCE METHODS
150              
151             =head3 C<connect() : DBIx::Handler>
152              
153             Create instance of DBIx::Handler.
154             You can override it in your custom handler class.
155              
156             =head2 ACCESSORS
157              
158             =over 4
159              
160             =item C<connect_info : ArrayRef>
161              
162             =item C<on_connect_do : CodeRef|ArrayRef[Str]|Str>
163              
164             =item C<on_disconnect_do : CodeRef|ArrayRef[Str]|Str>
165              
166             =item trace_query : Bool
167              
168             =item trace_ignore_if : CodeRef
169              
170             =item C<dbh : DBI::db>
171              
172             =item C<handler : DBIx::Handler>
173              
174             =item C<txn_manager : DBIx::TransactionManager>
175              
176             =back