SQLForm empty search field fix

This commit is contained in:
James Tolley 2007-06-23 00:21:17 +00:00
parent 522d87fed2
commit 0db9d14a94

View file

@ -3923,207 +3923,208 @@ my %sortWeights = (
);
sub _constructSearchQuery {
my (@tables, @joinConstraints, $tableCounter, @constraints, $currentField, $conditional, @joinSequence);
my $self = shift;
my $searchInFields = shift;
my $showFields = shift;
my $fieldProperties = shift;
my $passedQuery = shift;
my (@tables, @joinConstraints, $tableCounter, @constraints, $currentField, $conditional, @joinSequence);
my $self = shift;
my $searchInFields = shift;
my $showFields = shift;
my $fieldProperties = shift;
my $passedQuery = shift;
# order the results by a calculated field
# each clause is something like this: IF(test,$weight,0) where weight is higher for fields with
# certain names, like 7 'title' or 'name', 3 for 'description', and 1 for everything else
# the tests are the same as those in the where clause
# the final result is: " SELECT ..., (test + test + ...) AS sqlforms_orderby_field
# ... ORDER BY sqlforms_orderby_field "
my @sortClauses = ();
# order the results by a calculated field
# each clause is something like this: IF(test,$weight,0) where weight is higher for fields with
# certain names, like 7 'title' or 'name', 3 for 'description', and 1 for everything else
# the tests are the same as those in the where clause
# the final result is: " SELECT ..., (test + test + ...) AS sqlforms_orderby_field
# ... ORDER BY sqlforms_orderby_field "
my @sortClauses = ();
# This variable should be set to value of the minimum word length for fulltext searches
# as it is set in your MySQL database. Normally this is 3.
my $minimumFulltextLength = 3;
# This variable should be set to value of the minimum word length for fulltext searches
# as it is set in your MySQL database. Normally this is 3.
my $minimumFulltextLength = 3;
# Include the table the form writes to.
$tableCounter = 2;
# Include the table the form writes to.
$tableCounter = 2;
# Process search fields.
foreach $currentField (@$searchInFields) {
# Set conditional given for this field or to like or regexp mode if in normal search
my $searchMode = $self->session->form->process("searchMode") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchMode');
if ($searchMode) {
$conditional = 100 if ($searchMode eq 'normal');
$conditional = 101 if ($searchMode eq 'regexp');
} else {
$conditional = $self->session->form->process('_'.$currentField.'_conditional') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'c');
}
# Process search fields.
foreach $currentField (@$searchInFields) {
# Set conditional given for this field or to like or regexp mode if in normal search
my $searchMode = $self->session->form->process("searchMode") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchMode');
if ($searchMode) {
$conditional = 100 if ($searchMode eq 'normal');
$conditional = 101 if ($searchMode eq 'regexp');
} else {
$conditional = $self->session->form->process('_'.$currentField.'_conditional') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'c');
}
$tableCounter++;
$tableCounter++;
if ($conditional ne '') {
my $currentFieldProperties = $fieldProperties->{$currentField};
my $fieldName = $currentFieldProperties->{fieldName};
my $fieldType = $currentFieldProperties->{type};
my $fullFieldName = "t1.$fieldName";
my $constraint;
my $query = $passedQuery || $self->session->form->process("searchQuery") || $self->session->form->process($currentField.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v1') || $self->session->scratch->get('SQLForm_'.$self->getId.'query');
my $queryLike;
if ($conditional == 100 || $conditional == 101) {
$query =~ s/\\/\\\\/g;
$query =~ s/'/\\'/g;
if ($conditional ne '') {
my $currentFieldProperties = $fieldProperties->{$currentField};
my $fieldName = $currentFieldProperties->{fieldName};
my $fieldType = $currentFieldProperties->{type};
my $fullFieldName = "t1.$fieldName";
my $constraint;
my $query = $passedQuery || $self->session->form->process("searchQuery") || $self->session->form->process($currentField.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v1') || $self->session->scratch->get('SQLForm_'.$self->getId.'query');
my $queryLike;
if ($conditional == 100 || $conditional == 101) {
$query =~ s/\\/\\\\/g;
$query =~ s/'/\\'/g;
# Search on 'like'
if ($conditional == 100) {
$queryLike = $query;
$queryLike =~ s/%/\\%/g;
$queryLike =~ s/\*/%/g;
$queryLike = "'%".$queryLike."%'";
}
$query = "'$query'";
}
# Search on 'like'
if ($conditional == 100) {
$queryLike = $query;
$queryLike =~ s/%/\\%/g;
$queryLike =~ s/\*/%/g;
$queryLike = "'%".$queryLike."%'";
}
$query = "'$query'";
}
my $formValue1 = $self->session->form->process($currentField.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v1');
my $formValue2 = $self->session->form->process($currentField.'-2') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v2');
my $formValue1 = $self->session->form->process($currentField.'-1') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v1');
my $formValue2 = $self->session->form->process($currentField.'-2') || $self->session->scratch->get('SQLForm_'.$self->getId.'---'.$currentField.'v2');
# don't search this field unless there's something to search for
# next if ($query eq qq[''] and $formValue1 eq "" and (ref $formValue2 ne 'ARRAY' || @$formValue2 == 0));
if ($fieldType eq 'list') {
if ($self->session->form->process($currentField.'-2')) {
$formValue2 = [ $self->session->request->param($currentField.'-2') ];
} else {
$formValue2 = Storable::thaw($formValue2);
}
}
if ($fieldType eq 'list') {
if ($self->session->form->process($currentField.'-2')) {
$formValue2 = [ $self->session->request->param($currentField.'-2') ];
} else {
$formValue2 = Storable::thaw($formValue2);
}
}
if ($conditional == 200 && $formValue2) {
if ($conditional == 200 && ref $formValue2 eq 'ARRAY') {
if (@$formValue2) {
$constraint = "(".join(' or ', map {"$fullFieldName RegExp CONCAT('(^|\\n)',$_,'(\\n|\$)')"} map $self->session->db->quote($_), @$formValue2).")";
}
} elsif ($conditional == 201 && $formValue2) { # match all
$constraint = "(".join(' or ', map {"$fullFieldName RegExp CONCAT('(^|\\n)',$_,'(\\n|\$)')"} map $self->session->db->quote($_), @$formValue2).")";
}
} elsif ($conditional == 201 && $formValue2) { # match all
if (@$formValue2) {
$constraint = "(".join(' and ', map {"$fullFieldName RegExp CONCAT('(^|\\n)',$_,'(\\n|\$)')"} map $self->session->db->quote($_), @$formValue2).")";
}
# Match the joined columns only if type is a list and has joins.
# Else the regular like and regex will handle this.
} elsif ($fieldType eq 'list' && $currentFieldProperties->{numberOfJoins}) {
my $prepend = "t$tableCounter";
for my $joinCounter (1 .. $currentFieldProperties->{numberOfJoins}) {
my $joinStatement = $currentFieldProperties->{"database$joinCounter"}.'.'.
$currentFieldProperties->{"table$joinCounter"}." as ".$prepend."table$joinCounter";
if ($joinCounter > 1) {
$joinStatement .= " on ".
$prepend.$currentFieldProperties->{"joinOnA$joinCounter"}.'='.
$prepend.$currentFieldProperties->{"joinOnB$joinCounter"};
} else {
$joinStatement .= " on ".
$fullFieldName." RegExp CONCAT('(^|\\n)',".$prepend.$currentFieldProperties->{selectField1}.",'(\\n|\$)')";
$constraint = "(".join(' and ', map {"$fullFieldName RegExp CONCAT('(^|\\n)',$_,'(\\n|\$)')"} map $self->session->db->quote($_), @$formValue2).")";
}
# Match the joined columns only if type is a list and has joins.
# Else the regular like and regex will handle this.
} elsif ($fieldType eq 'list' && $currentFieldProperties->{numberOfJoins}) {
my $prepend = "t$tableCounter";
for my $joinCounter (1 .. $currentFieldProperties->{numberOfJoins}) {
my $joinStatement = $currentFieldProperties->{"database$joinCounter"}.'.'.
$currentFieldProperties->{"table$joinCounter"}." as ".$prepend."table$joinCounter";
if ($joinCounter > 1) {
$joinStatement .= " on ".
$prepend.$currentFieldProperties->{"joinOnA$joinCounter"}.'='.
$prepend.$currentFieldProperties->{"joinOnB$joinCounter"};
} else {
$joinStatement .= " on ".
$fullFieldName." RegExp CONCAT('(^|\\n)',".$prepend.$currentFieldProperties->{selectField1}.",'(\\n|\$)')";
# $fullFieldName." = ".$prepend.$currentFieldProperties->{selectField1};
$joinStatement .= " or ".$fullFieldName." = ''" if (!$currentFieldProperties->{isRequired});
}
push(@joinConstraints, $prepend."table$joinCounter.__archived='0'");
push(@joinSequence, $joinStatement);
}
if ($conditional == 100) {
$joinStatement .= " or ".$fullFieldName." = ''" if (!$currentFieldProperties->{isRequired});
}
push(@joinConstraints, $prepend."table$joinCounter.__archived='0'");
push(@joinSequence, $joinStatement);
}
if ($conditional == 100) {
if ($queryLike ne q['%%']) {
$constraint .= $prepend.$currentFieldProperties->{selectField2}." like ".$queryLike;
}
$constraint .= $prepend.$currentFieldProperties->{selectField2}." like ".$queryLike;
}
elsif (defined $formValue1 && $formValue1 ne '') {
$constraint = "$fullFieldName like ".$self->session->db->quote('%'.$formValue1.'%');
}
} else {
if ($query ne "''") {
$constraint .= $prepend.$currentFieldProperties->{selectField2}." regexp($query)";
}
} else {
if ($query and $query ne "''") {
$constraint .= $prepend.$currentFieldProperties->{selectField2}." regexp($query)";
}
elsif (defined $formValue1 && $formValue1 ne '') {
$constraint = "$fullFieldName like ".$self->session->db->quote($formValue1);
}
}
# 10 = between
} elsif ($conditional == 10) {
$constraint =
"($fullFieldName > ".$self->session->db->quote($formValue1)." and ".
" $fullFieldName <".$self->session->db->quote($formValue2).")";
# 100 = like
} elsif ($conditional == 100) {
if ($currentFieldProperties->{useFulltext} && length($query) >= $minimumFulltextLength) {
$constraint = "match($fullFieldName) against($query in boolean mode)";
} else {
if ($queryLike ne q['%%']) {
$constraint = "$fullFieldName like $queryLike";
}
# 10 = between
} elsif ($conditional == 10) {
$constraint =
"($fullFieldName > ".$self->session->db->quote($formValue1)." and ".
" $fullFieldName <".$self->session->db->quote($formValue2).")";
# 100 = like
} elsif ($conditional == 100) {
if ($currentFieldProperties->{useFulltext} && length($query) >= $minimumFulltextLength) {
$constraint = "match($fullFieldName) against($query in boolean mode)";
} else {
if ($queryLike ne q['%%']) {
$constraint = "$fullFieldName like $queryLike";
}
elsif (defined $formValue1 && $formValue1 ne '') {
$constraint = "$fullFieldName like ".$self->session->db->quote('%'.$formValue1.'%');
}
}
# 101 = regexp
} elsif ($conditional == 101) {
$constraint = "$fullFieldName regexp($query)";
} else {
$constraint = "$fullFieldName ".$types->{$fieldType}->{$conditional}." ".$self->session->db->quote($formValue1);
}
next unless $constraint;
my $sortWeight = exists $sortWeights{lc $fieldName} ? $sortWeights{lc $fieldName} : 1;
push @sortClauses, "IF($constraint,$sortWeight,0)";
push(@constraints, $constraint) if $constraint;
}
}
# 101 = regexp
} elsif ($conditional == 101) {
if ($query) {
$constraint = "$fullFieldName regexp($query)";
}
} else {
$constraint = "$fullFieldName ".$types->{$fieldType}->{$conditional}." ".$self->session->db->quote($formValue1);
}
my @selectColumns = qw(t1.__recordId t1.__deletionDate t1.__deletedBy t1.__initDate t1.__userId t1.__deleted t1.__archived t1.__revision);
foreach (@$showFields) {
my $fieldName = $fieldProperties->{$_}->{fieldName};
next unless $constraint;
my $sortWeight = exists $sortWeights{lc $fieldName} ? $sortWeights{lc $fieldName} : 1;
push @sortClauses, "IF($constraint,$sortWeight,0)";
push(@constraints, $constraint) if $constraint;
}
}
my @selectColumns = qw(t1.__recordId t1.__deletionDate t1.__deletedBy t1.__initDate t1.__userId t1.__deleted t1.__archived t1.__revision);
foreach (@$showFields) {
my $fieldName = $fieldProperties->{$_}->{fieldName};
push(@selectColumns, "t1.$fieldName");
push(@selectColumns, "t1.$fieldName");
# In case of files also select mimetype
if ($fieldProperties->{$_}->{formFieldType} eq 'file') {
push(@selectColumns, 't1.__'.$fieldName.'_mimeType');
}
# In case of files also select mimetype
if ($fieldProperties->{$_}->{formFieldType} eq 'file') {
push(@selectColumns, 't1.__'.$fieldName.'_mimeType');
}
}
my $searchInTrash = $self->session->scratch->get('SQLForm_'.$self->getId.'searchInTrash') || $self->session->form->process("searchInTrash") || '0';
my $searchInTrash = $self->session->scratch->get('SQLForm_'.$self->getId.'searchInTrash') || $self->session->form->process("searchInTrash") || '0';
my $searchType = ($self->session->form->process("searchType") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchType')) eq 'and' ? 'and' : 'or';
my $searchType = ($self->session->form->process("searchType") || $self->session->scratch->get('SQLForm_'.$self->getId.'searchType')) eq 'and' ? 'and' : 'or';
return undef if (!@constraints);
return undef if (!@constraints);
# Construct the search query
my $sortField = @sortClauses ? ('('.join('+', @sortClauses).') AS sqlform_orderby') : '1 AS sqlform_orderby';
$sortField = ' 1 AS sqlform_orderby ' if $searchType eq 'and';
# Construct the search query
my $sortField = @sortClauses ? ('('.join('+', @sortClauses).') AS sqlform_orderby') : '1 AS sqlform_orderby';
$sortField = ' 1 AS sqlform_orderby ' if $searchType eq 'and';
my $sql = " select distinct ".join(', ', @selectColumns, $sortField);
$sql .= " from ".$self->get('tableName').' as t1 ';
$sql .= " left join ".join(" left join \n", @joinSequence)."\n" if (@joinSequence);
$sql .= " where ";
$sql .= "(".join(" $searchType \n", @constraints).")\n" if (@constraints);
$sql .= " and " if (@constraints);
$sql .= "(".join(" and \n", @joinConstraints).")\n" if (@joinConstraints);
$sql .= " and " if (@joinConstraints);
$sql .= " t1.__archived=0 ";
$sql .= " and t1.__deleted=".$self->session->db->quote($searchInTrash) if ($searchInTrash < 2);
my $sql = " select distinct ".join(', ', @selectColumns, $sortField);
$sql .= " from ".$self->get('tableName').' as t1 ';
$sql .= " left join ".join(" left join \n", @joinSequence)."\n" if (@joinSequence);
$sql .= " where ";
$sql .= "(".join(" $searchType \n", @constraints).")\n" if (@constraints);
$sql .= " and " if (@constraints);
$sql .= "(".join(" and \n", @joinConstraints).")\n" if (@joinConstraints);
$sql .= " and " if (@joinConstraints);
$sql .= " t1.__archived=0 ";
$sql .= " and t1.__deleted=".$self->session->db->quote($searchInTrash) if ($searchInTrash < 2);
$sql .= " GROUP BY $selectColumns[0] ";
my $sortColumn = $self->session->form->process("sortColumn");
$sortColumn = $self->session->scratch->get('SQLForm_'.$self->getId.'sortColumn') unless ($sortColumn);
$self->session->scratch->set('SQLForm_'.$self->getId.'sortColumn', $sortColumn);
my $sortColumn = $self->session->form->process("sortColumn");
$sortColumn = $self->session->scratch->get('SQLForm_'.$self->getId.'sortColumn') unless ($sortColumn);
$self->session->scratch->set('SQLForm_'.$self->getId.'sortColumn', $sortColumn);
my $sortAscending = $self->session->form->process("sortAscending");
$sortAscending = $self->session->scratch->get('SQLForm_'.$self->getId.'sortAscending') unless (defined $self->session->form->process("sortAscending"));
$self->session->scratch->set('SQLForm_'.$self->getId.'sortAscending', $sortAscending);
my $sortAscending = $self->session->form->process("sortAscending");
$sortAscending = $self->session->scratch->get('SQLForm_'.$self->getId.'sortAscending') unless (defined $self->session->form->process("sortAscending"));
$self->session->scratch->set('SQLForm_'.$self->getId.'sortAscending', $sortAscending);
if (isIn($sortColumn, @$showFields)) {
$sql .= " order by ".$fieldProperties->{$sortColumn}->{fieldName};
$sql .= " desc " unless ($sortAscending);
}
else {
if (isIn($sortColumn, @$showFields)) {
$sql .= " order by ".$fieldProperties->{$sortColumn}->{fieldName};
$sql .= " desc " unless ($sortAscending);
}
else {
$sql .= " ORDER BY sqlform_orderby DESC ";
}
}
$self->session->errorHandler->warn($sql);
return $sql;
#$self->session->errorHandler->warn($sql);
return $sql;
}
#-------------------------------------------------------------------