diff options
Diffstat (limited to 'internal/keepass/search.go')
| -rw-r--r-- | internal/keepass/search.go | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/internal/keepass/search.go b/internal/keepass/search.go new file mode 100644 index 0000000..e345703 --- /dev/null +++ b/internal/keepass/search.go @@ -0,0 +1,94 @@ +package keepass + +import ( + "context" + "fmt" + "path/filepath" + "sort" + + "codeberg.org/snonux/foostore/internal/store" +) + +// Search collects all indexes matching searchTerm, sorts by Description, +// calls onMatch and actionFn per entry, and returns the sorted list. +func (b *Backend) Search( + ctx context.Context, + searchTerm string, + action store.Action, + actionFn func(context.Context, *store.Index, *store.Data) error, + onMatch func(*store.Index), +) ([]*store.Index, error) { + var indexes store.IndexSlice + if err := b.WalkIndexes(ctx, searchTerm, func(idx *store.Index) error { + indexes = append(indexes, idx) + return nil + }); err != nil { + return nil, err + } + sort.Sort(indexes) + + for _, idx := range indexes { + if onMatch != nil { + onMatch(idx) + } + if err := b.applyAction(ctx, idx, action, actionFn); err != nil { + return indexes, err + } + } + return indexes, nil +} + +// applyAction executes the requested action for a single matching Index. +// File-level actions (cat, export) are handled directly; external-tool actions +// (paste, open, edit) are delegated to the caller-supplied actionFn. +func (b *Backend) applyAction(ctx context.Context, idx *store.Index, action store.Action, actionFn func(context.Context, *store.Index, *store.Data) error) error { + switch action { + case store.ActionNone: + return nil + case store.ActionCat: + return b.actionCat(ctx, idx) + case store.ActionExport: + return b.actionExport(ctx, idx, false) + case store.ActionPathExport: + return b.actionExport(ctx, idx, true) + default: + if actionFn != nil { + d, err := b.LoadData(ctx, idx) + if err != nil { + return err + } + return actionFn(ctx, idx, d) + } + } + return nil +} + +// actionCat prints the decrypted content of an index entry to stdout. +// Binary entries are skipped with a warning. +func (b *Backend) actionCat(ctx context.Context, idx *store.Index) error { + if idx.IsBinary() { + fmt.Println("Not displaying/pasting binary data!") + return nil + } + d, err := b.LoadData(ctx, idx) + if err != nil { + return err + } + fmt.Print(d.String()) + return nil +} + +// actionExport writes the decrypted content to cfg.ExportDir. +// When fullPath is true the full description path is used; when false only the +// basename is used (matching the :export vs :pathexport behaviour). +func (b *Backend) actionExport(ctx context.Context, idx *store.Index, fullPath bool) error { + d, err := b.LoadData(ctx, idx) + if err != nil { + return err + } + destFile := idx.Description + if !fullPath { + destFile = filepath.Base(idx.Description) + } + return d.Export(ctx, b.cfg.ExportDir, destFile) +} |
