turash/bugulma/backend/internal/service/entity_loader_service.go

333 lines
10 KiB
Go

package service
import (
"bugulma/backend/internal/domain"
"bugulma/backend/internal/localization"
"fmt"
"gorm.io/gorm"
)
// EntityLoaderService provides generic entity loading functionality using the registry
type EntityLoaderService struct {
db *gorm.DB
}
// NewEntityLoaderService creates a new entity loader service
func NewEntityLoaderService(db *gorm.DB) *EntityLoaderService {
return &EntityLoaderService{db: db}
}
// LoadEntities loads all entities of a specific type using the registry handlers
func (s *EntityLoaderService) LoadEntities(entityType string, options localization.LoadOptions) ([]interface{}, error) {
desc, exists := localization.GetEntityDescriptor(entityType)
if !exists {
return nil, fmt.Errorf("unsupported entity type: %s", entityType)
}
// Use type-specific loading with proper type casting
switch entityType {
case "heritage_title":
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageTitle])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
case "timeline_item":
handler := desc.Handler.(domain.EntityHandler[*domain.TimelineItem])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
case "heritage_source":
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageSource])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
case "site":
handler := desc.Handler.(domain.EntityHandler[*domain.Site])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
case "organization":
handler := desc.Handler.(domain.EntityHandler[*domain.Organization])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
case "geographical_feature":
handler := desc.Handler.(domain.EntityHandler[*domain.GeographicalFeature])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
case "product":
handler := desc.Handler.(domain.EntityHandler[*domain.Product])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: options.IncludeAllSites})
if err != nil {
return nil, err
}
result := make([]interface{}, len(entities))
for i, e := range entities {
result[i] = e
}
return result, nil
default:
return nil, fmt.Errorf("unsupported entity type: %s", entityType)
}
}
// LoadEntityByID loads a single entity by ID using the registry
func (s *EntityLoaderService) LoadEntityByID(entityType, entityID string) (interface{}, error) {
desc, exists := localization.GetEntityDescriptor(entityType)
if !exists {
return nil, fmt.Errorf("unsupported entity type: %s", entityType)
}
// Use type-specific loading with proper type casting
switch entityType {
case "heritage_title":
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageTitle])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
case "timeline_item":
handler := desc.Handler.(domain.EntityHandler[*domain.TimelineItem])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
case "heritage_source":
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageSource])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
case "site":
handler := desc.Handler.(domain.EntityHandler[*domain.Site])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{IncludeAllSites: true})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
case "organization":
handler := desc.Handler.(domain.EntityHandler[*domain.Organization])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
case "geographical_feature":
handler := desc.Handler.(domain.EntityHandler[*domain.GeographicalFeature])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
case "product":
handler := desc.Handler.(domain.EntityHandler[*domain.Product])
entities, err := handler.LoadEntities(s.db, domain.EntityLoadOptions{})
if err != nil {
return nil, err
}
for _, e := range entities {
if handler.GetEntityID(e) == entityID {
return e, nil
}
}
return nil, fmt.Errorf("entity not found: %s", entityID)
default:
return nil, fmt.Errorf("unsupported entity type: %s", entityType)
}
}
// GetEntityID returns the ID of an entity using the registry handler
func (s *EntityLoaderService) GetEntityID(entity interface{}) string {
// Determine entity type from the entity itself
var entityType string
switch entity.(type) {
case *domain.HeritageTitle:
entityType = "heritage_title"
case *domain.TimelineItem:
entityType = "timeline_item"
case *domain.HeritageSource:
entityType = "heritage_source"
case *domain.Site:
entityType = "site"
case *domain.Organization:
entityType = "organization"
case *domain.GeographicalFeature:
entityType = "geographical_feature"
case *domain.Product:
entityType = "product"
default:
return ""
}
desc, exists := localization.GetEntityDescriptor(entityType)
if !exists {
return ""
}
// Use type-specific handler to get ID
switch e := entity.(type) {
case *domain.HeritageTitle:
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageTitle])
return handler.GetEntityID(e)
case *domain.TimelineItem:
handler := desc.Handler.(domain.EntityHandler[*domain.TimelineItem])
return handler.GetEntityID(e)
case *domain.HeritageSource:
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageSource])
return handler.GetEntityID(e)
case *domain.Site:
handler := desc.Handler.(domain.EntityHandler[*domain.Site])
return handler.GetEntityID(e)
case *domain.Organization:
handler := desc.Handler.(domain.EntityHandler[*domain.Organization])
return handler.GetEntityID(e)
case *domain.GeographicalFeature:
handler := desc.Handler.(domain.EntityHandler[*domain.GeographicalFeature])
return handler.GetEntityID(e)
case *domain.Product:
handler := desc.Handler.(domain.EntityHandler[*domain.Product])
return handler.GetEntityID(e)
}
return ""
}
// GetRussianContent returns the Russian content for an entity field using the registry handler
func (s *EntityLoaderService) GetRussianContent(entity interface{}, field string) string {
// Determine entity type from the entity itself
var entityType string
switch entity.(type) {
case *domain.HeritageTitle:
entityType = "heritage_title"
case *domain.TimelineItem:
entityType = "timeline_item"
case *domain.HeritageSource:
entityType = "heritage_source"
case *domain.Site:
entityType = "site"
case *domain.Organization:
entityType = "organization"
case *domain.GeographicalFeature:
entityType = "geographical_feature"
case *domain.Product:
entityType = "product"
default:
return ""
}
desc, exists := localization.GetEntityDescriptor(entityType)
if !exists {
return ""
}
// Use type-specific handler to get field value
switch e := entity.(type) {
case *domain.HeritageTitle:
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageTitle])
return handler.GetFieldValue(e, field)
case *domain.TimelineItem:
handler := desc.Handler.(domain.EntityHandler[*domain.TimelineItem])
return handler.GetFieldValue(e, field)
case *domain.HeritageSource:
handler := desc.Handler.(domain.EntityHandler[*domain.HeritageSource])
return handler.GetFieldValue(e, field)
case *domain.Site:
handler := desc.Handler.(domain.EntityHandler[*domain.Site])
return handler.GetFieldValue(e, field)
case *domain.Organization:
handler := desc.Handler.(domain.EntityHandler[*domain.Organization])
return handler.GetFieldValue(e, field)
case *domain.GeographicalFeature:
handler := desc.Handler.(domain.EntityHandler[*domain.GeographicalFeature])
return handler.GetFieldValue(e, field)
case *domain.Product:
handler := desc.Handler.(domain.EntityHandler[*domain.Product])
return handler.GetFieldValue(e, field)
}
return ""
}