Change-Id: Id4edc72e2e7748ff6e9adb4c3370720232065ab6changes/28/19228/8
parent
d30caf3d27
commit
3a1d30bee6
@ -0,0 +1,227 @@
|
||||
package NGCP::Panel::Utils::RedisLocationResultSet;
|
||||
|
||||
use Moose;
|
||||
|
||||
use TryCatch;
|
||||
use NGCP::Panel::Utils::RedisLocationResultSource;
|
||||
|
||||
use Data::Dumper;
|
||||
|
||||
has _c => (
|
||||
is => 'ro',
|
||||
isa => 'NGCP::Panel',
|
||||
);
|
||||
|
||||
has _redis => (
|
||||
is => 'ro',
|
||||
isa => 'Redis',
|
||||
);
|
||||
|
||||
has _rows => (
|
||||
is => 'rw',
|
||||
isa => 'ArrayRef',
|
||||
default => sub {[]}
|
||||
);
|
||||
|
||||
has _query_done => (
|
||||
is => 'rw',
|
||||
isa => 'Int',
|
||||
default => 0,
|
||||
);
|
||||
|
||||
has _domain_resellers => (
|
||||
is => 'rw',
|
||||
isa => 'HashRef',
|
||||
lazy => 1,
|
||||
default => sub {
|
||||
my $self = shift;
|
||||
my $h = {};
|
||||
my $domres_rs = $self->_c->model('DB')->resultset('domain_resellers')->search(undef, {
|
||||
join => 'domain'
|
||||
});
|
||||
while ((my $res = $domres_rs->next)) {
|
||||
$h->{$res->domain->domain} = $res->reseller_id;
|
||||
}
|
||||
return $h;
|
||||
},
|
||||
);
|
||||
|
||||
sub count {
|
||||
my ($self) = @_;
|
||||
|
||||
my $count = @{ $self->_rows };
|
||||
return $count;
|
||||
}
|
||||
|
||||
sub first {
|
||||
my ($self) = @_;
|
||||
return $self->_rows->[0];
|
||||
}
|
||||
|
||||
sub all {
|
||||
my ($self) = @_;
|
||||
return @{ $self->_rows };
|
||||
}
|
||||
|
||||
sub find {
|
||||
my ($self, $filter) = @_;
|
||||
my $id;
|
||||
|
||||
if (ref $filter eq "") {
|
||||
$id = $filter;
|
||||
$filter = { id => $id };
|
||||
} elsif(ref $filter eq "HASH" && exists $filter->{id}) {
|
||||
$id = $filter->{id};
|
||||
} else {
|
||||
$self->_c->log->error("id filter is mandatory for redis find()");
|
||||
return;
|
||||
}
|
||||
|
||||
my %entry = $self->_redis->hgetall("location:entry::$id");
|
||||
$entry{id} = $entry{ruid};
|
||||
if (exists $filter->{reseller_id} && $filter->{reseller_id} != $self->_domain_resellers->{$entry{domain}}) {
|
||||
return;
|
||||
}
|
||||
return NGCP::Panel::Utils::RedisLocationResultSource->new(_data => \%entry);
|
||||
}
|
||||
|
||||
sub search {
|
||||
my ($self, $filter, $opt) = @_;
|
||||
$filter //= {};
|
||||
|
||||
my $new_rs = $self->meta->clone_object($self);
|
||||
unless ($new_rs->_query_done) {
|
||||
if ($filter->{id}) {
|
||||
push @{ $new_rs->_rows }, $new_rs->find($filter);
|
||||
} elsif ($filter->{username} && $filter->{domain}) {
|
||||
push @{ $new_rs->_rows },
|
||||
@{ $new_rs->_rows_from_mapkey("location:usrdom::" .
|
||||
$filter->{username} . ":" . $filter->{domain}, $filter) };
|
||||
} else {
|
||||
$new_rs->_scan($filter);
|
||||
}
|
||||
$new_rs->_query_done(1);
|
||||
}
|
||||
$new_rs->_filter($filter);
|
||||
|
||||
if ($opt->{order_by}->{'-desc'}) {
|
||||
my $f = $opt->{order_by}->{'-desc'};
|
||||
$f =~ s/^me\.//;
|
||||
$new_rs->_rows([sort { $b->$f cmp $a->$f } @{ $new_rs->_rows }]);
|
||||
} elsif ($opt->{order_by}->{'-asc'} || ref $opt->{order_by} eq "") {
|
||||
my $f = $opt->{order_by}->{'-asc'} // $opt->{order_by};
|
||||
$f =~ s/^me\.//;
|
||||
$new_rs->_rows([sort { $a->$f cmp $b->$f } @{ $new_rs->_rows }]);
|
||||
}
|
||||
|
||||
$opt->{rows} //= -1;
|
||||
$opt->{offset} //= 0;
|
||||
if (!defined $opt->{page} && $opt->{rows} > -1 || $opt->{offset} > 0) {
|
||||
$new_rs->_rows([ splice @{ $new_rs->_rows }, $opt->{offset}, $opt->{rows} ]);
|
||||
}
|
||||
|
||||
if (defined $opt->{page} && $opt->{rows} > 0) {
|
||||
$new_rs->_rows([ splice(@{ $new_rs->_rows }, ($opt->{page} - 1 )*$opt->{rows}, $opt->{rows}) ]);
|
||||
}
|
||||
return $new_rs;
|
||||
}
|
||||
|
||||
sub _rows_from_mapkey {
|
||||
my ($self, $mapkey, $filter) = @_;
|
||||
my @rows = ();
|
||||
my $keys = $self->_redis->smembers($mapkey);
|
||||
foreach my $key (@{ $keys }) {
|
||||
my %entry = $self->_redis->hgetall($key);
|
||||
$entry{id} = $entry{ruid};
|
||||
if (exists $filter->{reseller_id} && $filter->{reseller_id} != $self->_domain_resellers->{$entry{domain}}) {
|
||||
next;
|
||||
}
|
||||
my $res = NGCP::Panel::Utils::RedisLocationResultSource->new(_data => \%entry);
|
||||
push @rows, $res;
|
||||
}
|
||||
return \@rows;
|
||||
}
|
||||
|
||||
sub _filter {
|
||||
my ($self, $filter) = @_;
|
||||
my @newrows = ();
|
||||
my $i = 0;
|
||||
foreach my $row (@{ $self->_rows }) {
|
||||
my $match = 0;
|
||||
my $filter_applied = 0;
|
||||
my %attr = map { $_->name => 1 } $row->meta->get_all_attributes;
|
||||
foreach my $f (keys %{ $filter }) {
|
||||
if ($f eq "-and" && ref $filter->{$f} eq "ARRAY") {
|
||||
foreach my $col (@{ $filter->{$f} }) {
|
||||
next unless (ref $col eq "ARRAY");
|
||||
foreach my $innercol (@{ $col }) {
|
||||
if (ref $innercol eq "HASH") {
|
||||
foreach my $colname (keys %{ $innercol }) {
|
||||
my $searchname = $colname;
|
||||
$colname =~ s/^me\.//;
|
||||
next if ($colname =~ /\./); # we don't support joined table columns
|
||||
$filter_applied = 1;
|
||||
if (ref $innercol->{$searchname} eq "") {
|
||||
if (!exists $attr{$colname} || lc($row->$colname) ne lc($innercol->{$searchname})) {
|
||||
} else {
|
||||
$match = 1;
|
||||
last;
|
||||
}
|
||||
} elsif (ref $innercol->{$searchname} eq "HASH" && exists $innercol->{$searchname}->{like}) {
|
||||
my $fil = $innercol->{$searchname}->{like};
|
||||
$fil =~ s/^\%//;
|
||||
$fil =~ s/\%$//;
|
||||
if (!exists $attr{$colname} || $row->$colname !~ /$fil/i) {
|
||||
} else {
|
||||
$match = 1;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
last if ($match);
|
||||
}
|
||||
}
|
||||
}
|
||||
last if ($match);
|
||||
}
|
||||
|
||||
}
|
||||
next if ($filter_applied && !$match);
|
||||
push @newrows, $row;
|
||||
}
|
||||
$self->_rows(\@newrows);
|
||||
}
|
||||
|
||||
sub _scan {
|
||||
my ($self, $filter) = @_;
|
||||
$filter //= {};
|
||||
my $match = ($filter->{username} // "") . ":" . ($filter->{domain} // "");
|
||||
if ($match eq ":") {
|
||||
$match = "*";
|
||||
} elsif ($match =~ /:$/) {
|
||||
$match .= '*';
|
||||
}
|
||||
|
||||
$self->_rows([]);
|
||||
my $cursor = 0;
|
||||
do {
|
||||
my $res = $self->_redis->scan($cursor, MATCH => "location:usrdom::$match", COUNT => 1000);
|
||||
$cursor = shift @{ $res };
|
||||
my $mapkeys = shift @{ $res };
|
||||
foreach my $mapkey (@{ $mapkeys }) {
|
||||
push @{ $self->_rows }, @{ $self->_rows_from_mapkey($mapkey, $filter) };
|
||||
}
|
||||
} while ($cursor);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub result_class {
|
||||
"dummy";
|
||||
}
|
||||
|
||||
sub result_source {
|
||||
NGCP::Panel::Utils::RedisLocationResultSource->new;
|
||||
}
|
||||
|
||||
1;
|
@ -0,0 +1,30 @@
|
||||
package NGCP::Panel::Utils::RedisLocationResultSource;
|
||||
|
||||
use Moose;
|
||||
|
||||
has _data => (
|
||||
is => 'ro',
|
||||
isa => 'HashRef',
|
||||
default => sub {{}},
|
||||
);
|
||||
|
||||
sub BUILD {
|
||||
my ($self) = @_;
|
||||
foreach my $k (keys %{ $self->_data }) {
|
||||
$self->meta->add_attribute(
|
||||
$k => (accessor => $k)
|
||||
);
|
||||
$self->$k($self->_data->{$k});
|
||||
}
|
||||
}
|
||||
|
||||
sub get_inflated_columns {
|
||||
my ($self) = @_;
|
||||
return %{ $self->_data };
|
||||
}
|
||||
|
||||
sub columns {
|
||||
|
||||
}
|
||||
|
||||
1;
|
Loading…
Reference in new issue