!/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 put on new lines
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 spacing
$sql =~ s/[\r\n]+/ /g;
$sql =~ s/\s+/ /g;
Add newlines before keywords (case-insensitive)
for my $kw (@newline_keywords) {
my $pattern = quotemeta($kw);
$sql =~ s/\b$pattern\b/\n$kw/ig;
}
Uppercase all SQL keywords safely
for my $kw (@newline_keywords) {
my $pattern = quotemeta(lc($kw));
$sql =~ s/\b$pattern\b/uc($1)/ieg if $sql =~ /$pattern/i;
}
Split into lines
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;
}
Trim whitespace
for (@out) {
s/^\s+//;
s/\s+$//;
}
print join("\n", @out), "\n";
Top comments (0)