File Coverage

blib/lib/App/CLI/Plugin/DBI.pm
Criterion Covered Total %
statement 43 46 93.4
branch 8 14 57.1
condition 2 3 66.6
subroutine 10 10 100.0
pod 3 5 60.0
total 66 78 84.6


line stmt bran cond sub pod time code
1             package App::CLI::Plugin::DBI;
2              
3             =pod
4              
5             =head1 NAME
6              
7             App::CLI::Plugin::DBI - for App::CLI::Extension database base module
8              
9             =head1 VERSION
10              
11             1.1
12              
13             =head1 SYNOPSIS
14              
15             # MyApp.pm
16             package MyApp;
17            
18             use strict;
19             use base qw(App::CLI::Extension);
20            
21             # extension method
22             __PACKAGE__->load_plugins(qw(DBI));
23             __PACKAGE__->config(dbi => ["dbi:Pg:dbname=app_db", "foo", "bar", { RaiseError => 1, pg_enable_utf8 => 1 }]);
24            
25             1;
26            
27             # MyApp/Hello.pm
28             package MyApp::Hello;
29             use strict;
30             use base qw(App::CLI::Command);
31             our $VERSION = '1.0';
32            
33             sub run {
34            
35             my($self, @args) = @_;
36             my $sql = "select id, name, age from member where id = ?";
37             my $sth = $self->dbh->prepare($sql);
38             $sth->execute($args[0]);
39             while (my $ref = $sth->fetchrow_hashref) {
40             # anything to do...
41             }
42             $sth->finish;
43             }
44              
45             =head1 DESCRIPTION
46              
47             App::CLI::Extension DBI plugin module
48              
49             dbh method setting
50              
51             normal setting
52              
53             # config (example: PostgreSQL)
54             __PACKAGE__->config(dbi => ["dbi:Pg:dbname=app_db", "foo", "bar", { RaiseError => 1, pg_enable_utf8 => 1 }]);
55            
56             # get DBI handle
57             my $dbh = $self->dbh;
58              
59             multi db setting
60              
61             # config
62             __PACKAGE__->config(dbi => {
63             default => ["dbi:Pg:dbname=app_db", "foo", "bar", { RaiseError => 1, pg_enable_utf8 => 1 }]
64             other => ["dbi:Pg:dbname=other_db;host=192.168.1.100;port=5432", "foo", "bar", { RaiseError => 1, pg_enable_utf8 => 1 }]
65             );
66            
67             # get DBI handle
68             my $default_dbh = $self->dbh; # same as $self->dbh("default")
69             my $other_dbh = $self->dbh("other");
70              
71             =cut
72              
73 4     4   158064 use strict;
  4         10  
  4         137  
74 4     4   21 use warnings;
  4         8  
  4         132  
75 4     4   21 use base qw(Class::Accessor::Grouped);
  4         8  
  4         1378  
76 4     4   36973 use DBI;
  4         90697  
  4         2336  
77              
78             our $DEFAULT_HANDLE = "default";
79             our $VERSION = '1.1';
80              
81             #__PACKAGE__->mk_classaccessor(_dbh => {});
82             #__PACKAGE__->mk_classaccessor(dbi_default_handle => $DEFAULT_HANDLE);
83             __PACKAGE__->mk_group_accessors(inherited => "_dbh", "dbi_default_handle");
84             __PACKAGE__->_dbh({});
85             __PACKAGE__->dbi_default_handle($DEFAULT_HANDLE);
86              
87             =pod
88              
89             =head1 METHOD
90              
91             =cut
92              
93             sub setup {
94              
95 3     3 0 32429 my($self, @argv) = @_;
96              
97 3 50       22 if (!exists $ENV{APPCLI_DISABLE_DB_AUTO_CONNECT}) {
98 3         36 $self->dbi_connect;
99             }
100 3         44041 $self->maybe::next::method(@argv);
101             }
102              
103             sub finish {
104              
105 3     3 0 598 my($self, @argv) = @_;
106              
107 3 50       26 if (!exists $ENV{APPCLI_DISABLE_DB_AUTO_CONNECT}) {
108 3         27 $self->dbi_disconnect;
109             }
110 3         128 $self->maybe::next::method(@argv);
111             }
112              
113             =pod
114              
115             =head2 dbi_connect
116              
117             initialize DBI connect setting. setup phase to run normally with no need to perform explicitly.
118              
119             However, the environment variable "APPCLI_DISABLE_DB_AUTO_CONNECT" If you have defined not to run the setup phase,
120              
121             the need to call this method yourself
122              
123             =cut
124              
125             sub dbi_connect {
126              
127 3     3 1 9 my $self = shift;
128              
129 3         23 my $dbi_option = $self->_dbi_option;
130 3         7 map { $self->_dbh->{$_} = DBI->connect(@{$dbi_option->{$_}}) } keys %{$dbi_option};
  4         23501  
  4         35  
  3         11  
131             }
132              
133             =head2 dbi_disconnect
134              
135             destroy DBI disconnect. finish phase to run normally with no need to perform explicitly.
136              
137             However, the environment variable "APPCLI_DISABLE_DB_AUTO_CONNECT" If you have defined not to run the setup phase,
138              
139             the need to call this method yourself
140              
141             =cut
142              
143             sub dbi_disconnect {
144              
145 3     3 1 7 my $self = shift;
146              
147 3         5 map { $self->_dbh->{$_}->disconnect } keys %{$self->_dbh};
  4         241  
  3         73  
148             }
149              
150             =pod
151              
152             =head2 dbh
153              
154             get DBD::db. default handle name is "default"(actual value and the value returned dbi_default_handle method)
155              
156             Example
157              
158             # same as $self->dbh($self->dbi_default_handle);
159             my $dbh = $self->dbh;
160            
161             # if you set up if you want to connect multiple databases
162             my $default_dbh = $self->dbh;
163             my $other1_dbh = $self->dbh("other1");
164             my $other2_dbh = $self->dbh("other2");
165              
166             =head2 dbi_default_handle
167              
168             get default handle name.
169              
170             get current default handle name
171              
172             # $handle is "default"
173             my $handle = $self->dbi_default_handle;
174              
175             to change the default handle name
176              
177             $self->dbi_default_handle("new_handle_name");
178             # get new_handle_name db handle
179             my $dbh = $self->dbh;
180              
181             =cut
182              
183             sub dbh {
184              
185 4     4 1 703 my($self, $handle) = @_;
186              
187 4   66     37 $handle ||= $self->dbi_default_handle;
188 4 50       77 if (keys(%{$self->_dbh}) == 0) {
  4         165  
189 0         0 die "still not connected to database?";
190             }
191 4 50       472 if (!exists $self->_dbh->{$handle}) {
192 0         0 die "$handle is not undefined dbh handle";
193             }
194 4         275 return $self->_dbh->{$handle};
195             }
196              
197              
198             ####################################
199             # private method
200             ####################################
201             sub _dbi_option {
202              
203 3     3   7 my $self = shift;
204              
205 3 50       15 if (!defined $self->config->{dbi}) {
206 0         0 die "dbi option is always required";
207             }
208 3         226 my $dbi_option;
209 3 100       12 if (ref($self->config->{dbi}) eq "ARRAY") {
    50          
210 2         211 $dbi_option = { $self->dbi_default_handle => $self->config->{dbi} };
211             } elsif (ref($self->config->{dbi}) eq "HASH") {
212 1         122 $dbi_option = $self->config->{dbi};
213             }
214              
215 3         274 return $dbi_option;
216             }
217              
218             1;
219              
220             __END__