diff --git a/db/query/geometries.sql b/db/query/geometries.sql index d6a0f14..8dab9f0 100644 --- a/db/query/geometries.sql +++ b/db/query/geometries.sql @@ -254,3 +254,4 @@ SELECT entity_id, geometry_id FROM entity_geometries WHERE entity_id = ANY($1::uuid[]); + diff --git a/internal/controllers/geometryController.go b/internal/controllers/geometryController.go index 3c6c053..f2dc3b9 100644 --- a/internal/controllers/geometryController.go +++ b/internal/controllers/geometryController.go @@ -142,3 +142,4 @@ func (h *GeometryController) GetGeometriesByBoundWith(c fiber.Ctx) error { Data: res, }) } + diff --git a/internal/dtos/request/relation.go b/internal/dtos/request/relation.go index 276e363..bd3f4dd 100644 --- a/internal/dtos/request/relation.go +++ b/internal/dtos/request/relation.go @@ -21,7 +21,7 @@ type GetGeometriesByEntityIDsDto struct { } type GetRelationsDto struct { - Type string `json:"type" query:"type" validate:"required,oneof=wiki-entity entity-wiki geometry-entity entity-geometry"` + Type string `json:"type" query:"type" validate:"required,oneof=wiki-entity entity-wiki geometry-entity entity-geometry entity-geometry-bound-with"` IDs []string `json:"ids" query:"ids" validate:"required,min=1,dive,uuid"` } diff --git a/internal/repositories/geometryRepository.go b/internal/repositories/geometryRepository.go index a859492..f2acc1c 100644 --- a/internal/repositories/geometryRepository.go +++ b/internal/repositories/geometryRepository.go @@ -626,3 +626,4 @@ func (r *geometryRepository) GetGeometryIDsByEntityIDs(ctx context.Context, enti return result, nil } + diff --git a/internal/services/geometryService.go b/internal/services/geometryService.go index 208ecea..0a6890b 100644 --- a/internal/services/geometryService.go +++ b/internal/services/geometryService.go @@ -182,3 +182,4 @@ func (s *geometryService) SearchGeometriesByEntityName( NextCursor: nextCursor, }, nil } + diff --git a/internal/services/relationService.go b/internal/services/relationService.go index 7432f38..f07476f 100644 --- a/internal/services/relationService.go +++ b/internal/services/relationService.go @@ -42,6 +42,10 @@ func (s *relationService) GetRelations(ctx context.Context, req *request.GetRela return s.getEntitiesByGeometryIDs(ctx, req.IDs) case "entity-geometry": return s.getGeometriesByEntityIDs(ctx, req.IDs) + case "entity-geometry-child": + return s.getGeometriesByEntityIDsFiltered(ctx, req.IDs, true) + case "entity-geometry-alone": + return s.getGeometriesByEntityIDsFiltered(ctx, req.IDs, false) default: return nil, fiber.NewError(fiber.StatusBadRequest, "Unsupported relation type") } @@ -238,3 +242,55 @@ func (s *relationService) getGeometriesByEntityIDs(ctx context.Context, entityID return result, nil } + +func (s *relationService) getGeometriesByEntityIDsFiltered(ctx context.Context, entityIDs []string, keepBoundWith bool) (map[string][]*response.GeometryResponse, *fiber.Error) { + mapping, err := s.geometryRepo.GetGeometryIDsByEntityIDs(ctx, entityIDs) + if err != nil { + return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch geometry IDs by entity IDs") + } + + totalGeometryIDs := 0 + for _, gIDs := range mapping { + totalGeometryIDs += len(gIDs) + } + + geometryIDMap := make(map[string]struct{}, totalGeometryIDs) + allGeometryIDs := make([]string, 0, totalGeometryIDs) + for _, gIDs := range mapping { + for _, gID := range gIDs { + if _, ok := geometryIDMap[gID]; !ok { + geometryIDMap[gID] = struct{}{} + allGeometryIDs = append(allGeometryIDs, gID) + } + } + } + + geometries, err := s.geometryRepo.GetByIDs(ctx, allGeometryIDs) + if err != nil { + return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch geometries") + } + + geometriesByID := make(map[string]*models.GeometryEntity, len(geometries)) + for _, g := range geometries { + geometriesByID[g.ID] = g + } + + result := make(map[string][]*response.GeometryResponse, len(entityIDs)) + for _, idStr := range entityIDs { + gIDs, exists := mapping[idStr] + result[idStr] = make([]*response.GeometryResponse, 0, len(gIDs)) + if exists { + for _, gID := range gIDs { + if g, found := geometriesByID[gID]; found { + hasBoundWith := g.BoundWith != nil && *g.BoundWith != "" + if (keepBoundWith && hasBoundWith) || (!keepBoundWith && !hasBoundWith) { + result[idStr] = append(result[idStr], g.ToResponse()) + } + } + } + } + } + + return result, nil +} +