package XPatResultSet; # $Id: XPatResultSet.pm,v 1.3 2000/07/21 18:17:32 pagliere Exp $ # $Log: XPatResultSet.pm,v $ # Revision 1.3 2000/07/21 18:17:32 pagliere # New fisheye code here and everywhere. # # Revision 1.2 2000/07/20 15:18:15 pagliere # Added $byte (byte offset of result) to return from GetResult function. # # Revision 1.1 2000/07/05 15:35:33 pagliere # Moved from /l1/lib/t/text/ to /l1/lib # # Revision 1.9 2000/06/21 15:19:07 pagliere # Search history related changes. # # Revision 1.8 2000/06/14 19:52:40 pagliere # Fisheye link. Some new info inside XPatResultSet object. # # Revision 1.7 2000/05/17 21:50:21 pagliere # Now have named searchsets and resultsets # # Revision 1.6 2000/05/15 20:30:32 pagliere # Changes to reslist filtering. # # Revision 1.5 2000/05/09 00:16:34 pagliere # Filtering on Guide Frame. New "total" records and hits vars in CollsInfo # which were needed for the guide frame information. # # Revision 1.4 2000/05/04 20:51:03 pagliere # Removed creation of TextClass objects from CollsInfo object's initialize. It # is now not automatic (ww2-idx after all did not need TC objects). There is now, # however, a new AddTextClassObjects method for CollsInfo. # # Revision 1.3 2000/05/03 16:31:36 pagliere # Changed Interator sorting in XPatResults # Added configurable session file path in DlpsSesion.pm by way of DlpsSession.cfg # # Revision 1.2 2000/04/27 18:39:10 pagliere # Moved some general routines into DlpsUtils. Some new filtering in TextClass. # # Revision 1.1 2000/04/26 14:31:51 pfarber # *** empty log message *** # # Revision 1.1 2000/04/21 18:58:01 pagliere # Initial commit of TextClass lib files. # # Revision 1.2 2000/04/20 12:47:15 pagliere # Still debugging XPat results, but wanted to commit this before launching # into a move of Session creation code from main a DlpsSession.pm wrapper of # Apache::Session. # # Revision 1.1 2000/04/16 20:49:39 pagliere # Added interaction of TextClass, XPat. Changed XResults to XPatResultSet. # Need next to parse out parts of results inside XPatResultSet. # # XPatResultSet.pm set object package for containing results of searches use CGI qw( :standard :html3 escape unescape escapeHTML ); sub new { my $class = shift; my $self = {}; bless $self, $class; # $self->_initialize(@_); return $self; } #sub _initialize #{ # my $self = shift; #} # ---------------------------------------------------------------------- # NAME : AddResults # PURPOSE : adds an XPat result to this XPatResultSet object # CALLED BY : TextClass->SubmitSearchSet # CALLS : NONE # INPUT : result type (SSize, PSet or RSet), XPat result string, # label (original label sent when doing query) # RETURNS : NONE # GLOBALS : # SIDE-EFFECTS : affects XPatResultSet object # NOTES : # ---------------------------------------------------------------------- sub AddResults { my $self = shift; # type is SSize, PSet or RSet # result is sgml result from XPat # $label is same label as was sent by AddSearchSet # $cgi is optional; used to get slice and size values if needed my ( $type, $results, $label, $cgi ) = @_; if ( $type eq 'SSize' ) { $self->{'ssizesearches'}{$label} = $results; # keep track of total number of hits if ( $label =~ m,^firstsearch, ) { $self->SetTotalMatches( $results ); } if ( $label =~ m,^slicesearch, ) { $self->SetSliceAndSize( $cgi ); } if ( $label =~ m,^mainslicesearch, ) { $self->SetTotalRecords( $results ); } } elsif ( $type eq 'Error' ) { } # must be a PSet or RSet else { my @results = split ( //, $results ); foreach $item ( @results ) { # this code ripped out of Set2 as is, could be clearer! next if ( $item eq "" ); study( $item ); my( $start, $end, $rawsize, $raw, $hdrsize, $hdr ); if (($j = index($item, "")) != -1) { $start = substr($item, 0, $j); } if ((($i = index($item, "")) != -1) && (($j = index($item, "")) != -1)) { $end = substr($item, ($i + 5), ($j - ($i + 5))); } if ((($i = index($item, "")) != -1) && (($j = index($item, "")) != -1)) { $hdr = substr($item, ($j - 10), 10); $hdrsize = substr($item, ($i + 11), ($j - 17 - ($i + 11))); } if ( (($i = index($item, "")) != -1) && (($j = index($item, "", $i)) != -1) ) { $rawsize = substr($item, ($i + 11), ($j - ($i + 11))); } if (($j = index($item, "")) != -1) { $k = length($rawsize); $raw = substr($item, ($i + 18 + $k), ($j - ($i + 18 + $k))); } # design this conditional better... my $set = (); if ($hdr) { # it's a hdr type, a pset $self->{'setsearches'}{$label}{$start} = { 'start' => $start, 'hdrsize' => $hdrsize, 'hdr' => $hdr, 'rawsize' => $rawsize, 'raw' => $raw, 'type' => 'PSet Raw Hdr' }; } elsif ($start && $end) { # it's a region set of some kind $self->{'setsearches'}{$label}{$start} = { 'start' => $start, 'end' => $end, 'rawsize' => $rawsize, 'raw' => $raw, 'type' => 'RSet Raw' }; } else { # it's some kind of PSet... $self->{'setsearches'}{$label}{$start} = { 'start' => $start, 'rawsize' => $rawsize, 'raw' => $raw, 'type' => 'PSet Raw' }; } } } if ( $ENV{'DEBUG'} >= 2 ) { print qq{

