]> Dogcows Code - chaz/p5-File-KDBX/blobdiff - lib/File/KDBX.pm
Fill out recycle bin functionality
[chaz/p5-File-KDBX] / lib / File / KDBX.pm
index 54bb76867e268aba6f4736b324daa28d96c36621..47b49a1dd342a31cd4bf926326c1a3f93588c592 100644 (file)
@@ -6,9 +6,8 @@ use strict;
 
 use Crypt::PRNG qw(random_bytes);
 use Devel::GlobalDestruction;
-use File::KDBX::Constants qw(:all);
+use File::KDBX::Constants qw(:all :icon);
 use File::KDBX::Error;
-use File::KDBX::Iterator;
 use File::KDBX::Safe;
 use File::KDBX::Util qw(:class :coercion :empty :search :uuid erase simple_expression_query snakify);
 use Hash::Util::FieldHash qw(fieldhashes);
@@ -488,14 +487,105 @@ sub _trace_lineage {
     my $base = $lineage[-1] or return [];
 
     my $uuid = $object->uuid;
-    return \@lineage if any { $_->uuid eq $uuid } @{$base->groups || []}, @{$base->entries || []};
+    return \@lineage if any { $_->uuid eq $uuid } @{$base->groups}, @{$base->entries};
 
-    for my $subgroup (@{$base->groups || []}) {
+    for my $subgroup (@{$base->groups}) {
         my $result = $self->_trace_lineage($object, @lineage, $subgroup);
         return $result if $result;
     }
 }
 
+=method recycle_bin
+
+    $group = $kdbx->recycle_bin;
+    $kdbx->recycle_bin($group);
+
+Get or set the recycle bin group. Returns C<undef> if there is no recycle bin and L</recycle_bin_enabled> is
+false, otherwise the current recycle bin or an autovivified recycle bin group is returned.
+
+=cut
+
+sub recycle_bin {
+    my $self = shift;
+    if (my $group = shift) {
+        $self->recycle_bin_uuid($group->uuid);
+        return $group;
+    }
+    my $group;
+    my $uuid = $self->recycle_bin_uuid;
+    $group = $self->groups->grep(uuid => $uuid)->next if $uuid ne UUID_NULL;
+    if (!$group && $self->recycle_bin_enabled) {
+        $group = $self->add_group(
+            name                => 'Recycle Bin',
+            icon_id             => ICON_TRASHCAN_FULL,
+            enable_auto_type    => false,
+            enable_searching    => false,
+        );
+        $self->recycle_bin_uuid($group->uuid);
+    }
+    return $group;
+}
+
+=method entry_templates
+
+    $group = $kdbx->entry_templates;
+    $kdbx->entry_templates($group);
+
+Get or set the entry templates group. May return C<undef> if unset.
+
+=cut
+
+sub entry_templates {
+    my $self = shift;
+    if (my $group = shift) {
+        $self->entry_templates_group($group->uuid);
+        return $group;
+    }
+    my $uuid = $self->entry_templates_group;
+    return if $uuid eq UUID_NULL;
+    return $self->groups->grep(uuid => $uuid)->next;
+}
+
+=method last_selected
+
+    $group = $kdbx->last_selected;
+    $kdbx->last_selected($group);
+
+Get or set the last selected group. May return C<undef> if unset.
+
+=cut
+
+sub last_selected {
+    my $self = shift;
+    if (my $group = shift) {
+        $self->last_selected_group($group->uuid);
+        return $group;
+    }
+    my $uuid = $self->last_selected_group;
+    return if $uuid eq UUID_NULL;
+    return $self->groups->grep(uuid => $uuid)->next;
+}
+
+=method last_top_visible
+
+    $group = $kdbx->last_top_visible;
+    $kdbx->last_top_visible($group);
+
+Get or set the last top visible group. May return C<undef> if unset.
+
+=cut
+
+sub last_top_visible {
+    my $self = shift;
+    if (my $group = shift) {
+        $self->last_top_visible_group($group->uuid);
+        return $group;
+    }
+    my $uuid = $self->last_top_visible_group;
+    return if $uuid eq UUID_NULL;
+    return $self->groups->grep(uuid => $uuid)->next;
+}
+
 ##############################################################################
 
 =method add_group
@@ -548,37 +638,9 @@ Get an iterator over I<groups> within a database. Options:
 sub groups {
     my $self = shift;
     my %args = @_ % 2 == 0 ? @_ : (base => shift, @_);
-    my $base = $args{base} // $self->root;
-
-    my @groups = ($args{inclusive} // 1) ? $base : @{$base->groups};
-    my $algo = lc($args{algorithm} || 'ids');
-
-    if ($algo eq 'dfs') {
-        my %visited;
-        return File::KDBX::Iterator->new(sub {
-            my $next = shift @groups or return;
-            if (!$visited{Hash::Util::FieldHash::id($next)}++) {
-                while (my @children = @{$next->groups}) {
-                    unshift @groups, @children, $next;
-                    $next = shift @groups;
-                    $visited{Hash::Util::FieldHash::id($next)}++;
-                }
-            }
-            $next;
-        });
-    }
-    elsif ($algo eq 'bfs') {
-        return File::KDBX::Iterator->new(sub {
-            my $next = shift @groups or return;
-            push @groups, @{$next->groups};
-            $next;
-        });
-    }
-    return File::KDBX::Iterator->new(sub {
-        my $next = shift @groups or return;
-        unshift @groups, @{$next->groups};
-        $next;
-    });
+    my $base = delete $args{base} // $self->root;
+
+    return $base->groups_deeply(%args);
 }
 
 ##############################################################################
@@ -634,35 +696,17 @@ ones:
 sub entries {
     my $self = shift;
     my %args = @_ % 2 == 0 ? @_ : (base => shift, @_);
+    my $base = delete $args{base} // $self->root;
 
-    my $searching   = $args{searching};
-    my $auto_type   = $args{auto_type};
-    my $history     = $args{history};
-
-    my $groups = $self->groups(%args);
-    my @entries;
-
-    return File::KDBX::Iterator->new(sub {
-        if (!@entries) {
-            while (my $group = $groups->next) {
-                next if $searching && !$group->effective_enable_searching;
-                next if $auto_type && !$group->effective_enable_auto_type;
-                @entries = @{$group->entries};
-                @entries = grep { $_->auto_type->{enabled} } @entries if $auto_type;
-                @entries = map { ($_, @{$_->history}) } @entries if $history;
-                last if @entries;
-            }
-        }
-        shift @entries;
-    });
+    return $base->entries_deeply(%args);
 }
 
 ##############################################################################
 
 =method objects
 
-    \&iterator = $kdbx->entries(%options);
-    \&iterator = $kdbx->entries($base_group, %options);
+    \&iterator = $kdbx->objects(%options);
+    \&iterator = $kdbx->objects($base_group, %options);
 
 Get an iterator over I<objects> within a database. Groups and entries are considered objects, so this is
 essentially a combination of L</groups> and L</entries>. This won't often be useful, but it can be convenient
@@ -673,27 +717,9 @@ for maintenance tasks. This method takes the same options as L</groups> and L</e
 sub objects {
     my $self = shift;
     my %args = @_ % 2 == 0 ? @_ : (base => shift, @_);
+    my $base = delete $args{base} // $self->root;
 
-    my $searching   = $args{searching};
-    my $auto_type   = $args{auto_type};
-    my $history     = $args{history};
-
-    my $groups = $self->groups(%args);
-    my @entries;
-
-    return File::KDBX::Iterator->new(sub {
-        if (!@entries) {
-            while (my $group = $groups->next) {
-                next if $searching && !$group->effective_enable_searching;
-                next if $auto_type && !$group->effective_enable_auto_type;
-                @entries = @{$group->entries};
-                @entries = grep { $_->auto_type->{enabled} } @entries if $auto_type;
-                @entries = map { ($_, @{$_->history}) } @entries if $history;
-                return $group;
-            }
-        }
-        shift @entries;
-    });
+    return $base->objects_deeply(%args);
 }
 
 sub __iter__ { $_[0]->objects }
This page took 0.025127 seconds and 4 git commands to generate.