001package ca.uhn.fhir.jpa.api.dao;
002
003/*
004 * #%L
005 * HAPI FHIR Storage api
006 * %%
007 * Copyright (C) 2014 - 2022 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 * http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.i18n.Msg;
024import ca.uhn.fhir.context.RuntimeResourceDefinition;
025import ca.uhn.fhir.jpa.api.model.DaoMethodOutcome;
026import ca.uhn.fhir.jpa.api.model.DeleteConflictList;
027import ca.uhn.fhir.jpa.api.model.DeleteMethodOutcome;
028import ca.uhn.fhir.jpa.api.model.ExpungeOptions;
029import ca.uhn.fhir.jpa.api.model.ExpungeOutcome;
030import ca.uhn.fhir.jpa.model.entity.BaseHasResource;
031import ca.uhn.fhir.jpa.model.entity.ResourceTable;
032import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
033import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
034import ca.uhn.fhir.model.api.IQueryParameterType;
035import ca.uhn.fhir.rest.api.EncodingEnum;
036import ca.uhn.fhir.rest.api.MethodOutcome;
037import ca.uhn.fhir.rest.api.PatchTypeEnum;
038import ca.uhn.fhir.rest.api.ValidationModeEnum;
039import ca.uhn.fhir.rest.api.server.IBundleProvider;
040import ca.uhn.fhir.rest.api.server.RequestDetails;
041import ca.uhn.fhir.rest.api.server.storage.ResourcePersistentId;
042import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
043import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
044import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
045import org.hl7.fhir.instance.model.api.IBaseMetaType;
046import org.hl7.fhir.instance.model.api.IBaseParameters;
047import org.hl7.fhir.instance.model.api.IBaseResource;
048import org.hl7.fhir.instance.model.api.IIdType;
049
050import javax.annotation.Nonnull;
051import javax.annotation.Nullable;
052import javax.servlet.http.HttpServletResponse;
053import java.util.Collection;
054import java.util.Date;
055import java.util.List;
056import java.util.Map;
057import java.util.Set;
058
059/**
060 * Note that this interface is not considered a stable interface. While it is possible to build applications
061 * that use it directly, please be aware that we may modify methods, add methods, or even remove methods from
062 * time to time, even within minor point releases.
063 */
064public interface IFhirResourceDao<T extends IBaseResource> extends IDao {
065
066        /**
067         * Create a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
068         * therefore can not fire any interceptors. Use only for internal system calls
069         */
070        DaoMethodOutcome create(T theResource);
071
072        DaoMethodOutcome create(T theResource, RequestDetails theRequestDetails);
073
074        /**
075         * Create a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
076         * therefore can not fire any interceptors. Use only for internal system calls
077         */
078        DaoMethodOutcome create(T theResource, String theIfNoneExist);
079
080        /**
081         * @param thePerformIndexing Use with caution! If you set this to false, you need to manually perform indexing or your resources
082         *                           won't be indexed and searches won't work.
083         * @param theRequestDetails  TODO
084         */
085        DaoMethodOutcome create(T theResource, String theIfNoneExist, boolean thePerformIndexing, @Nonnull TransactionDetails theTransactionDetails, RequestDetails theRequestDetails);
086
087        DaoMethodOutcome create(T theResource, String theIfNoneExist, RequestDetails theRequestDetails);
088
089        /**
090         * Delete a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
091         * therefore can not fire any interceptors. Use only for internal system calls
092         */
093        DaoMethodOutcome delete(IIdType theResource);
094
095        /**
096         * This method does not throw an exception if there are delete conflicts, but populates them
097         * in the provided list
098         */
099        DaoMethodOutcome delete(IIdType theResource, DeleteConflictList theDeleteConflictsListToPopulate, RequestDetails theRequestDetails, @Nonnull TransactionDetails theTransactionDetails);
100
101        /**
102         * This method throws an exception if there are delete conflicts
103         */
104        DaoMethodOutcome delete(IIdType theResource, RequestDetails theRequestDetails);
105
106        /**
107         * This method does not throw an exception if there are delete conflicts, but populates them
108         * in the provided list
109         */
110        DeleteMethodOutcome deleteByUrl(String theUrl, DeleteConflictList theDeleteConflictsListToPopulate, RequestDetails theRequestDetails);
111
112        /**
113         * This method throws an exception if there are delete conflicts
114         */
115        DeleteMethodOutcome deleteByUrl(String theString, RequestDetails theRequestDetails);
116
117        ExpungeOutcome expunge(ExpungeOptions theExpungeOptions, RequestDetails theRequestDetails);
118
119        ExpungeOutcome expunge(IIdType theIIdType, ExpungeOptions theExpungeOptions, RequestDetails theRequest);
120
121        ExpungeOutcome forceExpungeInExistingTransaction(IIdType theId, ExpungeOptions theExpungeOptions, RequestDetails theRequest);
122
123        Class<T> getResourceType();
124
125        IBundleProvider history(Date theSince, Date theUntil, Integer theOffset, RequestDetails theRequestDetails);
126
127        IBundleProvider history(IIdType theId, Date theSince, Date theUntil, Integer theOffset, RequestDetails theRequestDetails);
128
129        /**
130         * Not supported in DSTU1!
131         *
132         * @param theRequestDetails TODO
133         */
134        <MT extends IBaseMetaType> MT metaAddOperation(IIdType theId1, MT theMetaAdd, RequestDetails theRequestDetails);
135
136        /**
137         * Not supported in DSTU1!
138         *
139         * @param theRequestDetails TODO
140         */
141        <MT extends IBaseMetaType> MT metaDeleteOperation(IIdType theId1, MT theMetaDel, RequestDetails theRequestDetails);
142
143        /**
144         * Not supported in DSTU1!
145         *
146         * @param theRequestDetails TODO
147         */
148        <MT extends IBaseMetaType> MT metaGetOperation(Class<MT> theType, IIdType theId, RequestDetails theRequestDetails);
149
150        /**
151         * Not supported in DSTU1!
152         *
153         * @param theRequestDetails TODO
154         */
155        <MT extends IBaseMetaType> MT metaGetOperation(Class<MT> theType, RequestDetails theRequestDetails);
156
157        DaoMethodOutcome patch(IIdType theId, String theConditionalUrl, PatchTypeEnum thePatchType, String thePatchBody, IBaseParameters theFhirPatchBody, RequestDetails theRequestDetails);
158
159        /**
160         * Read a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
161         * therefore can not fire any interceptors. Use only for internal system calls
162         */
163        T read(IIdType theId);
164
165        /**
166         * Read a resource by its internal PID
167         */
168        T readByPid(ResourcePersistentId thePid);
169
170        /**
171         * Read a resource by its internal PID
172         */
173        default T readByPid(ResourcePersistentId thePid, boolean theDeletedOk) {
174                throw new UnsupportedOperationException(Msg.code(571));
175        }
176
177        /**
178         * @param theRequestDetails TODO
179         * @throws ResourceNotFoundException If the ID is not known to the server
180         */
181        T read(IIdType theId, RequestDetails theRequestDetails);
182
183        /**
184         * Should deleted resources be returned successfully. This should be false for
185         * a normal FHIR read.
186         */
187        T read(IIdType theId, RequestDetails theRequestDetails, boolean theDeletedOk);
188
189        BaseHasResource readEntity(IIdType theId, RequestDetails theRequest);
190
191        /**
192         * @param theCheckForForcedId If true, this method should fail if the requested ID contains a numeric PID which exists, but is
193         *                            obscured by a "forced ID" so should not exist as far as the outside world is concerned.
194         */
195        BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId, RequestDetails theRequest);
196
197        /**
198         * Updates index tables associated with the given resource. Does not create a new
199         * version or update the resource's update time.
200         */
201        void reindex(T theResource, ResourceTable theEntity);
202
203        void removeTag(IIdType theId, TagTypeEnum theTagType, String theSystem, String theCode, RequestDetails theRequestDetails);
204
205        void removeTag(IIdType theId, TagTypeEnum theTagType, String theSystem, String theCode);
206
207        IBundleProvider search(SearchParameterMap theParams);
208
209        IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails);
210
211        IBundleProvider search(SearchParameterMap theParams, RequestDetails theRequestDetails, HttpServletResponse theServletResponse);
212
213        /**
214         * Search for IDs for processing a match URLs, etc.
215         */
216        default List<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest) {
217                return searchForIds(theParams, theRequest, null);
218        }
219
220        /**
221         * Search for IDs for processing a match URLs, etc.
222         *
223         * @param theConditionalOperationTargetOrNull If we're searching for IDs in order to satisfy a conditional
224         *                                            create/update, this is the resource being searched for
225         * @since 5.5.0
226         */
227        default List<ResourcePersistentId> searchForIds(SearchParameterMap theParams, RequestDetails theRequest, @Nullable IBaseResource theConditionalOperationTargetOrNull) {
228                return searchForIds(theParams, theRequest);
229        }
230
231
232        /**
233         * Takes a map of incoming raw search parameters and translates/parses them into
234         * appropriate {@link IQueryParameterType} instances of the appropriate type
235         * for the given param
236         *
237         * @throws InvalidRequestException If any of the parameters are not known
238         */
239        void translateRawParameters(Map<String, List<String>> theSource, SearchParameterMap theTarget);
240
241        /**
242         * Update a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
243         * therefore can not fire any interceptors. Use only for internal system calls
244         */
245        DaoMethodOutcome update(T theResource);
246
247        DaoMethodOutcome update(T theResource, RequestDetails theRequestDetails);
248
249        /**
250         * Update a resource - Note that this variant of the method does not take in a {@link RequestDetails} and
251         * therefore can not fire any interceptors. Use only for internal system calls
252         */
253        DaoMethodOutcome update(T theResource, String theMatchUrl);
254
255        /**
256         * @param thePerformIndexing Use with caution! If you set this to false, you need to manually perform indexing or your resources
257         *                           won't be indexed and searches won't work.
258         * @param theRequestDetails  TODO
259         */
260        DaoMethodOutcome update(T theResource, String theMatchUrl, boolean thePerformIndexing, RequestDetails theRequestDetails);
261
262        DaoMethodOutcome update(T theResource, String theMatchUrl, RequestDetails theRequestDetails);
263
264        /**
265         * @param theForceUpdateVersion Create a new version with the same contents as the current version even if the content hasn't changed (this is mostly useful for
266         *                              resources mapping to external content such as external code systems)
267         */
268        DaoMethodOutcome update(T theResource, String theMatchUrl, boolean thePerformIndexing, boolean theForceUpdateVersion, RequestDetails theRequestDetails, @Nonnull TransactionDetails theTransactionDetails);
269
270        /**
271         * Not supported in DSTU1!
272         *
273         * @param theRequestDetails TODO
274         */
275        MethodOutcome validate(T theResource, IIdType theId, String theRawResource, EncodingEnum theEncoding, ValidationModeEnum theMode, String theProfile, RequestDetails theRequestDetails);
276
277        RuntimeResourceDefinition validateCriteriaAndReturnResourceDefinition(String criteria);
278
279        /**
280         * Delete a list of resource Pids
281         *
282         * @param theUrl             the original URL that triggered the delete
283         * @param theResourceIds     the ids of the resources to be deleted
284         * @param theDeleteConflicts out parameter of conflicts preventing deletion
285         * @param theRequest         the request that initiated the request
286         * @return response back to the client
287         */
288        DeleteMethodOutcome deletePidList(String theUrl, Collection<ResourcePersistentId> theResourceIds, DeleteConflictList theDeleteConflicts, RequestDetails theRequest);
289
290        /**
291         * Returns the current version ID for the given resource
292         */
293        default String getCurrentVersionId(IIdType theReferenceElement) {
294                return read(theReferenceElement.toVersionless()).getIdElement().getVersionIdPart();
295        }
296
297        /**
298         * Reindex the given resource
299         *
300         * @param theResourcePersistentId The ID
301         */
302        void reindex(ResourcePersistentId theResourcePersistentId, RequestDetails theRequest, TransactionDetails theTransactionDetails);
303}