On Sun, Jul 11, 2010 at 10:45 PM, redtigra <redti...@gmail.com> wrote:

> Folks,
>
> would you please explain me one string of code I could node
> understand?
> Here it is:
> $ perl -ne 'chomp; $fmt = "%-10s  %-10s  %s\n";
> >           if ($ARGV eq "name") {$x{$_}++}
> >           elsif (/^ALTER TABLE (.*)/ and defined $x{$1}) {$in=1; $tbl=$1}
> >           elsif ($in and /^ADD\s*\(\s*(\w+)\s*(.*?),/)
> {printf($fmt,$tbl,$1,$2)}
> >           elsif ($in and /^\s*(\w+)\s*(.*?)\s*\);/)
> {printf($fmt,$tbl,$1,$2)}
> >           elsif (/^\s*$/) {$in=0}
> >          ' name temp
>
> (here is the whole story:
> http://www.unix.com/shell-programming-scripting/139870-shell-script-using-loop-3.html
> ).
>
> Loop happens because of -n switch, correct?
>
> Could you please explain me that part:
> >           if ($ARGV eq "name") {$x{$_}++} - what happens here? And what
> is $in for?
>
> Thanks a lot in advance
>
> RT
>
>
> --
> To unsubscribe, e-mail: beginners-unsubscr...@perl.org
> For additional commands, e-mail: beginners-h...@perl.org
> http://learn.perl.org/
>
>
> Ok, lets see if we can work this out...

First of all let me just say I don't like the code it is really ugly and
quite confusing (typical DBA style coding ;-)

So we read the input files name and temp in a loop that much is clear from
the -n command.

The formatting of the output is done is done in the first string ($fmt).
Then it gets icky...
if ( $ARGV eq "name" { $x{$_}++ # Does nothing else then say if the file
name we are reading is called 'name' add to the hash %x a key called (what
ever is in $_ the first line in the file 'name' in this case) with the value
1.
elsif (/^ALTER TABLE (.*)/ and defined $x{$1} ) {$in=1; $tbl=$1} # clearly
the file name is not: 'name' so it must be relating to the file 'temp' where
we check if the first line contains a string starting with ALTER TABLE and
we have in the hash %x a key which is equal to the text captured with the
(.*) part of the regex, in that case we set $in=1 and $tbl=the captured
text;
elsif ($in and /^ADD\s*\(\s*(\w+)\s*(.*?),/) {printf($fmt,$tbl,$1,$2)} # So
we are still in the file 'temp' but the line does not start with ALTER TABLE
if it does start with ADD and $in is set to 1 (meaning this is a alter table
statement that we want to print) we caputre the collumn name ($1) and the
column type ($2) and print formated according to the $fmt string the values
of $tbl, $1, $2.
elsif ($in and /^\s*(\w+)\s*(.*?)\s*\);/) {printf($fmt,$tbl,$1,$2)} # We are
still in the file temp but now the line doesn't start with ALTER TABLE or
with ADD in that case we capture $1 and $2 and again print the same as
before foramted according to the $fmt string.
elsif (/^\s*$/) {$in=0} # else we set $in to 0.

The script is cool but it will trip on many things like a accidental ADd or
Alter Table which are still completely valid bits of SQL code, maybe not
pretty but they will cause you issues if you do not at the very least make
your regular expressions case insensitive. The other problem is what will
happen when someone is nice enough to want to use a different file name then
name (the second file name is not filtered for so that should be ok. If you
want to have a decent solution that others can understand and read put this
in a small script where you add comments and make sure that the file names
do not matter by using for instance a -names <filename> and -SQL <filename>
option so that the order and the naming are no longer possible problems. Of
course you will be using strict and warnings as well but I assume that you
have seen that so often mentioned that you will already have a default
template for starting of perl scripts that include these two modules
automatically ;-)

Rob

Reply via email to