MT#56239 api/callrecordings support filtering multiple metakeys

filtering an Entity-Attribute-Value model cannot be done as
simple conjunctions, but requires either INTERSECT set
operation, or joining the same table multiple times.

Change-Id: I5ce1ae1ece9406b6610487654f09d768a233b122
(cherry picked from commit 8e82715eb8)
mr10.5.7
Rene Krenn 2 years ago
parent d9ee558764
commit c57231de40

@ -48,12 +48,7 @@ sub query_params {
{ {
param => 'call_id', param => 'call_id',
description => 'Filter for callrecordings belonging to a specific call', description => 'Filter for callrecordings belonging to a specific call',
query => { query_type => 'wildcard',
first => sub {
my $q = shift;
{ 'me.call_id' => $q };
}
},
}, },
{ {
param => 'caller', param => 'caller',

@ -1088,7 +1088,7 @@ sub item_rs {
return unless($item_rs); return unless($item_rs);
if ($self->can('query_params')) { if ($self->can('query_params')) {
return $self->apply_query_params($orig_params[0],$self->query_params,$item_rs); return $self->apply_query_params($orig_params[0],$self->query_params(),$item_rs);
} }
return $item_rs; return $item_rs;
@ -1108,7 +1108,6 @@ sub apply_query_params {
#the only reason not to do this is a security #the only reason not to do this is a security
next unless($p[0]->{query} || $p[0]->{query_type} || $p[0]->{new_rs}); # skip "dummy" query parameters next unless($p[0]->{query} || $p[0]->{query_type} || $p[0]->{new_rs}); # skip "dummy" query parameters
my $q = $c->req->query_params->{$param}; # TODO: arrayref? my $q = $c->req->query_params->{$param}; # TODO: arrayref?
$q =~ s/\*/\%/g;
$q = undef if $q eq "NULL"; # IS NULL translation $q = undef if $q eq "NULL"; # IS NULL translation
if(@p) { if(@p) {
if (defined $p[0]->{new_rs}) { if (defined $p[0]->{new_rs}) {
@ -1162,11 +1161,21 @@ sub get_query_callbacks{
if ($param !~ /\./) { if ($param !~ /\./) {
$param = 'me.' . $param; $param = 'me.' . $param;
} }
if('string_like' eq $p[0]->{query_type}){
$sub_where = sub {my ($q, $c) = @_; { $param => { like => $q } };}; if ('string_like' eq $p[0]->{query_type}) {
}elsif('string_eq' eq $p[0]->{query_type}){ $sub_where = sub {my ($q, $c) = @_; $q =~ s/\*/\%/g; { $param => { like => $q } }; };
} elsif ('string_eq' eq $p[0]->{query_type}) {
$sub_where = sub {my ($q, $c) = @_; { $param => $q };}; $sub_where = sub {my ($q, $c) = @_; { $param => $q };};
} elsif ('wildcard' eq $p[0]->{query_type}) {
$sub_where = sub {my ($q, $c) = @_; { wildcard_search(
search_string => $q,
search => 1,
exact_search => check_wildcard_search($c->req->params),
int_search => 0,
col_name => $param,
) };};
} }
} }
if($p[0]->{query}){ if($p[0]->{query}){
$sub_where //= $p[0]->{query}->{first}; $sub_where //= $p[0]->{query}->{first};
@ -1867,21 +1876,23 @@ sub return_requested_type {
sub apply_caller_filter { sub apply_caller_filter {
my $self = shift; my $self = shift;
my %params = @_; my %params = @_;
my ($rs,$params,$conjunctions,$col) = @params{qw/rs params conjunctions col/}; my ($rs,$params,$conjunctions,$col,$joins,$join_idx) = @params{qw/rs params conjunctions col joins join_idx/};
if (exists $params->{caller}) { if (exists $params->{caller}) {
$rs = $rs->search_rs({ $$join_idx += 1 if $join_idx;
_wildcard_search( my %search = wildcard_search(
search_string => $params->{caller}, search_string => $params->{caller},
search => 1, search => 1,
exact_search => _check_wildcard_search($params), exact_search => check_wildcard_search($params),
int_search => 0, int_search => 0,
col_name => $col, col_name => $col,
comparison_op => undef, comparison_op => undef,
convert_code => undef, convert_code => undef,
conjunctions => $conjunctions, conjunctions => $conjunctions,
) );
}); $rs = $rs->search_rs({
map { $self->get_join_alias($_,$$join_idx) => $search{$_}; } keys %search
},$joins);
} }
return $rs; return $rs;
@ -1890,27 +1901,40 @@ sub apply_caller_filter {
sub apply_callee_filter { sub apply_callee_filter {
my $self = shift; my $self = shift;
my %params = @_; my %params = @_;
my ($rs,$params,$conjunctions,$col) = @params{qw/rs params conjunctions col/}; my ($rs,$params,$conjunctions,$col,$joins,$join_idx) = @params{qw/rs params conjunctions col joins join_idx/};
if (exists $params->{callee}) { if (exists $params->{callee}) {
$rs = $rs->search_rs({ $$join_idx += 1 if $join_idx;
_wildcard_search( my %search = wildcard_search(
search_string => $params->{callee}, search_string => $params->{callee},
search => 1, search => 1,
exact_search => _check_wildcard_search($params), exact_search => check_wildcard_search($params),
int_search => 0, int_search => 0,
col_name => $col, col_name => $col,
comparison_op => undef, comparison_op => undef,
convert_code => undef, convert_code => undef,
conjunctions => $conjunctions, conjunctions => $conjunctions,
) );
}); $rs = $rs->search_rs({
map { $self->get_join_alias($_,$$join_idx) => $search{$_}; } keys %search
},$joins);
} }
return $rs; return $rs;
} }
sub _wildcard_search { sub get_join_alias {
my $self = shift;
my ($alias_pattern,$join_idx) = @_;
if (defined $join_idx and $join_idx > 1) {
return sprintf($alias_pattern,'_' . $join_idx);
}
return sprintf($alias_pattern,'');
}
sub wildcard_search {
my %params = @_; my %params = @_;
my ($search_string, my ($search_string,
$search, $search,
@ -1963,7 +1987,7 @@ sub _wildcard_search {
return (); return ();
} }
sub _check_wildcard_search { sub check_wildcard_search {
my $params = shift; my $params = shift;
my $exact = 1; my $exact = 1;

@ -155,7 +155,7 @@ sub balances_rs {
contract => $contract, contract => $contract,
now => $now); now => $now);
return $self->apply_query_params($c,$self->can('query_params') ? $self->query_params : {},$contract->contract_balances); return $self->apply_query_params($c,$self->can('query_params') ? $self->query_params() : {},$contract->contract_balances);
} }

@ -41,60 +41,79 @@ sub _item_rs {
my ($self, $c) = @_; my ($self, $c) = @_;
my $item_rs = $c->model('DB')->resultset('recording_calls')->search_rs( my $item_rs = $c->model('DB')->resultset('recording_calls')->search_rs(
undef, { prefetch => 'recording_metakeys' }); undef, undef); #{ prefetch => 'recording_metakeys' }
$item_rs = $self->apply_caller_filter( my $join_idx = 0;
rs => $item_rs,
params => $c->req->params,
conjunctions => { 'recording_metakeys.key' => 'caller', },
col => 'recording_metakeys.value'
);
$item_rs = $self->apply_callee_filter(
rs => $item_rs,
params => $c->req->params,
conjunctions => { 'recording_metakeys.key' => 'callee', },
col => 'recording_metakeys.value'
);
if($c->user->roles eq "reseller") { if($c->user->roles eq "reseller") {
my $res_rs = $c->model('DB')->resultset('voip_subscribers')->search({ my $res_rs = $c->model('DB')->resultset('voip_subscribers')->search({
'contact.reseller_id' => $c->user->reseller_id 'contact.reseller_id' => $c->user->reseller_id
}, { },{
join => { 'contract' => 'contact' } join => { 'contract' => 'contact' }
}); });
$join_idx += 1;
$item_rs = $item_rs->search({ $item_rs = $item_rs->search({
status => { -in => [qw/completed confirmed/] }, status => { -in => [qw/completed confirmed/] },
'recording_metakeys.key' => 'uuid', $self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
'recording_metakeys.value' => { -in => $res_rs->get_column('uuid')->as_query } $self->get_join_alias('recording_metakeys%s.value',$join_idx) => { -in => $res_rs->get_column('uuid')->as_query }
}); },undef);
} elsif ($c->user->roles eq "subscriberadmin") { } elsif ($c->user->roles eq "subscriberadmin") {
my $res_rs = $c->model('DB')->resultset('provisioning_voip_subscribers')->search({ my $res_rs = $c->model('DB')->resultset('provisioning_voip_subscribers')->search({
'account_id' => $c->user->account_id 'account_id' => $c->user->account_id
}); });
$join_idx += 1;
$item_rs = $item_rs->search({ $item_rs = $item_rs->search({
status => { -in => [qw/completed confirmed/] }, status => { -in => [qw/completed confirmed/] },
'recording_metakeys.key' => 'uuid', $self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
'recording_metakeys.value' => { -in => $res_rs->get_column('uuid')->as_query } $self->get_join_alias('recording_metakeys%s.value',$join_idx) => { -in => $res_rs->get_column('uuid')->as_query }
}); },undef);
} elsif ($c->user->roles eq "subscriber") { } elsif ($c->user->roles eq "subscriber") {
$join_idx += 1;
$item_rs = $item_rs->search({ $item_rs = $item_rs->search({
status => { -in => [qw/completed confirmed/] }, status => { -in => [qw/completed confirmed/] },
'recording_metakeys.key' => 'uuid', $self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
'recording_metakeys.value' => $c->user->uuid, $self->get_join_alias('recording_metakeys%s.value',$join_idx) => $c->user->uuid,
}); },undef);
} }
if($c->req->params->{subscriber_id}) { if($c->req->params->{subscriber_id}) {
my $res_rs = $c->model('DB')->resultset('voip_subscribers')->search({ my $res_rs = $c->model('DB')->resultset('voip_subscribers')->search({
id => $c->req->params->{subscriber_id} id => $c->req->params->{subscriber_id}
}); });
$join_idx += 1;
$item_rs = $item_rs->search({ $item_rs = $item_rs->search({
'recording_metakeys.key' => 'uuid', $self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
'recording_metakeys.value' => { -in => $res_rs->get_column('uuid')->as_query } $self->get_join_alias('recording_metakeys%s.value',$join_idx) => { -in => $res_rs->get_column('uuid')->as_query }
},undef);
}
$item_rs = $self->apply_caller_filter(
rs => $item_rs,
params => $c->req->params,
conjunctions => { 'recording_metakeys%s.key' => 'caller', },
col => 'recording_metakeys%s.value',
join_idx => \$join_idx,
);
$item_rs = $self->apply_callee_filter(
rs => $item_rs,
params => $c->req->params,
conjunctions => { 'recording_metakeys%s.key' => 'callee', },
col => 'recording_metakeys%s.value',
join_idx => \$join_idx,
);
if ($join_idx > 0) {
$item_rs = $item_rs->search_rs(undef,{
join => [ ('recording_metakeys') x $join_idx ],
}); });
} }

Loading…
Cancel
Save