File::KDBX::Iterator(3p)

NAME
File::KDBX::Iterator - KDBX database iterator

VERSION
version 0.906

SYNOPSIS
    my $kdbx = File::KDBX->load('database.kdbx', 'masterpw');

    $kdbx->entries
        ->where(sub { $_->title =~ /bank/i })
        ->order_by('title')
        ->limit(5)
        ->each(sub {
            say $_->title;
        });

DESCRIPTION
A buffered iterator compatible with and expanding upon Iterator::Simple, this provides an easy way to navigate a File::KDBX database. The documentation for Iterator::Simple documents functions and methods supported by this iterator that are not documented here, so consider that additional reading.

  Buffer
This iterator is buffered, meaning it can drain from an iterator subroutine under the hood, storing items temporarily to be accessed later. This allows features like "peek" and "order_by" which might be useful in the context of KDBX databases which are normally pretty small so draining an iterator completely isn't cost-prohibitive in terms of memory usage.

The way this works is that if you call an iterator without arguments, it acts like a normal iterator. If you call it with arguments, however, the arguments are added to the buffer. When called without arguments, the buffer is drained before the iterator function is. Using "unget" is equivalent to calling the iterator with arguments, and "next" is equivalent to calling the iterator without arguments.

METHODS

  new
    \&iterator = File::KDBX::Iterator->new(\&iterator);

Bless an iterator to augment it with buffering plus some useful utility methods.

  next
    $item = $iterator->next;
    # OR equivalently
    $item = $iterator->();

    $item = $iterator->next(\&query);

Get the next item or "undef" if there are no more items. If a query is passed, get the next matching item, discarding any unmatching items before the matching item. Example:

    my $item = $iterator->next(sub { $_->label =~ /Gym/ });

  peek
    $item = $iterator->peek;

Peek at the next item. Returns "undef" if the iterator is empty. This allows you to access the next item without draining it from the iterator. The same item will be returned the next time "next" is called.

  unget
    # Replace buffer:
    $iterator->unget(\@items);
    # OR equivalently
    $iterator->(\@items);

    # Unshift onto buffer:
    $iterator->unget(@items);
    # OR equivalently
    $iterator->(@items);

Replace the buffer (first form) or unshift one or more items to the current buffer (second form).

See "Buffer".

  each
    @items = $iterator->each;

    $iterator->each(sub($item, $num, @args) { ... }, @args);

    $iterator->each($method_name, ...);

Get or act on the rest of the items. This method has three forms:

1.  Without arguments, "each" returns a list of the rest of the items.

2.  Pass a coderef to be called once per item, in order. Arguments to the coderef are the item itself (also available as $_), its index number and then any extra arguments that were passed to "each" after the coderef.

3.  Pass a string that is the name of a method to be called on each object, in order. Any extra arguments passed to "each" after the method name are passed through to each method call. This form requires each item be an object that "can" the given method.

NOTE: This method drains the iterator completely, leaving it empty. See "CAVEATS".

  grep

  where
    \&iterator = $iterator->grep(\&query);
    \&iterator = $iterator->grep(sub($item) { ... });

Get a new iterator draining from an existing iterator but providing only items that pass a test or are matched by a query. In its basic form this method is very much like perl's built-in grep function, except for iterators.

There are many examples of the various forms of this method at "QUERY" in File::KDBX.

  map
    \&iterator = $iterator->map(\&code);

Get a new iterator draining from an existing iterator but providing modified items. In its basic form this method is very much like perl's built-in map function, except for iterators.

  order_by
    \&iterator = $iterator->sort_by($field, %options);
    \&iterator = $iterator->sort_by(\&get_value, %options);

Get a new iterator draining from an existing iterator but providing items sorted by an object field. Sorting is done using Unicode::Collate (if available) or "cmp" to sort alphanumerically. The "\&get_value" subroutine is called once for each item and should return a string value. Options:

•   "ascending" - Order ascending if true, descending otherwise (default: true)

•   "case" - If true, take case into account, otherwise ignore case (default: true)

•   "collate" - If true, use Unicode::Collate (if available), otherwise use perl built-ins (default: true)

•   Any Unicode::Collate option is also supported.

NOTE: This method drains the iterator completely and places the sorted items onto the buffer. See "CAVEATS".

  sort_by
Alias for "order_by".

  norder_by
    \&iterator = $iterator->nsort_by($field, %options);
    \&iterator = $iterator->nsort_by(\&get_value, %options);

Get a new iterator draining from an existing iterator but providing items sorted by an object field. Sorting is done numerically using "<=>". The "\&get_value" subroutine or $field accessor is called once for each item and should return a numerical value. Options:

•   "ascending" - Order ascending if true, descending otherwise (default: true)

NOTE: This method drains the iterator completely and places the sorted items onto the buffer. See "CAVEATS".

  nsort_by
Alias for "norder_by".

  limit
    \&iterator = $iterator->limit($count);

Get a new iterator draining from an existing iterator but providing only a limited number of items.

"limit" is an alias for "$iterator->head($count)" in Iterator::Simple.

  to_array
    \@array = $iterator->to_array;

Get the rest of the items from an iterator as an arrayref.

NOTE: This method drains the iterator completely, leaving it empty. See "CAVEATS".

  count
    $size = $iterator->count;

Count the rest of the items from an iterator.

NOTE: This method drains the iterator completely but restores it to its pre-drained state. See "CAVEATS".

  size
Alias for "count".

CAVEATS
Some methods attempt to drain the iterator completely before returning. For obvious reasons, this won't work for infinite iterators because your computer doesn't have infinite memory. This isn't a practical issue with File::KDBX lists which are always finite -- unless you do something weird like force a child group to be its own ancestor -- but I'm noting it here as a potential issue if you use this iterator class for other things (which you probably shouldn't do).

KDBX databases are always fully-loaded into memory anyway, so there's not a significant memory cost to draining an iterator completely.

BUGS
Please report any bugs or feature requests on the bugtracker website <https://github.com/chazmcgarvey/File-KDBX/issues>

When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.

AUTHOR
Charles McGarvey <ccm@cpan.org>

COPYRIGHT AND LICENSE
This software is copyright (c) 2022 by Charles McGarvey.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.