001/*-
002 * #%L
003 * HAPI FHIR Server - SQL Migration
004 * %%
005 * Copyright (C) 2014 - 2023 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 ca.uhn.fhir.i18n.Msg;
023import ca.uhn.fhir.jpa.migrate.JdbcUtils;
024import org.apache.commons.lang3.Validate;
025import org.apache.commons.lang3.builder.EqualsBuilder;
026import org.apache.commons.lang3.builder.HashCodeBuilder;
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029
030import java.sql.SQLException;
031import java.util.Set;
032import java.util.stream.Collectors;
033
034import static org.apache.commons.lang3.StringUtils.isNotBlank;
035
036public class AddIdGeneratorTask extends BaseTask {
037
038        private static final Logger ourLog = LoggerFactory.getLogger(AddIdGeneratorTask.class);
039        private final String myGeneratorName;
040
041        public AddIdGeneratorTask(String theProductVersion, String theSchemaVersion, String theGeneratorName) {
042                super(theProductVersion, theSchemaVersion);
043                myGeneratorName = theGeneratorName;
044        }
045
046        @Override
047        public void validate() {
048                Validate.notBlank(myGeneratorName);
049                setDescription("Add id generator " + myGeneratorName);
050        }
051
052        @Override
053        public void doExecute() throws SQLException {
054                Set<String> tableNames = JdbcUtils.getTableNames(getConnectionProperties());
055                String sql = null;
056
057                switch (getDriverType()) {
058                        case MARIADB_10_1:
059                        case MYSQL_5_7:
060                                // These require a separate table
061                                if (!tableNames.contains(myGeneratorName)) {
062
063                                        String creationSql = "create table " + myGeneratorName + " ( next_val bigint ) engine=InnoDB";
064                                        executeSql(myGeneratorName, creationSql);
065
066                                        String initSql = "insert into " + myGeneratorName + " values ( 1 )";
067                                        executeSql(myGeneratorName, initSql);
068                                }
069                                break;
070                        case DERBY_EMBEDDED:
071                        case H2_EMBEDDED:
072                                sql = "create sequence " + myGeneratorName + " start with 1 increment by 50";
073                                break;
074                        case COCKROACHDB_21_1:
075                        case POSTGRES_9_4:
076                                sql = "create sequence " + myGeneratorName + " start 1 increment 50";
077                                break;
078                        case ORACLE_12C:
079                                sql = "create sequence " + myGeneratorName + " start with 1 increment by 50";
080                                break;
081                        case MSSQL_2012:
082                                sql = "create sequence " + myGeneratorName + " start with 1 increment by 50";
083                                break;
084                        default:
085                                throw new IllegalStateException(Msg.code(63));
086                }
087
088                if (isNotBlank(sql)) {
089                        Set<String> sequenceNames = JdbcUtils.getSequenceNames(getConnectionProperties()).stream()
090                                        .map(String::toLowerCase)
091                                        .collect(Collectors.toSet());
092                        ourLog.debug("Currently have sequences: {}", sequenceNames);
093                        if (sequenceNames.contains(myGeneratorName.toLowerCase())) {
094                                logInfo(ourLog, "Sequence {} already exists - No action performed", myGeneratorName);
095                                return;
096                        }
097
098                        executeSql(myGeneratorName, sql);
099                }
100        }
101
102        @Override
103        protected void generateEquals(EqualsBuilder theBuilder, BaseTask theOtherObject) {
104                AddIdGeneratorTask otherObject = (AddIdGeneratorTask) theOtherObject;
105                theBuilder.append(myGeneratorName, otherObject.myGeneratorName);
106        }
107
108        @Override
109        protected void generateHashCode(HashCodeBuilder theBuilder) {
110                theBuilder.append(myGeneratorName);
111        }
112}