DEV Community

Query Filter
Query Filter

Posted on

perl

!/usr/bin/perl

use strict;
use warnings;

Read full SQL from stdin or file

my $sql;
{
local $/;
if (-t STDIN) {
my $file = shift @ARGV or die "Usage: $0 \n";
open my $fh, '<', $file or die "Cannot open $file: $!";
$sql = <$fh>;
close $fh;
} else {
$sql = ;
}
}

List of keywords to uppercase and break before

my @newline_keywords = qw(
SELECT FROM WHERE GROUP BY HAVING ORDER BY UNION
JOIN LEFT JOIN RIGHT JOIN INNER JOIN OUTER JOIN
AND OR ON INTO VALUES SET WHEN ELSE END
);

Normalize spacing

$sql =~ s/[\r\n]+/ /g;
$sql =~ s/\s+/ /g;

Add newlines before keywords (case-insensitive)

for my $kw (@newline_keywords) {
$sql =~ s/\b$kw\b/\n$kw/ig;
}

Uppercase SQL keywords

$sql =~ s/\b($_)\b/uc($1)/ieg for @newline_keywords;

Indentation based on parentheses

my @lines = split /\n+/, $sql;
my $indent = 0;
my @out;
for my $line (@lines) {
my $opens = ($line =~ tr/(//);
my $closes = ($line =~ tr/)//);
$indent-- if $closes > $opens;
push @out, (' ' x ($indent > 0 ? $indent : 0)) . $line;
$indent++ if $opens > $closes;
}

Clean up spaces

for (@out) {
s/^\s+//;
s/\s+$//;
}

print join("\n", @out), "\n";

Top comments (0)