8a8c6597db6a52292d585a339c80b578c144286a
[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\e[J";
22    my $executing  = $args->{executing}  || eval { require Term::ANSIColor } ? do {
23        my $c = \&Term::ANSIColor::color;
24        $c->('blink white on_black') . 'EXECUTING...' . $c->('reset');;
25    } : 'EXECUTING...';
26    my $show_progress = $args->{show_progress};
27
28    my $squash_repeats = $args->{squash_repeats};
29    my $sqlat = SQL::Abstract::Tree->new($args);
30    my $self = $class->next::method(@_);
31    $self->_clear_line_str($clear_line);
32    $self->_executing_str($executing);
33    $self->_show_progress($show_progress);
34
35    $self->squash_repeats($squash_repeats);
36
37    $self->_sqlat($sqlat);
38    $self->_last_sql('');
39
40    return $self
41 }
42
43 sub print {
44   my $self = shift;
45   my $string = shift;
46   my $bindargs = shift || [];
47
48   my ($lw, $lr);
49   ($lw, $string, $lr) = $string =~ /^(\s*)(.+?)(\s*)$/s;
50
51   local $self->_sqlat->{fill_in_placeholders} = 0 if defined $bindargs
52     && defined $bindargs->[0] && $bindargs->[0] eq q('__BULK_INSERT__');
53
54   my $use_placeholders = !!$self->_sqlat->fill_in_placeholders;
55
56   # DBIC pre-quotes bindargs
57   $bindargs = [map { s/^'//; s/'$//; $_ } @{$bindargs}] if $use_placeholders;
58
59   my $sqlat = $self->_sqlat;
60   my $formatted;
61   if ($self->squash_repeats && $self->_last_sql eq $string) {
62      my ( $l, $r ) = @{ $sqlat->placeholder_surround };
63      $formatted = '... : ' . join(', ', map "$l$_$r", @$bindargs) . "\n";
64   } else {
65      $self->_last_sql($string);
66      $formatted = $sqlat->format($string, $bindargs) . "\n";
67      $formatted = "$formatted: " . join ', ', @{$bindargs}
68         unless $use_placeholders;
69   }
70
71   $self->next::method("$lw$formatted$lr", @_);
72 }
73
74 sub query_start {
75   my ($self, $string, @bind) = @_;
76
77   if(defined $self->callback) {
78     $string =~ m/^(\w+)/;
79     $self->callback->($1, "$string: ".join(', ', @bind)."\n");
80     return;
81   }
82
83   $string =~ s/\s+$//;
84
85   $self->print("$string\n", \@bind);
86
87   $self->debugfh->print($self->_executing_str) if $self->_show_progress
88 }
89
90 sub query_end {
91   $_[0]->debugfh->print($_[0]->_clear_line_str) if $_[0]->_show_progress
92 }
93
94 1;
95
96 =pod
97
98 =head1 SYNOPSIS
99
100  package MyApp::Schema;
101
102  use parent 'DBIx::Class::Schema';
103
104  use DBIx::Class::Storage::Debug::PrettyPrint;
105
106  __PACKAGE__->load_namespaces;
107
108  my $pp = DBIx::Class::Storage::Debug::PrettyPrint->new({
109    profile => 'console',
110  });
111
112  sub connection {
113    my $self = shift;
114
115    my $ret = $self->next::method(@_);
116
117    $self->storage->debugobj($pp);
118
119    $ret
120  }
121