Google-RestApi

 view release on metacpan or  search on metacpan

lib/Google/RestApi/SheetsApi4/Range.pm  view on Meta::CPAN

  # this fakes out the batch response with this immediate response.
  # batch response would be in an arrayref, so wrap it thusly.
  return $self->values_response_from_api([ $update ]);
}

# this stores the response to an update request, either batch or immediate:
# ---
# spreadsheetId: 1ky2czjhPArP71a6woeo_dxRr8gBOZZxGAPjOCXJvCwA
# updatedCells: 6
# updatedColumns: 3
# updatedRange: Sheet1!B3:D4
# updatedRows: 2
# if includeValuesInResponse was requested, the values are stashed
# from the updatedData response key.
# spreadsheet object will call this on a batch update response.
sub values_response_from_api {
  my $self = shift;

  state $check = signature(positional => [ArrayRef, { optional => 1 }]);
  my ($updates) = $check->(@_);
  return if !$updates;

  # shift off the next update from the batch api response. if this is
  # getting called from the spreadsheet object, it means we have an
  # update response to process.
  my $update = shift @$updates;

  # updatedData is included if includeValuesInResponse query param was sent.
  # updatedData:
  #   majorDimension: ROWS
  #   range: Sheet1!A1
  #   values:
  #   - - Fred
  # if the data is included, then replace any cached values with this latest
  # updated set of values.
  $self->_cache_range_values(%{ delete $update->{updatedData} })
    if $update->{updatedData};
  $self->{values_response_from_api} = $update;

  return $self->values();
}

# this returns the values and major dimension for a given range. it will store
# the values returned from an api fetch. it will store the values from a staged
# 'batch_values' call for later update from the api. it will store the values
# from an update if includeValuesInResponse was included.
# cache is in the format:
# majorDimension: ROWS
# range: Sheet1!A1    # only on an api return value.
# values:
# - - Fred
# if a range is included it's a flag that the dim and values are present from
# the returned api call.
sub _cache_range_values {
  my $self = shift;

  my %p = @_;
  # if a range is included, assume this cache is coming from the api as a reply.
  # this is to store the values for this range when includeValuesInResponse is
  # added to the url or content on the original values call. you can replace the
  # original values using the valueRenderOption to replace, say, formulas with their
  # calculated value.
  if ($p{range}) {
    state $check = signature(
      bless => !!0,
      named => [
        majorDimension => DimColRow,
        range          => StrMatch[qr/.+!/],
        values         => ArrayRef, { optional => 1 }  # will not exist if values aren't set in the ss.
      ],
    );
    my $p = $check->(@_);

    # remove all quotes for comparison.
    my $self_range = $self->range();
    $self_range =~ s/'//g;
    my $range = $p->{range};
    $range =~ s/'//g;
    my ($worksheet_name) = $range =~ /^(.+)!/;

    LOGDIE "Setting range data to worksheet name '$worksheet_name' that doesn't belong to this range: " . $self->worksheet_name()
      if $worksheet_name ne $self->worksheet_name();
    # TODO: sometimes the api returns a range that is different from the one we sent to the api.
    # a column A:A can be returned as A1:A1000 by the api, so have to come up with a way
    # of identifying when a returned range is a close enough match to the one we have.
    #LOGDIE "Setting range data to '$range' which is not this range: " . $self_range
    #  if $range ne $self_range;
    LOGDIE "Setting major dimention to '$p->{majorDimension}' that doesn't belong to this range: " . $self->dimention()
      if $p->{majorDimension} ne $self->dimension();

    delete $p->{range};  # we only cache the values and dimensions.
    $self->{cache_range_values} = $p;
    DEBUG("Saved cached values for range " . $self->range());
  }

  # if the value range was just stored (above) or was previously stored, return it.
  return $self->{cache_range_values} if $self->{cache_range_values};
  DEBUG("No local cache values exist for range " . $self->range() . ", checking for shared values");

  # used by iterators to use a 'parent' range to query the values for this 'child'
  # range. this is to reduce network calls when iterating through a range.
  my $shared = $self->{shared};
  if ($shared && $shared->has_values()) {
    my $dim = $shared->{cache_range_values}->{majorDimension};
    my $values = $shared->{cache_range_values}->{values};

    my ($top, $left, $bottom, $right) = $self->offsets($shared);
    my $data;
    if ($dim =~ /^col/i) {
      my @cols = @$values[$left..$right];
      $_ = [ @$_[$top..$bottom] ] foreach (@cols);
      $data = \@cols;
    } else {
      my @rows = @$values[$top..$bottom];
      $_ = [ @$_[$left..$right] ] foreach (@rows);
      $data = \@rows;
    }

    # return a subsection of the cached value for the iterator.
    DEBUG("Returning shared values for range " . $self->range());
    return {



( run in 1.910 second using v1.01-cache-2.11-cpan-df04353d9ac )