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.3';
4              
5 1     1   698 use Google::RestApi::Setup;
  1         4  
  1         8  
6              
7 1     1   13472 use Hash::Merge ();
  1         2  
  1         23  
8 1     1   6 use List::MoreUtils qw( first_index );
  1         2  
  1         10  
9 1     1   1109 use Storable ();
  1         3  
  1         1059  
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 393 my $self = shift;
15              
16 191         459 my %request = @_;
17              
18 191   100     582 $self->{requests} ||= [];
19 191         379 my $requests = $self->{requests};
20              
21 191 100       435 if (%request) {
22 97         228 delete $self->{requests_response}; # any previous responses are no longer valid.
23 97 100       291 push(@$requests, \%request) if !$self->merge_request(\%request);
24             }
25              
26 191         665 return @$requests;
27             }
28              
29             sub merge_request {
30 97     97 0 159 my $self = shift;
31              
32 97         146 state $check = compile(HashRef);
33 97         2337 my ($request) = $check->(@_);
34              
35 97 50       1003 my $requests = $self->{requests} or return;
36             my ($index) = first_index {
37 80     80   247 $self->_can_merge($request, $_);
38 97         614 } @$requests;
39 97 100       494 return if $index < 0;
40              
41 77         174 my $other_request = $requests->[$index];
42              
43 77         187 my $key = (keys %$request)[0];
44 77         202 my $fields = $request->{$key}->{fields};
45 77         184 my $other_fields = $other_request->{$key}->{fields};
46              
47 77         119 my %fields;
48 77 100 66     385 %fields = map { $_ => 1 } split(',', $fields), split(',', $other_fields)
  201         449  
49             if $fields && $other_fields;
50 77         313 $other_request = Hash::Merge::merge($request, $other_request);
51 77 100       33493 $other_request->{$key}->{fields} = join(',', sort keys %fields) if %fields;
52              
53 77         294 $requests->[$index] = $other_request;
54              
55 77         295 return $other_request;
56             }
57              
58             sub _can_merge {
59 80     80   131 my $self = shift;
60              
61 80         146 my ($request, $other_request) = @_;
62 80         266 my $key = (keys %$request)[0];
63 80         250 my $other_key = (keys %$other_request)[0];
64              
65 80 100       213 return if $key ne $other_key;
66 77 50       189 return if $key =~ /^(deleteProtected|deleteNamed|deleteEmbeded)/;
67              
68 77 50       203 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       167 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       180 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         218 return 1;
87             }
88              
89             sub requests_response_from_api {
90 9     9 0 23 my $self = shift;
91              
92             # we didn't ask for any requests, nothing more to do.
93 9 50 33     61 return if @_ && !$self->{requests};
94              
95 9         21 state $check = compile(ArrayRef, { optional => 1 });
96 9         2247 my ($requests) = $check->(@_);
97 9 50       120 return $self->{requests_response} if !$requests;
98              
99             # strip off a response for each request made.
100 9         24 $self->{requests_response} = [];
101 9         31 push(@{ $self->{requests_response} }, shift @$requests)
102 9         21 for (1..scalar @{ $self->{requests} });
  9         37  
103              
104             # don't store the original requests now that they've been done.
105 9         38 delete $self->{requests};
106              
107 9         30 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.