improving formatting
Matt S Trout [Sat, 24 Aug 2019 02:16:50 +0000 (02:16 +0000)]
lib/SQL/Abstract.pm
lib/SQL/Abstract/Formatter.pm [new file with mode: 0644]
lib/SQL/Abstract/Parts.pm
maint/sqlacexpr

index 9bb6b9c..682139d 100644 (file)
@@ -1095,9 +1095,11 @@ sub _render_func {
   my ($func, @args) = @$rest;
   return $self->join_query_parts('',
     $self->_sqlcase($func),
-    '(',
-    $self->join_query_parts(', ', @args),
-    ')'
+    $self->join_query_parts('',
+      '(',
+      $self->join_query_parts(', ', @args),
+      ')'
+    ),
   );
 }
 
@@ -1171,9 +1173,11 @@ sub _render_op_in {
   return $self->join_query_parts(' ',
     $lhs,
     $self->format_keyword($op),
-    '(',
-    $self->join_query_parts(', ', @rhs),
-    ')'
+    $self->join_query_parts(' ',
+      '(',
+      $self->join_query_parts(', ', @rhs),
+      ')'
+    ),
   );
 }
 
@@ -1181,8 +1185,8 @@ sub _render_op_andor {
   my ($self, $op, $args) = @_;
   return undef unless @$args;
   return $self->join_query_parts('', $args->[0]) if @$args == 1;
-  return $self->join_query_parts(
-    ' ' => '(', $self->_render_op_multop($op, $args), ')'
+  return $self->join_query_parts(' ',
+    '(', $self->_render_op_multop($op, $args), ')'
   );
 }
 
diff --git a/lib/SQL/Abstract/Formatter.pm b/lib/SQL/Abstract/Formatter.pm
new file mode 100644 (file)
index 0000000..b3c70ed
--- /dev/null
@@ -0,0 +1,24 @@
+package SQL::Abstract::Formatter;
+
+require SQL::Abstract::Parts; # it loads us too, don't cross the streams
+
+use Moo;
+
+has indent_by => (is => 'ro', default => '  ');
+has max_width => (is => 'ro', default => 78);
+
+sub _join {
+  shift;
+  SQL::Abstract::Parts::stringify(\@_);
+}
+
+sub format {
+  my ($self, $join, @parts) = @_;
+::Dwarn [ J => $join => @parts ];
+  my $sql = $self->_join($join, @parts);
+  return $sql unless length($sql) > $self->max_width;
+  local $self->{max_width} = $self->{max_width} - length($self->indent_by);
+  return join("\n", map $self->format(@$_), @parts);
+}
+
+1;  
index 95f7069..dc8f25c 100644 (file)
@@ -1,19 +1,32 @@
 package SQL::Abstract::Parts;
 
+use Module::Runtime ();
+use Scalar::Util ();
 use strict;
 use warnings;
 
 use overload '""' => 'stringify', fallback => 1;
 
 sub new {
-  my ($proto, @args) = @_;
-  bless(\@args, ref($proto) || $proto);
+  my ($proto, $join, @parts) = @_;
+  bless([
+    $join, map Scalar::Util::blessed($_) ? [ @$_ ] : $_, @parts
+  ], ref($proto) || $proto);
 }
 
 sub stringify {
   my ($self) = @_;
   my ($join, @parts) = @$self;
-  return join $join, @parts;
+  return join $join, map ref() ? stringify($_) : $_, @parts;
+}
+
+sub to_array { return @{$_[0]} }
+
+sub format {
+  my ($self, %opts) = @_;
+  Module::Runtime::use_module('SQL::Abstract::Formatter')
+    ->new(%opts)
+    ->format($self->to_array);
 }
 
 1;
index e9cd322..827c808 100755 (executable)
@@ -4,10 +4,17 @@ use Devel::DDCWarn;
 
 warn $ARGV[1];
 
-my $sqlac = SQL::Abstract::ExtraClauses->new(unknown_unop_always_func => 1);
+my $sqlac = SQL::Abstract::ExtraClauses->new(
+  unknown_unop_always_func => 1,
+  lazy_join_sql_parts => 1,
+);
 
 my @args = ($ARGV[1] =~ /^\.\// ? do $ARGV[1] : eval '+('.$ARGV[1].')');
 
 die $@ if $@;
 
-Dwarn([ $sqlac->${\$ARGV[0]}(@args) ]);
+my ($q, @bind) = $sqlac->${\$ARGV[0]}(@args);
+
+Dwarn [ Q => @$q ];
+
+Dwarn [ $q->format, @bind ];