On Mon, 12 Apr 1999 10:59:13 -0400 Richard Gordon <maccgi@bellsouth.net> wrote: >2. Second, it's very likely that a user is going to turn up more than >20-30 hits when a search occurs and I would like to provide an option >to limit the number of hits displayed per page. Looking at some of >the portals and trying to guess how they approach this has not been >very productive and I was wondering if anyone has either figured this >out? Do you write the first 20 (or whatever) to STDOUT, then start >writing to temporary text files? That sounds like it would really >suck for various reasons, not the least of which is getting rid of >all those files at some point, but I don't know. Any thoughts? WARNING: If you prefer to avoid object-oriented Perl, then this isn't for you... My solution to a similar problem (not in Perl orginally, but I'll do a rough translation) has been to implement an iterator class that can be "frozen" and "thawed". As someone else suggested, you'll keep track of what files still need to be searched and of your current offset in the current file. While your script is running, that info will exist in the form of an object. The replies you send back will include a "frozen" copy of the object -- i.e., a URL-safe string in the form of a param in the URL Say you're given a request with the following params: search_term=foobar num_matches_per_page=20 You construct an iterator whose job it is to search through the files, come up with the first 20 matches, and return an HTML file containing a link to pull up the next 20 matches; this link will contain the iterator in a "frozen" state. When the user follows this link, you'll "thaw" the iterator and resume the searching where it left off. The finished CGI script will look like something like this... # WARNING: Don't try to use this as is. I haven't actually written # any Perl CGIs, so this may be a little off. I haven't tried to # compile or run it, and there isn't even any error checking. # ... Write the beginning of the HTML file here ... my $iter; if exists($param{iterator}) { $iter = My::Search::Iterator->thaw ($param{iterator}); } else { $iter = My::Search::Iterator->new ( $param{search_term}, $param{num_matches_per_page} || 20 ); $iter->first(); } while (!$iter->all_done()) { my $match = $iter->cur(); # returns an object, a hash, or whatever $iter->next(); # ... Write the info for the match here ... } my $frozen_iter = $iter->freeze(); my $next_batch_url = "/...whatever...?iterator=$frozen_iter" # ... Write the end of the HTML file here ... The code for the My::Search::Iterator class will look something like this: package My::Search::Iterator; sub new { my ($class, $search_term, $n) = @_; bless { search_term => $search_term, num_matches_per_page => $n, files_remaining => [ ... ], # Files still to be searched cur_offset => 0, all_done => undef }, $class; } sub first { my $self = shift; # Find the first match ... } sub all_done { my $self = shift; return $self->{all_done}; } sub cur { my $self = shift; # Return the current match ... # This can be in the form of a string, a hash, an object, # etc. -- whatever you want it to be. } sub next { my $self = shift; # Continue searching ... } sub freeze { return url_encode ( join ("\n", $self->{search_term}, $self->{num_matches_per_page}, join("\t", $self->{files_remaining}), $self->{cur_offset}, $self->{all_done} ) ); } sub thaw { my $class = shift; my @frozen_attributes = split("\n", url_decode(shift)); bless { search_term => $frozen_attributes[0], num_matches_per_page => $frozen_attributes[1], files_remaining => split("\t", $frozen_attributes[2]), cur_offset => $frozen_attributes[3], all_done => $frozen_attributes[4] }, $class; } One advantage of this approach is that you can change the way iterators are implemented without changing your HTML-generating code. This way you can later eschew the file-and-offset paradigm altogether in favor of more sophisticated iteration -- e.g., allowing the user to choose how the results are to be sorted. HTH, Paul. -- Paul Hoffman :: Taubman Medical Library :: Univ. of Michigan nkuitse@umich.edu :: http://www-personal.umich.edu/~nkuitse/ ==== Want to unsubscribe from this list? ==== Send mail with body "unsubscribe" to macperl-webcgi-request@macperl.org