Commit | Line | Data |
b3b54441 |
1 | package SQL::Abstract::Formatter; |
2 | |
3 | require SQL::Abstract::Parts; # it loads us too, don't cross the streams |
4 | |
5 | use Moo; |
6 | |
7 | has indent_by => (is => 'ro', default => ' '); |
8 | has max_width => (is => 'ro', default => 78); |
9 | |
10 | sub _join { |
11 | shift; |
07070f1a |
12 | ::Dwarn [ JOIN => @_ ]; |
13 | return ::Dwarn SQL::Abstract::Parts::stringify(\@_); |
b3b54441 |
14 | } |
15 | |
16 | sub format { |
17 | my ($self, $join, @parts) = @_; |
07070f1a |
18 | $self->_fold_sql('', '', @{$self->_simplify($join, @parts)}); |
19 | } |
20 | |
21 | sub _simplify { |
22 | my ($self, $join, @parts) = @_; |
23 | return '' unless @parts; |
24 | return $parts[0] if @parts == 1 and !ref($parts[0]); |
25 | return $self->_simplify(@{$parts[0]}) if @parts == 1; |
26 | return [ $join, map ref() ? $self->_simplify(@$_) : $_, @parts ]; |
27 | } |
28 | |
29 | sub _fold_sql { |
30 | ::Dwarn \@_; |
31 | my ($self, $indent0, $indent, $join, @parts) = @_; |
32 | my @res; |
33 | my $w = $self->max_width; |
34 | my $join_len = 0; |
35 | (s/, \Z/,\n/ and $join_len = 1) |
36 | or s/\A /\n/ |
37 | or $_ = "\n" |
38 | for my $line_join = $join; |
39 | my ($nl_pre, $nl_post) = split "\n", $line_join; |
40 | my $line = $indent0; |
41 | my $next_indent = $indent.$self->indent_by; |
42 | PART: foreach my $idx (0..$#parts) { |
43 | ::Dwarn [ PARTSTART => $idx, \@parts, $line, \@res ]; |
44 | my $p = $parts[$idx]; |
45 | my $pre = $idx ? $join : ''; |
46 | my $j_part = $pre.(my $j = ref($p) ? $self->_join(@$p) : $p); |
47 | if (length($j_part) + length($line) + $join_len <= $w) { |
48 | $line .= $j_part; |
49 | } else { |
50 | push @res, $line.$nl_pre."\n"; |
51 | if (length($line = $indent.$nl_post.$j) <= $w) { |
52 | next PART; |
53 | } |
54 | my $folded = $self->_fold_sql($indent, $next_indent, @$p); |
55 | push @res, $folded.$pre."\n"; |
56 | $line = $indent.$nl_post; |
57 | } |
58 | ::Dwarn [ PART => $idx => $line => $j_part => \@res ]; |
59 | } |
60 | return +(::Dwarn [ join '', @res, $line ])->[0]; |
b3b54441 |
61 | } |
62 | |
63 | 1; |