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.config;
021
022import ca.uhn.fhir.jpa.model.entity.StorageSettings;
023
024/**
025 * @since 5.0.0
026 */
027public class PartitionSettings {
028
029        private boolean myPartitioningEnabled = false;
030        private CrossPartitionReferenceMode myAllowReferencesAcrossPartitions = CrossPartitionReferenceMode.NOT_ALLOWED;
031        private boolean myIncludePartitionInSearchHashes = false;
032        private boolean myUnnamedPartitionMode;
033        private Integer myDefaultPartitionId;
034        private boolean myAlwaysOpenNewTransactionForDifferentPartition;
035        private boolean myConditionalCreateDuplicateIdentifiersEnabled = false;
036        private boolean myPartitionIdsInPrimaryKeys = false;
037
038        public PartitionSettings() {
039                super();
040        }
041
042        /**
043         * This flag activates partition IDs in PKs mode, which is newly introduced in HAPI FHIR 8.0.0.
044         * This mode causes partition IDs to be included in all primary keys, joins, and emitted
045         * SQL. It also affects the generated schema and migrations. This setting should not be changed
046         * after the database has been initialized, unless you have performed an appropriate migration.
047         *
048         * @since 8.0.0
049         */
050        public boolean isPartitionIdsInPrimaryKeys() {
051                return myPartitionIdsInPrimaryKeys;
052        }
053
054        /**
055         * This flag activates partition IDs in PKs mode, which is newly introduced in HAPI FHIR 8.0.0.
056         * This mode causes partition IDs to be included in all primary keys, joins, and emitted
057         * SQL. It also affects the generated schema and migrations. This setting should not be changed
058         * after the database has been initialized, unless you have performed an appropriate migration.
059         *
060         * @since 8.0.0
061         */
062        public void setPartitionIdsInPrimaryKeys(boolean thePartitionIdsInPrimaryKeys) {
063                myPartitionIdsInPrimaryKeys = thePartitionIdsInPrimaryKeys;
064        }
065
066        /**
067         * Should we always open a new database transaction if the partition context changes
068         *
069         * @since 6.6.0
070         */
071        public boolean isAlwaysOpenNewTransactionForDifferentPartition() {
072                return myAlwaysOpenNewTransactionForDifferentPartition;
073        }
074
075        /**
076         * Should we always open a new database transaction if the partition context changes
077         *
078         * @since 6.6.0
079         */
080        public void setAlwaysOpenNewTransactionForDifferentPartition(
081                        boolean theAlwaysOpenNewTransactionForDifferentPartition) {
082                myAlwaysOpenNewTransactionForDifferentPartition = theAlwaysOpenNewTransactionForDifferentPartition;
083        }
084
085        /**
086         * If set to <code>true</code> (default is <code>false</code>) the <code>PARTITION_ID</code> value will be factored into the
087         * hash values used in the <code>HFJ_SPIDX_xxx</code> tables, removing the need to explicitly add a selector
088         * on this column in queries. If set to <code>false</code>, an additional selector is used instead, which may perform
089         * better when using native database partitioning features.
090         * <p>
091         * This setting has no effect if partitioning is not enabled via {@link #isPartitioningEnabled()}.
092         * </p>
093         * <p>
094         * If {@link StorageSettings#isIndexStorageOptimized()} is enabled this setting should be set to <code>false</code>.
095         * </p>
096         */
097        public boolean isIncludePartitionInSearchHashes() {
098                return myIncludePartitionInSearchHashes;
099        }
100
101        /**
102         * If set to <code>true</code> (default is <code>false</code>) the <code>PARTITION_ID</code> value will be factored into the
103         * hash values used in the <code>HFJ_SPIDX_xxx</code> tables, removing the need to explicitly add a selector
104         * on this column in queries. If set to <code>false</code>, an additional selector is used instead, which may perform
105         * better when using native database partitioning features.
106         * <p>
107         * This setting has no effect if partitioning is not enabled via {@link #isPartitioningEnabled()}.
108         * </p>
109         * <p>
110         * If {@link StorageSettings#isIndexStorageOptimized()} is enabled this setting should be set to <code>false</code>.
111         * </p>
112         */
113        public PartitionSettings setIncludePartitionInSearchHashes(boolean theIncludePartitionInSearchHashes) {
114                myIncludePartitionInSearchHashes = theIncludePartitionInSearchHashes;
115                return this;
116        }
117
118        /**
119         * If enabled (default is <code>false</code>) the JPA server will support data partitioning
120         *
121         * @since 5.0.0
122         */
123        public boolean isPartitioningEnabled() {
124                return myPartitioningEnabled;
125        }
126
127        /**
128         * If enabled (default is <code>false</code>) the JPA server will support data partitioning
129         *
130         * @since 5.0.0
131         */
132        public void setPartitioningEnabled(boolean theMultiTenancyEnabled) {
133                myPartitioningEnabled = theMultiTenancyEnabled;
134        }
135
136        /**
137         * Should resources references be permitted to cross partition boundaries. Default is {@link CrossPartitionReferenceMode#NOT_ALLOWED}.
138         *
139         * @since 5.0.0
140         */
141        public CrossPartitionReferenceMode getAllowReferencesAcrossPartitions() {
142                return myAllowReferencesAcrossPartitions;
143        }
144
145        /**
146         * Should resources references be permitted to cross partition boundaries. Default is {@link CrossPartitionReferenceMode#NOT_ALLOWED}.
147         *
148         * @since 5.0.0
149         */
150        public void setAllowReferencesAcrossPartitions(CrossPartitionReferenceMode theAllowReferencesAcrossPartitions) {
151                myAllowReferencesAcrossPartitions = theAllowReferencesAcrossPartitions;
152        }
153
154        /**
155         * If set to <code>true</code> (default is <code>false</code>), partitions will be unnamed and all IDs from {@link Integer#MIN_VALUE} through
156         * {@link Integer#MAX_VALUE} will be allowed without needing to be created ahead of time.
157         *
158         * @since 5.5.0
159         */
160        public boolean isUnnamedPartitionMode() {
161                return myUnnamedPartitionMode;
162        }
163
164        /**
165         * If set to <code>true</code> (default is <code>false</code>), partitions will be unnamed and all IDs from {@link Integer#MIN_VALUE} through
166         * {@link Integer#MAX_VALUE} will be allowed without needing to be created ahead of time.
167         *
168         * @since 5.5.0
169         */
170        public void setUnnamedPartitionMode(boolean theUnnamedPartitionMode) {
171                myUnnamedPartitionMode = theUnnamedPartitionMode;
172        }
173
174        /**
175         * If set, the given ID will be used for the default partition. The default is
176         * <code>null</code> which will result in the use of a null value for default
177         * partition items.
178         *
179         * @since 5.5.0
180         */
181        public Integer getDefaultPartitionId() {
182                return myDefaultPartitionId;
183        }
184
185        /**
186         * If set, the given ID will be used for the default partition. The default is
187         * <code>null</code> which will result in the use of a null value for default
188         * partition items.
189         *
190         * @since 5.5.0
191         */
192        public void setDefaultPartitionId(Integer theDefaultPartitionId) {
193                myDefaultPartitionId = theDefaultPartitionId;
194        }
195
196        /**
197         * If enabled the JPA server will allow unqualified cross partition reference
198         */
199        public boolean isAllowUnqualifiedCrossPartitionReference() {
200                return myAllowReferencesAcrossPartitions.equals(
201                                PartitionSettings.CrossPartitionReferenceMode.ALLOWED_UNQUALIFIED);
202        }
203
204        public boolean isConditionalCreateDuplicateIdentifiersEnabled() {
205                return myConditionalCreateDuplicateIdentifiersEnabled;
206        }
207
208        public void setConditionalCreateDuplicateIdentifiersEnabled(
209                        boolean theConditionalCreateDuplicateIdentifiersEnabled) {
210                myConditionalCreateDuplicateIdentifiersEnabled = theConditionalCreateDuplicateIdentifiersEnabled;
211        }
212
213        public enum CrossPartitionReferenceMode {
214
215                /**
216                 * References between resources are not allowed to cross partition boundaries
217                 */
218                NOT_ALLOWED,
219
220                /**
221                 * References can cross partition boundaries, with an assumption that boundaries
222                 * will be managed by the database.
223                 */
224                ALLOWED_UNQUALIFIED,
225        }
226
227        public enum BlockPatientCompartmentUpdateMode {
228                /**
229                 * Resource updates which would change resource's patient compartment are blocked.
230                 */
231                ALWAYS,
232
233                /**
234                 * Resource updates which would change resource's patient compartment are blocked
235                 * when Partition Selection Mode is PATIENT_ID
236                 */
237                DEFAULT,
238
239                /**
240                 * Resource updates which would change resource's patient compartment are allowed.
241                 */
242                NEVER,
243        }
244}