File Coverage

blib/lib/ArangoDB/Cursor.pm
Criterion Covered Total %
statement 31 85 36.4
branch 1 26 3.8
condition 0 16 0.0
subroutine 10 16 62.5
pod 4 4 100.0
total 46 147 31.2


line stmt bran cond sub pod time code
1             package ArangoDB::Cursor;
2 8     8   47 use strict;
  8         16  
  8         295  
3 8     8   41 use warnings;
  8         17  
  8         201  
4 8     8   42 use utf8;
  8         16  
  8         183  
5 8     8   289 use 5.008001;
  8         27  
  8         344  
6 8     8   66 use Carp qw(croak);
  8         28  
  8         769  
7 8     8   124 use Scalar::Util qw(weaken);
  8         26  
  8         584  
8 8     8   59 use ArangoDB::Document;
  8         19  
  8         317  
9 8     8   43 use ArangoDB::Constants qw(:api);
  8         14  
  8         1842  
10 8     8   48 use Class::Accessor::Lite ( ro => [qw/id count length/], );
  8         17  
  8         68  
11              
12             BEGIN {
13 8 50   8   2745 if ( eval { require Data::Clone; 1; } ) {
  8         7533  
  8         15452  
14 8         2980969 *_clone = \&Data::Clone::clone;
15             }
16             else {
17              
18             # Clone nested ARRAY and HASH reference data structure.
19             *_clone = sub {
20 0           my $orig = shift;
21 0 0         return unless defined $orig;
22 0           my $reftype = ref $orig;
23 0 0         if ( $reftype eq 'ARRAY' ) {
    0          
24 0 0         return [ map { !ref($_) ? $_ : _clone($_) } @$orig ];
  0            
25             }
26             elsif ( $reftype eq 'HASH' ) {
27 0 0         return { map { !ref($_) ? $_ : _clone($_) } %$orig };
  0            
28             }
29 0           };
30             }
31             }
32              
33             sub new {
34 0     0 1   my ( $class, $conn, $cursor ) = @_;
35 0           my $len = 0;
36 0 0 0       if ( defined $cursor->{result} && ref( $cursor->{result} ) eq 'ARRAY' ) {
37 0           $len = scalar @{ $cursor->{result} };
  0            
38             }
39 0   0       my $self = bless {
40             connection => $conn,
41             id => $cursor->{id},
42             length => $len,
43             count => $cursor->{count},
44             has_more => $cursor->{hasMore},
45             position => 0,
46             result => $cursor->{result} || [],
47             }, $class;
48 0 0         if ( $self->{id} ) {
49 0           $self->{_api_path} = API_CURSOR . '/' . $self->{id};
50             }
51 0           weaken( $self->{connection} );
52 0           return $self;
53             }
54              
55             sub next {
56 0     0 1   my $self = shift;
57 0 0 0       if ( $self->{position} < $self->{length} || $self->_get_next_batch() ) {
58 0           return ArangoDB::Document->new( $self->{connection}, _clone( $self->{result}->[ $self->{position}++ ] ) );
59             }
60 0           return;
61             }
62              
63             sub all {
64 0     0 1   my $self = shift;
65 0           my @result;
66 0   0       while ( !@result || $self->_get_next_batch() ) {
67 0           my $last = $self->{length} - 1;
68 0           push @result, ( @{ $self->{result} } )[ 0 .. $last ];
  0            
69             }
70 0           my $conn = $self->{connection};
71 0           return [ map { ArangoDB::Document->new( $conn, $_ ) } @result ];
  0            
72             }
73              
74             sub _get_next_batch {
75 0     0     my $self = shift;
76 0 0         return unless $self->{has_more};
77 0           eval {
78 0           my $res = $self->{connection}->http_put( $self->{_api_path}, {} );
79 0           $self->{has_more} = $res->{hasMore};
80 0           $self->{length} = scalar( @{ $res->{result} } );
  0            
81 0           $self->{result} = $res->{result};
82 0           $self->{position} = 0;
83             };
84 0 0         if ($@) {
85 0           $self->_server_error_handler( $@, 'Failed to get next batch cursor(%d)' );
86             }
87 0           return 1;
88             }
89              
90             sub delete {
91 0     0 1   my $self = shift;
92 0           eval { $self->{connection}->http_delete( $self->{_api_path} ) };
  0            
93 0 0         if ($@) {
94 0           $self->_server_error_handler( $@, 'Failed to delete cursor(%d)' );
95             }
96             }
97              
98             sub _server_error_handler {
99 0     0     my ( $self, $error, $message ) = @_;
100 0           my $msg = sprintf( $message, $self->id );
101 0 0 0       if ( ref($error) && $error->isa('ArangoDB::ServerException') ) {
102 0   0       $msg .= ':' . ( $error->detail->{errorMessage} || q{} );
103             }
104 0           croak $msg;
105             }
106              
107             1;
108             __END__