1 package File
::KDBX
::Iterator
;
2 # PACKAGE: KDBX database iterator
8 use File
::KDBX
::Util
qw(:class :load :search);
11 use Ref
::Util
qw(is_arrayref is_coderef is_scalarref);
14 BEGIN { mark_as_loaded
('Iterator::Simple::Iterator') }
15 extends
'Iterator::Simple::Iterator';
17 our $VERSION = '999.999'; # VERSION
21 \
&iterator
= File
::KDBX
::Iterator-
>new(\
&iterator
);
23 Blesses an iterator to augment it with buffering plus some useful utility methods
.
29 my $code = is_coderef
($_[0]) ? shift : sub { undef };
31 my $items = @_ == 1 && is_arrayref
($_[0]) ? $_[0] : \
@_;
32 return $class->SUPER::new
(sub {
34 if (@_ == 1 && is_arrayref
($_[0])) {
43 my $next = shift @$items;
44 return $next if defined $next;
52 $item = $iterator->next;
54 $item = $iterator->();
56 $item = $iterator->next(\
&query
);
57 $item = $iterator->next([\'simple expression
', @fields]);
59 Get the next item or C<undef> if there are no more items. If a query is passed, get the next matching item,
60 discarding any unmatching items before the matching item. Example:
62 my $item = $iterator->next(sub { $_->label =~ /Gym/ });
68 my $code = shift or return $self->();
70 $code = query_any($code, @_);
72 while (defined (local $_ = $self->())) {
73 return $_ if $code->($_);
80 $item = $iterator->peek;
82 Peek at the next item. Returns C<undef> if the iterator is empty. This allows you to access the next item
83 without draining it from the iterator. The same item will be returned the next time L</next> is called.
91 $self->($next) if defined $next;
97 $iterator->unget(\@items);
98 $iterator->unget(...);
100 $iterator->(\@items);
103 Replace the buffer or unshift one or more items to the current buffer.
110 my $self = shift; # Must shift in a statement before calling.
116 @items = $iterator->each;
118 $iterator->each(sub($item, $num) { ... });
120 Get the rest of the items. There are two forms: Without arguments, C<each> returns a list of the rest of the
121 items. Or pass a coderef to be called once per item, in order. The item is passed as the first argument to the
122 given subroutine and is also available as C<$_>.
124 B<NOTE:> This method drains the iterator completely, leaving it empty. See L</CAVEATS>.
130 my $cb = shift or return @{$self->to_array};
133 $cb->($_, $count++) while defined (local $_ = $self->());
141 \&iterator = $iterator->grep(\&query);
142 \&iterator = $iterator->grep([\'simple expression', @fields]);
144 Get a new iterator draining from an existing iterator but providing only items that pass a test
or are matched
149 sub where
{ shift-
>grep(@_) }
153 my $code = query_any
(@_);
155 ref($self)->new(sub {
156 while (defined (local $_ = $self->())) {
157 return $_ if $code->($_);
165 \
&iterator
= $iterator->map(\
&code
);
167 Get a new iterator draining from an existing iterator but providing modified items
.
175 ref($self)->new(sub {
176 local $_ = $self->();
177 return if !defined $_;
184 \
&iterator
= $iterator->sort_by($field, %options);
185 \
&iterator
= $iterator->sort_by(\
&get_value
, %options);
187 Get a new iterator draining from an existing iterator but providing items sorted by an object field
. Sorting
188 is done using L
<Unicode
::Collate
> (if available
) or C
<cmp> to
sort alphanumerically
. The C
<\
&get_value
>
189 subroutine
is called once
for each item
and should
return a string value
. Options
:
192 * C<ascending> - Order ascending if true, descending otherwise (default: true)
193 * C<case> - If true, take case into account, otherwise ignore case (default: true)
194 * C<collate> - If true, use B<Unicode::Collate> (if available), otherwise use perl built-ins (default: true)
195 * Any B<Unicode::Collate> option is also supported.
197 C<sort_by> and C<order_by> are aliases.
199 B<NOTE:> This method drains the iterator completely and places the sorted items onto the buffer. See
209 my $ascending = delete $args{ascending
} // !delete $args{descending
} // 1;
210 my $case = delete $args{case
} // !delete $args{no_case
} // 1;
211 my $collate = (delete $args{collate
} // !delete $args{no_collate
} // 1)
212 && try_load_optional
('Unicode::Collate');
214 if ($collate && !$case) {
216 # use a proper Unicode::Collate level to ignore case
219 $args{upper_before_lower
} //= 1;
222 $value = $case ? sub { $_[0]->$field // '' } : sub { uc($_[0]->$field) // '' } if !is_coderef
($value);
223 my @all = CORE
::map { [$_, $value->($_)] } @{$self->to_array};
226 my $c = Unicode
::Collate-
>new(%args);
228 @all = CORE
::map { $_->[0] } CORE
::sort { $c->cmp($a->[1], $b->[1]) } @all;
230 @all = CORE
::map { $_->[0] } CORE
::sort { $c->cmp($b->[1], $a->[1]) } @all;
234 @all = CORE
::map { $_->[0] } CORE
::sort { $a->[1] cmp $b->[1] } @all;
236 @all = CORE
::map { $_->[0] } CORE
::sort { $b->[1] cmp $a->[1] } @all;
246 Alias
for L
</order_by
>.
250 sub sort_by
{ shift-
>order_by(@_) }
254 \
&iterator
= $iterator->nsort_by($field, %options);
255 \
&iterator
= $iterator->nsort_by(\
&get_value
, %options);
257 Get a new iterator draining from an existing iterator but providing items sorted by an object field
. Sorting
258 is done numerically using C
<< <=> >>. The C
<\
&get_value
> subroutine
or C
<$field> accessor
is called once
for
259 each item
and should
return a numerical value
. Options
:
262 * C<ascending> - Order ascending if true, descending otherwise (default: true)
264 C<nsort_by> and C<norder_by> are aliases.
266 B<NOTE:> This method drains the iterator completely and places the sorted items onto the buffer. See
276 my $ascending = $args{ascending
} // !$args{descending
} // 1;
279 $value = sub { $_[0]->$field // 0 } if !is_coderef
($value);
280 my @all = CORE
::map { [$_, $value->($_)] } @{$self->to_array};
283 @all = CORE
::map { $_->[0] } CORE
::sort { $a->[1] <=> $b->[1] } @all;
285 @all = CORE
::map { $_->[0] } CORE
::sort { $b->[1] <=> $a->[1] } @all;
294 Alias
for L
</norder_by
>.
298 sub nsort_by
{ shift-
>norder_by(@_) }
302 \
&iterator
= $iterator->limit($count);
304 Get a new iterator draining from an existing iterator but providing only a limited number of items
.
306 C
<limit
> as an alias
for L
<Iterator
::Simple
/"$iterator->head($count)">.
310 sub limit
{ shift-
>head(@_) }
314 \
@array = $iterator->to_array;
316 Get the rest of the items from an iterator as an arrayref
.
318 B
<NOTE
:> This
method drains the iterator completely
, leaving it empty
. See L
</CAVEATS
>.
326 push @all, $_ while defined (local $_ = $self->());
332 $size = $iterator->count;
334 Count the rest of the items from an iterator
.
336 B
<NOTE
:> This
method drains the iterator completely but restores it to its pre-drained
state. See L
</CAVEATS
>.
343 my $items = $self->to_array;
345 return scalar @$items;
354 sub size
{ shift-
>count }
356 ##############################################################################
358 sub TO_JSON
{ $_[0]->to_array }
363 =for Pod::Coverage TO_JSON
367 my $kdbx = File::KDBX->load('database.kdbx', 'masterpw');
370 ->where(sub { $_->title =~ /bank/i })
379 A buffered iterator compatible with and expanding upon L<Iterator::Simple>, this provides an easy way to
380 navigate a L<File::KDBX> database. The documentation for B<Iterator::Simple> documents functions and methods
381 supported but this iterator that are not documented here, so consider that additional reading.
385 This iterator is buffered, meaning it can drain from an iterator subroutine under the hood, storing items
386 temporarily to be accessed later. This allows features like L</peek> and L</sort> which might be useful in the
387 context of KDBX databases which are normally pretty small so draining an iterator isn't cost-prohibitive.
389 The way this works is that if you call an iterator without arguments, it acts like a normal iterator. If you
390 call it with arguments, however, the arguments are added to the buffer. When called without arguments, the
391 buffer is drained before the iterator function is. Using L</unget> is equivalent to calling the iterator with
392 arguments, and as L</next> is equivalent to calling the iterator without arguments.
396 Some methods attempt to drain the iterator completely before returning. For obvious reasons, this won't work
397 for infinite iterators because your computer doesn't have infinite memory. This isn't a practical issue with
398 B<File::KDBX> lists which are always finite -- unless you do something weird like force a child group to be
399 its own ancestor -- but I'm noting it here as a potential issue if you use this iterator class for other
400 things (which you probably shouldn't do).