|
|
|
|
@ -375,7 +375,13 @@ sub require_valid_patch {
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub item_by_id_valid {
|
|
|
|
|
my ($self, $c, $id) = @_;
|
|
|
|
|
return unless $self->valid_id($c, $id);
|
|
|
|
|
my $item = $self->item_by_id($c, $id);
|
|
|
|
|
return unless $self->resource_exists($c, $self->item_name => $item);
|
|
|
|
|
return $item;
|
|
|
|
|
}
|
|
|
|
|
sub resource_exists {
|
|
|
|
|
my ($self, $c, $entity_name, $resource) = @_;
|
|
|
|
|
return 1 if $resource;
|
|
|
|
|
@ -384,12 +390,41 @@ sub resource_exists {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub paginate_order_collection {
|
|
|
|
|
my ($self, $c, $item_rs) = @_;
|
|
|
|
|
my ($self, $c, $items) = @_;
|
|
|
|
|
my $params = {
|
|
|
|
|
page => $c->request->params->{page} // 1,
|
|
|
|
|
rows => $c->request->params->{rows} // 10,
|
|
|
|
|
order_by => $c->request->params->{order_by},
|
|
|
|
|
direction => $c->request->params->{order_by_direction} // "asc",
|
|
|
|
|
};
|
|
|
|
|
my($total_count, $item_rs);
|
|
|
|
|
if('ARRAY' eq ref $items){
|
|
|
|
|
($total_count, $item_rs) = $self->paginate_order_collection_array($c, $items, $params);
|
|
|
|
|
}else{
|
|
|
|
|
($total_count, $item_rs) = $self->paginate_order_collection_rs($c, $items, $params);
|
|
|
|
|
}
|
|
|
|
|
return ($total_count, $item_rs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub paginate_order_collection_array {
|
|
|
|
|
my ($self, $c, $items, $params) = @_;
|
|
|
|
|
my($page,$rows,$order_by,$direction) = @$params{qw/page rows order_by direction/};
|
|
|
|
|
my $total_count = scalar @$items;
|
|
|
|
|
if(defined $order_by ){
|
|
|
|
|
if(defined $order_by && defined $direction && (lc($direction) eq 'desc') ){
|
|
|
|
|
$items = [sort { $b->{$order_by} cmp $a->{$order_by} } @$items];
|
|
|
|
|
}else{
|
|
|
|
|
$items = [sort { $a->{$order_by} cmp $b->{$order_by} } @$items];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$items = [splice(@$items, ( $page - 1 )*$rows, $rows) ];
|
|
|
|
|
return ($total_count, $items);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub paginate_order_collection_rs {
|
|
|
|
|
my ($self, $c, $item_rs, $params) = @_;
|
|
|
|
|
my($page,$rows,$order_by,$direction) = @$params{qw/page rows order_by direction/};
|
|
|
|
|
|
|
|
|
|
my $page = $c->request->params->{page} // 1;
|
|
|
|
|
my $rows = $c->request->params->{rows} // 10;
|
|
|
|
|
my $order_by = $c->request->params->{order_by};
|
|
|
|
|
my $direction = $c->request->params->{order_by_direction} // "asc";
|
|
|
|
|
my $total_count = int($item_rs->count);
|
|
|
|
|
$item_rs = $item_rs->search(undef, {
|
|
|
|
|
page => $page,
|
|
|
|
|
@ -596,7 +631,9 @@ sub apply_query_params {
|
|
|
|
|
|
|
|
|
|
foreach my $param(keys %{ $c->req->query_params }) {
|
|
|
|
|
my @p = grep { $_->{param} eq $param } @{ $query_params };
|
|
|
|
|
next unless($p[0]->{query} || $p[0]->{new_rs}); # skip "dummy" query parameters
|
|
|
|
|
#todo: we can generate default filters for all item_rs fields here
|
|
|
|
|
#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
|
|
|
|
|
@ -604,7 +641,7 @@ sub apply_query_params {
|
|
|
|
|
if (defined $p[0]->{new_rs}) {
|
|
|
|
|
#compose fresh rs based on current, to support set operations with filters:
|
|
|
|
|
$item_rs = $p[0]->{new_rs}($c,$q,$item_rs);
|
|
|
|
|
} elsif (defined $p[0]->{query}) {
|
|
|
|
|
} elsif (defined $p[0]->{query} || defined $p[0]->{query_type}) {
|
|
|
|
|
#regular chaining:
|
|
|
|
|
my($sub_where,$sub_attributes) = $self->get_query_callbacks(\@p);
|
|
|
|
|
$item_rs = $item_rs->search($sub_where->($q,$c), $sub_attributes->($q,$c));
|
|
|
|
|
@ -649,9 +686,14 @@ sub delay_commit {
|
|
|
|
|
$guard->commit();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#---------------- Entities staff
|
|
|
|
|
#---------------- default methods
|
|
|
|
|
|
|
|
|
|
sub hal_from_item {
|
|
|
|
|
my ($self, $c, $item, $form) = @_;
|
|
|
|
|
my $resource = {$item->get_inflated_columns};
|
|
|
|
|
my ($self, $c, $item, $form, $params) = @_;
|
|
|
|
|
my ($form_exceptions) = @$params{qw/form_exceptions/};
|
|
|
|
|
my $resource = $self->resource_from_item($c, $item, $form);
|
|
|
|
|
|
|
|
|
|
$resource = $self->process_hal_resource($c, $item, $resource, $form);
|
|
|
|
|
my $links = $self->hal_links($c, $item, $resource, $form) // [];
|
|
|
|
|
my $hal = Data::HAL->new(
|
|
|
|
|
@ -664,71 +706,151 @@ sub hal_from_item {
|
|
|
|
|
),
|
|
|
|
|
Data::HAL::Link->new(relation => 'collection', href => sprintf("/api/%s/", $self->resource_name)),
|
|
|
|
|
Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'),
|
|
|
|
|
Data::HAL::Link->new(relation => 'self', href => sprintf("%s%d", $self->dispatch_path, $item->id)),
|
|
|
|
|
Data::HAL::Link->new(relation => 'self', href => sprintf("%s%s", $self->dispatch_path, $self->get_item_id($c, $item))),
|
|
|
|
|
@$links
|
|
|
|
|
],
|
|
|
|
|
relation => 'ngcp:'.$self->resource_name,
|
|
|
|
|
);
|
|
|
|
|
if(!$form){
|
|
|
|
|
($form,$form_exceptions) = $self->get_form($c);
|
|
|
|
|
}
|
|
|
|
|
if($form){
|
|
|
|
|
$self->validate_form(
|
|
|
|
|
c => $c,
|
|
|
|
|
resource => $resource,
|
|
|
|
|
form => $form,
|
|
|
|
|
run => 0,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
$resource->{id} = $self->get_item_id($c, $item);
|
|
|
|
|
$hal->resource({%$resource});
|
|
|
|
|
return $hal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$form //= $self->get_form($c);
|
|
|
|
|
sub update_item {
|
|
|
|
|
my ($self, $c, $item, $old_resource, $resource, $form, $params) = @_;
|
|
|
|
|
my ($form_exceptions, $process_extras);
|
|
|
|
|
($form, $form_exceptions, $process_extras) = @{$params}{qw/form form_exceptions process_extras/};
|
|
|
|
|
|
|
|
|
|
$self->validate_form(
|
|
|
|
|
c => $c,
|
|
|
|
|
resource => $resource,
|
|
|
|
|
form => $form,
|
|
|
|
|
run => 0,
|
|
|
|
|
);
|
|
|
|
|
if(!$form){
|
|
|
|
|
($form, $form_exceptions) = $self->get_form($c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($form){
|
|
|
|
|
return unless $self->validate_form(
|
|
|
|
|
c => $c,
|
|
|
|
|
resource => $resource,
|
|
|
|
|
form => $form,
|
|
|
|
|
$form_exceptions ? (exceptions => $form_exceptions) : (),
|
|
|
|
|
);
|
|
|
|
|
return unless $resource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$old_resource //= $self->resource_from_item($c, $item, $form);
|
|
|
|
|
|
|
|
|
|
$process_extras //= {};
|
|
|
|
|
|
|
|
|
|
return unless $self->process_form_resource($c, $item, $old_resource, $resource, $form, $process_extras);
|
|
|
|
|
return unless $resource;
|
|
|
|
|
return unless $self->check_duplicate($c, $item, $old_resource, $resource, $form, $process_extras);
|
|
|
|
|
return unless $self->check_resource($c, $item, $old_resource, $resource, $form, $process_extras);
|
|
|
|
|
|
|
|
|
|
$item = $self->update_item_model($c, $item, $old_resource, $resource, $form, $process_extras);
|
|
|
|
|
|
|
|
|
|
return $item, $form;
|
|
|
|
|
|
|
|
|
|
$resource->{id} = int($item->id);
|
|
|
|
|
$hal->resource({%$resource});
|
|
|
|
|
return $hal;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub hal_links {
|
|
|
|
|
my($self, $c, $item, $resource, $form) = @_;
|
|
|
|
|
return [];
|
|
|
|
|
#------ dummy & default methods
|
|
|
|
|
|
|
|
|
|
sub query_params {
|
|
|
|
|
return [
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub item_by_id {
|
|
|
|
|
my ($self, $c, $id) = @_;
|
|
|
|
|
my $item_rs = $self->item_rs($c);
|
|
|
|
|
return $item_rs->find($id);
|
|
|
|
|
sub _set_config{
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub update_item {
|
|
|
|
|
my ($self, $c, $item, $old_resource, $resource, $form) = @_;
|
|
|
|
|
sub check_duplicate{
|
|
|
|
|
my($self, $c, $item, $old_resource, $resource, $form) = @_;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$form //= $self->get_form($c);
|
|
|
|
|
return unless $self->validate_form(
|
|
|
|
|
c => $c,
|
|
|
|
|
form => $form,
|
|
|
|
|
resource => $resource,
|
|
|
|
|
);
|
|
|
|
|
last unless $resource;
|
|
|
|
|
$resource = $self->process_form_resource($c, $item, $old_resource, $resource, $form);
|
|
|
|
|
last unless $resource;
|
|
|
|
|
last unless $self->check_duplicate($c, $item, $old_resource, $resource, $form);
|
|
|
|
|
$item = $self->update($c, $item, $old_resource, $resource, $form);
|
|
|
|
|
return $item;
|
|
|
|
|
sub check_resource{
|
|
|
|
|
my($self, $c, $item, $old_resource, $resource, $form) = @_;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#process_form_resource - added as method for custom preparation form data,like:
|
|
|
|
|
# my $ft = File::Type->new();
|
|
|
|
|
# my $content_type = $ft->mime_type(${$process_extras->{binary_ref}});
|
|
|
|
|
# if($type eq 'mac') {
|
|
|
|
|
# $resource->{mac_image} = ${$process_extras->{binary_ref}};
|
|
|
|
|
# $resource->{mac_image_type} = $content_type;
|
|
|
|
|
# } else {
|
|
|
|
|
# $resource->{front_image} = ${$process_extras->{binary_ref}};
|
|
|
|
|
# $resource->{front_image_type} = $content_type;
|
|
|
|
|
# }
|
|
|
|
|
#
|
|
|
|
|
#etc. Method still can be used as exit point, if form data processing can be performed due to incorrect input data
|
|
|
|
|
#used in update_item
|
|
|
|
|
sub process_form_resource {
|
|
|
|
|
my($self, $c, $item, $old_resource, $resource, $form) = @_;
|
|
|
|
|
return $resource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#process_hal_resource is rarely used method, which intnded to transform somehow db resource data to the hal we want
|
|
|
|
|
#something like:
|
|
|
|
|
#$resource{contract_id} = delete $resource{peering_contract_id};
|
|
|
|
|
#used at least in hal_from_item
|
|
|
|
|
sub process_hal_resource {
|
|
|
|
|
my($self, $c, $item, $resource, $form) = @_;
|
|
|
|
|
return $resource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub update {
|
|
|
|
|
my($self, $c, $item, $old_resource, $resource, $form) = @_;
|
|
|
|
|
sub hal_links {
|
|
|
|
|
my($self, $c, $item, $resource, $form) = @_;
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub get_form {
|
|
|
|
|
my($self, $c) = @_;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub get_item_id{
|
|
|
|
|
my($self, $c, $item, $resource, $form) = @_;
|
|
|
|
|
return int($item->id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub item_by_id {
|
|
|
|
|
my ($self, $c, $id) = @_;
|
|
|
|
|
my $item_rs = $self->item_rs($c);
|
|
|
|
|
return $item_rs->find($id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub resource_from_item{
|
|
|
|
|
my($self, $c, $item) = @_;
|
|
|
|
|
my $res;
|
|
|
|
|
if('HASH' eq ref $item){
|
|
|
|
|
$res = $item;
|
|
|
|
|
}else{
|
|
|
|
|
$res = { $item->get_inflated_columns };
|
|
|
|
|
}
|
|
|
|
|
return $res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub update_item_model{
|
|
|
|
|
my($self, $c, $item, $old_resource, $resource, $form, $process_extras) = @_;
|
|
|
|
|
$item->update($resource);
|
|
|
|
|
return $item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#------ accessors ---
|
|
|
|
|
|
|
|
|
|
#------ accessors ---
|
|
|
|
|
|
|
|
|
|
sub dispatch_path {
|
|
|
|
|
my $self = shift;
|
|
|
|
|
return '/api/'.$self->resource_name.'/';
|
|
|
|
|
@ -738,8 +860,10 @@ sub relation {
|
|
|
|
|
my $self = shift;
|
|
|
|
|
return 'http://purl.org/sipwise/ngcp-api/#rel-'.$self->resource_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#------ /accessors ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub return_csv(){
|
|
|
|
|
my($self,$c) = @_;
|
|
|
|
|
try{
|
|
|
|
|
@ -751,8 +875,9 @@ sub return_csv(){
|
|
|
|
|
$self->create_csv($c);
|
|
|
|
|
$c->response->body(q());
|
|
|
|
|
}catch($e){
|
|
|
|
|
$self->error($c, HTTP_BAD_REQUEST, $e);
|
|
|
|
|
$self->error($c, HTTP_BAD_REQUEST, $e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
1;
|
|
|
|
|
# vim: set tabstop=4 expandtab:
|
|
|
|
|
|