[Rt-commit] rt branch, 5.0-trunk, updated. rt-5.0.1-21-g94c9c1d2d4

? sunnavy sunnavy at bestpractical.com
Fri Mar 5 12:06:50 EST 2021


The branch, 5.0-trunk has been updated
       via  94c9c1d2d457b0e8e8b3c7dbca1a8b28017b74e8 (commit)
       via  81dd62332e8293328e5bae2fd13a89f77ae72c85 (commit)
       via  6e64ebcd344f1634446e468f549b266327bb404e (commit)
       via  8c8151a7a2d3ddc22ace6ed0ef52a969966609e4 (commit)
       via  59d884ddfe16b29ed132d3823a7c4c1beb876158 (commit)
       via  750a8ecf07e0b0547c95e35907bba092ec7dd8ba (commit)
      from  15c75879685632f3d23f20d9460975a5a7476188 (commit)

Summary of changes:
 lib/RT/REST2.pm                                    | 18 ++++++++++
 lib/RT/REST2/Resource/Assets.pm                    |  1 +
 lib/RT/REST2/Resource/Collection.pm                | 21 +++++++++++-
 lib/RT/REST2/Resource/Collection/QueryByJSON.pm    | 28 +++++-----------
 .../{ProcessPOSTasGET.pm => QueryBySQL.pm}         | 39 ++++++++++++++++------
 lib/RT/REST2/Resource/Transactions.pm              |  1 +
 lib/RT/Transactions.pm                             |  8 +++--
 t/rest2/assets.t                                   | 17 ++++++++++
 t/rest2/transactions.t                             | 29 ++++++++++++++++
 9 files changed, 129 insertions(+), 33 deletions(-)
 copy lib/RT/REST2/Resource/Collection/{ProcessPOSTasGET.pm => QueryBySQL.pm} (76%)

- Log -----------------------------------------------------------------
commit 750a8ecf07e0b0547c95e35907bba092ec7dd8ba
Author: craig kaiser <craig at bestpractical.com>
Date:   Fri Feb 26 15:57:06 2021 -0500

    Support FromSQL queries for Assets and Transactions in REST2

diff --git a/lib/RT/REST2/Resource/Assets.pm b/lib/RT/REST2/Resource/Assets.pm
index 0b988d05ed..0c3069fd38 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 9dfb548b1a..e7feaffc19 100644
--- a/lib/RT/REST2/Resource/Collection.pm
+++ b/lib/RT/REST2/Resource/Collection.pm
@@ -58,7 +58,7 @@ extends 'RT::REST2::Resource';
 use Scalar::Util qw( blessed );
 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 RT::REST2::Util qw( serialize_record expand_uid format_datetime error_as_json );
 use POSIX qw( ceil );
 
 has 'collection_class' => (
@@ -99,6 +99,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 00e03e2e32..0caa28d7d1 100644
--- a/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
+++ b/lib/RT/REST2/Resource/Collection/QueryByJSON.pm
@@ -63,19 +63,20 @@ 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*\[/;
+    return JSON::decode_json($content);
 }
 
 sub allowed_methods {
@@ -86,16 +87,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 1 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 +115,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 0b988d05ed..c3493c67a4 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 ( my $query = $self->request->param('query') ) {
+        $query_sql = decode_utf8($query) unless $query =~ /^\s*\[/;
+    }
+
+    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 e7a318f82e..c83f5e3a9b 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 59d884ddfe16b29ed132d3823a7c4c1beb876158
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 1107831efe..7f87c8329c 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->CleanSlate;
+        $self->_InitSQL();
+    }
 
     return (1, $self->loc("No Query")) unless $query;
 

commit 8c8151a7a2d3ddc22ace6ed0ef52a969966609e4
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 6e64ebcd344f1634446e468f549b266327bb404e
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,

commit 81dd62332e8293328e5bae2fd13a89f77ae72c85
Author: craig kaiser <craig at bestpractical.com>
Date:   Fri Mar 5 08:40:29 2021 -0500

    Update REST2 docs for TransactionSQL and AssetSQL

diff --git a/lib/RT/REST2.pm b/lib/RT/REST2.pm
index 2ea9fb3201..957c778dc9 100644
--- a/lib/RT/REST2.pm
+++ b/lib/RT/REST2.pm
@@ -575,6 +575,10 @@ a single ticket id or an array.
 
 =head3 Transactions
 
+    GET /transactions?query=<TransactionSQL>
+    POST /transactions
+        search for transactions using TransactionSQL
+
     GET /transactions?query=<JSON>
     POST /transactions
         search for transactions using L</JSON searches> syntax
@@ -591,6 +595,12 @@ a single ticket id or an array.
     GET /transaction/:id
         retrieve a transaction
 
+=head3 Transactions Examples
+
+    # Search transactions using C<TransactionSQL>
+    curl -X POST -u 'root:password' -d "query=Creator='Dave' AND Type='Correspond'"
+        'https://myrt.com/REST/2.0/transactions'
+
 =head3 Attachments and Messages
 
     GET /attachments?query=<JSON>
@@ -642,6 +652,10 @@ a single ticket id or an array.
 
 =head3 Assets
 
+    GET /assets?query=<AssetSQL>
+    POST /assets
+        search for assets using AssetSQL
+
     GET /assets?query=<JSON>
     POST /assets
         search for assets using L</JSON searches> syntax
@@ -675,6 +689,10 @@ Below are some examples using the endpoints above.
     -d '[{ "field" : "id", "operator" : ">=", "value" : 0 }]'
     'https://myrt.com/REST/2.0/assets'
 
+    # Search assets using AssetSQL
+    curl -X POST -u 'root:password' -d "query=Catalog='General assets' AND 'CF.{Asset Type}' LIKE 'Computer'"
+        'https://myrt.com/REST/2.0/assets'
+
 =head3 Catalogs
 
     GET /catalogs/all

commit 94c9c1d2d457b0e8e8b3c7dbca1a8b28017b74e8
Merge: 15c7587968 81dd62332e
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Mar 6 00:40:58 2021 +0800

    Merge branch '5.0/rest2-add-asset-and-transaction-sql-endpoints' into 5.0-trunk


-----------------------------------------------------------------------


More information about the rt-commit mailing list