NAME

Podius::Persistence::ComponentIterator - API to component collection


SYNOPSIS

  use Podius;
  use Podius::Shortcuts qw(:beans);
  my $cache = create_component_cache('project.cfg', ['Edition', [1]]);
  $cache->begin_tx;
  my $edition = $cache->get_root->main_components->get_first1;
  my $iterator = $cache->create_component_persistent_iterator
    ($edition, "sections");
  # or the same:
  # my $iterator = $edition->sections;
  print "Number of sections in edition: ", $iterator->count, "\n";
  print "Retrieving next 10 sections\n";
  my  $first10_sections = $iterator->get_next(10);
  print "Retrieving next 10 sections\n";
  my $second10_sections = $iterator->get_next(10);
  print "Have no more than 10 sections.\n" unless @$second10_sections;
  # Prints 20, if there are more than 20 sections, else - count
  print "Current index of iterator is: ", $iterator->index, "\n";
  print "Retrieving prev 20 sections\n";
  my  $first20_sections = $iterator->get_prev(20);
  # or the same:
  # my $first20_sections = $iterator->get_first(20);
  # Surely is 0
  print "Current index of iterator is: ", $iterator->index, "\n";
  # This does nothing, the iterator is reset already
  $iterator->reset;
  try {
    map { print $_->get_id, " -> ", $_->name, "\n"; } @{$iterator->get_all};
  } catch('Exception::Podius::Persistence::ComponentIterator'), sub {
    # too many components requested from iterator at once
    print "There are too many sections.\n";
    print "Try: get_next(", $iterator->limit, ").\n";
  };
  $new_section = new Podius::Component::Section;
  $new_section->name('tmp');
  $iterator->add_non_persistent([$new_section]);
  # or the same:
  $iterator->add([$cache->make_persistent_component($new_section)]);
  # this deletes the component from persistent storage too
  $iterator->destroy($iterator->get_last(1));
  my $all_ids = $iterator->get_ids;
  print "Deleting all components by maximal chunks\n";
  while ($iterator->count) { $iterator->delete($iterator->get_last); }
  # Just to verify, there is nothing inside
  print "Number of sections in edition: ", $iterator->count, "\n";
  #print "Restoring all deleted components one by one\n";
  #map { $iterator->add([$id]); } @$all_ids;
  print "Restoring all deleted components by maximal chunks\n";
  for (my $i = 0; $i < @all_ids; $i += $iterator->limit) {
    my $num_to_add = $iterator->limit;  # fix last group
    $num_to_add = @$all_ids - $i if $num_to_add > @$all_ids - $i;
    my @ids = @{$all_ids}[$i .. $i + $num_to_add - 1];
    $iterator->add(\@ids);
  }
  # Just to verify that all components restored
  print "Number of sections in edition: ", $iterator->count, "\n";
  $cache->commit_tx;


DESCRIPTION

Implements an interface to component collections.

Always remember, you can operate with limited number of components at once. This number can be obtained by limit method. The only exception is getting all component ids in collection by get_ids method.


REQUIREMENTS

the Exception manpage, the Debug manpage, the Data::NeatFormat manpage, the Podius::Property::AbstractComponentCollection manpage, the Podius::ComponentClasses manpage, the Podius::Exceptions manpage.


CONSTRUCTORS

new

description
Class constructor.

parameters
1) when requesting iterator for persistent component collection:
  * Podius::Component reference (container)
  * scalar, component collection property name
  * Podius::Persistence::ComponentCache reference
  * number, component limit to get at once

2) when requesting iterator for non-persistent list of components:

  * scalar, component type
  * array ref of scalars, component ids
  * Podius::Persistence::ComponentCache reference
  * number, component limit to get at once

returns
New formed iterator reference.


METHODS

reset

description
Resets the iterator.

returns
none

index

description
Returns current index in iterator's collection. Optionally sets new current index (if specified).

