add field-based find functions

This commit is contained in:
Sky Johnson 2025-08-18 10:42:53 -05:00
parent 25ad394f17
commit 93a3b6c559

View File

@ -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
}