001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2023 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.entity.MdmLink;
023import ca.uhn.fhir.mdm.api.MdmMatchResultEnum;
024import org.springframework.data.domain.Pageable;
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.history.RevisionRepository;
029import org.springframework.data.repository.query.Param;
030import org.springframework.stereotype.Repository;
031
032import java.util.Date;
033import java.util.List;
034import java.util.Optional;
035
036@Repository
037public interface IMdmLinkJpaRepository
038                extends RevisionRepository<MdmLink, Long, Long>, JpaRepository<MdmLink, Long>, IHapiFhirJpaRepository {
039        @Modifying
040        @Query("DELETE FROM MdmLink f WHERE myGoldenResourcePid = :pid OR mySourcePid = :pid")
041        int deleteWithAnyReferenceToPid(@Param("pid") Long thePid);
042
043        @Modifying
044        @Query(
045                        "DELETE FROM MdmLink f WHERE (myGoldenResourcePid = :pid OR mySourcePid = :pid) AND myMatchResult <> :matchResult")
046        int deleteWithAnyReferenceToPidAndMatchResultNot(
047                        @Param("pid") Long thePid, @Param("matchResult") MdmMatchResultEnum theMatchResult);
048
049        @Modifying
050        @Query("DELETE FROM MdmLink f WHERE myGoldenResourcePid IN (:goldenPids) OR mySourcePid IN (:goldenPids)")
051        void deleteLinksWithAnyReferenceToPids(@Param("goldenPids") List<Long> theResourcePids);
052
053        @Query("SELECT ml2.myGoldenResourcePid as goldenPid, ml2.mySourcePid as sourcePid FROM MdmLink ml2 "
054                        + "WHERE ml2.myMatchResult=:matchResult "
055                        + "AND ml2.myGoldenResourcePid IN ("
056                        + "SELECT ml.myGoldenResourcePid FROM MdmLink ml "
057                        + "INNER JOIN ResourceLink hrl "
058                        + "ON hrl.myTargetResourcePid=ml.mySourcePid "
059                        + "AND hrl.mySourceResourcePid=:groupPid "
060                        + "AND hrl.mySourcePath='Group.member.entity' "
061                        + "AND hrl.myTargetResourceType='Patient'"
062                        + ")")
063        List<MdmPidTuple> expandPidsFromGroupPidGivenMatchResult(
064                        @Param("groupPid") Long theGroupPid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
065
066        @Query("SELECT ml FROM MdmLink ml WHERE ml.mySourcePid = :sourcePid AND ml.myMatchResult = :matchResult")
067        Optional<MdmLink> findBySourcePidAndMatchResult(
068                        @Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMatch);
069
070        interface MdmPidTuple {
071                Long getGoldenPid();
072
073                Long getSourcePid();
074        }
075
076        @Query("SELECT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid " + "FROM MdmLink ml "
077                        + "INNER JOIN MdmLink ml2 "
078                        + "on ml.myGoldenResourcePid=ml2.myGoldenResourcePid "
079                        + "WHERE ml2.mySourcePid=:sourcePid "
080                        + "AND ml2.myMatchResult=:matchResult "
081                        + "AND ml.myMatchResult=:matchResult")
082        List<MdmPidTuple> expandPidsBySourcePidAndMatchResult(
083                        @Param("sourcePid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
084
085        @Query("SELECT ml " + "FROM MdmLink ml "
086                        + "INNER JOIN MdmLink ml2 "
087                        + "on ml.myGoldenResourcePid=ml2.myGoldenResourcePid "
088                        + "WHERE ml2.mySourcePid=:sourcePid "
089                        + "AND ml2.myMatchResult!=:matchResult")
090        List<MdmLink> findLinksAssociatedWithGoldenResourceOfSourceResourceExcludingMatchResult(
091                        @Param("sourcePid") Long theSourcePid,
092                        @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnumToExclude);
093
094        @Query(
095                        "SELECT ml.myGoldenResourcePid as goldenPid, ml.mySourcePid as sourcePid FROM MdmLink ml WHERE ml.myGoldenResourcePid = :goldenPid and ml.myMatchResult = :matchResult")
096        List<MdmPidTuple> expandPidsByGoldenResourcePidAndMatchResult(
097                        @Param("goldenPid") Long theSourcePid, @Param("matchResult") MdmMatchResultEnum theMdmMatchResultEnum);
098
099        @Query(
100                        "SELECT ml.myId FROM MdmLink ml WHERE ml.myMdmSourceType = :resourceName AND ml.myCreated <= :highThreshold ORDER BY ml.myCreated DESC")
101        List<Long> findPidByResourceNameAndThreshold(
102                        @Param("resourceName") String theResourceName,
103                        @Param("highThreshold") Date theHighThreshold,
104                        Pageable thePageable);
105
106        @Query(
107                        "SELECT ml.myId FROM MdmLink ml WHERE ml.myMdmSourceType = :resourceName AND ml.myCreated <= :highThreshold AND ml.myPartitionIdValue IN :partitionId ORDER BY ml.myCreated DESC")
108        List<Long> findPidByResourceNameAndThresholdAndPartitionId(
109                        @Param("resourceName") String theResourceName,
110                        @Param("highThreshold") Date theHighThreshold,
111                        @Param("partitionId") List<Integer> thePartitionIds,
112                        Pageable thePageable);
113}