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

Hello:

Running database driven search system. Right now, I'm testing the search function.

#!/usr/bin/perl -w use strict; use Fcntl; use DBI; use File::Basename; use Text::English; #input Words print "Give a list of words:\n\n"; my $query = <STDIN>; my @words = split /\s*(,|\s+)/, $query; #File Type: print "Give a file type (email, article):\n\n"; my $type = <STDIN>; my %paths = search(\@words, $type); for my $val (keys %paths) { my $file = $paths{$val}; print "$file \n"; } sub search { my($words, $type) = @_; my($dbh, $sth1, $sth2, $rule_append, $word, $file_index); my %matches; #Database Connection: $dbh = DBI->connect( "DBI:mysql:host=localhost;database=testd +b", "testuser", "testpass", {PrintError=>0,RaiseError= +>1}); #Establish Rules for file type: CASE: { if(type == 'email') { $rule_append = "where filetype = 'email' "; last CASE; } if(type == 'article') { $rule_append = "where filetype = 'article' "; last CASE; } $rule_append = "where filetype = 'article' OR filetype + = 'email' "; }#End of Rule foreach $word(@$words) { my $match; my $stem = Text::English::stem($word); #round 1: Find all file pertaining to word. my $statement1 = "SELECT files FROM catalog WHERE word +s LIKE %".$stem."%"; $sth1 = $dbh -> prepare($statement1); $sth1 -> execute(); while(my @val = $sth1 -> fetchrow_array()) { $match = $val[0] #Get List of files. #Parse Files and Check for matches within. my (@poss) = split(/:/, $match); foreach $file_index(@poss) { $sth2 = $dbh ->prepare("select filenam +e, type from library where filename + = $file_index and".$rule_app +end); $sth2 -> execute(); if(my @val2 = $sth2->fetchrow_array()) { $matches{$val2[0]} = $val2[1] +; } } # All Relevant Files found. }# Cycle through all possible matches. } #End of word search loop return(%matches); #$dbh -> disconnect; }#End of search Function

here is are the errors:

syntax error at search.pl line 77, near "my " Global symbol "@poss" requires explicit package name at search.pl line + 77. Global symbol "@poss" requires explicit package name at search.pl line + 78. Execution of search.pl aborted due to compilation errors.

Any suggestion? - Cappa

GrandFather removed tr tags and readmore tags added

Replies are listed 'Best First'.
Re: Trying to Debug DB Search
by Tanktalus (Canon) on Oct 26, 2005 at 23:10 UTC

    Any time you have a syntax error that you can't figure out, check the previous line for a missing semicolon. In your case, that's what it is: "$match = $val[0];".

Re: Trying to Debug DB Search
by samtregar (Abbot) on Oct 26, 2005 at 23:10 UTC
    I would look for the syntax error on line 77 and fix it. I can't easily tell which one that is but I'm sure your editor can. Or was there something about the error message you didn't understand?

    -sam

