package repository import ( "context" "fmt" "gorm.io/gorm" ) // EntityQueryBuilder provides a way to build queries for different entity types type EntityQueryBuilder[T any] interface { BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB GetEntityType() string } // SiteQueryBuilder implements EntityQueryBuilder for Site entities type SiteQueryBuilder struct{} func (b *SiteQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "name": return db.Where("name = ?", value) case "notes": return db.Where("notes = ?", value) case "builder_owner": return db.Where("builder_owner = ?", value) case "architect": return db.Where("architect = ?", value) case "original_purpose": return db.Where("original_purpose = ?", value) case "current_use": return db.Where("current_use = ?", value) case "style": return db.Where("style = ?", value) case "materials": return db.Where("materials = ?", value) default: return db } } func (b *SiteQueryBuilder) GetEntityType() string { return "site" } // HeritageTitleQueryBuilder implements EntityQueryBuilder for HeritageTitle entities type HeritageTitleQueryBuilder struct{} func (b *HeritageTitleQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "title": return db.Where("title = ?", value) case "content": return db.Where("content = ?", value) default: return db } } func (b *HeritageTitleQueryBuilder) GetEntityType() string { return "heritage_title" } // HeritageTimelineItemQueryBuilder implements EntityQueryBuilder for HeritageTimelineItem entities type HeritageTimelineItemQueryBuilder struct{} func (b *HeritageTimelineItemQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "title": return db.Where("title = ?", value) case "content": return db.Where("content = ?", value) default: return db } } func (b *HeritageTimelineItemQueryBuilder) GetEntityType() string { return "heritage_timeline_item" } // HeritageSourceQueryBuilder implements EntityQueryBuilder for HeritageSource entities type HeritageSourceQueryBuilder struct{} func (b *HeritageSourceQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "title": return db.Where("title = ?", value) default: return db } } func (b *HeritageSourceQueryBuilder) GetEntityType() string { return "heritage_source" } // OrganizationQueryBuilder implements EntityQueryBuilder for Organization entities type OrganizationQueryBuilder struct{} func (b *OrganizationQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "name": return db.Where("name = ?", value) case "description": return db.Where("description = ?", value) case "sector": return db.Where("sector = ?", value) case "sub_type": return db.Where("subtype = ?", value) default: return db } } func (b *OrganizationQueryBuilder) GetEntityType() string { return "organization" } // GeographicalFeatureQueryBuilder implements EntityQueryBuilder for GeographicalFeature entities type GeographicalFeatureQueryBuilder struct{} func (b *GeographicalFeatureQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "name": return db.Where("name = ?", value) case "properties": return db.Where("properties::text LIKE ?", "%"+value+"%") default: return db } } func (b *GeographicalFeatureQueryBuilder) GetEntityType() string { return "geographical_feature" } // ProductQueryBuilder implements EntityQueryBuilder for Product entities type ProductQueryBuilder struct{} func (b *ProductQueryBuilder) BuildFieldQuery(db *gorm.DB, field, value string) *gorm.DB { switch field { case "name": return db.Where("name = ?", value) case "description": return db.Where("description = ?", value) default: return db } } func (b *ProductQueryBuilder) GetEntityType() string { return "product" } // FindEntitiesByFieldValue is a generic function to find entities by field value func FindEntitiesByFieldValue[T any](ctx context.Context, db *gorm.DB, builder EntityQueryBuilder[T], field, value string, limit int) ([]*T, error) { query := builder.BuildFieldQuery(db.Model(new(T)), field, value) if limit > 0 { query = query.Limit(limit) } var entities []*T err := query.WithContext(ctx).Find(&entities).Error if err != nil { return nil, fmt.Errorf("failed to find entities: %w", err) } return entities, nil } // GetEntityByID retrieves a single entity by ID func GetEntityByID[T any](ctx context.Context, db *gorm.DB, id string) (*T, error) { var entity T err := db.WithContext(ctx).First(&entity, "id = ?", id).Error if err != nil { return nil, fmt.Errorf("failed to get entity: %w", err) } return &entity, nil }