File Coverage

blib/lib/DigitalOcean/Collection.pm
Criterion Covered Total %
statement 9 56 16.0
branch 0 16 0.0
condition 0 9 0.0
subroutine 3 9 33.3
pod 2 2 100.0
total 14 92 15.2


line stmt bran cond sub pod time code
1 1     1   3 use strict;
  1         1  
  1         27  
2             package DigitalOcean::Collection;
3 1     1   3 use Mouse;
  1         1  
  1         3  
4 1     1   188 use DigitalOcean::Types;
  1         1  
  1         569  
5              
6             #ABSTRACT: Represents a Collection object in the DigitalOcean API
7              
8             has DigitalOcean => (
9             is => 'rw',
10             isa => 'DigitalOcean',
11             required => 1,
12             );
13              
14             has type_name => (
15             is => 'rw',
16             isa => 'Str',
17             required => 1,
18             );
19              
20             has json_key => (
21             is => 'rw',
22             isa => 'Str',
23             required => 1,
24             );
25              
26              
27             has objects => (
28             is => 'rw',
29             isa => 'ArrayRef[Any]',
30             default => sub { [] },
31             );
32              
33              
34             has cur_page => (
35             is => 'rw',
36             isa => 'Int',
37             default => 0,
38             );
39              
40              
41             has last_page => (
42             is => 'rw',
43             isa => 'Int',
44             default => 1,
45             );
46              
47              
48             has params => (
49             is => 'rw',
50             isa => 'Undef|HashRef',
51             default => undef,
52             );
53              
54             has response => (
55             is => 'rw',
56             isa => 'DigitalOcean::Response',
57             required => 1,
58             );
59              
60              
61             has pages => (
62             is => 'rw',
63             isa => 'DigitalOcean::Pages',
64             );
65              
66              
67             has next_element => (
68             is => 'rw',
69             isa => 'Int',
70             default => 0,
71             );
72              
73              
74             has total => (
75             is => 'rw',
76             isa => 'Int',
77             );
78              
79              
80             has init_objects => (
81             is => 'rw',
82             isa => 'ArrayRef[ArrayRef]',
83             default => sub { [] },
84             );
85              
86             sub BUILD {
87 0     0 1   my ($self) = @_;
88 0           $self->_update;
89             }
90              
91             sub _update {
92 0     0     my ($self) = @_;
93              
94             #if no request have been made yet, just set current page to 1
95 0 0         if($self->cur_page == 0) {
    0          
96 0           $self->cur_page($self->cur_page + 1);
97             }
98             #otherwise, set to our next page
99             elsif($self->pages->next) {
100 0           my ($path, $cur_page) = $self->_get_path_and_page($self->pages->next);
101 0           $self->cur_page($cur_page);
102             }
103              
104             #get returned objects
105 0           $self->objects($self->DigitalOcean->_decode_many($self->type_name, $self->response->json->{$self->json_key}));
106              
107 0           $self->_init_obj;
108              
109 0 0 0       if($self->response->links and $self->response->links->pages) {
110 0           $self->pages($self->response->links->pages);
111             }
112              
113             #only if last page was returned
114 0 0 0       if($self->pages and $self->pages->last) {
115 0           my ($path, $last_page) = $self->_get_path_and_page($self->pages->last);
116              
117 0           $self->last_page($last_page);
118             }
119              
120 0           $self->next_element(0);
121              
122 0           $self->total($self->response->meta->total);
123             }
124              
125             sub _init_obj {
126 0     0     my ($self) = @_;
127 0 0         return unless $self->init_objects;
128              
129 0           for my $obj (@{$self->objects}) {
  0            
130 0           for my $arr (@{$self->init_objects}) {
  0            
131 0           my ($init_obj_name, $init_obj) = @$arr;
132 0           $obj->$init_obj_name($init_obj);
133             }
134             }
135             }
136              
137              
138             sub next {
139 0     0 1   my ($self) = @_;
140            
141 0           my $object;
142              
143 0           my $next_element = $self->next_element;
144 0           my $last_index = $#{$self->objects};
  0            
145              
146             #if next element is within the array of objects we already have, just return the object
147 0 0 0       if($next_element <= $last_index) {
    0          
148 0           $object = $self->objects->[$next_element];
149             }
150             #if we are out of elements in this set of objects and we are not on the last page, request the next page of objects
151             elsif($self->cur_page < $self->last_page and $self->pages->next) {
152 0           $self->_request_next_page;
153 0           $object = $self->objects->[$self->next_element];
154             }
155             #otherwise we are out of total elements. and will return undef
156              
157 0           $self->next_element($self->next_element + 1);
158 0           return $object;
159             }
160              
161             sub _request_next_page {
162 0     0     my ($self) = @_;
163 0 0         return unless $self->pages->next;
164              
165 0           my ($path, $cur_page) = $self->_get_path_and_page($self->pages->next);
166 0           $self->params->{page} = $cur_page;
167              
168             #request next set of objects
169 0           my $do_response = $self->DigitalOcean->_GET(path => $path, params => $self->params);
170 0           $self->response($do_response);
171              
172 0           $self->_update;
173             }
174              
175             sub _get_path_and_page {
176 0     0     my ($self, $url) = @_;
177              
178 0           my $uri = URI->new($url);
179 0           my $path = substr($uri->path, 4);
180 0           my %form = $uri->query_form;
181              
182 0           return ($path, $form{page});
183             }
184              
185              
186             __PACKAGE__->meta->make_immutable();
187              
188             1;
189              
190             __END__