From 0c7e94c8348ddce6c2ebfbb10910f056ffff8e5d Mon Sep 17 00:00:00 2001 From: Aleksandr Trushkin Date: Sat, 10 Feb 2024 20:21:55 +0300 Subject: [PATCH] try to abstract matcher --- cmd/cli/main.go | 63 +++++++++++++++++++++++-------------- internal/matcher/matcher.go | 13 ++++++++ 2 files changed, 53 insertions(+), 23 deletions(-) create mode 100644 internal/matcher/matcher.go diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 7fcda16..49bebfd 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -411,8 +411,14 @@ func newViewItemsParamsKnownValues() *cli.Command { func newViewItemsCountCmd() *cli.Command { return &cli.Command{ - Name: "count", - Usage: "iterates over collection and counts number of items", + Name: "count", + Usage: "iterates over collection and counts number of items", + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "param-key-match", + Usage: "filters by parameters with AND logic", + }, + }, Action: decorateAction(viewItemsCountAction), } } @@ -649,36 +655,47 @@ func viewItemsCountAction(ctx context.Context, c *cli.Command) error { return fmt.Errorf("getting repository: %w", err) } - itemChan, err := r.GoodsItem().ListIter(ctx, 10) - if err != nil { - if !errors.Is(err, entity.ErrNotImplemented) { - return fmt.Errorf("getting list iter: %w", err) + filters := c.StringSlice("param-key-match") + m := matcher.NewRadix() + patternMapped := make(map[string]struct{}, len(filters)) + if len(filters) == 0 { + m.Register("*") + } else { + for _, f := range filters { + m.Register(f) + } + for _, pattern := range m.Patterns() { + patternMapped[pattern] = struct{}{} } } var count int - if err == nil { - var done bool - for !done { - select { - case _, ok := <-itemChan: - if !ok { - done = true - continue - } - count++ - case <-ctx.Done(): - return ctx.Err() + items, err := r.GoodsItem().List(ctx) + if err != nil { + return fmt.Errorf("getting items: %w", err) + } + for _, item := range items { + seenPatterns := map[string]struct{}{} + + for k := range item.Parameters { + pattern := m.MatchByPattern(k) + if pattern == "" { + continue } + if _, ok := seenPatterns[pattern]; ok { + continue + } + seenPatterns[pattern] = struct{}{} + } + + if len(seenPatterns) == len(patternMapped) { + println("Item matched", item.Articul, item.Cart) + count++ } } - items, err := r.GoodsItem().List(ctx) - if err != nil { - return fmt.Errorf("getting list: %w", err) - } + println(count) - zerolog.Ctx(ctx).Info().Int("count", count).Int("list_count", len(items)).Msg("read all items") return nil } diff --git a/internal/matcher/matcher.go b/internal/matcher/matcher.go new file mode 100644 index 0000000..450d610 --- /dev/null +++ b/internal/matcher/matcher.go @@ -0,0 +1,13 @@ +package matcher + +type Unit interface { + MatchByPattern(value string) (pattern string) + Match(value string) bool + + // Move this to init stage because some of matchers + // might not be applicable to it + RegisterRegexp(regexpPattern string) + Register(pattern string) + + Patterns() []string +}