Added to results set:

} . join ("
\n", ( $type, $label ) ) . "
\n"; } } # ---------------------------------------------------------------------- # NAME : InitIterator # PURPOSE : set up an order for the GetNextResult to work # CALLED BY : TextClass->Output # CALLS : # INPUT : # RETURNS : # GLOBALS : # SIDE-EFFECTS : # NOTES : This iterator currently is set up so that things are # ordered by byte offset order # ---------------------------------------------------------------------- # loop by label, # push all byte/label pairs into an array # then sort numeric by byte: sub InitIterator { my $self = shift; my @itemArray = (); foreach my $label ( keys % { $self->{'setsearches'} } ) { foreach $byte ( keys %{$self->{'setsearches'}{$label}} ) { push ( @itemArray, [ $label, $byte ] ); } } @itemArray = sort { $$a[1] <=> $$b[1] } @itemArray; $self->{'iterator'} = \@itemArray; $self->{'iteratorIndex'} = 0; } # ---------------------------------------------------------------------- # NAME : GetNextResult # PURPOSE : return next result in this XPatResultSet object in order # set up for Iterator # CALLED BY : # CALLS : # INPUT : # RETURNS : label sent with search and ref to results text # GLOBALS : # SIDE-EFFECTS : # NOTES : # ---------------------------------------------------------------------- sub GetNextResult { my $self = shift; my @itemArray = @ { $self->{'iterator'} }; my $index = $self->{'iteratorIndex'}; ## see if we are out of bounds if ( $index > scalar( @itemArray ) ) { return ( undef, undef ); } ## otherwise, all is okay return next item's information else { ## this should return a label and a byte offset ## it is a dereferencing of the anonymous array in each ## element of the @itemArray array my $labelBytePairRef = $itemArray[$index]; my ( $label, $byte ) = @$labelBytePairRef; my $resultText = $self->{'setsearches'}{$label}{$byte}{'raw'}; my @returnArray = ( $label, \$resultText, $byte ); # increment for next time $self->{'iteratorIndex'} += 1; return @returnArray; } } # ---------------------------------------------------------------------- # NAME : # PURPOSE : # # CALLED BY : # CALLS : # INPUT : # RETURNS : # GLOBALS : # SIDE-EFFECTS : # NOTES : # ---------------------------------------------------------------------- sub SniffNextResult { my $self = shift; my @itemArray = @ { $self->{'iterator'} }; my $index = $self->{'iteratorIndex'}; ## see if we are out of bounds if ( $index > scalar( @itemArray ) ) { return ( undef ); } ## otherwise, all is okay return next item's label ## without incrementing the index else { my $labelBytePairRef = $itemArray[$index]; my $label = $$labelBytePairRef[0]; return $label; } } # ---------------------------------------------------------------------- # NAME : GetMainSearchResult # PURPOSE : find the number of hits for a TextClass obj's result set # (indexed by 'firstsearch') # CALLED BY : # CALLS : # INPUT : # RETURNS : # GLOBALS : # SIDE-EFFECTS : # NOTES : # ---------------------------------------------------------------------- sub GetMainSearchResult { my $self = shift; my $sid = shift; my $index = 'firstsearch' . $sid; return $self->{'ssizesearches'}{$index}; } # ---------------------------------------------------------------------- # NAME : GetMainSubsetResult # PURPOSE : find the number of records with hits for a TextClass obj's result set # (indexed by 'mainslicesearch') # CALLED BY : # CALLS : # INPUT : # RETURNS : # GLOBALS : # SIDE-EFFECTS : # NOTES : # ---------------------------------------------------------------------- sub GetMainSubsetResult { my $self = shift; my $sid = shift; my $index = 'mainslicesearch' . $sid; return $self->{'ssizesearches'}{$index}; } # ---------------------------------------------------------------------- # NAME : GetNextLabeledResult # PURPOSE : return next result in this XPatResultSet object which is # labeled by the input label # CALLED BY : # CALLS : # INPUT : label # RETURNS : ref to results text # GLOBALS : # SIDE-EFFECTS : # NOTES : This does not change the index on the iterator # ---------------------------------------------------------------------- sub GetNextLabeledResult { my $self = shift; my $label = shift; my @itemArray = @ { $self->{'iterator'} }; my $index = $self->{'iteratorIndex'}; my $limit = scalar( @itemArray ); ## see if we are out of bounds if ( $index > $limit ) { return ( undef, undef ); } # make copy of index my $i; for ( $i = $index; $i <= $limit; $i++ ) { my $nextLabel = $self->SniffNextResult( ); if ( $nextLabel =~ m,$label, ) { ## this should return a label and a byte offset ## it is a dereferencing of the anonymous array in each ## element of the @itemArray array my $labelBytePairRef = $itemArray[$i]; my ( $label, $byte ) = @$labelBytePairRef; my $resultText = $self->{'setsearches'}{$label}{$byte}{'raw'}; return \$resultText; } } # if here, never found label return undef; } sub SetTotalMatches { my $self = shift; my $matches = shift; $self->{'stats'}{'totalmatches'} = $matches; } sub GetTotalMatches { my $self = shift; return $self->{'stats'}{'totalmatches'}; } sub SetTotalRecords { my $self = shift; my $records = shift; $self->{'stats'}{'totalrecords'} = $records; } sub GetTotalRecords { my $self = shift; return $self->{'stats'}{'totalrecords'}; } sub SetSliceAndSize { my $self = shift; my $cgi = shift; $self->{'stats'}{'slice'} = $cgi->param( 'slice' ); $self->{'stats'}{'slicesize'} = $cgi->param( 'size' ); $self->{'stats'}{'start'} = $cgi->param( 'start' ); } sub GetSliceAndSize { my $self = shift; my $slice = $self->{'stats'}{'slice'}; my $start = $self->{'stats'}{'start'}; my $size = $self->{'stats'}{'slicesize'}; return ( $slice, $size, $start ); } # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- 1;