Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Bug found on search.pm

Quote Reply
Bug found on search.pm
bug found on search.pm

Playing around with search.pm I encountered this bug:

Using a filter in some cols and then entering a query like 'a'. Search.pm blocks then 'a' word because too little and give an error on the SQL command:
Code:
DBD::mysql::st execute failed: You have an error in your SQL syntax near ') and (( Hidden = "No")) ' at line 1 at admin/Links/Search.pm line 729.


Also. A wish list:
I think should be very interesting adding these two particular featues:
- Search in a particular part of the category tree (or more parts)
- Search everywhere but not in category 1,2,3,4 and so on.

I tried to do it changing some code in Seach.pm:

Code:
sub filter {
#------------------------------------------------------------
# a post applied item to the where clause to "filter"
# the result set
#
my ($self, $filter, $inlist, $notinlist) = @_;
my ($message) = undef;
foreach (keys %$filter) {
$filter->{$_} and $self->{filter}->{$_} = $filter->{$_};
$message .= "$_ => ${$filter}{$_}" if ($filter->{$_});
}
$message and $self->_debug_message ("filter: setting filter to $message", 4);

$message = undef;
foreach (keys %$inlist) {
$inlist->{$_} and $self->{inlist}->{$_} = $inlist->{$_};
$message .= "$_ => [${$inlist}{$_}] " if ($inlist->{$_});
}
$message and $self->_debug_message ("inlist: setting to $message", 4);

$message = undef;
foreach (keys %$notinlist) {
$notinlist->{$_} and $self->{notinlist}->{$_} = $notinlist->{$_};
$message .= "$_ => [${$notinlist}{$_}]" if ($notinlist->{$_});
}
$message and $self->_debug_message ("notinlist: setting to $message", 4);

}


inlist and notinlist are hash references containing cols (in my case IDs) I want target the search.
I chenged a little this piece of code but the meaning remains almost unchanged.

also:
Code:
my $filterref = $self->{filter};
my $inlistref = $self->{inlist};
my $notinlistref= $self->{notinlist};
my $filter = undef;
my $inlist = undef;
my $notinlist = undef;
my $where;

if ( $filterref or $inlist or $notinlist) {
$filterref and $filter = (" and (( " .
join ( ") and ( ", map { "$_ = \"". quotemeta($$filterref{$_}) ."\"" } keys %$filterref )
. "))" );

$inlistref and
$inlist = (" and (( " .
join ( ") and ( ", map { "$_ IN (". ($$inlistref{$_}) .")" } keys %$inlistref )
. "))" );

$notinlistref and
$notinlist = (" and (( " .
join ( ") and ( ", map { "$_ NOT IN (". ($$notinlistref{$_}) .")" } keys %$notinlistref )
. "))" );

$where = "$id_col in (" .
join ( ",", map ( $$_[0], @query_results) ) .
") $filter $inlist $notinlist";

my $query = "SELECT count(*) FROM " . $self->{target_table} . " WHERE $where";
my $sth = $self->{dbh}->prepare ( $query ) or $self->_debug_message ("query: Can't prepare: $query ($DBI::errstr)\n\n<tt>$where</tt>", 1);
$self->_debug_message ("query: $query", 5);
$sth->execute () or $self->_debug_message ("query: Can't execute: $query ($DBI::errstr)", 1);

my ( $results ) = $sth->fetchrow_array ();
$self->_debug_message ("query: filtered results: $results from " . $self->{total_results} . " unfiltered total.", 4);

# ... if the number of elements has changed
if ( $self->{total_results} != $results ) {
$self->{total_results} = $results;

# ... if there are 0 or more results, do the appropriate thing
if ( $results ) {

# ... since there was a change in the number of results AND there were elements, tweak the list so that it's proper...,
my $query = "SELECT $id_col FROM " . $self->{target_table} . " WHERE $id_col in (" .
join ( ",", map ( $$_[0], @query_results) ) .") $filter $inlist $notinlist";
my $sth = $self->{dbh}->prepare ( $query );
$sth->execute ();
my $row;
my %needed = map { $$_[0] => 1 } @query_results;
foreach $row ( $sth->fetchrow_hashref () ) {
delete $needed { $$row { $id_col } };
}
foreach $row ( keys %needed ) {
delete $$id_results { $row };
}
@query_results = sort { $$b[1] <=> $$a[1] } map ( [$_, $$id_results {$_} ], keys %$id_results );
} else {
@query_results = ();
return undef;
}
}
} else {
$filter = undef;
$inlist = undef;
$notinlist = undef;
}
....

Aldo added around the script a couple of minor changes: ($where .... $filter $inlist $notinlist).


It works fine except the bug problem reported at the beginning. Iìm not shure it's the bestway to do that.




Bye bye


lepo
Quote Reply
Re: Bug found on search.pm In reply to
Found also another little very little bug.
Just changed sub query in search.pm as follow:

original code:
Code:
my %needed = map { $$_[0] => 1 } @query_results;
foreach $row ( $sth->fetchrow_hashref () ) {
delete $needed { $$row { $id_col } };
}
foreach $row ( keys %needed ) {
delete $$id_results { $row };
}


changed in....
Code:
my %needed = map { $$_[0] => 1 } @query_results;
while ($row = $sth->fetchrow_hashref () ) {
$self->_debug_message ("deleted(1): $id_col-".$$row { $id_col } , 4);
delete $needed { $$row { $id_col } };
}
foreach $row ( keys %needed ) {
$self->_debug_message ("deleted(2): $row-".$$id_results { $row } , 4);
delete $$id_results { $row };
}


Quote Reply
Re: Bug found on search.pm In reply to
Thanks Lepo! I'll fix it up.