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;
021
022import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable;
023import org.springframework.data.domain.Pageable;
024import org.springframework.data.domain.Slice;
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;
031
032public interface IResourceHistoryTableDao extends JpaRepository<ResourceHistoryTable, Long>, IHapiFhirJpaRepository {
033
034        /**
035         * This is really only intended for unit tests - There can be many versions of resources in
036         * the real world, use a pageable query for real uses.
037         */
038        @Query("SELECT t FROM ResourceHistoryTable t WHERE t.myResourceId = :resId ORDER BY t.myResourceVersion ASC")
039        List<ResourceHistoryTable> findAllVersionsForResourceIdInOrder(@Param("resId") Long theId);
040
041        @Query(
042                        "SELECT t FROM ResourceHistoryTable t LEFT OUTER JOIN FETCH t.myProvenance WHERE t.myResourceId = :id AND t.myResourceVersion = :version")
043        ResourceHistoryTable findForIdAndVersionAndFetchProvenance(
044                        @Param("id") long theId, @Param("version") long theVersion);
045
046        @Query(
047                        "SELECT t.myId FROM ResourceHistoryTable t WHERE t.myResourceId = :resId AND t.myResourceVersion <> :dontWantVersion")
048        Slice<Long> findForResourceId(
049                        Pageable thePage, @Param("resId") Long theId, @Param("dontWantVersion") Long theDontWantVersion);
050
051        @Query(
052                        "SELECT t FROM ResourceHistoryTable t LEFT OUTER JOIN FETCH t.myProvenance WHERE t.myResourceId = :resId AND t.myResourceVersion <> :dontWantVersion")
053        Slice<ResourceHistoryTable> findForResourceIdAndReturnEntitiesAndFetchProvenance(
054                        Pageable thePage, @Param("resId") Long theId, @Param("dontWantVersion") Long theDontWantVersion);
055
056        @Query("" + "SELECT v.myId FROM ResourceHistoryTable v "
057                        + "LEFT OUTER JOIN ResourceTable t ON (v.myResourceId = t.myId) "
058                        + "WHERE v.myResourceVersion <> t.myVersion AND "
059                        + "t.myId = :resId")
060        Slice<Long> findIdsOfPreviousVersionsOfResourceId(Pageable thePage, @Param("resId") Long theResourceId);
061
062        @Query("" + "SELECT v.myId FROM ResourceHistoryTable v "
063                        + "LEFT OUTER JOIN ResourceTable t ON (v.myResourceId = t.myId) "
064                        + "WHERE v.myResourceVersion <> t.myVersion AND "
065                        + "t.myResourceType = :restype")
066        Slice<Long> findIdsOfPreviousVersionsOfResources(Pageable thePage, @Param("restype") String theResourceName);
067
068        @Query("" + "SELECT v.myId FROM ResourceHistoryTable v "
069                        + "LEFT OUTER JOIN ResourceTable t ON (v.myResourceId = t.myId) "
070                        + "WHERE v.myResourceVersion <> t.myVersion")
071        Slice<Long> findIdsOfPreviousVersionsOfResources(Pageable thePage);
072
073        @Modifying
074        @Query(
075                        "UPDATE ResourceHistoryTable r SET r.myResourceVersion = :newVersion WHERE r.myResourceId = :id AND r.myResourceVersion = :oldVersion")
076        void updateVersion(
077                        @Param("id") long theId, @Param("oldVersion") long theOldVersion, @Param("newVersion") long theNewVersion);
078
079        @Modifying
080        @Query("DELETE FROM ResourceHistoryTable t WHERE t.myId = :pid")
081        void deleteByPid(@Param("pid") Long theId);
082
083        /**
084         * This method is only for use in unit tests - It is used to move the stored resource body contents from the new
085         * <code>RES_TEXT_VC</code> column to the legacy <code>RES_TEXT</code> column, which is where data may have
086         * been stored by versions of HAPI FHIR prior to 7.0.0
087         *
088         * @since 7.0.0
089         */
090        @Modifying
091        @Query(
092                        "UPDATE ResourceHistoryTable r SET r.myResourceTextVc = null, r.myResource = :text, r.myEncoding = 'JSONC' WHERE r.myId = :pid")
093        void updateNonInlinedContents(@Param("text") byte[] theText, @Param("pid") long thePid);
094}