# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
package CrashTest::Plugin::Storage::Sql::Utils;
use Mojo::Base -base;
use Storable 'dclone';
use Search::QueryParser::SQL;
has [ qw/instance app config/ ];
has qw/db/;
sub new {
my $self = shift->SUPER::new(@_);
$self->db($self->instance->dbh->db);
return $self;
}
sub build_query_from_search_string {
my ($self, $search, $extra_columns, $extra_search_fields) = @_;
my @values;
# define a callback to collect values safely (without magic markers)
my $cb = sub {
my ($column, $this_op, $value) = @_;
my $sql;
if($column->type eq "fuzzy") {
if ( $this_op =~ /!|NOT/ ) {
$this_op = " NOT ILIKE ";
} else {
$this_op = " ILIKE ";
}
$value = "%$value%";
} elsif($column->type eq "sql") {
$sql = $column->name;
$sql =~ s/\s+\?op\?\s+/ $this_op /;
}
if(!defined($sql)) {
$sql = join('', $column->stringify, $this_op, '?');
}
push @values, $value;
return $sql;
};
my $search_fields = dclone($extra_search_fields);
foreach my $k(keys %$search_fields) {
$search_fields->{$k}->{callback} = $cb;
}
foreach my $extra_col(@$extra_columns) {
$search_fields->{$extra_col->{id}} = { callback => $cb, name => $extra_col->{db_column} };
}
my $parser = Search::QueryParser::SQL->new(
columns => $search_fields,
default_column => "function",
strict => 1,
);
my $query;
eval {
$query = $parser->parse($search, 1);
};
if($@) {
# strip file and line info from message
$@ =~ /(.+)(?:\s+at\s+[^\s]+\s+line\s+\d+\.)$/;
my $msg = $1 || $@;
die($msg . "\n");
} elsif(!defined($query)) {
die($parser->err . "\n");
}
# reset before calling dbi
@values = ();
my $dbi = $query->dbi();
return [ $dbi->[0], \@values ];
}
1;