# ==================================================================== # Gossamer Threads Module Library - http://gossamer-threads.com/ # # GT::SQL::Search::STH # Author: Aki Mimoto # CVS Info : 087,071,086,086,085 # CVS Info : 087,071,086,086,085 # $Id: STH.pm,v 1.1 2006/12/07 07:04:51 aki Exp $ # # Copyright (c) 2004 Gossamer Threads Inc. All Rights Reserved. # ==================================================================== # package GT::SQL::Search::LUCENE::STH; #-------------------------------------------------------------------------------- use strict; use vars qw/@ISA $ATTRIBS $VERSION $DEBUG $ERRORS $ERROR_MESSAGE /; require GT::SQL::Search::Base::STH; @ISA = ('GT::SQL::Search::STH'); $ATTRIBS = { 'db_sort' => 1, 'hits' => undef }; $ERROR_MESSAGE = 'GT::SQL::Search::STH'; sub init { #-------------------------------------------------------------------------------- # GT::SQL::Search::STH expects a full set of results in $self->{results}. For # Lucene the only time a full set of results is there is when we are sorting # on a field that is not weighted, otherwise the results in $self->{results} is # the proper page and number of results. my $self = shift; $self->set(@_); --$self->{nh} if $self->{nh}; # Here we allow hits to override our concept of rows. This is only useful # when !$self->{db_sort} $self->{rows} = $self->{hits} ? $self->{hits} : $self->{results} ? scalar(keys %{$self->{results}}) : 0; if ($self->{db_sort}) { $self->get_db_sorted_results; } else { $self->get_sorted_results; } } sub get_sorted_results { # Just sorts the results out of $self->{results} which should have been setup # by a search driver my ($self) = @_; my $results = $self->{results}; $self->{index} = 0; $self->{max_index} = $self->{mh} - 1; $self->{'order'} = [ sort { ( $results->{$b} || return 0 ) <=> ( $results->{$a} || 0 ) } keys %{$results} ]; $self->debug_dumper( "Results will be presented in the following order: ", $self->{'order'} ) if ($self->{_debug}); } sub get_db_sorted_results { # This assumes $self->{results} has a full result set, i.e. without any LIMIT # It then selects the result set using the SQL driver to do the sorting. This # is for Search modules which can not handle their own sorting my ($self) = @_; my $sb = GT::SQL::Search::Base::Search->clean_sb($self->{sb}, $self->{so}); $self->{index} = $self->{nh} * $self->{mh} || 0; $self->{max_index} = $self->{index} + $self->{mh} - 1; # index + mh is the first record which should not be returned. if ($self->{max_index} > $self->{rows}) { $self->{max_index} = $self->{rows}; $self->{rows} = $self->{rows} - $self->{index}; $self->{rows} < 0 ? $self->{rows} = 0 : 0; } else { $self->{rows} = $self->{mh}; } my ( $table, $pk ) = $self->_table_info(); my ( $query, $where, $st, $limit ); $where = qq!$pk in(! . join( ",", keys %{$self->{results}}) . ')'; $self->{mh} and $limit = qq!LIMIT $self->{index}, $self->{rows}!; $query = qq! SELECT $pk FROM $table WHERE $where $sb $limit !; $self->debug( "Row fetch query: $query" ) if ($self->{_debug}); my $sth = $self->{table}->{driver}->prepare( $query ); $sth->execute(); $self->{index} = 0; $self->{max_hits} = $self->{rows}; # Fetch the results in sorted order my $order = $sth->fetchall_arrayref(); $sth->finish(); $self->{'order'} = [ map { $_->[0] } @{$order} ]; } 1;