Podius::Persistence::ComponentIterator - API to component collection
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;
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.
the Exception manpage, the Debug manpage, the Data::NeatFormat manpage, the Podius::Property::AbstractComponentCollection manpage, the Podius::ComponentClasses manpage, the Podius::Exceptions manpage.
* 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
count - index.
Can be used in this form: while ($iterator->left) { my $components = $iterator->get_next;
If you specify parameter (array ref of components), array ref of their ids will be returned (default is all ids in iterator's collection).
Currently exception is not thrown on bad input.
If the parameter was array ref, the result will also be array ref, i.e. array of either indexes or -1 error results.
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].
* 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
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.
* starting index (offset) * number components to get
If specified index of component to get is greater/equal to count, exception is thrown.
* index of component to get
get_by_ids.
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.
* optional number of components to get (defaults to C<limit>)
get_by_ids.
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.
* optional number of components to get (defaults to C<limit>)
get_by_ids.
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.
* optional number of components to get (defaults to C<limit>)
get_by_ids.
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.
* optional number of components to get (defaults to C<limit>)
get_by_ids.
This is just a shortcut to get_first(1)->[0].
This is just a shortcut to get_last(1)->[0].
This is just a shortcut to get_next(1)->[0].
This is just a shortcut to get_prev(1)->[0].
If number of components in collection is greater than limit, exception is thrown.
get_by_ids.
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.
* 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.
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.
* 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.
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.
$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
* 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).
If the number of components to delete is greater than the configured limit, exception is thrown.
See also a corresponding example for foreach method.
* array ref of ids or components to delete. If non-array is given, it is given as single element of one-element array.
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.
* array ref of ids or components to destroy
destroy for the given components and all their children
recursivelly.
Use this method with caution.
See also a corresponding example for foreach method.
* array ref of ids or components to destroy
$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.
* CODE ref, the subroutine to apply on every interval
or
* scalar, the C<ComponentIterator> method name to be applied
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');
* CODE ref, the subroutine to apply on every interval
or
* scalar, the C<ComponentIterator> method name to be applied
* property name (will be: or array ref of property names)
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.
* 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".
* sorting code (perl anonymous sub, getting the component and returning
-1, 0 or 1)
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.
* 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
my $code = sub ($) {
my $component = shift;
return $component->is_ready;
};
my $iterator2 = $iterator->filter($code);
* filter code (perl anonymous sub, getting the component and returning
a boolean)
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));
* starting index, 0 <= start_index < count * number of sequenced components, start_index + number <= count
or:
* array ref of indexes, 0 <= index < count