use v5.14;
use warnings;
package Neo4j::Driver::Result::JSON 1.02;
# ABSTRACT: JSON/REST result handler
# This package is not part of the public Neo4j::Driver API.
use parent 'Neo4j::Driver::Resu
use Carp qw(croak);
our @CARP_NOT = qw(Neo4j::Driver::Net::HTTP);
use Feature::Compat::Try;
use JSON::MaybeXS 1.002004 ();
use Neo4j::Driver::Type::Bytes;
use Neo4j::Driver::Type::DateTime;
use Neo
n/json";
my $ACCEPT_HEADER = "$MEDIA_TYPE";
my $ACCEPT_HEADER_POST = "$MEDIA_TYPE;q=0.5";
sub new {
# uncoverable pod (private method)
my ($class, $params) = @_;
my $json = $class->_parse_json(
TP);
use HTTP::Tiny 0.034 ();
use JSON::MaybeXS 1.003003 ();
use URI 1.25 ();
use URI::Escape 3.26 ();
my %DEFAULT_HEADERS = (
'Content-Type' => 'application/json',
'X-Stream' => 'true',
);
# Use
e pod
my ($class, $driver) = @_;
my $config = $driver->{config};
my $self = bless {
json_coder => JSON::MaybeXS->new( utf8 => 1, allow_nonref => 0 ),
}, $class;
my $uri = $config->{uri};
i
$self->{uri_base};
}
# Return a JSON:XS-compatible coder object (for result parsers).
sub json_coder {
# uncoverable pod
my $self = shift;
return $self->{json_coder};
}
# Return the HTTP Dat
) = @$statement;
my $json = { statement => '' . $cypher };
$json->{resultDataContents} = $RESULT_DATA_CONTENTS;
$json->{includeStats} = \1 if $self->{return_stats};
$json->{parameters} = $parame
ters if %$parameters;
return $json;
}
sub _begin {
my ($self) = @_;
# no-op for HTTP
return $self;
}
sub _run_autocommit {
my ($self, $query, @parameters) = @_;
$self->{transaction_end
+ $scalar,
string => '' . $scalar,
true => builtin::true, # or JSON::PP::true
false => builtin::false, # or JSON::PP::false
null => undef,
list => [ ],
map => { },
};
the same, but it should be good enough for us.
# (original idea from https://github.com/makamaka/JSON-PP/commit/87bd6a4)
sub _SvNIOKp {
no warnings 'numeric';
return length( (my $string = '') & shi
false|builtin/"false">) are only available
starting with Perl v5.36. On older Perls, L<JSON::PP>::true
and L<JSON::PP>::false are used instead. These are blessed
objects overloaded to evaluate correct
pressions. If necessary, you can force
conversion of such values into the correct type by using
L<JSON::Types> or with simple unary coercions like this:
$number = 0 + $scalar;
$string = '' . $scal
n/"false"> in query parameters
requires recent enough JSON module versions
(S<L<Cpanel::JSON::XS> 4.38> / S<L<JSON::PP> 4.11>).
=back
=head2 JSON networking
For connecting to a Neo4j server earlier
config(jolt => undef); # prefer Jolt v2 (the default)
$d->config(jolt => 0); # accept only JSON
$d->config(jolt => 1); # accept only Jolt v2
# Accept only Jolt and request ...
$d->con
ig(jolt => 'ndjson'); # newline delimited mode (non RFC)
Since driver S<version 0.24>, the
L<Jolt|https://neo4j.com/docs/http-api/4.3/actions/result-format/#_jolt>
response format (JSON Bolt) is pre
ferred for HTTP connections
because the older REST-style JSON response format has several
known issues and is much slower than Jolt.
This option is no longer useful. The driver will pick the fastest
b/Neo4j/Driver/Net.pod>
for more information.
$adapter->request('GET', '/', undef, 'application/json');
$status = $adapter->http_header->{status};
$type = $adapter->http_header->{content_type}
st.
A future version of this driver will likely replace this method
with something that performs JSON decoding on the event before
returning it; this change may allow for better optimisation of
Jolt
ders and status of the last response.
=over
=item * C<content_type> – S<e. g.> C<"application/json">
=item * C<location> – URI reference
=item * C<status> – status code, S<e. g.> C<"404">
=
elf->{attached} = $fake_attached;
return $self if $fake_attached; # (only used in testing)
# JSON results are completely available immediately and can be fully
# buffered right away, avoiding th
lf) = @_;
# simulate a JSON-backed result stream (only used in testing, $fake_attached 1)
$self->{json_cursor} //= 0;
my $record = $self->{result}->{data}->[ $self->{json_cursor}++ ];
return und
ge v5.36 ) {
return builtin::false(), builtin::true();
}
else {
require JSON::PP;
return JSON::PP::false(), JSON::PP::true();
}
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
Neo4j::Dr
un($tx, @statements);
# Parsing a JSON result
die unless $helper->{http_agent}->http_header->{success};
$json_coder = $helper->{http_agent}->json_coder;
$json_coder->decode( $helper->{http_agent
on-3.4.1>)
to obtain a suitable response from the Neo4j server. The driver
supports both Jolt and JSON as result formats. There is also
a fallback result handler, which is used to parse error
messages
s compatibility,
a lot of the internal data structures currently (0.52) match the
format of Neo4j JSON responses.
The first HTTP connection to a Neo4j server is always made to the
L<Discovery API|htt
@CARP_NOT = qw(
Neo4j::Driver::Result::Bolt
Neo4j::Driver::Result::Jolt
Neo4j::Driver::Result::JSON
Neo4j::Driver::Result::Text
);
use Scalar::Util qw(weaken);
our $STACK_TRACE = 0; # die with
use Neo4j::Driver::Net::HTTP::Tiny;
use Neo4j::Driver::Result::Jolt;
use Neo4j::Driver::Result::JSON;
use Neo4j::Driver::Result::Text;
use Neo4j::Driver::ServerInfo;
my $DISCOVERY_ENDPOINT = '/';
ENDPOINT = 'commit';
my @RESULT_MODULES = qw( Neo4j::Driver::Result::Jolt Neo4j::Driver::Result::JSON );
my $RESULT_FALLBACK = 'Neo4j::Driver::Result::Text';
my $RFC5322_DATE = '%a, %d %b %Y %H:%M:%
ransaction_endpoint => shift @discovery_queue,
};
my $service = $self->_request($tx, 'GET')->_json;
$neo4j_version = $service->{neo4j_version};
$tx_endpoint = $service->{transaction};
las
ationship 1.02;
# ABSTRACT: Describes a relationship from a Neo4j graph, delivered via Jolt v1 or JSON
# For documentation, see Neo4j::Driver::Types.
use parent 'Neo4j::Driver::Type::Relationship'
r::Type::V1::Node 1.02;
# ABSTRACT: Describes a node from a Neo4j graph, delivered via Jolt v1 or JSON
# For documentation, see Neo4j::Driver::Types.
use parent 'Neo4j::Driver::Type::Node';
sub
on_error} = 0;
# $d->{net_module} = 'Neo4j::Driver::Net::HTTP::AnyEvent';
# $d->{jolt} = 'ndjson'; # 'ndjson' might be problematic for some reason ... whatever, it's unsupported anyway
#XXX $d->sessi
if defined $v && ! _looks_like_number $v;
$t = ref($v) if ref($v);
$t .= " \\$v" if ref($v) eq 'JSON::PP::Boolean';
$t .= " " . $v->id . " " . join ",", map {":$_"} $v->labels if ref($v) eq 'Neo4j:
ic type instead (requires Types v2);
also, the Types generic constructor should prolly accept the JSON int array, so
that users at least have a simple way to manually get a unified API.
=item * Gener
at the top of the list.)
=item * Refactor Node etc. to match the Jolt data structures instead of JSON;
refactor Record to be implemented as just a single array representing the row,
with the (C<get("
e check if for DELETE requests, accepting only Jolt yields an
octet-stream response that contains JSON; if so, perhaps add to #12644 report
=back
=head2 L<Neo4j::Driver::ResultSummary>
=over
=item
ref($v) if ref($v);
$t .= " (core bool)" if builtin::is_bool($v);
$t .= " \\$v" if ref($v) eq 'JSON::PP::Boolean';
$t .= " " . $v->type if blessed $v && $v->isa('Neo4j::Types::DateTime');
$t .= s
URN n.test')->single->get;
# Byte array in JSON:
# { meta => [undef], rest => [[70, 111, 111]], row => [[70, 111, 111]] }
# at lib/Neo4j/Driver/Result/JSON.pm line 139
# Byte array in Jolt:
# { "#"
cert'); # 4
my $m = Neo4j::Driver::Net::HTTP::AnyEvent->new($d);
my $type;
$type = 'application/json';
#$type = 'text/html';
$m->request('GET', 'http://localhost:7474/', undef, $type);
YYY $m->http_
lt';
use Carp qw(croak);
our @CARP_NOT = qw(Neo4j::Driver::Net::HTTP Neo4j::Driver::Result);
use JSON::MaybeXS 1.002004 ();
use Neo4j::Driver::Type::Bytes;
use Neo4j::Driver::Type::DateTime;
use Neo
= "$MEDIA_TYPE-v2+json-seq";
my $ACCEPT_HEADER_V1 = "$MEDIA_TYPE+json-seq";
my $ACCEPT_HEADER_STRICT = "$MEDIA_TYPE+json-seq;strict=true";
my $ACCEPT_HEADER_SPARSE = "$MEDIA_TYPE+json-seq;strict=false
";
my $ACCEPT_HEADER_NDJSON = "$MEDIA_TYPE";
my @CYPHER_TYPES = (
{ # Types with legacy numeric ID (Jolt v1)
node => 'Neo4j::Driver::Type::V1::Node',
relationship => 'Neo4j::Driver::Type::V1::R
j::Driver::Net::Bolt;
our $gather_results = 0; # 1: detach from the stream immediately (yields JSON-style result; used for testing)
sub new {
# uncoverable pod (private method)
my ($class, $par
se JSON::MaybeXS 1.003003 qw();
use LWP::UserAgent 6.04 qw();
use URI 1.31;
my $CONTENT_TYPE = 'application/json';
sub new {
my ($class, $driver) = @_;
my $self = bless {
json_coder => JSON::
;
}
return $self;
}
sub ua { shift->{agent} }
sub uri { shift->{uri_base} }
sub json_coder { shift->{json_coder} }
sub http_reason { shift->{response}->message // '' }
sub date_header { scal
{
my ($self, $method, $url, $json, $accept, $mode) = @_;
$self->{buffer} = undef;
$url = URI->new_abs( $url, $self->{uri_base} );
$method = lc $method;
if ($json) {
$self->{response} = $sel
tions will use B<Jolt> (JSON Bolt) when offered by the server.
For older Neo4j servers (before S<version 4.2>), the driver
will automatically fall back to slower REST-style JSON.
The driver also supp