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