1d5fd2e2c98655340940b23f3f7352ce7077cbd9
[dbsrgits/SQL-Abstract.git] / lib / DBIx / Class / Storage / Debug / PrettyPrint.pm
1 package DBIx::Class::Storage::Debug::PrettyPrint;
2
3 use strict;
4 use warnings;
5
6 use base 'DBIx::Class::Storage::Statistics';
7
8 use SQL::Abstract::Tree;
9
10 __PACKAGE__->mk_group_accessors( simple => '_sqlat' );
11 __PACKAGE__->mk_group_accessors( simple => '_clear_line_str' );
12 __PACKAGE__->mk_group_accessors( simple => '_executing_str' );
13 __PACKAGE__->mk_group_accessors( simple => '_show_progress' );
14 __PACKAGE__->mk_group_accessors( simple => '_last_sql' );
15 __PACKAGE__->mk_group_accessors( simple => 'squash_repeats' );
16
17 sub new {
18    my $class = shift;
19    my $args  = shift;
20
21    my $clear_line = $args->{clear_line} || "\r\x1b[J";
22    my $executing  = $args->{executing}  || (
23       eval { require Term::ANSIColor } ? do {
24           my $c = \&Term::ANSIColor::color;
25           $c->('blink white on_black') . 'EXECUTING...' . $c->('reset');
26       } : 'EXECUTING...'
27    );
28    my $show_progress = $args->{show_progress};
29
30    my $squash_repeats = $args->{squash_repeats};
31    my $sqlat = SQL::Abstract::Tree->new($args);
32    my $self = $class->next::method(@_);
33    $self->_clear_line_str($clear_line);
34    $self->_executing_str($executing);
35    $self->_show_progress($show_progress);
36
37    $self->squash_repeats($squash_repeats);
38
39    $self->_sqlat($sqlat);
40    $self->_last_sql('');
41
42    return $self
43 }
44
45 sub print {
46   my $self = shift;
47   my $string = shift;
48   my $bindargs = shift || [];
49
50   my ($lw, $lr);
51   ($lw, $string, $lr) = $string =~ /^(\s*)(.+?)(\s*)$/s;
52
53   local $self->_sqlat->{fill_in_placeholders} = 0 if defined $bindargs
54     && defined $bindargs->[0] && $bindargs->[0] eq q('__BULK_INSERT__');
55
56   my $use_placeholders = !!$self->_sqlat->fill_in_placeholders;
57
58   my $sqlat = $self->_sqlat;
59   my $formatted;
60   if ($self->squash_repeats && $self->_last_sql eq $string) {
61      my ( $l, $r ) = @{ $sqlat->placeholder_surround };
62      $formatted = '... : ' . join(', ', map "$l$_$r", @$bindargs)
63   } else {
64      $self->_last_sql($string);
65      $formatted = $sqlat->format($string, $bindargs);
66      $formatted = "$formatted : " . join ', ', @{$bindargs}
67         unless $use_placeholders;
68   }
69
70   $self->next::method("$lw$formatted$lr", @_);
71 }
72
73 sub query_start {
74   my ($self, $string, @bind) = @_;
75
76   if(defined $self->callback) {
77     $string =~ m/^(\w+)/;
78     $self->callback->($1, "$string: ".join(', ', @bind)."\n");
79     return;
80   }
81
82   $string =~ s/\s+$//;
83
84   $self->print("$string\n", \@bind);
85
86   $self->debugfh->print($self->_executing_str) if $self->_show_progress
87 }
88
89 sub query_end {
90   $_[0]->debugfh->print($_[0]->_clear_line_str) if $_[0]->_show_progress
91 }
92
93 1;
94
95 =pod
96
97 =head1 NAME
98
99 DBIx::Class::Storage::Debug::PrettyPrint - Pretty Printing DebugObj
100
101 =head1 SYNOPSIS
102
103  DBIC_TRACE_PROFILE=~/dbic.json perl -Ilib ./foo.pl
104
105 Where dbic.json contains:
106
107  {
108    "profile":"console",
109    "show_progress":1,
110    "squash_repeats":1
111  }
112
113 =head1 METHODS
114
115 =head2 new
116
117  my $pp = DBIx::Class::Storage::Debug::PrettyPrint->new({
118    show_progress  => 1,             # tries it's best to make it clear that a SQL
119                                     # statement is still running
120    executing      => '...',         # the string that is added to the end of SQL
121                                     # if show_progress is on.  You probably don't
122                                     # need to set this
123    clear_line     => '<CR><ESC>[J', # the string used to erase the string added
124                                     # to SQL if show_progress is on.  Again, the
125                                     # default is probably good enough.
126
127    squash_repeats => 1,             # set to true to make repeated SQL queries
128                                     # be ellided and only show the new bind params
129    # any other args are passed through directly to SQL::Abstract::Tree
130  });
131
132