Re: Trying to Debug DB Search
by Cappadonna3030 (Sexton) on Oct 26, 2005 at 23:38 UTC
    Alright:

    I did a little snooping and tweaked my code:

    #!/usr/bin/perl -w use strict; use Fcntl; use DBI; use File::Basename; use Text::English; #input Words print "Give a list of words:\n\n"; my $query = <STDIN>; my @words = split /\s*(,|\s+)/, $query; #File Type: print "Give a file type (email, article):\n\n"; my $type = <STDIN>; my %paths = search(\@words, $type); for my $val (keys %paths) { my $file = $paths{$val}; print "$file \n"; } sub search { my($words, $type) = @_; my($dbh, $sth1, $sth2, $rule_append, $word, $file_index); my %matches; #Database Connection: $dbh = DBI->connect( "DBI:mysql:host=localhost;database=test" +, "test", "test", {PrintError=>0,RaiseError=>1}); #Establish Rules for file type: CASE: { if($type = "email") { $rule_append = "where filetype = 'email' "; last CASE; } if($type = "article") { $rule_append = "where filetype = 'article' "; last CASE; } $rule_append = "where filetype = 'article' OR filetype + = 'email' "; }#End of Rule foreach $word(@$words) { my $match; ( $word ) = Text::English::stem( $word ); my @poss; #round 1: Find all file pertaining to word. my $statement1 = "SELECT files FROM catalog WHERE word +s LIKE %".$word."%"; $sth1 = $dbh -> prepare($statement1); $sth1 -> execute(); while(my @val = $sth1 -> fetchrow_array()) { $match = $val[0]; #Get List of files. #Parse Files and Check for matches within. @poss = split(/:/, $match); foreach $file_index(@poss) { $sth2 = $dbh ->prepare("select filenam +e, type from library where filename + = $file_index and".$rule_app +end); $sth2 -> execute(); if(my @val2 = $sth2->fetchrow_array()) { $matches{$val2[0]} = $val2[1] +; } } # All Relevant Files found. }# Cycle through all possible matches. } #End of word search loop return(%matches); #$dbh -> disconnect; }#End of search Function

    Now I get these errors:

    Undefined subroutine &Text::English::stem called at search.pl line 64, + <STDIN> line 2. Issuing rollback() for database handle being DESTROY'd without explici +t disconnect(), <STDIN> line 2.

    However, I know that the English stem module is installed, as I have used it before. Any ideas?

      One mistake I see in your code is this:
      my @words = split /\s*(,|\s+)/, $query;
      I think you want:
      my @words = split /\s*(?:,|\s+)/, $query;
      If you have capturing parens in your split regex, what they capture gets returned also! You don't want commas and whitespace in your @words array, do you? As for the Text::English problem, I can't figure out why the module would load without incident but stem() not exist.

      Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
      How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
        Turns out that someone removed the English pm from my server. I put it back. (I'm the programmer, its my party.) Now it fails on the email searches.
Re: Trying to Debug DB Search
by Cappadonna3030 (Sexton) on Oct 27, 2005 at 02:15 UTC

    Here is the revised code:

    #!/usr/bin/perl -w use strict; use Fcntl; use DBI; use File::Basename; use Text::English; #input Words print "Give a list of words:\t"; my $query = <STDIN>; my @words = split(/\s*(?:,|\s+)/, $query); #File Type: print "Give a file type (email, article):\t"; my $type = <STDIN>; my %paths = search(\@words, $type); for my $val (keys %paths) { my $ft = $paths{$val}; print "$ft : $val \n"; } sub search { my($words, $type) = @_; my($dbh, $sth1, $sth2, $rule_append, $word, $file_index); my %matches; #Database Connection: $dbh = DBI->connect( "DBI:mysql:host=localhost;database=testd +b", "testuser", "testpass", {PrintError=>0,RaiseError= +>1}); #Establish Rules for file type: CASE: { if($type eq "email") { $rule_append = "filetype = \"email\" "; last CASE; } if($type eq "article") { $rule_append = "filetype = \"article\" "; last CASE; } $rule_append = "filetype = \"article\" OR \"email\" " +; }#End of Rule foreach $word(@$words) { my $match; ( $word ) = Text::English::stem( $word ); my @poss; #round 1: Find all file pertaining to word. my $statement1 = "SELECT files FROM catalog WHERE word + LIKE \"%$word%\" "; $sth1 = $dbh -> prepare($statement1); $sth1 -> execute(); while(my @val = $sth1 -> fetchrow_array()) { $match = $val[0]; #Get List of files. #Parse Files and Check for matches within. @poss = split(/:/, $match); foreach $file_index(@poss) { $sth2 = $dbh ->prepare("select filenam +e, filetype from library where filename + like \"%$file_index%\" and ".$rule_ap +pend); $sth2 -> execute(); if(my @val2 = $sth2->fetchrow_array()) { $matches{$val2[0]} = $val2[1] +; } } # All Relevant Files found. }# Cycle through all possible matches. } #End of word search loop return(%matches); #$dbh -> disconnect; }#End of search Function

    Now, it runs through the DB w/o a problem, but now it dies on the search itself.

    Give a list of words: test,diamonds,perl Give a file type (email, article): article Issuing rollback() for database handle being DESTROY'd without explici +t disconnect() at search.pl line 26, <STDIN> line 2.