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.entity; 021 022import ca.uhn.fhir.context.FhirVersionEnum; 023import ca.uhn.fhir.jpa.model.entity.IBaseResourceEntity; 024import ca.uhn.fhir.jpa.model.entity.PartitionablePartitionId; 025import ca.uhn.fhir.jpa.model.entity.ResourceEncodingEnum; 026import ca.uhn.fhir.jpa.model.entity.ResourceHistoryTable; 027import ca.uhn.fhir.jpa.model.entity.ResourceTable; 028import ca.uhn.fhir.model.primitive.IdDt; 029import ca.uhn.fhir.model.primitive.InstantDt; 030import ca.uhn.fhir.rest.api.Constants; 031import jakarta.annotation.Nullable; 032import jakarta.persistence.Column; 033import jakarta.persistence.Entity; 034import jakarta.persistence.EnumType; 035import jakarta.persistence.Enumerated; 036import jakarta.persistence.Id; 037import jakarta.persistence.Lob; 038import jakarta.persistence.Temporal; 039import jakarta.persistence.TemporalType; 040import org.hibernate.annotations.Immutable; 041import org.hibernate.annotations.Subselect; 042 043import java.io.Serializable; 044import java.util.Date; 045 046@SuppressWarnings("SqlDialectInspection") 047@Entity 048@Immutable 049// Ideally, all tables and columns should be in UPPERCASE if we ever choose to use a case-sensitive collation for MSSQL 050// and there's a risk that queries on lowercase database objects fail. 051@Subselect("SELECT h.PID as PID, " 052 + " r.RES_ID as RES_ID, " 053 + " h.RES_TYPE as RES_TYPE, " 054 + " h.RES_VERSION as RES_VERSION, " 055 // FHIR version 056 + " h.RES_VER as RES_VER, " 057 // resource version 058 + " h.HAS_TAGS as HAS_TAGS, " 059 + " h.RES_DELETED_AT as RES_DELETED_AT, " 060 + " h.RES_PUBLISHED as RES_PUBLISHED, " 061 + " h.RES_UPDATED as RES_UPDATED, " 062 + " h.RES_TEXT as RES_TEXT, " 063 + " h.RES_TEXT_VC as RES_TEXT_VC, " 064 + " h.RES_ENCODING as RES_ENCODING, " 065 + " h.PARTITION_ID as PARTITION_ID, " 066 + " p.SOURCE_URI as PROV_SOURCE_URI," 067 + " p.REQUEST_ID as PROV_REQUEST_ID," 068 + " r.FHIR_ID as FHIR_ID " 069 + "FROM HFJ_RESOURCE r " 070 + " INNER JOIN HFJ_RES_VER h ON r.RES_ID = h.RES_ID and r.RES_VER = h.RES_VER" 071 + " LEFT OUTER JOIN HFJ_RES_VER_PROV p ON p.RES_VER_PID = h.PID ") 072public class ResourceSearchView implements IBaseResourceEntity, Serializable { 073 074 private static final long serialVersionUID = 1L; 075 076 @Id 077 @Column(name = "PID") 078 private Long myId; 079 080 @Column(name = "RES_ID") 081 private Long myResourceId; 082 083 @Column(name = "RES_TYPE", length = Constants.MAX_RESOURCE_NAME_LENGTH) 084 private String myResourceType; 085 086 @Column(name = "RES_VERSION") 087 @Enumerated(EnumType.STRING) 088 private FhirVersionEnum myFhirVersion; 089 090 @Column(name = "RES_VER") 091 private Long myResourceVersion; 092 093 @Column(name = "PROV_REQUEST_ID", length = Constants.REQUEST_ID_LENGTH) 094 private String myProvenanceRequestId; 095 096 @Column(name = "PROV_SOURCE_URI", length = ResourceHistoryTable.SOURCE_URI_LENGTH) 097 private String myProvenanceSourceUri; 098 099 @Column(name = "HAS_TAGS") 100 private boolean myHasTags; 101 102 @Column(name = "RES_DELETED_AT") 103 @Temporal(TemporalType.TIMESTAMP) 104 private Date myDeleted; 105 106 @Temporal(TemporalType.TIMESTAMP) 107 @Column(name = "RES_PUBLISHED") 108 private Date myPublished; 109 110 @Temporal(TemporalType.TIMESTAMP) 111 @Column(name = "RES_UPDATED") 112 private Date myUpdated; 113 114 @Column(name = "RES_TEXT") 115 @Lob() 116 private byte[] myResource; 117 118 @Column(name = "RES_TEXT_VC") 119 private String myResourceTextVc; 120 121 @Column(name = "RES_ENCODING") 122 @Enumerated(EnumType.STRING) 123 private ResourceEncodingEnum myEncoding; 124 125 @Column(name = "FHIR_ID", length = ResourceTable.MAX_FORCED_ID_LENGTH) 126 private String myFhirId; 127 128 @Column(name = "PARTITION_ID") 129 private Integer myPartitionId; 130 131 public ResourceSearchView() { 132 // public constructor for Hibernate 133 } 134 135 public String getResourceTextVc() { 136 return myResourceTextVc; 137 } 138 139 public String getProvenanceRequestId() { 140 return myProvenanceRequestId; 141 } 142 143 public String getProvenanceSourceUri() { 144 return myProvenanceSourceUri; 145 } 146 147 @Override 148 public Date getDeleted() { 149 return myDeleted; 150 } 151 152 public void setDeleted(Date theDate) { 153 myDeleted = theDate; 154 } 155 156 @Override 157 public FhirVersionEnum getFhirVersion() { 158 return myFhirVersion; 159 } 160 161 public void setFhirVersion(FhirVersionEnum theFhirVersion) { 162 myFhirVersion = theFhirVersion; 163 } 164 165 public String getFhirId() { 166 return myFhirId; 167 } 168 169 @Override 170 public Long getId() { 171 return myResourceId; 172 } 173 174 @Override 175 public IdDt getIdDt() { 176 if (myFhirId == null) { 177 Long id = myResourceId; 178 return new IdDt(myResourceType + '/' + id + '/' + Constants.PARAM_HISTORY + '/' + getVersion()); 179 } else { 180 return new IdDt(getResourceType() + '/' + getFhirId() + '/' + Constants.PARAM_HISTORY + '/' + getVersion()); 181 } 182 } 183 184 @Override 185 public InstantDt getPublished() { 186 if (myPublished != null) { 187 return new InstantDt(myPublished); 188 } else { 189 return null; 190 } 191 } 192 193 public void setPublished(Date thePublished) { 194 myPublished = thePublished; 195 } 196 197 @Override 198 public Long getResourceId() { 199 return myResourceId; 200 } 201 202 @Override 203 public String getResourceType() { 204 return myResourceType; 205 } 206 207 @Override 208 public InstantDt getUpdated() { 209 return new InstantDt(myUpdated); 210 } 211 212 @Override 213 public Date getUpdatedDate() { 214 return myUpdated; 215 } 216 217 @Override 218 public long getVersion() { 219 return myResourceVersion; 220 } 221 222 @Override 223 public boolean isHasTags() { 224 return myHasTags; 225 } 226 227 @Override 228 @Nullable 229 public PartitionablePartitionId getPartitionId() { 230 if (myPartitionId != null) { 231 return new PartitionablePartitionId(myPartitionId, null); 232 } else { 233 return null; 234 } 235 } 236 237 public byte[] getResource() { 238 return myResource; 239 } 240 241 public ResourceEncodingEnum getEncoding() { 242 return myEncoding; 243 } 244}