[Rt-commit] rt branch, 5.0/rest2-add-asset-and-transaction-sql-endpoints, created. rt-5.0.0-4-g90cf24e377
Craig Kaiser
craig at bestpractical.com
Thu Mar 4 17:34:19 EST 2021
The branch, 5.0/rest2-add-asset-and-transaction-sql-endpoints has been created
at 90cf24e37742d5c7c56bd6a3865e8ac656a28b75 (commit)
- Log -----------------------------------------------------------------
commit fddc958fecbc8253a33cb726b8707169d2bf525f
Author: craig kaiser <craig at bestpractical.com>
Date: Fri Feb 26 15:57:06 2021 -0500
Add RT::REST2::Collection::QueryBySQL role
Break our JSON and SQL search into two seperate methods that are called
by RT::REST2::Collection::limit_collection.
diff --git a/lib/RT/REST2/Resource/Assets.pm b/lib/RT/REST2/Resource/Assets.pm
index 907534e9c6..676b559a58 100644
--- a/lib/RT/REST2/Resource/Assets.pm
+++ b/lib/RT/REST2/Resource/Assets.pm
@@ -55,6 +55,7 @@ use namespace::autoclean;
extends 'RT::REST2::Resource::Collection';
with 'RT::REST2::Resource::Collection::QueryByJSON';
+with 'RT::REST2::Resource::Collection::QueryBySQL';
sub dispatch_rules {
Path::Dispatcher::Rule::Regex->new(
diff --git a/lib/RT/REST2/Resource/Collection.pm b/lib/RT/REST2/Resource/Collection.pm
index 39cfecc2e2..30afde7657 100644
--- a/lib/RT/REST2/Resource/Collection.pm
+++ b/lib/RT/REST2/Resource/Collection.pm
@@ -60,6 +60,7 @@ use Web::Machine::FSM::States qw( is_status_code );
use Module::Runtime qw( require_module );
use RT::REST2::Util qw( serialize_record expand_uid format_datetime );
use POSIX qw( ceil );
+use RT::REST2::Util qw( error_as_json );
has 'collection_class' => (
is => 'ro',
@@ -99,6 +100,25 @@ sub limit_collection {
$collection->{'find_disabled_rows'} = 1
if $self->request->param('find_disabled_rows');
+ if ( $self->can('limit_collection_from_json') ) {
+ $self->limit_collection_from_json();
+ }
+ if ( $self->can('limit_collection_from_sql') ) {
+ my ($ret, $msg) = $self->limit_collection_from_sql();
+ return error_as_json( $self->response, $ret, $msg ) unless $ret;
+ }
+
+ my @orderby_cols;
+ my @orders = $self->request->param('order');
+ foreach my $orderby ($self->request->param('orderby')) {
+ my $order = shift @orders || 'ASC';
+ $order = uc($order);
+ $order = 'ASC' unless $order eq 'DESC';
+ push @orderby_cols, {FIELD => $orderby, ORDER => $order};
+ }
+ $self->collection->OrderByCols(@orderby_cols)
+ if @orderby_cols;
+
return 1;
}
diff --git a/lib/RT/REST2/Resource/Collection/QueryByJSON.pm b/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
index 9b415d575f..2a9c023bff 100644
--- a/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
+++ b/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
@@ -63,19 +63,22 @@ with (
requires 'collection';
-has 'query' => (
+has 'query_json' => (
is => 'ro',
isa => 'ArrayRef[HashRef]',
required => 1,
lazy_build => 1,
);
-sub _build_query {
+sub _build_query_json {
my $self = shift;
my $content = $self->request->method eq 'GET'
? $self->request->param('query')
: $self->request->content;
- return $content ? JSON::decode_json($content) : [];
+ return [] unless $content && $content =~ /\s*\[/;
+
+ $content = $content ? JSON::decode_json($content) : [];
+ return $content;
}
sub allowed_methods {
@@ -86,16 +89,16 @@ sub searchable_fields {
$_[0]->collection->RecordClass->ReadableAttributes
}
-sub limit_collection {
+sub limit_collection_from_json {
my $self = shift;
my $collection = $self->collection;
- my $query = $self->query;
+ my $query = $self->query_json;
+
+ return unless ref $query eq 'ARRAY' && scalar @{$query};
+
my @fields = $self->searchable_fields;
my %searchable = map {; $_ => 1 } @fields;
- $collection->{'find_disabled_rows'} = 1
- if $self->request->param('find_disabled_rows');
-
for my $limit (@$query) {
next unless $limit->{field}
and $searchable{$limit->{field}}
@@ -114,17 +117,6 @@ sub limit_collection {
);
}
- my @orderby_cols;
- my @orders = $self->request->param('order');
- foreach my $orderby ($self->request->param('orderby')) {
- my $order = shift @orders || 'ASC';
- $order = uc($order);
- $order = 'ASC' unless $order eq 'DESC';
- push @orderby_cols, {FIELD => $orderby, ORDER => $order};
- }
- $self->collection->OrderByCols(@orderby_cols)
- if @orderby_cols;
-
return 1;
}
diff --git a/lib/RT/REST2/Resource/Assets.pm b/lib/RT/REST2/Resource/Collection/QueryBySQL.pm
similarity index 74%
copy from lib/RT/REST2/Resource/Assets.pm
copy to lib/RT/REST2/Resource/Collection/QueryBySQL.pm
index 907534e9c6..bda813cd75 100644
--- a/lib/RT/REST2/Resource/Assets.pm
+++ b/lib/RT/REST2/Resource/Collection/QueryBySQL.pm
@@ -46,23 +46,43 @@
#
# END BPS TAGGED BLOCK }}}
-package RT::REST2::Resource::Assets;
+package RT::REST2::Resource::Collection::QueryBySQL;
use strict;
use warnings;
-use Moose;
+use Moose::Role;
use namespace::autoclean;
-extends 'RT::REST2::Resource::Collection';
-with 'RT::REST2::Resource::Collection::QueryByJSON';
+use Encode qw( decode_utf8 );
-sub dispatch_rules {
- Path::Dispatcher::Rule::Regex->new(
- regex => qr{^/assets/?$},
- block => sub { { collection_class => 'RT::Assets' } },
- )
+requires 'collection';
+
+has 'query_sql' => (
+ is => 'ro',
+ isa => 'Str',
+ required => 1,
+ lazy_build => 1,
+);
+
+sub _build_query_sql {
+ my $self = shift;
+
+ my $query_sql = "";
+ if ( $self->request->method eq 'GET' && $self->request->param('query') ) {
+ $query_sql = decode_utf8($self->request->param('query') || "");
+ }
+
+ return $query_sql;
}
-__PACKAGE__->meta->make_immutable;
+sub limit_collection_from_sql {
+ my $self = shift;
+ return 1 unless $self->query_sql;
+
+ my ($ok, $msg) = $self->collection->FromSQL( $self->query_sql );
+ return ( 0, $msg ) unless $ok;
+
+ return 1;
+};
1;
diff --git a/lib/RT/REST2/Resource/Transactions.pm b/lib/RT/REST2/Resource/Transactions.pm
index 719a4e754a..fe0527c8ea 100644
--- a/lib/RT/REST2/Resource/Transactions.pm
+++ b/lib/RT/REST2/Resource/Transactions.pm
@@ -55,6 +55,7 @@ use namespace::autoclean;
extends 'RT::REST2::Resource::Collection';
with 'RT::REST2::Resource::Collection::QueryByJSON';
+with 'RT::REST2::Resource::Collection::QueryBySQL';
sub dispatch_rules {
Path::Dispatcher::Rule::Regex->new(
commit 3eb0917e3754ba113b45b02cf1f4e595b1c2cf65
Author: craig kaiser <craig at bestpractical.com>
Date: Mon Mar 1 09:55:57 2021 -0500
Preserve first_row and show_rows across the CleanSlate
diff --git a/lib/RT/Transactions.pm b/lib/RT/Transactions.pm
index 43458aaaf9..88ae9c21aa 100644
--- a/lib/RT/Transactions.pm
+++ b/lib/RT/Transactions.pm
@@ -1080,8 +1080,12 @@ sub _parser {
sub FromSQL {
my ($self,$query) = @_;
- $self->CleanSlate;
- $self->_InitSQL;
+ {
+ # preserve first_row and show_rows across the CleanSlate
+ local ($self->{'first_row'}, $self->{'show_rows'}, $self->{_sql_looking_at});
+ $self->CleanSlate;
+ $self->_InitSQL();
+ }
return (1, $self->loc("No Query")) unless $query;
commit bc3c1e62e100af8ecb30d1c734a902673fc1d025
Author: craig kaiser <craig at bestpractical.com>
Date: Mon Mar 1 13:07:00 2021 -0500
Add test for REST2 assetSQL search
diff --git a/t/rest2/assets.t b/t/rest2/assets.t
index 1f1712bfed..619564ae9c 100644
--- a/t/rest2/assets.t
+++ b/t/rest2/assets.t
@@ -142,6 +142,23 @@ my ($asset_url, $asset_id);
is($asset->{type}, 'asset');
is($asset->{id}, 1);
like($asset->{_url}, qr{$rest_base_path/asset/1$});
+
+ # Ensure our JSON search matches the assetSQL search
+ $res = $mech->get("$rest_base_path/assets?query=id>0",
+ 'Authorization' => $auth,
+ );
+ is($res->code, 200);
+ $content = $mech->json_response;
+ is($content->{count}, 1);
+ is($content->{page}, 1);
+ is($content->{per_page}, 20);
+ is($content->{total}, 1);
+ is(scalar @{$content->{items}}, 1);
+
+ $asset = $content->{items}->[0];
+ is($asset->{type}, 'asset');
+ is($asset->{id}, 1);
+ like($asset->{_url}, qr{$rest_base_path/asset/1$});
}
# Asset Update
commit 90cf24e37742d5c7c56bd6a3865e8ac656a28b75
Author: craig kaiser <craig at bestpractical.com>
Date: Mon Mar 1 13:09:28 2021 -0500
Add test for REST2 transactionSQL search
diff --git a/t/rest2/transactions.t b/t/rest2/transactions.t
index 65e705d8f9..6096b54c6c 100644
--- a/t/rest2/transactions.t
+++ b/t/rest2/transactions.t
@@ -59,6 +59,35 @@ my ($comment_txn_url, $comment_txn_id);
ok(($comment_txn_id) = $comment_txn_url =~ qr[/transaction/(\d+)]);
}
+# search transactions for a specific ticket using TransactionSQL
+{
+ my $res = $mech->get("$rest_base_path/transactions?query=ObjectType='RT::Ticket' AND ObjectId=".$ticket->Id,
+ 'Authorization' => $auth,
+ );
+ is($res->code, 200);
+
+ my $content = $mech->json_response;
+ is($content->{count}, 5);
+ is($content->{page}, 1);
+ is($content->{per_page}, 20);
+ is($content->{total}, 5);
+ is(scalar @{$content->{items}}, 5);
+
+ my ($create, $priority1, $subject, $priority2, $comment) = @{ $content->{items} };
+
+ is($create->{type}, 'transaction');
+ is($priority1->{type}, 'transaction');
+ is($subject->{type}, 'transaction');
+ is($priority2->{type}, 'transaction');
+ is($comment->{type}, 'transaction');
+
+ $create_txn_url = $create->{_url};
+ ok(($create_txn_id) = $create_txn_url =~ qr[/transaction/(\d+)]);
+
+ $comment_txn_url = $comment->{_url};
+ ok(($comment_txn_id) = $comment_txn_url =~ qr[/transaction/(\d+)]);
+}
+
# Transaction display
{
my $res = $mech->get($create_txn_url,
-----------------------------------------------------------------------
More information about the rt-commit
mailing list