DEV Community

Query Filter
Query Filter

Posted on

perl3

!/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 = ;
}
}

Keywords to break onto new lines and uppercase

my @newline_keywords = (
'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 spaces

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

Add newlines before keywords (case-insensitive)

foreach my $word (@newline_keywords) {
my $pattern = quotemeta($word);
$sql =~ s/\b$pattern\b/\n$word/ig;
}

Uppercase keywords safely (case-insensitive)

foreach my $word (@newline_keywords) {
my $lcword = lc($word);
$sql =~ s/\b$lcword\b/\U$word\E/ig;
}

Split lines and indent parentheses

my @lines = split /\n+/, $sql;
my $indent = 0;
my @out;

foreach 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;
}

Trim leading/trailing spaces on each line

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

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

Top comments (0)