turash/bugulma/backend/internal/repository/generic_entity_repository.go

182 lines
4.7 KiB
Go

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
}