File Coverage

lib/Google/RestApi/SheetsApi4/Request.pm
Criterion Covered Total %
statement 59 69 85.5
branch 19 38 50.0
condition 5 8 62.5
subroutine 9 10 90.0
pod 2 4 50.0
total 94 129 72.8


line stmt bran cond sub pod time code
1             package Google::RestApi::SheetsApi4::Request;
2              
3             our $VERSION = '1.0.4';
4              
5 1     1   563 use Google::RestApi::Setup;
  1         3  
  1         7  
6              
7 1     1   13238 use Hash::Merge ();
  1         2  
  1         22  
8 1     1   9 use List::MoreUtils qw( first_index );
  1         4  
  1         10  
9 1     1   1102 use Storable ();
  1         2  
  1         1104  
10              
11 0     0 1 0 sub submit_requests { LOGDIE "Pure virtual function 'submit_requests' must be overridden"; }
12              
13             sub batch_requests {
14 191     191 1 374 my $self = shift;
15              
16 191         416 my %request = @_;
17              
18 191   100     577 $self->{requests} ||= [];
19 191         452 my $requests = $self->{requests};
20              
21 191 100       410 if (%request) {
22 97         246 delete $self->{requests_response}; # any previous responses are no longer valid.
23 97 100       292 push(@$requests, \%request) if !$self->merge_request(\%request);
24             }
25              
26 191         704 return @$requests;
27             }
28              
29             sub merge_request {
30 97     97 0 165 my $self = shift;
31              
32 97         147 state $check = compile(HashRef);
33 97         2477 my ($request) = $check->(@_);
34              
35 97 50       1080 my $requests = $self->{requests} or return;
36             my ($index) = first_index {
37 80     80   255 $self->_can_merge($request, $_);
38 97         609 } @$requests;
39 97 100       471 return if $index < 0;
40              
41 77         177 my $other_request = $requests->[$index];
42              
43 77         164 my $key = (keys %$request)[0];
44 77         177 my $fields = $request->{$key}->{fields};
45 77         205 my $other_fields = $other_request->{$key}->{fields};
46              
47 77         121 my %fields;
48 77 100 66     350 %fields = map { $_ => 1 } split(',', $fields), split(',', $other_fields)
  201         472  
49             if $fields && $other_fields;
50 77         274 $other_request = Hash::Merge::merge($request, $other_request);
51 77 100       34975 $other_request->{$key}->{fields} = join(',', sort keys %fields) if %fields;
52              
53 77         331 $requests->[$index] = $other_request;
54              
55 77         273 return $other_request;
56             }
57              
58             sub _can_merge {
59 80     80   148 my $self = shift;
60              
61 80         166 my ($request, $other_request) = @_;
62 80         260 my $key = (keys %$request)[0];
63 80         210 my $other_key = (keys %$other_request)[0];
64              
65 80 100       197 return if $key ne $other_key;
66 77 50       201 return if $key =~ /^(deleteProtected|deleteNamed|deleteEmbeded)/;
67              
68 77 50       172 if ($key =~ /^updateProtected/) {
69 0 0       0 my $id = $request->{$key}->{protectedRangeId} or return;
70 0 0       0 my $other_id = $other_request->{$key}->{protectedRangeId} or return;
71 0         0 return $id == $other_id;
72             }
73              
74 77 50       163 if ($key =~ /^updateNamedRange/) {
75 0 0       0 my $id = $request->{$key}->{namedRange}->{namedRangeId} or return;
76 0 0       0 my $other_id = $other_request->{$key}->{namedRange}->{namedRangeId} or return;
77 0         0 return $id == $other_id;
78             }
79              
80 77 50       147 if ($key =~ /^updateEmbededObject/) {
81 0 0       0 my $id = $request->{$key}->{objectId} or return;
82 0 0       0 my $other_id = $other_request->{$key}->{objectId} or return;
83 0         0 return $id == $other_id;
84             }
85              
86 77         239 return 1;
87             }
88              
89             sub requests_response_from_api {
90 9     9 0 21 my $self = shift;
91              
92             # we didn't ask for any requests, nothing more to do.
93 9 50 33     69 return if @_ && !$self->{requests};
94              
95 9         22 state $check = compile(ArrayRef, { optional => 1 });
96 9         2103 my ($requests) = $check->(@_);
97 9 50       127 return $self->{requests_response} if !$requests;
98              
99             # strip off a response for each request made.
100 9         38 $self->{requests_response} = [];
101 9         32 push(@{ $self->{requests_response} }, shift @$requests)
102 9         18 for (1..scalar @{ $self->{requests} });
  9         47  
103              
104             # don't store the original requests now that they've been done.
105 9         39 delete $self->{requests};
106              
107 9         36 return $self->{requests_response};
108             }
109              
110             1;
111              
112             __END__
113              
114             =head1 NAME
115              
116             Google::RestApi::SheetsApi4::Request - A base class to build Google API's batchRequest.
117              
118             =head1 DESCRIPTION
119              
120             A Request is a lightweight object that is used to collect and then
121             submit a number of batch requests such as formatting, spreadsheet
122             properties, worksheet properties etc.
123              
124             Other classes in this api derive from this object and its child
125             objects. You would not normally have to interact with this object
126             directly as it is already built in to the other classes in this
127             api. It is documented here for background understanding.
128              
129             Batch requests are formulated and queued up to be submitted later
130             via 'submit_requests'. This class hierarchy encapsulates the
131             tedious work of constructing the complex, deep hashes required for
132             cell formatting or setting various properties.
133              
134             Spreadsheet: Derives from Request::Spreadsheet.
135             Worksheet: Derives from Request::Spreadsheet::Worksheet.
136             Range: Derives from Request::Spreadsheet::Worksheet::Range.
137              
138             A Spreadsheet object can only submit requests that have to do with
139             spreadsheets. A Worksheet object can submit requests that have to
140             do with worksheets, and also for parent spreadsheets. A Range object
141             can submit requests that have to do with ranges, worksheets, and
142             spreadsheets.
143              
144             In some cases, multiple calls for the same-named request can be
145             merged into a single request. For example $range->bold()->blue()->center()
146             targets three Google API requests of the same name: 'repeatCell'.
147             Instead of sending three small 'repeatCell' requests, these are
148             all merged together into one 'repeatCell' request for efficiency.
149              
150             See the description and synopsis at Google::RestApi::SheetsApi4.
151              
152             =head1 SUBROUTINES
153              
154             =over
155              
156             =item batch_requests(%request);
157              
158             Returns all the queued requests if none is passed, or adds the passed
159             request to the queue. A request may be merged into an already-existing
160             request of the same name.
161              
162             =item submit_requests(%args);
163              
164             This is a pure virtual function that must be overridden in the derived
165             class. The derived class must decide what to do when the queued requests
166             are ready to be sumitted. It must eventually pass the requests to the
167             parent SheetsApi4 object.
168              
169             =back
170              
171             =head1 AUTHORS
172              
173             =over
174              
175             =item
176              
177             Robin Murray mvsjes@cpan.org
178              
179             =back
180              
181             =head1 COPYRIGHT
182              
183             Copyright (c) 2021, Robin Murray. All rights reserved.
184              
185             This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.