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