File Coverage

blib/lib/Net/Presto/Statement.pm
Criterion Covered Total %
statement 12 75 16.0
branch 1 26 3.8
condition 0 9 0.0
subroutine 4 15 26.6
pod 5 7 71.4
total 22 132 16.6


line stmt bran cond sub pod time code
1             package Net::Presto::Statement;
2 3     3   12 use Moo;
  3         4  
  3         24  
3 3     3   854 use JSON::XS;
  3         3  
  3         160  
4 3     3   16 use Carp qw(confess);
  3         19  
  3         171  
5              
6 3 50   3   14 use constant DEBUG => $ENV{PERL_PRESTO_DEBUG} ? 1 : 0;
  3         4  
  3         2196  
7              
8             has furl => (
9             is => 'ro',
10             required => 1,
11             );
12              
13             has headers => (
14             is => 'ro',
15             required => 1,
16             );
17              
18             has res => (
19             is => 'rw',
20             required => 1,
21             );
22              
23             has columns => (
24             is => 'rw',
25             );
26              
27             has stats => (
28             is => 'rw',
29             );
30              
31             has state => (
32             is => 'rw',
33             );
34              
35             has error => (
36             is => 'rw',
37             );
38              
39             sub create {
40 0     0 0   my $class = shift;
41 0           my $self = $class->new(@_);
42 0           $self->_set_state($self->res);
43 0           $self;
44             }
45              
46             sub fetch {
47 0     0 1   my $self = shift;
48 0           my $data;
49             $self->poll(sub {
50 0 0   0     return 1 unless $_[0]->{data};
51 0           $data = $_[0]->{data};
52 0           return 0;
53 0           });
54 0           $data;
55             }
56              
57             sub fetch_hashref {
58 0     0 1   my $self = shift;
59 0 0         my $data = $self->fetch or return;
60 0           my @names = $self->column_names;
61 0           my @rows;
62 0           for my $row (@$data) {
63 0           my %row;
64 0           @row{@names} = @$row;
65 0           push @rows, \%row;
66             }
67 0           \@rows;
68             }
69              
70             sub column_names {
71 0     0 0   my $self = shift;
72 0 0         my $columns = $self->columns or return;
73 0           map { $_->{name} } @$columns;
  0            
74             }
75              
76             sub poll {
77 0     0 1   my ($self, $cb) = @_;
78 0           until ($self->state eq 'FINISHED') {
79 0 0         my $url = $self->res->{nextUri} or return;
80 0           my $res = $self->_request(get => $url);
81 0 0         my @ret = $cb->($res) if $cb;
82 0 0 0       last if @ret && !$ret[0];
83             }
84 0           return;
85             }
86              
87             sub wait_for_completion {
88 0     0 1   my $self = shift;
89 0           $self->poll;
90 0           return;
91             }
92              
93             sub cancel {
94 0     0 1   my $self = shift;
95 0 0         my $url = $self->res->{nextUri} or return;
96 0           $self->_request(delete => $url);
97 0           1;
98             }
99              
100             sub _request {
101 0     0     my ($self, $method, $url) = @_;
102 0           my $response = $self->furl->$method($url, $self->headers);
103 0 0         confess $response->status_line unless $response->is_success;
104 0           warn "$method $url " . $response->content || '' if DEBUG;
105 0 0         if ($response->content) {
106 0           my $res = decode_json $response->content;
107 0           $self->_set_state($res);
108 0           return $res;
109             } else {
110 0           $self->_set_state({});
111 0           return;
112             }
113             }
114              
115             sub _set_state {
116 0     0     my ($self, $res) = @_;
117 0   0       $self->columns($res->{columns} || []);
118 0   0       $self->stats($res->{stats} || {});
119 0   0       $self->state($res->{stats}->{state} || '');
120 0           $self->error($res->{error});
121 0           $self->res($res);
122 0 0         if ($self->error) {
123 0           confess 'ERROR ' . $self->error->{errorCode} . ': ' . $self->error->{message};
124             }
125 0           return;
126             }
127              
128             sub DESTROY {
129 0     0     my $self = shift;
130 0 0         unless ($self->state eq 'FINISHED') {
131 0           eval { $self->cancel };
  0            
132 0 0         if ($@) {
133 0           warn "Error at Net::Presto::Statement::DESTROY: $@";
134             }
135             }
136             }
137              
138             1;
139             __END__