discourse-legacysite-perl/site/slowtwitch.com/cgi-bin/articles/GT/SQL/Search/LUCENE/STH.pm
2024-06-17 21:49:12 +10:00

116 lines
3.7 KiB
Perl

# ====================================================================
# 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;