cens has asked for the wisdom of the Perl Monks concerning the following question:

I think there is a way to do this, but I am having a hard time finding someone who as already asked this. Basically I have a huge SQL table schema, and I am trying to identify certian table the structure of the file looks like this:

{ TABLE "foo".bar row size = 50 number of columns = 5 index size = 25 +} create table "foo".bar ( var1 char(3) not null constraint "foo".n676_5452, var2 char(3) not null constraint "foo".n676_5453, var3 date not null constraint "foo".n676_5454, _rcd smallint default 0 not null ); revoke all on "foo".bar from "public";

What I want to do is to grab the name of the table (bar) and then look through the table declaration section to determine how many variables there are and which vars are in there. The problem is that I don't think I have the control over the file handle to walk back and forth through the file. This is what I have so far:

$file_name = @ARGV[0]; open (SCHEMA, $file_name); open (BIGLIST, ">>table_names.txt"); open (SMALLLIST, ">>refined_tbl_name.txt"); #open the file while(<SCHEMA>) { $line = $_; #is this a line that declares a new table? if ($line =~ /create table \".+?\"\.(.+?)$/mos) { #if so, print the name into a list print BIGLIST "$1 \n"; #create a new variable that has the name $table_nm = $1; } }
At this point, I basically want to say
while ($line ne ')') { $line_cnt++; if ($line =~ /$var_of_interest/) {$keep = 1}; } if ($line_cnt > $n and $keep == 1} then {$table_hash{$table_nm} = 1;}
However, this does not even come close to working very well. Because It can only work if $line is between the two parentheses. Is there a way to look ahead into the file? I can't figure it out, and the camel book is at home. Any pointers would be appreciated.

Thanks a lot.

Replies are listed 'Best First'.
Re: Look Ahead/Behind Via a File Handle
by Zaxo (Archbishop) on Aug 11, 2003 at 21:29 UTC
Re: Look Ahead/Behind Via a File Handle
by graff (Chancellor) on Aug 12, 2003 at 04:22 UTC
    If you have the module that Zaxo mentioned, try using it; if not, try installing it; if that fails, try again.

    But if you really have a problem with the module, and you think your task shouldn't be that much work (or you don't have time), you could consider the following approach:

    Assuming the huge schema file is written in a consistent manner (suggested by your examples), there are bound to be semicolons at the end of every statement, and end-of-statement is bound to be the only place where semicolon is followed by newline, so use the "input record separator" variable in perl to read a whole statement at a time:

    { $/ = ";\n"; while (<SCHEMA>) { # everything up to/including the next ";\n" has been read into $_ s/\s+/ /g; # normalize all white space to " " if ( /create table (\S+)/ ) { # table definition statement my $tablename = $1; ... } ... } }
Re: Look Ahead/Behind Via a File Handle
by benn (Vicar) on Aug 11, 2003 at 23:32 UTC
    As Zaxo says, using SQL::Statement, or a parsing module of some kind may be easier, but I think your problem could be solved simply using another 'inner' read...something like this (untested!).
    while (my $line = <SCHEMA>) { if ($line =~/create table \".+?\"\.(.+?)$/mos) { $table_nm = $1; print BIGLIST "$1 \n"; my $keep = 0; while ($line = <SCHEMA> && $line ne ')') { $table_hash{$table_nm} = 1 if ($line =~ /$var_of_interest/); } } }
    Cheers,
    Ben.