--- loncom/interface/lonsearchcat.pm 2001/03/19 16:45:38 1.41 +++ loncom/interface/lonsearchcat.pm 2001/03/20 17:49:03 1.44 @@ -2,6 +2,8 @@ # Search Catalog # # 03/08/2001 Scott Harrison +# Scott Harrison: 03/12/2001, 03/13/2001, 03/14/2001, 03/15/2001, 03/19/2001 +# Scott Harrison: 03/20/2001 # # Functions # @@ -18,14 +20,22 @@ # for a calendar date # selectbox(title,name,value,%HASH=options) : returns HTML formatted string for # a selection box field -# advancedsearch() : +# advancedsearch(server reference, environment reference) : perform a complex +# multi-field logical query # filled(field) : determines whether a given field has been filled -# basicsearch() : -# output_blank_field_error() : outputs a message saying that more fields need -# to be filled in -# output_results() : outputs results from search -# build_SQL_query() : builds a SQL query string from a logical expression -# with AND/OR keywords +# basicsearch(server reference, environment reference) : perform a simple +# single-field logical query +# output_blank_field_error(server reference) : outputs a message saying that +# more fields need to be filled in +# output_results(output mode, +# server reference, +# environment reference, +# reply list reference) : outputs results from search +# build_SQL_query(field name, logic) : builds a SQL query string from a +# logical expression with AND/OR keywords +# recursive_SQL_query_build(field name, reverse notation expression) : +# builds a SQL query string from a reverse notation expression +# logical expression with AND/OR keywords package Apache::lonsearchcat; @@ -458,13 +468,23 @@ sub advancedsearch { } my $query=''; + + my $testquery=''; + # Go through logical expression AND/OR/NOT phrase fields. + foreach my $field ('title','author','subject','notes','abstract') { + if ($ENV{'form.'.$field}) { + $testquery=build_SQL_query($field,$ENV{'form.'.$field}); + } + } + # my $concatarg=join('," ",', # ('title', 'author', 'subject', 'notes', 'abstract')); - $query="select * from metadata where concat(title) like '\%$ENV{'form.title'}\%'"; + $query="select * from metadata where $testquery"; + my $reply=&Apache::lonnet::metadata_query($query); - &output_results($r,$envhash,$reply); + &output_results('Advanced',$r,$envhash,$query,$reply); return OK; } @@ -495,10 +515,11 @@ sub basicsearch { $query="select * from metadata where concat($concatarg) like '\%$ENV{'form.basicexp'}\%'"; my $reply=&Apache::lonnet::metadata_query($query); - &output_results($r,$envhash,$reply); + &output_results('Basic',$r,$envhash,$query,$reply); return OK; } +# ---------------- Message to output when there are not enough fields filled in sub output_blank_field_error { my ($r)=@_; # make query information persistent to allow for subsequent revision @@ -545,8 +566,10 @@ RESULTS # ----------------------------- format and output results based on a reply list sub output_results { - my ($r,$envhash,@replylist)=@_; + my ($mode,$r,$envhash,$query,@replylist)=@_; my %ENV=%{$envhash}; + my $compiledresult=''; + foreach my $reply (@replylist) { my @results; @@ -569,8 +592,6 @@ sub output_results { @results=<$fh>; } - my $compiledresult=''; - foreach my $result (@results) { my ($title,$author,$subject,$url,$keywords,$version, $notes,$abstract,$mime,$lang, @@ -660,9 +681,23 @@ onClick='self.close();'> $persistent

Search Query

+RESULTS + if ($mode eq 'Basic') { + $r->print(< Basic search: $ENV{'form.basicexp'}

+RESULTS + } + elsif ($mode eq 'Advanced') { + $r->print(< +Advanced search +$query +

+RESULTS + } + $r->print(<Search Results $compiledresult @@ -673,7 +708,43 @@ RESULTS # ------------------------------------------------------------- build_SQL_query sub build_SQL_query { - + my ($field_name,$logic_statement)=@_; + my $q=new Text::Query('abc', + -parse => 'Text::Query::ParseAdvanced', + -build => 'Text::Query::Build'); + $q->prepare($logic_statement); + my $matchexp=${$q}{'matchexp'}; chomp $matchexp; + my $sql_query=&recursive_SQL_query_build($field_name,$matchexp); + return $sql_query; +} + +# - Recursively parse a reverse notation expression into a SQL query expression +sub recursive_SQL_query_build { + my ($dkey,$pattern)=@_; + my @matches=($pattern=~/(\[[^\]|\[]*\])/g); + return $pattern unless @matches; + foreach my $match (@matches) { + $match=~/\[ (\w+)\s(.*) \]/; + my ($key,$value)=($1,$2); + my $replacement=''; + if ($key eq 'literal') { + $replacement="($dkey like \"\%$value\%\")"; + } + elsif ($key eq 'and') { + $value=~/(.*[\"|\)]) ([|\(|\^].*)/; + $replacement="($1 AND $2)"; + } + elsif ($key eq 'or') { + $value=~/(.*[\"|\)]) ([|\(|\^].*)/; + $replacement="($1 OR $2)"; + } + substr($pattern, + index($pattern,$match), + length($match), + $replacement + ); + } + &recursive_SQL_query_build($dkey,$pattern); } 1;