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',
description => 'Filter for callrecordings belonging to a specific call',
query => {
first => sub {
my $q = shift;
{ 'me.call_id' => $q };
}
},
query_type => 'wildcard',
},
{
param => 'caller',

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

@ -155,7 +155,7 @@ sub balances_rs {
contract => $contract,
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 $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(
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'
);
my $join_idx = 0;
if($c->user->roles eq "reseller") {
my $res_rs = $c->model('DB')->resultset('voip_subscribers')->search({
'contact.reseller_id' => $c->user->reseller_id
}, {
},{
join => { 'contract' => 'contact' }
});
$join_idx += 1;
$item_rs = $item_rs->search({
status => { -in => [qw/completed confirmed/] },
'recording_metakeys.key' => 'uuid',
'recording_metakeys.value' => { -in => $res_rs->get_column('uuid')->as_query }
});
$self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
$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") {
my $res_rs = $c->model('DB')->resultset('provisioning_voip_subscribers')->search({
'account_id' => $c->user->account_id
});
$join_idx += 1;
$item_rs = $item_rs->search({
status => { -in => [qw/completed confirmed/] },
'recording_metakeys.key' => 'uuid',
'recording_metakeys.value' => { -in => $res_rs->get_column('uuid')->as_query }
});
$self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
$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") {
$join_idx += 1;
$item_rs = $item_rs->search({
status => { -in => [qw/completed confirmed/] },
'recording_metakeys.key' => 'uuid',
'recording_metakeys.value' => $c->user->uuid,
});
$self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
$self->get_join_alias('recording_metakeys%s.value',$join_idx) => $c->user->uuid,
},undef);
}
if($c->req->params->{subscriber_id}) {
my $res_rs = $c->model('DB')->resultset('voip_subscribers')->search({
id => $c->req->params->{subscriber_id}
});
$join_idx += 1;
$item_rs = $item_rs->search({
'recording_metakeys.key' => 'uuid',
'recording_metakeys.value' => { -in => $res_rs->get_column('uuid')->as_query }
$self->get_join_alias('recording_metakeys%s.key',$join_idx) => 'uuid',
$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