001/*-
002 * #%L
003 * HAPI FHIR JPA Model
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.model.entity;
021
022import ca.uhn.fhir.interceptor.model.RequestPartitionId;
023import ca.uhn.fhir.jpa.model.config.PartitionSettings;
024import jakarta.persistence.Column;
025import jakarta.persistence.Entity;
026import jakarta.persistence.ForeignKey;
027import jakarta.persistence.GeneratedValue;
028import jakarta.persistence.GenerationType;
029import jakarta.persistence.Id;
030import jakarta.persistence.Index;
031import jakarta.persistence.JoinColumn;
032import jakarta.persistence.ManyToOne;
033import jakarta.persistence.SequenceGenerator;
034import jakarta.persistence.Table;
035import jakarta.persistence.Transient;
036import org.apache.commons.lang3.builder.CompareToBuilder;
037import org.apache.commons.lang3.builder.EqualsBuilder;
038import org.apache.commons.lang3.builder.HashCodeBuilder;
039import org.apache.commons.lang3.builder.ToStringBuilder;
040import org.hl7.fhir.instance.model.api.IIdType;
041
042import static ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam.hash;
043
044@Entity
045@Table(
046                name = "HFJ_IDX_CMB_TOK_NU",
047                indexes = {
048                        @Index(name = "IDX_IDXCMBTOKNU_STR", columnList = "IDX_STRING", unique = false),
049                        @Index(name = "IDX_IDXCMBTOKNU_RES", columnList = "RES_ID", unique = false)
050                })
051public class ResourceIndexedComboTokenNonUnique extends BaseResourceIndex
052                implements Comparable<ResourceIndexedComboTokenNonUnique>, IResourceIndexComboSearchParameter {
053
054        @SequenceGenerator(name = "SEQ_IDXCMBTOKNU_ID", sequenceName = "SEQ_IDXCMBTOKNU_ID")
055        @GeneratedValue(strategy = GenerationType.AUTO, generator = "SEQ_IDXCMBTOKNU_ID")
056        @Id
057        @Column(name = "PID")
058        private Long myId;
059
060        @ManyToOne
061        @JoinColumn(
062                        name = "RES_ID",
063                        referencedColumnName = "RES_ID",
064                        foreignKey = @ForeignKey(name = "FK_IDXCMBTOKNU_RES_ID"))
065        private ResourceTable myResource;
066
067        @Column(name = "RES_ID", insertable = false, updatable = false)
068        private Long myResourceId;
069
070        @Column(name = "HASH_COMPLETE", nullable = false)
071        private Long myHashComplete;
072
073        @Column(name = "IDX_STRING", nullable = false, length = ResourceIndexedComboStringUnique.MAX_STRING_LENGTH)
074        private String myIndexString;
075
076        @Transient
077        private transient PartitionSettings myPartitionSettings;
078
079        @Transient
080        private IIdType mySearchParameterId;
081
082        /**
083         * Constructor
084         */
085        public ResourceIndexedComboTokenNonUnique() {
086                super();
087        }
088
089        public ResourceIndexedComboTokenNonUnique(
090                        PartitionSettings thePartitionSettings, ResourceTable theEntity, String theQueryString) {
091                myPartitionSettings = thePartitionSettings;
092                myResource = theEntity;
093                myIndexString = theQueryString;
094                calculateHashes();
095        }
096
097        @Override
098        public String getIndexString() {
099                return myIndexString;
100        }
101
102        public void setIndexString(String theIndexString) {
103                myIndexString = theIndexString;
104        }
105
106        @Override
107        public boolean equals(Object theO) {
108                if (this == theO) {
109                        return true;
110                }
111
112                if (theO == null || getClass() != theO.getClass()) {
113                        return false;
114                }
115
116                ResourceIndexedComboTokenNonUnique that = (ResourceIndexedComboTokenNonUnique) theO;
117
118                EqualsBuilder b = new EqualsBuilder();
119                b.append(myIndexString, that.myIndexString);
120                return b.isEquals();
121        }
122
123        @Override
124        public <T extends BaseResourceIndex> void copyMutableValuesFrom(T theSource) {
125                ResourceIndexedComboTokenNonUnique source = (ResourceIndexedComboTokenNonUnique) theSource;
126                myPartitionSettings = source.myPartitionSettings;
127                myHashComplete = source.myHashComplete;
128                myIndexString = source.myIndexString;
129        }
130
131        @Override
132        public Long getId() {
133                return myId;
134        }
135
136        @Override
137        public void setId(Long theId) {
138                myId = theId;
139        }
140
141        @Override
142        public void clearHashes() {
143                myHashComplete = null;
144        }
145
146        @Override
147        public void calculateHashes() {
148                if (myHashComplete != null) {
149                        return;
150                }
151
152                PartitionSettings partitionSettings = getPartitionSettings();
153                PartitionablePartitionId partitionId = getPartitionId();
154                String queryString = myIndexString;
155                setHashComplete(calculateHashComplete(partitionSettings, partitionId, queryString));
156        }
157
158        @Override
159        public int hashCode() {
160                return new HashCodeBuilder(17, 37).append(myIndexString).toHashCode();
161        }
162
163        public PartitionSettings getPartitionSettings() {
164                return myPartitionSettings;
165        }
166
167        public void setPartitionSettings(PartitionSettings thePartitionSettings) {
168                myPartitionSettings = thePartitionSettings;
169        }
170
171        @Override
172        public ResourceTable getResource() {
173                return myResource;
174        }
175
176        @Override
177        public void setResource(ResourceTable theResource) {
178                myResource = theResource;
179        }
180
181        public Long getHashComplete() {
182                return myHashComplete;
183        }
184
185        public void setHashComplete(Long theHashComplete) {
186                myHashComplete = theHashComplete;
187        }
188
189        @Override
190        public int compareTo(ResourceIndexedComboTokenNonUnique theO) {
191                CompareToBuilder b = new CompareToBuilder();
192                b.append(myHashComplete, theO.getHashComplete());
193                return b.toComparison();
194        }
195
196        @Override
197        public String toString() {
198                return new ToStringBuilder(this)
199                                .append("id", myId)
200                                .append("resourceId", myResourceId)
201                                .append("hashComplete", myHashComplete)
202                                .append("indexString", myIndexString)
203                                .toString();
204        }
205
206        public static long calculateHashComplete(
207                        PartitionSettings partitionSettings, PartitionablePartitionId thePartitionId, String queryString) {
208                RequestPartitionId requestPartitionId = PartitionablePartitionId.toRequestPartitionId(thePartitionId);
209                return hash(partitionSettings, requestPartitionId, queryString);
210        }
211
212        public static long calculateHashComplete(
213                        PartitionSettings partitionSettings, RequestPartitionId partitionId, String queryString) {
214                return hash(partitionSettings, partitionId, queryString);
215        }
216
217        /**
218         * Note: This field is not persisted, so it will only be populated for new indexes
219         */
220        @Override
221        public void setSearchParameterId(IIdType theSearchParameterId) {
222                mySearchParameterId = theSearchParameterId;
223        }
224
225        /**
226         * Note: This field is not persisted, so it will only be populated for new indexes
227         */
228        @Override
229        public IIdType getSearchParameterId() {
230                return mySearchParameterId;
231        }
232}