001/*
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2025 Smile CDR, Inc.
006 * %%
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 * You may obtain a copy of the License at
010 *
011 *      http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 * #L%
019 */
020package ca.uhn.fhir.jpa.dao.data;
021
022import ca.uhn.fhir.jpa.model.dao.JpaPid;
023import ca.uhn.fhir.jpa.model.entity.ResourceLink;
024import ca.uhn.fhir.model.primitive.IdDt;
025import org.springframework.data.jpa.repository.JpaRepository;
026import org.springframework.data.jpa.repository.Modifying;
027import org.springframework.data.jpa.repository.Query;
028import org.springframework.data.repository.query.Param;
029
030import java.util.List;
031import java.util.stream.Stream;
032
033public interface IResourceLinkDao extends JpaRepository<ResourceLink, Long>, IHapiFhirJpaRepository {
034
035        @Modifying
036        @Query("DELETE FROM ResourceLink t WHERE t.mySourceResource.myPid = :resId")
037        void deleteByResourceId(@Param("resId") JpaPid theResourcePid);
038
039        @Query("SELECT t FROM ResourceLink t WHERE t.mySourceResource.myPid = :resId")
040        List<ResourceLink> findAllForSourceResourceId(@Param("resId") JpaPid thePatientId);
041
042        @Query("SELECT t FROM ResourceLink t WHERE t.myTargetResource.myPid in :resIds")
043        List<ResourceLink> findWithTargetPidIn(@Param("resIds") List<JpaPid> thePids);
044
045        /**
046         * Loads a collection of ResourceLink entities by PID, but also  eagerly fetches
047         * the target resources and their forced IDs
048         */
049        @Query("SELECT t FROM ResourceLink t LEFT JOIN FETCH t.myTargetResource tr WHERE t.myId in :pids")
050        List<ResourceLink> findByPidAndFetchTargetDetails(@Param("pids") List<Long> thePids);
051
052        /**
053         * Stream Resource Ids of all resources that have a reference to the provided resource id
054         *
055         * @param theTargetResourceType the resource type part of the id
056         * @param theTargetResourceFhirId the value part of the id
057         * @return
058         */
059        @Query(
060                        "SELECT DISTINCT new ca.uhn.fhir.model.primitive.IdDt(t.mySourceResourceType, t.mySourceResource.myFhirId) FROM ResourceLink t WHERE t.myTargetResourceType = :resourceType AND t.myTargetResource.myFhirId = :resourceFhirId")
061        Stream<IdDt> streamSourceIdsForTargetFhirId(
062                        @Param("resourceType") String theTargetResourceType,
063                        @Param("resourceFhirId") String theTargetResourceFhirId);
064
065        /**
066         * Count the number of resources that have a reference to the provided resource id
067         *
068         * @param theTargetResourceType the resource type part of the id
069         * @param theTargetResourceFhirId the value part of the id
070         * @return
071         */
072        @Query(
073                        "SELECT COUNT(DISTINCT t.mySourceResourcePid) FROM ResourceLink t WHERE t.myTargetResourceType = :resourceType AND t.myTargetResource.myFhirId = :resourceFhirId")
074        Integer countResourcesTargetingFhirTypeAndFhirId(
075                        @Param("resourceType") String theTargetResourceType,
076                        @Param("resourceFhirId") String theTargetResourceFhirId);
077}