| package Kalamar::Plugin::QueryReference; |
| use Mojo::Base 'Mojolicious::Plugin'; |
| |
| # This is a plugin to support query references. |
| # It currently only mocks endpoints for development purposes. |
| |
| sub register { |
| my ($plugin, $mojo) = @_; |
| |
| # Namespace not yet established |
| if ($ENV{QUERY_REF_MOCKUP}) { |
| unless (exists $mojo->renderer->helpers->{chi} && |
| $mojo->chi('queryref')) { |
| $mojo->plugin(CHI => { |
| queryref => { |
| driver => 'Memory', |
| global => 1 |
| } |
| }); |
| }; |
| }; |
| |
| # Establishes routes under '/query' |
| my $r = $mojo->routes; |
| |
| $r->add_type('qname' => qr![-_\.a-zA-Z0-9]+!); |
| |
| |
| # List queries |
| $r->get('/query')->to( |
| cb => sub { |
| my $c = shift; |
| |
| # Use mock up |
| if ($ENV{QUERY_REF_MOCKUP}) { |
| my $chi = $c->chi('queryref'); |
| my $qs = $chi->get('~queries') // []; |
| my @queries = (); |
| foreach (@$qs) { |
| push @queries, $chi->get($_); |
| }; |
| return $c->render(json => \@queries); |
| }; |
| |
| # Get user handle |
| my $user = $c->user_handle; |
| if ($user eq 'not_logged_in') { |
| return $c->render( |
| json => { |
| errors => [ |
| message => 'User not logged in' |
| ] |
| }, status => 400 |
| ); |
| }; |
| |
| $c->render_later; |
| |
| # API for query adding |
| my $url = Mojo::URL->new($c->korap->api); |
| $url->path->merge( |
| Mojo::Path->new->parts(['query', '~' . $user]) |
| )->trailing_slash(0); |
| |
| # Issue backend request |
| $c->korap_request('get', $url)->then( |
| sub { |
| my $tx = shift; |
| |
| # Catch errors and warnings |
| if ($c->catch_errors_and_warnings($tx)) { |
| my $json = $tx->res->json; |
| if ($json) { |
| $c->notify_on_warnings($json); |
| $c->stash(api_response => $json); |
| }; |
| return $c->render( |
| status => $tx->res->code, |
| json => $json |
| ); |
| }; |
| Mojo::Promise->reject; |
| } |
| )->catch( |
| sub { |
| my $err_msg = shift; |
| |
| # Only raised in case of connection errors |
| if ($err_msg) { |
| $c->notify(error => { src => 'Backend' } => $err_msg) |
| }; |
| |
| return $c->render( |
| status => 400, |
| json => $c->notifications(json => {}) |
| ); |
| } |
| ); |
| } |
| ); |
| |
| |
| # Create query |
| $r->put('/query/<qname:qname>')->to( |
| cb => sub { |
| my $c = shift; |
| my $v = $c->validation; |
| |
| # Missing: definition |
| $v->required('q'); |
| $v->optional('ql'); |
| $v->optional('desc'); |
| |
| my $qname = $c->stash('qname'); |
| |
| if ($v->has_error()) { |
| return $c->render( |
| json => { |
| errors => [ |
| { |
| message => 'Unable to store query reference' |
| } |
| ] |
| }, status => 400 |
| ); |
| }; |
| |
| # Use mock up |
| if ($ENV{QUERY_REF_MOCKUP}) { |
| my $chi = $c->chi('queryref'); |
| if ($chi->is_valid($qname)) { |
| return $c->render( |
| json => { |
| errors => [ |
| { |
| message => 'Unable to store query reference' |
| } |
| ] |
| }, status => 400 |
| ); |
| }; |
| |
| my $json = { |
| name => $qname, |
| # TODO: Actually this is KQ - not pq or similar |
| koralQuery => $v->param('q'), |
| q => $v->param('q'), |
| ql => ($v->param('ql') // 'poliqarp') |
| }; |
| |
| if ($v->param('desc')) { |
| $json->{description} = $v->param('desc'); |
| }; |
| |
| # Set query reference |
| $chi->set($qname => $json); |
| |
| my $queries = $chi->get('~queries') // []; |
| push @$queries, $qname; |
| $chi->set('~queries' => $queries); |
| |
| return $c->render( |
| status => 201, |
| text => '' |
| ); |
| }; |
| |
| # Get user handle |
| my $user = $c->user_handle; |
| if ($user eq 'not_logged_in') { |
| return $c->render( |
| json => { |
| errors => [ |
| message => 'User not logged in' |
| ] |
| }, status => 400 |
| ); |
| }; |
| |
| # API for query adding |
| my $url = Mojo::URL->new($c->korap->api); |
| $url->path->merge( |
| Mojo::Path->new->parts(['query', '~' . $user, $qname]) |
| )->trailing_slash(0); |
| |
| my $json = { |
| type => 'PRIVATE', |
| queryType => 'QUERY', |
| queryLanguage => ($v->param('ql') // 'poliqarp'), |
| query => $v->param('q') |
| }; |
| |
| if ($v->param('desc')) { |
| $json->{description} = $v->param('desc'); |
| }; |
| |
| $c->render_later; |
| |
| # Issue backend request |
| $c->korap_request('put', $url => json => $json)->then( |
| sub { |
| my $tx = shift; |
| |
| if ($tx->res->is_error) { |
| my $json = $tx->res->json; |
| $c->notify_on_warnings($json); |
| $c->stash(api_response => $json); |
| return $c->render( |
| status => $tx->res->code, |
| json => $json |
| ); |
| }; |
| |
| return $c->render( |
| status => 201, |
| text => '' |
| ); |
| } |
| )->catch( |
| sub { |
| my $err_msg = shift; |
| |
| # Only raised in case of connection errors |
| if ($err_msg) { |
| $c->notify(error => { src => 'Backend' } => $err_msg) |
| }; |
| |
| return $c->render( |
| status => 400, |
| json => $c->notifications(json => {}) |
| ); |
| } |
| ); |
| } |
| ); |
| |
| |
| # Delete query |
| $r->delete('/query/<qname:qname>')->to( |
| cb => sub { |
| my $c = shift; |
| my $qname = $c->stash('qname'); |
| |
| # Use mock up |
| if ($ENV{QUERY_REF_MOCKUP}) { |
| my $chi = $c->chi('queryref'); |
| |
| $chi->remove($qname); |
| |
| my $queries = $chi->get('~queries') // []; |
| |
| my @clean = (); |
| foreach (@$queries) { |
| push @clean, $_ unless $_ eq $qname |
| }; |
| $chi->set('~queries' => \@clean); |
| |
| return $c->render( |
| status => 200, |
| text => '' |
| ); |
| }; |
| |
| # Get user handle |
| my $user = $c->user_handle; |
| if ($user eq 'not_logged_in') { |
| return $c->render( |
| json => { |
| errors => [ |
| message => 'User not logged in' |
| ] |
| }, status => 400 |
| ); |
| }; |
| |
| $c->render_later; |
| |
| # API for query adding |
| my $url = Mojo::URL->new($c->korap->api); |
| $url->path->merge( |
| Mojo::Path->new->parts(['query', '~' . $user, $qname]) |
| )->trailing_slash(0); |
| |
| # Issue backend request |
| $c->korap_request('delete', $url)->then( |
| sub { |
| my $tx = shift; |
| |
| if ($tx->res->is_error) { |
| my $json = $tx->res->json; |
| $c->notify_on_warnings($json); |
| $c->stash(api_response => $json); |
| return $c->render( |
| status => $tx->res->code, |
| json => $json |
| ); |
| }; |
| |
| return $c->render( |
| status => 200, |
| text => '' |
| ); |
| } |
| )->catch( |
| sub { |
| my $err_msg = shift; |
| |
| # Only raised in case of connection errors |
| if ($err_msg) { |
| $c->notify(error => { src => 'Backend' } => $err_msg) |
| }; |
| |
| return $c->render( |
| status => 400, |
| json => $c->notifications(json => {}) |
| ); |
| } |
| ); |
| } |
| ); |
| |
| |
| # Retrieve query |
| $r->get('/query/<qname:qname>')->to( |
| cb => sub { |
| my $c = shift; |
| my $qname = $c->stash('qname'); |
| |
| # Use mock up |
| if ($ENV{QUERY_REF_MOCKUP}) { |
| my $chi = $c->chi('queryref'); |
| my $json = $chi->get($qname); |
| |
| if ($json) { |
| return $c->render( |
| json => $json |
| ); |
| }; |
| |
| return $c->render( |
| json => { |
| errors => [ |
| { |
| message => 'Query reference not found' |
| } |
| ] |
| }, status => 404 |
| ); |
| }; |
| |
| # Get user handle |
| my $user = $c->user_handle; |
| if ($user eq 'not_logged_in') { |
| return $c->render( |
| json => { |
| errors => [ |
| message => 'User not logged in' |
| ] |
| }, status => 400 |
| ); |
| }; |
| |
| # API for query adding |
| my $url = Mojo::URL->new($c->korap->api); |
| $url->path->merge( |
| Mojo::Path->new->parts(['query', '~' . $user, $qname]) |
| )->trailing_slash(0); |
| |
| # Issue backend request |
| $c->korap_request('get', $url)->then( |
| sub { |
| my $tx = shift; |
| |
| if ($tx->res->code == 404) { |
| return $c->render( |
| status => 404, |
| json => $tx->res->json |
| ); |
| }; |
| |
| # Catch errors and warnings |
| if ($c->catch_errors_and_warnings($tx)) { |
| my $json = $tx->res->json; |
| if ($json) { |
| $c->notify_on_warnings($json); |
| $c->stash(api_response => $json); |
| }; |
| return $c->render( |
| status => $tx->res->code, |
| json => $json |
| ); |
| }; |
| Mojo::Promise->reject; |
| } |
| )->catch( |
| sub { |
| my $err_msg = shift; |
| |
| # Only raised in case of connection errors |
| if ($err_msg) { |
| $c->notify(error => { src => 'Backend' } => $err_msg) |
| }; |
| |
| return $c->render( |
| status => 400, |
| json => $c->notifications(json => {}) |
| ); |
| } |
| ); |
| } |
| ); |
| }; |
| |
| |
| 1; |