001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2024 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.custom;
021
022import jakarta.persistence.EntityManager;
023import jakarta.persistence.PersistenceContext;
024import org.springframework.stereotype.Component;
025
026import java.util.Collection;
027import java.util.List;
028
029@Component
030/**
031 * Custom query implementations.
032 * Don't change the name of this class.  Spring Data requires the name to match.
033 * https://stackoverflow.com/questions/11880924/how-to-add-custom-method-to-spring-data-jpa
034 */
035public class IResourceTableDaoImpl implements IForcedIdQueries {
036
037        @PersistenceContext
038        private EntityManager myEntityManager;
039
040        /**
041         * This method returns a Collection where each row is an element in the collection. Each element in the collection
042         * is an object array, where the order matters (the array represents columns returned by the query).
043         * Deleted resources are not filtered.
044         */
045        @Override
046        public Collection<Object[]> findAndResolveByForcedIdWithNoTypeIncludeDeleted(
047                        String theResourceType, Collection<String> theForcedIds) {
048                return findAndResolveByForcedIdWithNoType(theResourceType, theForcedIds, false);
049        }
050
051        /**
052         * This method returns a Collection where each row is an element in the collection. Each element in the collection
053         * is an object array, where the order matters (the array represents columns returned by the query).
054         * Deleted resources are optionally filtered. Be careful if you change this query in any way.
055         */
056        @Override
057        public Collection<Object[]> findAndResolveByForcedIdWithNoType(
058                        String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted) {
059                String query =
060                                "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
061                                                + "FROM ResourceTable t "
062                                                + "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id )";
063
064                if (theExcludeDeleted) {
065                        query += " AND t.myDeleted IS NULL";
066                }
067
068                return myEntityManager
069                                .createQuery(query)
070                                .setParameter("resource_type", theResourceType)
071                                .setParameter("forced_id", theForcedIds)
072                                .getResultList();
073        }
074
075        /**
076         * This method returns a Collection where each row is an element in the collection. Each element in the collection
077         * is an object array, where the order matters (the array represents columns returned by the query).
078         * Deleted resources are optionally filtered. Be careful if you change this query in any way.
079         */
080        @Override
081        public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartition(
082                        String theResourceType,
083                        Collection<String> theForcedIds,
084                        Collection<Integer> thePartitionId,
085                        boolean theExcludeDeleted) {
086                String query =
087                                "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
088                                                + "FROM ResourceTable t "
089                                                + "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND t.myPartitionIdValue IN ( :partition_id )";
090
091                if (theExcludeDeleted) {
092                        query += " AND t.myDeleted IS NULL";
093                }
094
095                return myEntityManager
096                                .createQuery(query)
097                                .setParameter("resource_type", theResourceType)
098                                .setParameter("forced_id", theForcedIds)
099                                .setParameter("partition_id", thePartitionId)
100                                .getResultList();
101        }
102
103        /**
104         * This method returns a Collection where each row is an element in the collection. Each element in the collection
105         * is an object array, where the order matters (the array represents columns returned by the query).
106         * Deleted resources are optionally filtered. Be careful if you change this query in any way.
107         */
108        @Override
109        public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionNull(
110                        String theResourceType, Collection<String> theForcedIds, boolean theExcludeDeleted) {
111                // we fetch myPartitionIdValue and myPartitionDateValue for resultSet processing consistency
112                String query =
113                                "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
114                                                + "FROM ResourceTable t "
115                                                + "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND t.myPartitionIdValue IS NULL";
116
117                if (theExcludeDeleted) {
118                        query += " AND t.myDeleted IS NULL";
119                }
120
121                return myEntityManager
122                                .createQuery(query)
123                                .setParameter("resource_type", theResourceType)
124                                .setParameter("forced_id", theForcedIds)
125                                .getResultList();
126        }
127
128        /**
129         * This method returns a Collection where each row is an element in the collection. Each element in the collection
130         * is an object array, where the order matters (the array represents columns returned by the query).
131         * Deleted resources are optionally filtered. Be careful if you change this query in any way.
132         */
133        @Override
134        public Collection<Object[]> findAndResolveByForcedIdWithNoTypeInPartitionIdOrNullPartitionId(
135                        String theResourceType,
136                        Collection<String> theForcedIds,
137                        List<Integer> thePartitionIdsWithoutDefault,
138                        boolean theExcludeDeleted) {
139                String query =
140                                "SELECT t.myResourceType, t.myId, t.myFhirId, t.myDeleted, t.myPartitionIdValue, t.myPartitionDateValue "
141                                                + "FROM ResourceTable t "
142                                                + "WHERE t.myResourceType = :resource_type AND t.myFhirId IN ( :forced_id ) AND (t.myPartitionIdValue IS NULL OR t.myPartitionIdValue IN ( :partition_id ))";
143
144                if (theExcludeDeleted) {
145                        query += " AND t.myDeleted IS NULL";
146                }
147
148                return myEntityManager
149                                .createQuery(query)
150                                .setParameter("resource_type", theResourceType)
151                                .setParameter("forced_id", theForcedIds)
152                                .setParameter("partition_id", thePartitionIdsWithoutDefault)
153                                .getResultList();
154        }
155}