File Coverage

blib/lib/Catalyst/Plugin/DBIC/ConsoleQueryLog.pm
Criterion Covered Total %
statement 9 17 52.9
branch 0 2 0.0
condition n/a
subroutine 3 5 60.0
pod 2 2 100.0
total 14 26 53.8


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::DBIC::ConsoleQueryLog;
2              
3 1     1   1233 use Moo::Role;
  1         21352  
  1         21  
4 1     1   1289 use Catalyst::Utils;
  1         201981  
  1         33  
5 1     1   307 use Text::SimpleTable;
  1         1387  
  1         507  
6              
7             our $VERSION = '0.002';
8              
9             my $_model_name = '';
10             my $model_name = sub {
11             my $c = shift;
12             return $_model_name ||= do {
13             if(my $config = $c->config->{'Plugin::DBIC::ConsoleQueryLog'}) {
14             $config->{'model_name'};
15             } else {
16             undef;
17             }
18             };
19             };
20              
21             my $model = sub {
22             my $c = shift;
23             my $model = $c->model($c->$model_name);
24             if($model) {
25             return $model;
26             } else {
27             $c->log->info("You specified a model '$model_name' but I can't find it.") if $model_name;
28             return;
29             }
30             };
31              
32             my $querylog = sub {
33             my $c = shift;
34             my $model = $c->$model || return;
35             if($model->can('querylog')) {
36             return $model->querylog;
37             } else {
38             $c->log->info("You requested querylog for model $model but there's no querylog_analyzer");
39             return;
40             }
41             };
42              
43             my $time_elapsed = sub {
44             my $c = shift;
45             return ($c->$querylog || return)->time_elapsed;
46             };
47              
48             my $query_count = sub {
49             my $c = shift;
50             return ($c->$querylog || return)->count;
51             };
52              
53             my $querylog_analyzer = sub {
54             my $c = shift;
55             my $model = $c->$model || return;
56             if($model->can('querylog_analyzer')) {
57             return $model->querylog_analyzer;
58             } else {
59             $c->log->info("You requested querylog_analyzer for model $model but there's no querylog_analyzer");
60             return;
61             }
62             };
63              
64             my $sorted_queries = sub {
65             my $c = shift;
66             my @sorted_queries = @{($c->$querylog_analyzer||return)
67             ->get_sorted_queries ||[]};
68             return @sorted_queries;
69             };
70              
71             after 'finalize', sub {
72             return unless (my $c = shift)->debug;
73             my $t = $c->querylog_table;
74             my @sorted_queries = $c->$sorted_queries;
75             foreach my $q (@sorted_queries) {
76             $c->add_querylog_table_row($t, $q);
77             }
78             my $count = $c->$query_count;
79             my $time = sprintf('%0.6fs', $c->$time_elapsed);
80             my $q_display = $count > 1 ? 'queries':'query';
81             $c->log->info( "SQL Profile Data ($count $q_display / $time elapsed time):\n" . $t->draw . "\n" ) if @sorted_queries;
82             };
83              
84             sub querylog_table {
85 0     0 1   my $column_width = Catalyst::Utils::term_width() - 6 - 16;
86 0           my $t = Text::SimpleTable->new( [ $column_width, 'SQL' ], [ 9, 'Time' ] );
87 0           return $t;
88             };
89              
90             sub add_querylog_table_row {
91 0     0 1   my ($c, $t, $q) = @_;
92 0 0         my $q_sql = $q->sql . ' : ' . join(', ', @{$q->params||[]});
  0            
93 0           my $q_total = sprintf('%0.6fs', $q->time_elapsed);
94 0           $t->row($q_sql, $q_total);
95             };
96              
97             =head1 NAME
98            
99             Catalyst::Plugin::DBIC::ConsoleQueryLog - Log DBIC queries and timings to the console
100              
101             =head1 SYNOPSIS
102            
103             Use the plugin in your application class:
104            
105             package MyApp;
106              
107             use Catalyst qw/DBIC::ConsoleQueryLog/;
108              
109             __PACKAGE__->config(
110             'Plugin::DBIC::ConsoleQueryLog' => { model_name => 'Schema' },
111             'Model::Schema' => { # This is a model of Catalyst::Model::DBIC::Schema
112             schema_class => 'MyApp::Schema',
113             traits => ['QueryLog'], # Please note you NEED to use this trait.
114             },
115             );
116              
117             __PACKAGE__->setup;
118            
119             =head1 DESCRIPTION
120            
121             This is a very basic console logger for L<DBIx::Class::QueryLog::Analyzer>, which you
122             might be using in L<Catalyst> via L<Catalyst::TraitFor::Model::DBIC::Schema::QueryLog>
123             in order to get tracing and performance information on you SQL calls. You must be
124             using L<Catalyst::Model::DBIC::Schema> and have added the L<Catalyst::TraitFor::Model::DBIC::Schema::QueryLog>
125             trait in configuration as in the L</SYNOPSIS> example.
126              
127             I wrote this because I got tired of adding it manually over and over to my basic
128             application framework. However its a very basic logger that doesn't support some of
129             the more powerful bits such as creating buckets to classify you logging, etc. It will
130             get you started but eventually you'll need to roll your own as you needs become more complex.
131              
132             Console logging will only occur when the application is run in debug mode. I recommend
133             only adding this plugin in development since it's needless overhead in production.
134              
135             =head1 METHOD
136              
137             This plugin exposes the following public methods.
138              
139             =head2 querylog_table
140              
141             Returns an instance of L<Text::SimpleTable> that is setup to display the rows of querylog
142             information. You can override this if you trying to customize the querylog information.
143              
144             =head2 add_querylog_table_row
145              
146             Receives an instance of L<Text::SimpleTable>, and L<DBIx::Class::QueryLog::Analyzer> so
147             that you can customize drawing a row of data. Override if you are adding custom display
148             information.
149              
150             =head1 AUTHOR
151            
152             John Napiorkowski L<email:jjnapiork@cpan.org>
153            
154             =head1 SEE ALSO
155            
156             L<DBIx::Class>, L<DBIx::Class::QueryLog>, L<DBIx::Class::QueryLog::Analyzer>, L<Catalyst>,
157             L<Catalyst::Model::DBIC::Schema>, L<Catalyst::TraitFor::Model::DBIC::Schema::QueryLog>,
158            
159             =head1 COPYRIGHT & LICENSE
160            
161             Copyright 2017, John Napiorkowski L<email:jjnapiork@cpan.org>
162            
163             This library is free software; you can redistribute it and/or modify it under
164             the same terms as Perl itself.
165            
166             =cut
167              
168             1;