|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
36
  
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
503
 | 
 use v5.10;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
138
 | 
    | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package REST::Neo4p::Query;  | 
| 
3
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
15393
 | 
 use REST::Neo4p::Path;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1121
 | 
    | 
| 
4
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
257
 | 
 use REST::Neo4p::Exceptions;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
610
 | 
    | 
| 
5
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
1699
 | 
 use JSON::XS;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7302
 | 
    | 
| 
6
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
16464
 | 
 use REST::Neo4p::ParseStream;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2166
 | 
    | 
| 
7
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
264
 | 
 use HOP::Stream qw/drop/;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5830
 | 
    | 
| 
8
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
19977
 | 
 use Tie::IxHash;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
114151
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1393
 | 
    | 
| 
9
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
275
 | 
 use File::Temp qw(:seekable);  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5441
 | 
    | 
| 
10
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
261
 | 
 use Carp qw(croak carp);  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
65
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1627
 | 
    | 
| 
11
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
208
 | 
 use strict;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
676
 | 
    | 
| 
12
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
166
 | 
 use warnings;  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
986
 | 
    | 
| 
13
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
178
 | 
 no warnings qw(once);  | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
 
 | 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1368
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 BEGIN {  | 
| 
16
 | 
36
 | 
 
 | 
 
 | 
  
36
  
 | 
 
 | 
148162
 | 
   $REST::Neo4p::Query::VERSION = '0.4001';  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $BUFSIZE = 50000;  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
22
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
1
  
 | 
3747
 | 
   my $class = shift;  | 
| 
23
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
   my ($q_string, $params) = @_;  | 
| 
24
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
33
 | 
   unless (defined $q_string and !ref $q_string) {  | 
| 
25
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     REST::Neo4p::LocalException->throw( "First argument must be the query string\n");  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
27
 | 
2
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
21
 | 
   unless (!defined $params || ref($params) eq 'HASH') {  | 
| 
28
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     REST::Neo4p::LocalException->throw( "Second argment must be a hashref of query parameters\n" );  | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
30
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   $q_string =~ s/\s/ /g;  | 
| 
31
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   ($q_string) = $q_string =~ m/^\s*(.*)\s*$/;  | 
| 
32
 | 
2
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
33
 | 
   bless { '_query' => $q_string,  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  '_params' => $params || {},  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  '_handle' => REST::Neo4p->handle, # current handle  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  'Statement' => $q_string,  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  'NUM_OF_PARAMS' => $params ? scalar keys %$params : 0,  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #	  'ParamValues' => $params,  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  'ResponseAsObjects' => 1,  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  '_tempfile' => ''  | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}, $class;  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
42
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
6
 | 
 sub tmpf { shift->{_tempfile} }  | 
| 
43
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
49
 | 
 sub _handle { shift->{_handle} }  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub execute {  | 
| 
45
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
  
1
  
 | 
4109
 | 
   my $self = shift;  | 
| 
46
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
   my @params = @_;  | 
| 
47
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my %params;  | 
| 
48
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
31
 | 
   if (@params) {  | 
| 
49
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     %params = ref $params[0] ? %{$params[0]} : @params;  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
50
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{_params} = \%params;  | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # current handle  | 
| 
53
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   local $REST::Neo4p::HANDLE;  | 
| 
54
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
   REST::Neo4p->set_handle($self->_handle);  | 
| 
55
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
   REST::Neo4p::CommException->throw("Not connected\n") unless REST::Neo4p->connected;  | 
| 
56
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
   my $agent = REST::Neo4p->agent;  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
89
 | 
   if ($agent->batch_mode) {  | 
| 
59
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     REST::Neo4p::NotSuppException->throw("Query execution not supported in batch mode\n");  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
61
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
850
 | 
   delete $self->{_error};  | 
| 
62
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   delete $self->{_error_list};  | 
| 
63
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
   delete $self->{_decoded_resp};  | 
| 
64
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   delete $self->{NAME};  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
66
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   my $endpt = 'post_'.REST::Neo4p->q_endpoint;  | 
| 
67
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
   $self->{_tempfile} = File::Temp->new;  | 
| 
68
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4567
 | 
   unless ($self->tmpf) {  | 
| 
69
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     REST::Neo4p::LocalException->throw(  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       "Can't create query result tempfile : $!\n"  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
      );  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
73
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2298
 | 
   eval {  | 
| 
74
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     for ($endpt) {  | 
| 
75
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
       /cypher/ && do {  | 
| 
76
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	$agent->$endpt(  | 
| 
77
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  [],   | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  { query => $self->query, params => $self->params },  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {':content_file' => $self->tmpf->filename}  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 );  | 
| 
81
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
459
 | 
 	last;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
83
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
22
 | 
       /transaction/ && do {  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# unfortunately, the order of 'statement' and 'parameters'  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# is strict in the content (2.0.0-M06)  | 
| 
86
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 	tie my %stmt, 'Tie::IxHash';  | 
| 
87
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
98
 | 
 	$stmt{statement} = $self->query;  | 
| 
88
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
100
 | 
 	$stmt{parameters} = $self->params;  | 
| 
89
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
 	$agent->$endpt(  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  [REST::Neo4p->_transaction],  | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {   | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    statements => [ \%stmt ]  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	   },  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  {':content_file' => $self->tmpf->filename}  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 );  | 
| 
96
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
417
 | 
 	last;  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
98
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       do {  | 
| 
99
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	REST::Neo4p::TxException->throw(  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  "Unknown query REST endpoint '".REST::Neo4p->q_endpoint."'\n"  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	 );  | 
| 
102
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
105
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
   if (my $e = REST::Neo4p::Neo4jException->caught ) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{_error} = $e;  | 
| 
107
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $e->can('error_list') && ($self->{_error_list} = $e->error_list);  | 
| 
108
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $e->rethrow if ($self->{RaiseError});  | 
| 
109
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif ($e = REST::Neo4p::Exception->caught()) {  | 
| 
112
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{_error} = $e;  | 
| 
113
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $e->rethrow if ($self->{RaiseError});  | 
| 
114
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif ( $e = Exception::Class->caught) {  | 
| 
117
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     (ref $e && $e->can("rethrow")) ? $e->rethrow : die $e;  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
119
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
264
 | 
   if ( ref(REST::Neo4p->agent) !~ /Neo4j::Driver/ ) {  | 
| 
120
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
     $self->_parse_response;  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   else { # Neo4j::Driver  | 
| 
123
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->_wrap_statement_result;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
125
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
   1;  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub fetchrow_arrayref {   | 
| 
129
 | 
29
 | 
 
 | 
 
 | 
  
29
  
 | 
  
1
  
 | 
53
 | 
   my $self = shift;  | 
| 
130
 | 
29
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
89
 | 
   unless ( defined $self->{_iterator} ) {  | 
| 
131
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     REST::Neo4p::LocalException->throw("Can't run fetch(), query not execute()'d yet\nCheck query object for error with err()/errstr()\n");  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
133
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
   $self->{_iterator}->();  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
29
 | 
 
 | 
 
 | 
  
29
  
 | 
  
1
  
 | 
25921
 | 
 sub fetch { shift->fetchrow_arrayref(@_) }  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub column_names {  | 
| 
139
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
0
  
 | 
0
 | 
   my $self = shift;  | 
| 
140
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   return $self->{_column_names} && @{$self->{_column_names}};  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub err {   | 
| 
144
 | 
16
 | 
 
 | 
 
 | 
  
16
  
 | 
  
1
  
 | 
12701
 | 
   my $self = shift;  | 
| 
145
 | 
16
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
62
 | 
   return $self->{_error} && ($self->{_error}->code || 599);  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub errstr {   | 
| 
149
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
150
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   return $self->{_error} && ( $self->{_error}->message || $self->{_error}->neo4j_message );  | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
1
  
 | 
944
 | 
 sub errobj { shift->{_error} }  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub err_list {  | 
| 
156
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my $self = shift;  | 
| 
157
 | 
  
0
  
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   return $self->{_error} && $self->{_error_list};  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
0
  
 | 
56
 | 
 sub query { shift->{_query} }  | 
| 
162
 | 
11
 | 
 
 | 
 
 | 
  
11
  
 | 
  
0
  
 | 
53
 | 
 sub params { shift->{_params} }  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _wrap_statement_result {  | 
| 
166
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
   my $self = shift;  | 
| 
167
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $result = REST::Neo4p->agent->last_result;  | 
| 
168
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $errors = REST::Neo4p->agent->last_errors;  | 
| 
169
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $self->{NAME} = $result->keys;  | 
| 
170
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $n = $self->{NUM_OF_FIELDS} = scalar @{$self->{NAME}};  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $self->{_iterator} = sub {  | 
| 
172
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
     my @row;  | 
| 
173
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $rec =  $result->fetch;  | 
| 
174
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return unless $rec;  | 
| 
175
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     eval {  | 
| 
176
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $as_object = $self->{ResponseAsObjects};  | 
| 
177
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       for (my $i=0;$i<$n;$i++) {  | 
| 
178
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $elt = $rec->get($i);  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	my $cvt = sub {  | 
| 
180
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  return $_[0] unless ref($_[0]) =~ /Driver/;  | 
| 
181
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  my ($type) = ref($_[0]) =~ /::([^:]+)$/;  | 
| 
182
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  my $cls = "REST::Neo4p::$type";  | 
| 
183
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  return $as_object ? $cls->new_from_json_response($_[0]) :  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    $cls->simple_from_json_response($_[0]);  | 
| 
185
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  };  | 
| 
186
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for (ref($elt)) {  | 
| 
187
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  /Driver/ && do {  | 
| 
188
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $elt = $cvt->($elt);  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  };  | 
| 
190
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  /HASH/ && do {  | 
| 
191
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    for (keys %$elt) {  | 
| 
192
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $elt->{$_} = $cvt->($elt->{$_})  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  };  | 
| 
195
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  /ARRAY/ && do {  | 
| 
196
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    for (@$elt) {  | 
| 
197
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $_ = $cvt->($_);  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  };  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  #else  | 
| 
201
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  push @row, $elt;  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
205
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if (my $e = Exception::Class->caught()) {  | 
| 
206
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($e =~ /j_parse|json/i) {  | 
| 
207
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$e = REST::Neo4p::StreamException->new(message => $e);  | 
| 
208
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$self->{_error} = $e;  | 
| 
209
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	$e->throw if $self->{RaiseError};  | 
| 
210
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return;  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       else {  | 
| 
213
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	die $e;  | 
| 
214
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # flatten if single array ref returned  | 
| 
217
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if (@row==1 and ref($row[0]) eq 'ARRAY') {  | 
| 
218
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return $row[0];  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
221
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return \@row;  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
223
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   };  | 
| 
224
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return;  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _parse_response sets up an iterator that pulls a row's worth of objects from  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # the servers JSON stream, parses the row into objects, and returns the row.  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # this iterator is placed in $self->{_iterator} as a side effect.  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # It is hit in fetchrow_arrayref.  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _parse_response {  | 
| 
233
 | 
10
 | 
 
 | 
 
 | 
  
10
  
 | 
 
 | 
20
 | 
   my $self = shift;  | 
| 
234
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
62
 | 
   my $jsonr = JSON::XS->new->utf8;  | 
| 
235
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
   my ($buf,$res,$str,$rowstr,$obj);  | 
| 
236
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $row_count;  | 
| 
237
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
   $self->tmpf->read($buf, $BUFSIZE);  | 
| 
238
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
272
 | 
   $jsonr->incr_parse($buf);  | 
| 
239
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
   eval { # capture j_parse errors  | 
| 
240
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     $res = j_parse($jsonr);  | 
| 
241
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
     die 'j_parse: No text to parse' unless $res;  | 
| 
242
 | 
10
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
72
 | 
     die 'j_parse: JSON is not a query or txn response' unless $res->[0] =~ /QUERY|TXN/;  | 
| 
243
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
     for ($res->[0]) {  | 
| 
244
 | 
9
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
       /QUERY/ && do {  | 
| 
245
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	$obj = drop($str = $res->[1]->());  | 
| 
246
 | 
2
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
42
 | 
 	die 'j_parse: columns key not present' unless $obj && ($obj->[0] eq 'columns');  | 
| 
247
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	$self->{NAME} = $obj->[1];  | 
| 
248
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	$self->{NUM_OF_FIELDS} = scalar @{$obj->[1]};  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
249
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	$obj = drop($str);  | 
| 
250
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
101
 | 
 	die 'j_parse: data key not present' unless $obj->[0] eq 'data';  | 
| 
251
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	$rowstr = $obj->[1]->();  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# query iterator  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	$self->{_iterator} =  sub {  | 
| 
254
 | 
6
 | 
  
 50
  
 | 
 
 | 
  
6
  
 | 
 
 | 
74
 | 
 	  return unless defined $self->tmpf;  | 
| 
255
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 	  my $row;  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  my $item;  | 
| 
257
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	  $item = drop($rowstr);  | 
| 
258
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
65
 | 
 	  unless ($item) {  | 
| 
259
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    undef $rowstr;  | 
| 
260
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    return;  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
262
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	  $row = $item->[1];  | 
| 
263
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	  if (ref $row) {  | 
| 
264
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    return $self->_process_row($row);  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
267
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 	    my $ret;  | 
| 
268
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	    eval {  | 
| 
269
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	      if ($row eq 'PENDING') {  | 
| 
270
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 		if ($self->tmpf->read($buf, $BUFSIZE)) {  | 
| 
271
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
93
 | 
 		  $jsonr->incr_parse($buf);  | 
| 
272
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 		  $ret = $self->{_iterator}->();  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		else {  | 
| 
275
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 		  $item = drop($rowstr);  | 
| 
276
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
 		  $ret = $self->_process_row($item->[1]);  | 
| 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      else {  | 
| 
281
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		die "j_parse: barf(qry)"  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    };  | 
| 
284
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
 	    if (my $e = Exception::Class->caught()) {  | 
| 
285
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
27
 | 
 	      if ($e =~ /j_parse|json/i) {  | 
| 
286
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
737
 | 
 		$e = REST::Neo4p::StreamException->new(message => $e);  | 
| 
287
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1726
 | 
 		$self->{_error} = $e;  | 
| 
288
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 		$e->throw if $self->{RaiseError};  | 
| 
289
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		return;  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      else {  | 
| 
292
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		die $e;  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
295
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
 	    return $ret;  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
297
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
 	};  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	# error check  | 
| 
299
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
 	last;  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
301
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
26
 | 
       /TXN/ && do {  | 
| 
302
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
 	$obj = drop($str = $res->[1]->());  | 
| 
303
 | 
5
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
90
 | 
 	die 'j_parse: commit key not present' unless $obj && ($obj->[0] eq 'commit');  | 
| 
304
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 	$obj = drop($str);  | 
| 
305
 | 
5
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
78
 | 
 	die 'j_parse: results key not present' unless $obj && ($obj->[0] eq 'results');  | 
| 
306
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
 	my $res_str = $obj->[1]->();  | 
| 
307
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
 	my $row_str;  | 
| 
308
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 	my $item = drop($res_str);  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	$self->{_iterator} = sub {  | 
| 
310
 | 
33
 | 
  
 50
  
 | 
 
 | 
  
33
  
 | 
 
 | 
108
 | 
 	  return unless defined $self->tmpf;  | 
| 
311
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
233
 | 
 	  my $row;  | 
| 
312
 | 
33
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
 	  unless ($item) {  | 
| 
313
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    undef $row_str;  | 
| 
314
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    undef $res_str;  | 
| 
315
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    return;  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
317
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
48
 | 
 	  my $ret;  | 
| 
318
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
 	  eval {  | 
| 
319
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
80
 | 
 	    if ($item->[0] eq 'columns') {  | 
| 
320
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	      $self->{NAME} = $item->[1];  | 
| 
321
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
 	      $self->{NUM_OF_FIELDS} = scalar @{$item->[1]};  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
322
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	      $item = drop($res_str); # move to data  | 
| 
323
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
47
 | 
 	      die 'j_parse: data key not present' unless $item->[0] eq 'data';  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
325
 | 
33
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
157
 | 
 	    if ($item->[0] eq 'data' && ref($item->[1])) {  | 
| 
326
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
 	      $row_str = $item->[1]->();  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
328
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
358
 | 
 	    if ($row_str) {  | 
| 
329
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
78
 | 
 	      $row = drop($row_str);  | 
| 
330
 | 
30
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
495
 | 
 	      if (ref $row && ref $row->[1]) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
331
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
 		$ret =  $self->_process_row($row->[1]->{row}, $row->[1]->{meta});  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
333
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      elsif (!defined $row) {  | 
| 
334
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 		$item = drop($res_str);  | 
| 
335
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
 		$ret = $self->{_iterator}->();  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      else {  | 
| 
338
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 		if ($row->[1] eq 'PENDING') {  | 
| 
339
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
 		  $self->tmpf->read($buf, $BUFSIZE);  | 
| 
340
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
 		  $jsonr->incr_parse($buf);  | 
| 
341
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
 		  $ret = $self->{_iterator}->();  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		else {  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
345
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		  die "j_parse: barf(txn)";  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else { # $row_str undef  | 
| 
350
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
 	      $item = drop($res_str);  | 
| 
351
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
48
 | 
 	      $item = drop($res_str) if $item->[1] =~ /STREAM/;  | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
353
 | 
33
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
123
 | 
 	    return if $ret || ($self->err && $self->errobj->isa('REST::Neo4p::TxQueryException'));  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
354
 | 
4
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
22
 | 
 	    if ($item && $item->[0] eq 'transaction') {  | 
| 
355
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	      $item = drop($res_str) # skip  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
357
 | 
4
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
71
 | 
 	    if ($item && $item->[0] eq 'errors') {  | 
| 
358
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
 	      my $err_str = $item->[1]->();  | 
| 
359
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
 	      my @error_list;  | 
| 
360
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	      while (my $err_item = drop($err_str)) {  | 
| 
361
 | 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1589
 | 
 		my $err = $err_item->[1];  | 
| 
362
 | 
139
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
240
 | 
 		if (ref $err) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
363
 | 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
367
 | 
 		  push @error_list, $err;  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		elsif ($err eq 'PENDING') {  | 
| 
366
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 		  $self->tmpf->read($buf,$BUFSIZE);  | 
| 
367
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
 		  $jsonr->incr_parse($buf);  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		else {  | 
| 
370
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 		  die 'j_parse: error parsing txn error list';  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		}  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	      }  | 
| 
373
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
87
 | 
 	      my $e = REST::Neo4p::TxQueryException->new(  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		message => "Query within transaction returned errors (see error_list)\n",  | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		error_list => \@error_list, code => '304'  | 
| 
376
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	       ) if @error_list;  | 
| 
377
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2026
 | 
 	      $item = drop($item);  | 
| 
378
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
61
 | 
 	      $e->throw if $e;  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
380
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  };  | 
| 
381
 | 
33
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
120
 | 
 	  if (my $e = Exception::Class->caught()) {  | 
| 
382
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
24
 | 
 	    if (ref $e) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
383
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
 	      $self->{_error} = $e;  | 
| 
384
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
 	      $e->rethrow if $self->{RaiseError};  | 
| 
385
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    elsif ($e =~ /j_parse|json/i) {  | 
| 
387
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $e = REST::Neo4p::StreamException->new(message => $e);  | 
| 
388
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $self->{_error} = $e;  | 
| 
389
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $e->throw if $self->{RaiseError};  | 
| 
390
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      return;  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
392
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else {  | 
| 
393
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      die $e;  | 
| 
394
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
396
 | 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
229
 | 
 	  return $ret;  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
398
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
116
 | 
 	};  | 
| 
399
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
 	last;  | 
| 
400
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # default  | 
| 
402
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       REST::Neo4p::StreamException->throw( "j_parse: unknown item" );  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
404
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   };  | 
| 
405
 | 
10
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
   if (my $e = Exception::Class->caught('REST::Neo4p::LocalException')) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
406
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $self->{_error} = $e;  | 
| 
407
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $e->rethrow if ($self->{RaiseError});  | 
| 
408
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return;  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif ($e = Exception::Class->caught()) {  | 
| 
411
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
     if (ref $e) {  | 
| 
412
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $e->rethrow;  | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
414
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     else {  | 
| 
415
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
34
 | 
       if ($e =~ /j_parse|json/i) {  | 
| 
416
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
 	$e = REST::Neo4p::StreamException->new(message => $e);  | 
| 
417
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3887
 | 
 	$self->{_error} = $e;  | 
| 
418
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
 	$e->throw if $self->{RaiseError};  | 
| 
419
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	return;  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
421
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       else {  | 
| 
422
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	die $e;  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
425
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
426
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
427
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _response_entity {  | 
| 
428
 | 
75
 | 
 
 | 
 
 | 
  
75
  
 | 
 
 | 
130
 | 
   my ($resp,$meta) = @_;  | 
| 
429
 | 
75
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
294
 | 
   if ( ref($resp) eq '' ) { #handle arrays of barewords  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
430
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return 'bareword';  | 
| 
431
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif ($meta) {  | 
| 
433
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $type = $meta->{type};  | 
| 
434
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $type =~ s/^(.)/\U$1\E/;  | 
| 
435
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $type;  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif (defined $resp->{self}) {  | 
| 
438
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     for ($resp->{self}) {  | 
| 
439
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
21
 | 
       m|data/node| && do {  | 
| 
440
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
 	return 'Node';  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
442
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       m|data/relationship| && do {  | 
| 
443
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
 	return 'Relationship';  | 
| 
444
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
445
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       do {  | 
| 
446
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	REST::Neo4p::QueryResponseException->throw(message => "Can't identify object type by JSON response\n");  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
448
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
449
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   elsif (defined $resp->{start} && defined $resp->{end}  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	   && defined $resp->{nodes}) {  | 
| 
452
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return 'Path';  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   else {  | 
| 
455
 | 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
150
 | 
     return 'Simple';  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
459
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _process_row {  | 
| 
460
 | 
25
 | 
 
 | 
 
 | 
  
25
  
 | 
 
 | 
52
 | 
   my $self = shift;  | 
| 
461
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
   my ($row,$meta) = @_;  | 
| 
462
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
   my @ret;  | 
| 
463
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   foreach my $elt (@$row) {  | 
| 
464
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
100
 | 
     my $info;  | 
| 
465
 | 
75
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
129
 | 
     if ($meta) {  | 
| 
466
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $info = shift @$meta;  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
468
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
153
 | 
     for ($elt) {  | 
| 
469
 | 
75
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
141
 | 
        !ref && do { #bareword  | 
| 
470
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	 push @ret, $elt;  | 
| 
471
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	 last;  | 
| 
472
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
        };  | 
| 
473
 | 
75
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
214
 | 
       (ref =~ /HASH/) && do {  | 
| 
474
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
106
 | 
 	my $entity_type;  | 
| 
475
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
102
 | 
 	eval {  | 
| 
476
 | 
75
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
149
 | 
 	  if ($info && $info->{type}) {  | 
| 
477
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $elt->{self} = "$$info{type}/$$info{id}";  | 
| 
478
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $entity_type = $info->{type};  | 
| 
479
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    $entity_type =~ s/^(.)/\U$1\E/;  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
481
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
482
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
182
 | 
 	    $entity_type = _response_entity($elt);  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	};  | 
| 
485
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
109
 | 
 	my $e;  | 
| 
486
 | 
75
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
180
 | 
 	if ($e = Exception::Class->caught()) {  | 
| 
487
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	  (ref $e && $e->can("rethrow")) ? $e->rethrow : die $e;  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
489
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
432
 | 
 	my $entity_class = 'REST::Neo4p::'.$entity_type;  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	push @ret, $self->{ResponseAsObjects} ?  | 
| 
491
 | 
75
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
264
 | 
 	  $entity_class->new_from_json_response($elt) :  | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  $entity_class->simple_from_json_response($elt);  | 
| 
493
 | 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
157
 | 
 	last;  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
495
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       (ref =~ /ARRAY/) && do {  | 
| 
496
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	my $array;  | 
| 
497
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	for my $ary_elt (@$elt) {  | 
| 
498
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  my $entity_type;  | 
| 
499
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  eval {  | 
| 
500
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	    if ($info && $info->{type}) {  | 
| 
501
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $elt->{self} = "$$info{type}/$$info{id}";  | 
| 
502
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $entity_type = $info->{type};  | 
| 
503
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $entity_type =~ s/^(.)/\U$1\E/;  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    else {  | 
| 
506
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $entity_type = _response_entity($ary_elt);  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    }  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  };  | 
| 
509
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  my $e;  | 
| 
510
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  if ($e = Exception::Class->caught()) {  | 
| 
511
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
 	    (ref $e && $e->can("rethrow")) ? $e->rethrow : die $e;  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
513
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	  if ($entity_type eq 'bareword') {  | 
| 
514
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    push @$array, $ary_elt;  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  else {  | 
| 
517
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	    my $entity_class = 'REST::Neo4p::'.$entity_type;  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	    push @$array, $self->{ResponseAsObjects} ?  | 
| 
519
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	      $entity_class->new_from_json_response($ary_elt) :  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 		$entity_class->simple_from_json_response($ary_elt) ;  | 
| 
521
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	  }  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 	}  | 
| 
523
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	push @ret, $array;  | 
| 
524
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	last;  | 
| 
525
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
526
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       do {  | 
| 
527
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	REST::Neo4p::QueryResponseException->throw("Can't parse query response (row doesn't make sense)\n");  | 
| 
528
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
 	last;  | 
| 
529
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       };  | 
| 
530
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # guess whether to flatten response:  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # if more than one row element, don't flatten,   | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # return an array reference in the response  | 
| 
535
 | 
25
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
115
 | 
   return (@ret == 1 and ref($ret[0]) eq 'ARRAY') ? $ret[0] : \@ret;  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub finish {  | 
| 
539
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
1
  
 | 
3
 | 
   my $self = shift;  | 
| 
540
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   delete $self->{_iterator};  | 
| 
541
 | 
1
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
   unlink $self->tmpf->filename if ($self->tmpf);  | 
| 
542
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
   delete $self->{_tempfile};  | 
| 
543
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
265
 | 
   return 1;  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
545
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
546
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
770
 | 
 sub DESTROY { shift->finish }  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 REST::Neo4p::Query - Execute Neo4j Cypher queries  | 
| 
551
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  REST::Neo4p->connect('http:/127.0.0.1:7474');  | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $query = REST::Neo4p::Query->new('MATCH (n) WHERE n.name = "Boris" RETURN n');  | 
| 
556
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $query->execute;  | 
| 
557
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $node = $query->fetch->[0];  | 
| 
558
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $node->relate_to($other_node, 'link');  | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 REST::Neo4p::Query encapsulates Neo4j Cypher language queries,  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 executing them via L and returning an iterator  | 
| 
564
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 over the rows, in the spirit of L.  | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Streaming  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L|/execute()> captures the Neo4j query response in a temp  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 file. L|/fetch()> iterates (in a non-blocking way if  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 possible) over the JSON in the response using the incremental parser  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 of L (see L if  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 interested). So go ahead and make those 100 meg queries. The tempfile  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 is unlinked after the iterator runs out of rows, or upon object  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 destruction, whichever comes first.  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Parameters  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 C understands Cypher L
 | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 parameters|http://docs.neo4j.org/chunked/stable/cypher-parameters.html>. These  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 are represented in Cypher, unfortunately, as dollar-prefixed tokens.  | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  MATCH (n) WHERE n.first_name = $name RETURN n  | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Here, C<$name> is the named parameter.   | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Don't forget to escape the dollar sign if you're also doing string interpolation:  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $prop = "n.name";  | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $qry = "MATCH (n) WHERE $prop = \$name RETURN n";  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 A single query object can be executed multiple times with different parameter values:  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  my $q = REST::Neo4p::Query->new(  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
            'MATCH (n) WHERE n.first_name = $name RETURN n'  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
          );  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  foreach (@names) {  | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    $q->execute(name => $_);  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    while ($row = $q->fetch) {  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ...process  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    }  | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is very highly recommended over creating multiple query objects like so:  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  foreach (@names) {  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    my $q = REST::Neo4p::Query->new(  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
              "MATCH (n) WHERE n.first_name = '$_' RETURN n"  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
            );  | 
| 
609
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    $q->execute;  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    ...  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 As with any database engine, a large amount of overhead is saved by  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 planning a parameterized query once. In addition, the REST side of the  | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Neo4j server will balk at handling 1000s of individual queries in a row.  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Parameterizing queries gets around this issue.  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Paths  | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If your query returns a path, L|/fetch()> returns a  | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L object from which you can obtain the Nodes and  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Relationships.  | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 Transactions  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 See L.  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item new()  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $stmt = 'MATCH (n) WHERE id(n) = $node_id RETURN n';  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $query = REST::Neo4p::Query->new($stmt,{node_id => 1});  | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Create a new query object. First argument is the Cypher query  | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 (required). Second argument is a hashref of parameters (optional).  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item execute()  | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $numrows = $query->execute;  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $numrows = $query->execute( param1 => 'value1', param2 => 'value2');  | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $numrows = $query->execute( $param_hashref );  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Execute the query on the server. Not supported in batch mode.  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item fetch()  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item fetchrow_arrayref()  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $query = REST::Neo4p::Query->new('MATCH (n) RETURN n, n.name LIMIT 10');  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $query->execute;  | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  while ($row = $query->fetch) {   | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    print 'It works!' if ($row->[0]->get_property('name') == $row->[1]);  | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  }  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Fetch the next row of returned data (as an arrayref). Nodes are  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 returned as L objects,  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 relationships are returned as  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L objects,  | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 scalars are returned as-is.  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item err(), errstr(), errobj()  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $query->execute;  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if ($query->err) {  | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     printf "status code: %d\n", $query->err;  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     printf "error message: %s\n", $query->errstr;  | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     printf "Exception class was %s\n", ref $query->errobj;  | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Returns the HTTP error code, Neo4j server error message, and exception  | 
| 
674
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 object if an error was encountered on execution.  | 
| 
675
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
676
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item err_list()  | 
| 
677
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
678
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item finish()  | 
| 
679
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
680
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   while (my $row = $q->fetch) {  | 
| 
681
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ($row->[0] eq 'What I needed') {  | 
| 
682
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       $q->finish();  | 
| 
683
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       last;  | 
| 
684
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
685
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
686
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
687
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Call finish() to unlink the tempfile before all items have been  | 
| 
688
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 fetched.  | 
| 
689
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
690
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
691
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
692
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 ATTRIBUTES  | 
| 
693
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
694
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =over   | 
| 
695
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
696
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item RaiseError  | 
| 
697
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
698
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $q->{RaiseError} = 1;  | 
| 
699
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
700
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Set C<$query-E{RaiseError}> to die immediately (e.g., to catch the exception in an C block).  | 
| 
701
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
702
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item ResponseAsObjects  | 
| 
703
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
704
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $q->{ResponseAsObjects} = 0;  | 
| 
705
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $row_as_plain_perl = $q->fetch;  | 
| 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
707
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 If set to true (the default), query reponses are returned as  | 
| 
708
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 REST::Neo4p objects.  If false, nodes, relationships and paths are  | 
| 
709
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 returned as simple perl structures.  See  | 
| 
710
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L,  | 
| 
711
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L,  | 
| 
712
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L for details.  | 
| 
713
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
714
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =item Statement  | 
| 
715
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
716
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  $stmt = $q->{Statement};  | 
| 
717
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
718
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Get the Cypher statement associated with the query object.  | 
| 
719
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
720
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =back  | 
| 
721
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
722
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SEE ALSO  | 
| 
723
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
724
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L, L, L, L.  | 
| 
725
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
726
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
727
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
728
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    Mark A. Jensen  | 
| 
729
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    CPAN ID: MAJENSEN  | 
| 
730
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    majensen -at- cpan -dot- org  | 
| 
731
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
732
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 LICENSE  | 
| 
733
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
734
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Copyright (c) 2012-2021 Mark A. Jensen. This program is free software; you  | 
| 
735
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 can redistribute it and/or modify it under the same terms as Perl  | 
| 
736
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 itself.  | 
| 
737
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
738
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
739
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |