From e7ca25a311db1d861d03d6749fb293e92fbedad9 Mon Sep 17 00:00:00 2001 From: Arne Johannessen Date: Thu, 5 Dec 2024 02:40:35 +0100 Subject: [PATCH] Add support for Neo4j::Types Neo4j::Driver 1.02 no longer reblesses values received via Neo4j::Bolt. Like before, the returned values are still Neo4j::Types implementations, so their interface doesn't actually change. But the package name of such values changes from Neo4j::Driver::Type::* to Neo4j::Bolt::*, which trips up some checks in REST::Neo4p that expect to see "Driver" in the package name. Original discussion: https://github.com/majensen/perlbolt/pull/37 --- Build.PL | 2 +- lib/REST/Neo4p/Entity.pm | 3 ++- lib/REST/Neo4p/Node.pm | 6 +++--- lib/REST/Neo4p/Path.pm | 3 ++- lib/REST/Neo4p/Query.pm | 17 ++++++++++------- lib/REST/Neo4p/Relationship.pm | 6 +++--- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Build.PL b/Build.PL index d98a972..6e30372 100644 --- a/Build.PL +++ b/Build.PL @@ -78,7 +78,7 @@ my $build = $class->new 'experimental' => 0, 'MIME::Base64' => 0, perl => 5.010001, - 'Neo4j::Driver' => '0.19', + 'Neo4j::Driver' => '0.21', # Neo4j::Types }, recommends => { 'Mojo::UserAgent' => 0, diff --git a/lib/REST/Neo4p/Entity.pm b/lib/REST/Neo4p/Entity.pm index 2830371..737438f 100644 --- a/lib/REST/Neo4p/Entity.pm +++ b/lib/REST/Neo4p/Entity.pm @@ -4,6 +4,7 @@ package REST::Neo4p::Entity; use REST::Neo4p::Exceptions; use Carp qw(croak carp); use JSON; +use Scalar::Util qw(blessed); use URI::Escape; use strict; use warnings; @@ -65,7 +66,7 @@ sub new_from_json_response { unless (defined $decoded_resp) { REST::Neo4p::LocalException->throw("new_from_json_response() called with undef argument\n"); } - my $is_json = !(ref($decoded_resp) =~ /Neo4j::Driver/); + my $is_json = ! blessed $decoded_resp; # blessed via Neo4j::Driver unless ($ENTITY_TABLE->{$entity_type}{_actions} || !$is_json) { # capture the url suffix patterns for the entity actions: for (keys %$decoded_resp) { diff --git a/lib/REST/Neo4p/Node.pm b/lib/REST/Neo4p/Node.pm index ee54230..180b5da 100644 --- a/lib/REST/Neo4p/Node.pm +++ b/lib/REST/Neo4p/Node.pm @@ -222,8 +222,8 @@ sub simple_from_json_response { my $class = shift; my ($decoded_resp) = @_; my $ret; - for (ref $decoded_resp) { - /HASH/ && do { + for ($decoded_resp) { + ref eq 'HASH' && do { # node id ($ret->{_node}) = $decoded_resp->{self} =~ m{.*/([0-9]+)$}; # node properties @@ -235,7 +235,7 @@ sub simple_from_json_response { } last; }; - /Driver/ && do { + $_->isa('Neo4j::Types::Node') && do { # via Neo4j::Driver $ret->{_node} = $decoded_resp->id; $ret->{$_} = $decoded_resp->properties->{$_} for keys %{$decoded_resp->properties}; last; diff --git a/lib/REST/Neo4p/Path.pm b/lib/REST/Neo4p/Path.pm index ef4444d..258f55f 100644 --- a/lib/REST/Neo4p/Path.pm +++ b/lib/REST/Neo4p/Path.pm @@ -2,6 +2,7 @@ package REST::Neo4p::Path; use REST::Neo4p::Exceptions; use Carp qw(croak carp); +use Scalar::Util qw(blessed); use strict; use warnings; BEGIN { @@ -16,7 +17,7 @@ sub new { sub new_from_json_response { my $class = shift; my ($decoded_resp) = @_; - return $class->new_from_driver_obj(@_) if (ref($decoded_resp) =~ /Neo4j::Driver/); + return $class->new_from_driver_obj(@_) if blessed $decoded_resp; REST::Neo4p::LocalException->throw("Arg does not describe a Neo4j path response\n") unless $decoded_resp->{start} && $decoded_resp->{end} && $decoded_resp->{relationships} && $decoded_resp->{nodes}; my $obj = bless {}, $class; $obj->{_length} = $decoded_resp->{length}; diff --git a/lib/REST/Neo4p/Query.pm b/lib/REST/Neo4p/Query.pm index c29a098..f7b9804 100644 --- a/lib/REST/Neo4p/Query.pm +++ b/lib/REST/Neo4p/Query.pm @@ -5,6 +5,7 @@ use REST::Neo4p::Exceptions; use JSON::XS; use REST::Neo4p::ParseStream; use HOP::Stream qw/drop/; +use Scalar::Util qw(blessed); use Tie::IxHash; use File::Temp qw(:seekable); use Carp qw(croak carp); @@ -177,22 +178,24 @@ sub _wrap_statement_result { for (my $i=0;$i<$n;$i++) { my $elt = $rec->get($i); my $cvt = sub { - return $_[0] unless ref($_[0]) =~ /Driver/; - my ($type) = ref($_[0]) =~ /::([^:]+)$/; - my $cls = "REST::Neo4p::$type"; + return $_[0] unless blessed $_[0]; + my $cls = $_[0]->isa('Neo4j::Types::Node') ? 'REST::Neo4p::Node' + : $_[0]->isa('Neo4j::Types::Relationship') ? 'REST::Neo4p::Relationship' + : $_[0]->isa('Neo4j::Types::Path') ? 'REST::Neo4p::Path' + : undef or return $_[0]; # spatial/temporal values return $as_object ? $cls->new_from_json_response($_[0]) : $cls->simple_from_json_response($_[0]); }; - for (ref($elt)) { - /Driver/ && do { + for ($elt) { + blessed $_ && do { # Neo4j::Types::*, via Neo4j::Driver $elt = $cvt->($elt); }; - /HASH/ && do { + ref eq 'HASH' && do { for (keys %$elt) { $elt->{$_} = $cvt->($elt->{$_}) } }; - /ARRAY/ && do { + ref eq 'ARRAY' && do { for (@$elt) { $_ = $cvt->($_); } diff --git a/lib/REST/Neo4p/Relationship.pm b/lib/REST/Neo4p/Relationship.pm index 4feb419..a2cdc3e 100644 --- a/lib/REST/Neo4p/Relationship.pm +++ b/lib/REST/Neo4p/Relationship.pm @@ -49,8 +49,8 @@ sub simple_from_json_response { my $class = shift; my ($decoded_resp) = @_; my $ret; - for (ref $decoded_resp) { - /HASH/ && do { + for ($decoded_resp) { + ref eq 'HASH' && do { # reln id ($ret->{_relationship}) = $decoded_resp->{self} =~ m{.*/([0-9]+)$}; # reln type @@ -62,7 +62,7 @@ sub simple_from_json_response { ($ret->{_end}) = $decoded_resp->{end} =~ m{.*/([0-9]+)$}; last; }; - /Driver/ && do { + $_->isa('Neo4j::Types::Relationship') && do { # via Neo4j::Driver $ret->{_relationship} = $decoded_resp->id; $ret->{_type} = $decoded_resp->type; $ret->{$_} = $decoded_resp->properties->{$_} for keys %{$decoded_resp->properties};