001/*-
002 * #%L
003 * HAPI FHIR Server - SQL Migration
004 * %%
005 * Copyright (C) 2014 - 2025 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.migrate.taskdef;
021
022import jakarta.annotation.Nonnull;
023import jakarta.annotation.Nullable;
024import org.apache.commons.lang3.Validate;
025import org.apache.commons.lang3.builder.EqualsBuilder;
026import org.apache.commons.lang3.builder.HashCodeBuilder;
027
028import java.util.Optional;
029import java.util.Set;
030import java.util.function.Function;
031
032public abstract class BaseTableColumnTypeTask extends BaseTableColumnTask {
033        private ColumnTypeEnum myColumnType;
034        private Boolean myNullable;
035        private Long myColumnLength;
036
037        @Nullable
038        private Object myDefaultValue;
039
040        /**
041         * Constructor
042         */
043        public BaseTableColumnTypeTask(String theProductVersion, String theSchemaVersion) {
044                super(theProductVersion, theSchemaVersion);
045        }
046
047        BaseTableColumnTypeTask(
048                        String theProductVersion,
049                        String theSchemaVersion,
050                        ColumnNameCase theColumnNameCase,
051                        Set<ColumnDriverMappingOverride> theColumnDriverMappingOverrides) {
052                super(theProductVersion, theSchemaVersion, theColumnNameCase, theColumnDriverMappingOverrides);
053        }
054
055        public ColumnTypeEnum getColumnType() {
056                return myColumnType;
057        }
058
059        public BaseTableColumnTask setColumnType(ColumnTypeEnum theColumnType) {
060                myColumnType = theColumnType;
061                return this;
062        }
063
064        @Override
065        public void validate() {
066                super.validate();
067                Validate.notNull(myColumnType, "myColumnType must not be null");
068                Validate.notNull(myNullable, "myNullable must not be null");
069
070                if (myColumnType == ColumnTypeEnum.STRING) {
071                        Validate.notNull(
072                                        myColumnLength, "No length specified for " + ColumnTypeEnum.STRING + " column " + getColumnName());
073                } else {
074                        Validate.isTrue(myColumnLength == null);
075                }
076        }
077
078        protected String getSqlType() {
079                return getSqlType(getColumnLength());
080        }
081
082        protected String getSqlType(Long theColumnLength) {
083                return getSqlType(myColumnType, theColumnLength);
084        }
085
086        public boolean isNullable() {
087                return myNullable;
088        }
089
090        public BaseTableColumnTask setNullable(boolean theNullable) {
091                myNullable = theNullable;
092                return this;
093        }
094
095        protected String getSqlNotNull() {
096                return isNullable() ? " null " : " not null";
097        }
098
099        public Long getColumnLength() {
100                return myColumnLength;
101        }
102
103        public BaseTableColumnTypeTask setColumnLength(long theColumnLength) {
104                myColumnLength = theColumnLength;
105                return this;
106        }
107
108        @Nullable
109        public Object getDefaultValue() {
110                return myDefaultValue;
111        }
112
113        @Nonnull
114        String buildString(@Nullable Object theValue, Function<Object, String> doIfNull, String theDefaultResult) {
115                return Optional.ofNullable(theValue).map(doIfNull).orElse(theDefaultResult);
116        }
117
118        public BaseTableColumnTypeTask setDefaultValue(Object theDefaultValue) {
119                myDefaultValue = theDefaultValue;
120                return this;
121        }
122
123        @Override
124        protected void generateHashCode(HashCodeBuilder theBuilder) {
125                super.generateHashCode(theBuilder);
126                theBuilder.append(getColumnTypeName(myColumnType));
127                theBuilder.append(myNullable);
128                theBuilder.append(myColumnLength);
129        }
130
131        @Override
132        protected void generateEquals(EqualsBuilder theBuilder, BaseTask theOtherObject) {
133                BaseTableColumnTypeTask otherObject = (BaseTableColumnTypeTask) theOtherObject;
134                super.generateEquals(theBuilder, otherObject);
135                theBuilder.append(getColumnTypeName(myColumnType), getColumnTypeName(otherObject.myColumnType));
136                theBuilder.append(myNullable, otherObject.myNullable);
137                theBuilder.append(myColumnLength, otherObject.myColumnLength);
138        }
139
140        @Nullable
141        private Object getColumnTypeName(ColumnTypeEnum theColumnType) {
142                if (theColumnType == null) {
143                        return null;
144                }
145                return myColumnType.name();
146        }
147}