File Coverage

blib/lib/Mojolicious/Plugin/DBViewer.pm
Criterion Covered Total %
statement 64 70 91.4
branch 14 18 77.7
condition 13 14 92.8
subroutine 9 9 100.0
pod 1 1 100.0
total 101 112 90.1


line stmt bran cond sub pod time code
1 3     3   730787 use 5.008001;
  3         18  
2             package Mojolicious::Plugin::DBViewer;
3 3     3   490 use Mojo::Base 'Mojolicious::Plugin';
  3         195457  
  3         21  
4              
5 3     3   1360 use Cwd 'abs_path';
  3         7  
  3         153  
6 3     3   684 use DBIx::Custom;
  3         57411  
  3         39  
7 3     3   2031 use Validator::Custom;
  3         54879  
  3         27  
8 3     3   127 use Carp 'croak';
  3         8  
  3         3229  
9              
10             our $VERSION = '0.30';
11              
12             has 'command';
13             has 'prefix';
14             has 'validator';
15             has 'dbi';
16              
17 8     8   32 sub _driver { lc shift->dbi->dbh->{Driver}->{Name} }
18              
19             sub register {
20 8     8 1 149373 my ($self, $app, $conf) = @_;
21            
22             # Prefix
23 8         63 my $prefix = $conf->{prefix};
24 8 100       43 $prefix = 'dbviewer' unless defined $prefix;
25            
26             # Slash and prefix
27 8 100       49 my $sprefix = $prefix eq '' ? $prefix : "/$prefix";
28            
29             # Default charset
30 8   100     56 my $charset = $conf->{charset} || 'UTF-8';
31            
32             # DBI
33             my $dbi = DBIx::Custom->connect(
34             dsn => $conf->{dsn},
35             user => $conf->{user},
36             password => $conf->{password},
37             option => $conf->{option} || {},
38 8   50     143 connector => 1
39             );
40 8         36151 $self->dbi($dbi);
41 8 100       114 if (ref $conf->{connector_get} eq 'SCALAR') {
42 7         140 ${$conf->{connector_get}} = $dbi->connector;
  7         56  
43             }
44            
45             # Validator
46 8         77 my $validator = Validator::Custom->new;
47             $validator->register_constraint(
48             safety_name => sub {
49 313     313   190211 my $name = shift;
50 313 100 100     2254 return ($name || '') =~ /^[a-zA-Z0-9_\.]+$/ ? 1 : 0;
51             }
52 8         1618 );
53 8         413 $self->validator($validator);
54            
55             # Commaned and namespace
56 8         101 my $driver = $self->_driver;
57 8         1087 my $command;
58             my $namespace;
59 8 50       44 if ($driver eq 'mysql') {
    50          
60 0         0 require Mojolicious::Plugin::DBViewer::MySQL::Command;
61 0         0 $command = Mojolicious::Plugin::DBViewer::MySQL::Command->new(dbi => $dbi);
62 0         0 $namespace = 'Mojolicious::Plugin::DBViewer::MySQL';
63             }
64             elsif ($driver eq 'sqlite') {
65 8         1197 require Mojolicious::Plugin::DBViewer::SQLite::Command;
66 8         106 $command = Mojolicious::Plugin::DBViewer::SQLite::Command->new(dbi => $dbi);
67 8         83 $namespace = 'Mojolicious::Plugin::DBViewer::SQLite';
68             }
69 0         0 else { croak "Mojolicious::Plugin::DBViewer don't support $driver" }
70 8         41 $self->command($command);
71            
72             # Add public and template path
73 8         63 my $class = __PACKAGE__;
74 8         49 $class =~ s/::/\//g;
75 8         25 $class .= '.pm';
76 8         954 my $base_path = abs_path $INC{$class};
77 8         75 $base_path =~ s/\.pm$//;
78 8         22 push @{$app->static->paths}, "$base_path/public";
  8         66  
79 8         135 push @{$app->renderer->paths}, "$base_path/templates";
  8         37  
80              
81             # Mojolicious compatibility
82 8         105 my $any_method_name;
83 8 50       39 if ($Mojolicious::VERSION >= '8.67') {
84 8         17 $any_method_name = 'any'
85             }
86             else {
87 0         0 $any_method_name = 'route'
88             }
89            
90             # Routes
91 8         21 my $r = $conf->{route};
92 8 100       58 $r = $app->routes unless defined $r;
93 8         70 $self->prefix($prefix);
94             {
95             # Config
96 8   100     52 my $site_title = $conf->{site_title} || 'DBViewer';
  8         48  
97 8   100     44 my $footer_text = $conf->{footer_text} || 'Mojolicious::Plugin::DBViewer';
98             my $footer_link = $conf->{footer_link}
99 8   100     42 || 'http://search.cpan.org/dist/Mojolicious-Plugin-DBViewer'
100             . '/lib/Mojolicious/Plugin/DBViewer.pm';
101              
102             # Utilities
103 8         71 my $utilities = [
104             {path => 'create-tables', title => 'Create tables'},
105             {path => 'primary-keys', title => 'Primary keys'},
106             {path => 'null-allowed-columns', title => 'Null allowed columns'},
107             ];
108 8 50       33 if ($driver eq 'mysql') {
109 0         0 push @$utilities,
110             {path => 'database-engines', title => 'Database engines'},
111             {path => 'charsets', title => 'Charsets'}
112             }
113 8         35 push @$utilities,
114             {path => 'select-statements', title => 'Selects statements'};
115            
116             # Route Config
117             my $r = $r->$any_method_name("/$prefix")->to(
118             'dbviewer#',
119             namespace => $namespace,
120             plugin => $self,
121             sprefix => $sprefix,
122             site_title => $site_title,
123             driver => $driver,
124             dbviewer => $self,
125             charset => $charset,
126             footer_text => $footer_text,
127             footer_link => $footer_link,
128             utilities => $utilities,
129             join => $conf->{join} || {}
130 8   100     102 );
131            
132             # Auto Route
133 8         4292 $app->plugin('AutoRoute', route => $r, top_dir => 'dbviewer/auto');
134             }
135             }
136              
137             1;
138              
139             =head1 NAME
140              
141             Mojolicious::Plugin::DBViewer - Mojolicious plugin to display database information on browser
142              
143             =head1 SYNOPSYS
144              
145             # Mojolicious::Lite
146             plugin(
147             'DBViewer',
148             dsn => "dbi:mysql:database=bookshop",
149             user => 'ken',
150             password => '!LFKD%$&'
151             );
152              
153             # Mojolicious
154             $app->plugin(
155             'DBViewer',
156             dsn => "dbi:mysql:database=bookshop",
157             user => 'ken',
158             password => '!LFKD%$&'
159             );
160            
161             # Access
162             http://localhost:3000/dbviewer
163            
164             # Prefix change (http://localhost:3000/dbviewer2)
165             plugin 'DBViewer', dsn => $dsn, prefix => 'dbviewer2';
166              
167             # Route
168             my $bridge = $app->route->under(sub {...});
169             plugin 'DBViewer', dsn => $dsn, route => $bridge;
170              
171             =head1 DESCRIPTION
172              
173             L is L plugin
174             to display Database information on your browser.
175              
176             L have the following features.
177              
178             =over 4
179              
180             =item *
181              
182             Support C and C
183              
184             =item *
185              
186             Display all table names
187              
188             =item *
189              
190             Display C
191              
192             =item *
193              
194             Execute simple select statement
195              
196             =item *
197              
198             Display C, C, C
199             and C in all tables.
200              
201             =back
202              
203             =head1 OPTIONS
204              
205             =head2 connector_get
206              
207             connector_get => \$connector
208              
209             Get L object internally used.
210            
211             # Get database handle
212             my $connector;
213             plugin('DBViewer', ..., connector_get => \$connector);
214             my $dbh = $connector->dbh;
215              
216             =head2 charset
217              
218             charset => 'euc-jp'
219              
220             Database charset, default is C.
221              
222             =head2 dsn
223              
224             dsn => "dbi:SQLite:dbname=proj"
225              
226             Datasource name.
227              
228              
229             =head2 password
230              
231             password => 'secret';
232              
233             Database password.
234              
235             =head2 prefix
236              
237             prefix => 'dbviewer2'
238              
239             Application base path, default to C.
240             You can access DB viewer by the following path.
241              
242             http://somehost.com/dbviewer2
243              
244             =head2 footer_text
245              
246             footer_text => 'Web DB Viewer'
247              
248             Footer text.
249              
250             =head2 footer_link
251              
252             footer_link => 'https://github.com/yuki-kimoto/webdbviewer'
253              
254             Footer link
255              
256             =head2 join
257              
258             join => {
259             book => [
260             'left join author on book.author_id = author.id',
261             'left join title on book.title_id = title.id'
262             ]
263             }
264              
265             Join clause. If you set join clause, you can use join mode in select page.
266              
267             =head2 option
268              
269             option => $option
270            
271             DBI option (L connect method's fourth argument).
272              
273             =head2 route
274              
275             route => $route
276              
277             Router for bridge, default to C<$app->routes>.
278              
279             my $bridge = $r->under(sub {...});
280             plugin 'DBViewer', dsn => $dsn, route => $bridge;
281              
282             =head2 user
283              
284             user => 'kimoto'
285              
286             =head2 site_title
287              
288             site_title => 'Your DB Viewer';
289              
290             Site title.
291              
292             Database user.
293              
294             =head1 BACKWARDS COMPATIBILITY POLICY
295              
296             If a feature is DEPRECATED, you can know it by DEPRECATED warnings.
297             DEPRECATED feature is removed after C,
298             but if at least one person use the feature and tell me that thing
299             I extend one year each time he tell me it.
300              
301             DEPRECATION warnings can be suppressed
302             by C
303             environment variable.
304              
305             EXPERIMENTAL features will be changed without warnings.
306              
307             =head1 COPYRIGHT & LICENSE
308              
309             Copyright 2013 Yuki Kimoto, all rights reserved.
310              
311             This program is free software; you can redistribute it and/or modify it
312             under the same terms as Perl itself.
313              
314             =cut