From 93a3b6c559f275a9d725884eb83b0776b213bb9f Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Mon, 18 Aug 2025 10:42:53 -0500 Subject: [PATCH] add field-based find functions --- store.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/store.go b/store.go index 8af722a..e1cfe15 100644 --- a/store.go +++ b/store.go @@ -646,3 +646,85 @@ func NewSingleton[S any](initFunc func() *S) func() *S { return store } } + +// ============================================================================ +// Find Functions +// ============================================================================ + +// FindByField performs a linear search for items where fieldName equals value +func (bs *BaseStore[T]) FindByField(fieldName string, value any) []*T { + bs.mu.RLock() + defer bs.mu.RUnlock() + + var result []*T + for _, item := range bs.items { + itemValue := reflect.ValueOf(item).Elem() + fieldValue := itemValue.FieldByName(fieldName) + if !fieldValue.IsValid() { + continue + } + + if fieldValue.Interface() == value { + result = append(result, item) + } + } + return result +} + +// FindFirstByField returns the first item where fieldName equals value +func (bs *BaseStore[T]) FindFirstByField(fieldName string, value any) (*T, bool) { + bs.mu.RLock() + defer bs.mu.RUnlock() + + for _, item := range bs.items { + itemValue := reflect.ValueOf(item).Elem() + fieldValue := itemValue.FieldByName(fieldName) + if !fieldValue.IsValid() { + continue + } + + if fieldValue.Interface() == value { + return item, true + } + } + return nil, false +} + +// FindByFields performs a linear search with multiple field conditions (AND logic) +func (bs *BaseStore[T]) FindByFields(conditions map[string]any) []*T { + bs.mu.RLock() + defer bs.mu.RUnlock() + + var result []*T + for _, item := range bs.items { + itemValue := reflect.ValueOf(item).Elem() + matches := true + + for fieldName, expectedValue := range conditions { + fieldValue := itemValue.FieldByName(fieldName) + if !fieldValue.IsValid() || fieldValue.Interface() != expectedValue { + matches = false + break + } + } + + if matches { + result = append(result, item) + } + } + return result +} + +// FindByPredicate allows custom filtering logic +func (bs *BaseStore[T]) FindByPredicate(predicate func(*T) bool) []*T { + bs.mu.RLock() + defer bs.mu.RUnlock() + + var result []*T + for _, item := range bs.items { + if predicate(item) { + result = append(result, item) + } + } + return result +}