returns
Optional new current index to set that is either integer (less then count and greater-equal that negative count when counting from the end) or special value 'end' meaning count.

returns
Number in the range 0 .. count. 0 corresponds to reseted iterator; count - to fully processed iterator.

limit

description
Returns iterator's limit on components to get at once, which is constant for the iterator.

returns
Positive number.

count

description
Returns number of components in iterator's collection.

returns
Number in the range 0 .. count. 0 corresponds to reseted iterator; count - to fully processed iterator.

left

description
Returns number of components in left unprocessed iterator's collection, acctually it is: count - index.

Can be used in this form: while ($iterator->left) { my $components = $iterator->get_next;

returns
Number in the range 0 .. count. 0 corresponds to fully processed iterator; count - to reseted iterator.

get_ids

description
Returns list of component ids in iterator's collection.

returns
Array ref of scalars, read-only.

If you specify parameter (array ref of components), array ref of their ids will be returned (default is all ids in iterator's collection).

get_component_type

description
Returns component (super) type in iterator's collection.

returns
Scalar.

get_acceptable_component_types

description
Returns all acceptable component types which can be contained in iterator's collection.

returns
Array ref of scalars.

get_index_of

description
Evaluates index of given component in the iterator's collection.

Currently exception is not thrown on bad input.

parameters
Component or its id from the collection. Or array ref of components or ids.

returns
Index in the range 0 .. count-1, if found. If the given component is not in the collection (not found), returns -1.

If the parameter was array ref, the result will also be array ref, i.e. array of either indexes or -1 error results.

set_index_of

description
$iterator->set_index_of($component) is more or less a shortcut to $iterator->index($iterator->get_index_of($component)).

Except that if the component is not found, then index 0 (or the third param if given, possibly 'end') is set, but -1 is returned in this case, as expected.

Reminder: index(-1) normally means setting the last index, but in this case (not found) resetting index to 0 by default is more intuitive.

If the offset is given (usually -1 or +1), then resulting index is auto-corrected if needed to be in the proper range [0 .. count].

parameters
  * component or id to find and seek to
  * index offset from the found component/id, by default 0
  * the fallback index when the component/id is not found
returns
The found index (-1 means not found).

has

description
Answers whether given components (one or more) are all included in the iterator's collection.

parameters
Component or list of components (or id or list of ids).

returns
0 if any of the components are not in the collection. 1 otherwise.

has_any

description
Answers whether any of the given components (one or more) are included in the iterator's collection. The difference from any is that logical OR is used instead of AND; and when no parameters are passed the default 0 is returned (unlike the default 1 for any).

parameters
List of components or ids.

returns
1 if any of the components are in the collection. 0 otherwise.

get_by_ids

description
Returns component list from iterator's collection according to given ids.

No special verifying, that number of given ids is less than limit. Cache exception will be thrown anyway in this case.

If some ids do not point to existing components, resulting list will not contain then, so it will be smaller than the requested. In this case internal list of ids is corrected.

parameters
  * starting index (offset)
  * number components to get
returns
array ref [array ref of components, number of unexisting ids]

get_n

description
Returns component with given index in collection.

If specified index of component to get is greater/equal to count, exception is thrown.

parameters
  * index of component to get
returns
Component returned by get_by_ids.

get_first

description
Returns ascending component list from iterator's collection, starting from current zero.

If specified number of components to get is greater than limit, exception is thrown.

If number of components is less than given number of components, the resulting list accordingly will contain less components, than specified.

parameters
  * optional number of components to get (defaults to C<limit>)
returns
Array ref of components returned by get_by_ids.

get_last

description
Returns ascending component list from iterator's collection, starting from current index.

If specified number of components to get is greater than limit, exception is thrown.

If number of components is less than given number of components, the resulting list accordingly will contain less components, than specified.

parameters
  * optional number of components to get (defaults to C<limit>)
returns
Array ref of components returned by get_by_ids.

get_next

description
Returns component list from iterator's collection, starting from current index up.

If specified number of components to get is greater than limit, exception is thrown.

If number of leaved components is less than given number of components, the resulting list accordingly will contain less components, than specified.

parameters
  * optional number of components to get (defaults to C<limit>)
returns
Array ref of components returned by get_by_ids.

get_prev

description
Returns component list from iterator's collection, starting from current index down.

If specified number of components to get is greater than limit, exception is thrown.

If number of leaved components is less than given number of components, the resulting list accordingly will contain less components, than specified.

parameters
  * optional number of components to get (defaults to C<limit>)
returns
Array ref of components returned by get_by_ids.

get_first1

This is just a shortcut to get_first(1)->[0].

get_last1

This is just a shortcut to get_last(1)->[0].

get_next1

This is just a shortcut to get_next(1)->[0].

get_prev1

This is just a shortcut to get_prev(1)->[0].

get_all

description
Returns ascending list of all components in iterator's collection, starting from zero until count.

If number of components in collection is greater than limit, exception is thrown.

returns
Array ref of components returned by get_by_ids.

add

description
Adds given component(s) to iterator's collection. By default the component(s) are added to the end, but this may be controlled.

If number of components to add is greater than limit, exception is thrown.

parameters
  * array ref of ids or components to add. If non-array is given, it is
given as single element of one-element array.
  * optional index, if set the added components is also shifted from the end
to this index using C<doshift> method.
returns
array ref of actually added component ids

move

description
Moves given component(s) from one collection to iterator's collection. By default the component(s) are added to the end, but this may be controlled.

Basically, this operation is delete+add at once.

parameters
  * array ref of ids or components to add. If non-array is given, it is
given as single element of one-element array.
  * optional index, if set the added components is also shifted from the end
to this index using C<doshift> method.
returns
array ref of actually added component ids

doshift

description
Shifts specified component(s) inside iterator's collection.

If src_index is greater-equal than limit or less than negative limit, exception is thrown. The same with dst_index. Also exception is thrown, if shifted components cross the collection borders according to the specified indexes.

examples
  $iterator->doshift(-1, 0, 1) # move last component to the start
  $iterator->doshift(0, -2, 2) # move two first components to the end
  $iterator->doshift(2, 3)     # swap components at indexes 2 and 3
parameters
  * src_idx - source index of component(s) to shift.
Negative value coresponds to the index starting from the end to the start.
  * dst_idx - destination index of component(s) to shift to.
Negative value coresponds to the index starting from the end to the start.
  * optional number of components to shift (default is 1).
returns
none

delete

description
Deletes given components from iterator's collection.

If the number of components to delete is greater than the configured limit, exception is thrown.

See also a corresponding example for foreach method.

parameters
  * array ref of ids or components to delete. If non-array is given, it is
given as single element of one-element array.
returns
array ref of actually deleted component ids

destroy

description
Like delete, but deletes (destroys) components from the storage too.

If the number of components to destroy is greater than the configured limit, exception is thrown.

Be aware, if you destroy a component that has children, then these children become phantom components (with no parent), better use destroy_recursively.

See also a corresponding example for foreach method.

parameters
  * array ref of ids or components to destroy
returns
array ref of actually destroyed component ids

destroy_recursively

description
Executes destroy for the given components and all their children recursivelly.

Use this method with caution.

See also a corresponding example for foreach method.

parameters
  * array ref of ids or components to destroy
returns
array ref of actually (recursively) destroyed component ids

foreach_interval

description
Applies the given sub (CODE ref) to the iterator's collection interval, An array of components is passed to the sub in $_ variable.

examples
  $iterator->foreach_interval(sub { $iterator2->add($_); });
  $iterator->foreach_interval('delete');

In these examples foreach can be used too, but components will be added/deleted one by one instead of by maximal size groups.

parameters
  * CODE ref, the subroutine to apply on every interval

or

  * scalar, the C<ComponentIterator> method name to be applied
returns
The resulting array (a compositions of arrays returned by applied subroutines). If nothing is expected to be returned, the return value is not composed.

foreach

description
Applies the given sub (CODE ref) to each component in the iterator's collection, the component is passed to the sub in $_ variable.

examples
  my $names = $iterator->foreach(sub { $_->name; });
  # like: my $names = $iterator->get_each_property_value('name');
  $name_tip_pairs = $iterator->foreach(sub { [$_->name, $_->tip] });
  $name_tip_mixed = $iterator->foreach(sub { ($_->name, $_->tip) });
  $iterator->foreach(sub ($) {
    push @names, $_->name; push @tips, $_->tip;
  });
  $iterator->foreach(sub { print "\t", $_->as_string, "\n"; });
  print join("\n", @{$iterator->foreach(sub { $_->as_string })}), "\n";
  $iterator->foreach(sub { $_->publish; });
  $iterator->foreach(sub { $iterator2->add($_) if $_->is_modified; });
  $iterator->foreach('get_index_of');  # useless, returns [0 .. count-1]
  # clean iterator for VComponentCollection
  $iterator->foreach('delete');
  # destroy children in ComponentCollection; just 'destroy' may be bad
  $iterator->foreach('destroy_recursively');
parameters
  * CODE ref, the subroutine to apply on every interval

or

  * scalar, the C<ComponentIterator> method name to be applied
returns
The array of results returned by applied subroutines. If nothing is expected to be returned, the return value is not composed.

get_each_property_value

description
Returns array of property values (by given property name) for all components in collection sorted as original components.

parameters
  * property name (will be: or array ref of property names)
returns
Array ref of property values (will be: array ref of array refs of property values).

set

description
Replaces the iterator's components with the given one(s).

There are actually 3 scenarios:

  * new items are the same as the existing, nothing is done, status=0
  * new items are the same just reordered, ordering is done, status=-1
  * new items are different, delete existing then add new, status=1

See also foreach, delete and add methods, they are called in the last scenario.

parameters
  * array ref of ids or components to set. If non-array is given, it is
taken as single element of one-element array.
  * optional params hash, currently the supported keys are: "want_status".
returns
An iterator object (self), or status (if specially requested).

sort

description
Sorts iterator's collection inline using custom subroutine.

parameters
  * sorting code (perl anonymous sub, getting the component and returning
    -1, 0 or 1)
returns
An iterator object (self).

sort_by_property

description
Sorts iterator's collection inline by property value(s) in ascending or descending order. If all property values look like numeric, the numeric comparison is taken place intead of the textual comparison. All undefined property values are replaced by empty strings or zeros.

parameters
  * property name (will be: or array ref of property names)
  * optional flag (will be: or array ref of flags): 1 ascending (default),
    -1 or 0 descending
returns
An iterator object (self).

filter

description
Applies the given filter to the iterator's collection and returns another (non-persistent) iterator, which includes only matching components.

example
  my $code = sub ($) {
    my $component = shift;
    return $component->is_ready;
  };
  my $iterator2 = $iterator->filter($code);
parameters
  * filter code (perl anonymous sub, getting the component and returning
    a boolean)
returns
A new iterator object.

filter_by_indexes

description
Applies the given filter to the iterator's collection and returns another (non-persistent) iterator, which includes only matching components.

example
  my $iterator2 = $iterator->filter_by_indexes($start_index, $number);
  my $iterator2 = $iterator->filter_by_indexes([2, 3, 0, 6]);
  my $iterator2 = $iterator->filter_by_indexes($iterator->get_index_of($ids));
parameters
  * starting index, 0 <= start_index < count
  * number of sequenced components, start_index + number <= count

or:

  * array ref of indexes, 0 <= index < count
returns
A new iterator object.

as_string

description
Returns the string presentation of the object in the human readable way.

returns
String, like ``[Container, 2001]-(items, 6 Item components)'', or ``{transient-iterator}-(6 Item components)''.